Skip to content

Commit

Permalink
Merge pull request #1 from octera/feat/enableCI
Browse files Browse the repository at this point in the history
chore(ci) : enable CI
  • Loading branch information
octera authored Jul 30, 2024
2 parents ee3f833 + fa92aae commit 2209d5a
Show file tree
Hide file tree
Showing 68 changed files with 855 additions and 816 deletions.
13 changes: 13 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
- package-ecosystem: "gradle" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"
open-pull-requests-limit: 3
target-branch: "main"
46 changes: 46 additions & 0 deletions .github/workflows/develop-release-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Develop Release CI

on:
push:
branches:
- 'develop'
pull_request:
branches:
- 'master'
- 'release*'
- 'develop'

jobs:
test-and-build-android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: set up Ruby for fastlane
uses: ruby/setup-ruby@v1
with:
ruby-version: '2.6'
- name: set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '17'
- name: Configure Keystore
run: |
echo "$ANDROID_KEYSTORE_FILE" > keystore.jks.b64
base64 -d -i keystore.jks.b64 > app/keystore.jks
echo "storeFile=keystore.jks" >> keystore.properties
echo "keyAlias=$KEYSTORE_KEY_ALIAS" >> keystore.properties
echo "storePassword=$KEYSTORE_STORE_PASSWORD" >> keystore.properties
echo "keyPassword=$KEYSTORE_KEY_PASSWORD" >> keystore.properties
env:
ANDROID_KEYSTORE_FILE: ${{ secrets.ANDROID_KEYSTORE_FILE }}
KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }}
KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }}
KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }}
# Step 3: Check the code with ktlint, you can remove this job if you don't use ktlint
- name: Run Kotlin Linter
run: ./gradlew ktlintCheck

# Step 3: Check the code with Android linter
- name: Run Android Linter
run: ./gradlew lintDebug
47 changes: 47 additions & 0 deletions .github/workflows/master-release-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Master Release CI

on:
push:
branches:
- 'master'

jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: set up Ruby for fastlane
uses: ruby/setup-ruby@v1
with:
ruby-version: '2.6'
- name: set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '17'
- name: Configure Keystore
run: |
echo "$ANDROID_KEYSTORE_FILE" > keystore.jks.b64
base64 -d -i keystore.jks.b64 > app/keystore.jks
echo "storeFile=keystore.jks" >> keystore.properties
echo "keyAlias=$KEYSTORE_KEY_ALIAS" >> keystore.properties
echo "storePassword=$KEYSTORE_STORE_PASSWORD" >> keystore.properties
echo "keyPassword=$KEYSTORE_KEY_PASSWORD" >> keystore.properties
env:
ANDROID_KEYSTORE_FILE: ${{ secrets.ANDROID_KEYSTORE_FILE }}
KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }}
KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }}
KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }}
# Step 3: Check the code with ktlint, you can remove this job if you don't use ktlint
- name: Run Kotlin Linter
run: ./gradlew ktlintCheck

# Step 3: Check the code with Android linter
- name: Run Android Linter
run: ./gradlew lintDebug
- name: Create Google Play Config file
run: |
echo "$PLAY_CONFIG_JSON" > play_config.json.b64
base64 -d -i play_config.json.b64 > api-service-account.json
env:
PLAY_CONFIG_JSON: ${{ secrets.PLAY_CONFIG_JSON }}
38 changes: 22 additions & 16 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ plugins {
id("kotlin-kapt")
id("com.google.dagger.hilt.android")
id("kotlin-parcelize")
id("org.jlleitschuh.gradle.ktlint")
}

ktlint {
android.set(true)
outputColorName.set("RED")
ignoreFailures.set(true)
}

android {
Expand All @@ -28,7 +35,7 @@ android {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
"proguard-rules.pro",
)
}
}
Expand Down Expand Up @@ -68,40 +75,39 @@ dependencies {
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest) //Splash Api
debugImplementation(libs.androidx.ui.test.manifest) // Splash Api
implementation(libs.androidx.core.splashscreen)

//Compose Navigation
// Compose Navigation
implementation("androidx.navigation:navigation-compose:2.7.7")

//Dagger Hilt
// Dagger Hilt
implementation("com.google.dagger:hilt-android:2.51.1")
kapt("com.google.dagger:hilt-compiler:2.51.1")
implementation("androidx.hilt:hilt-navigation-compose:1.2.0")


//Retrofit
// Retrofit
implementation("com.squareup.retrofit2:retrofit:2.11.0")
implementation("com.squareup.retrofit2:converter-gson:2.11.0")

//Coil
// Coil
implementation("io.coil-kt:coil-compose:2.6.0")

//Datastore
implementation ("androidx.datastore:datastore-preferences:1.1.1")
// Datastore
implementation("androidx.datastore:datastore-preferences:1.1.1")

//Compose Foundation
implementation (libs.androidx.foundation)
// Compose Foundation
implementation(libs.androidx.foundation)

//Accompanist
implementation ("com.google.accompanist:accompanist-systemuicontroller:0.31.4-beta")
// Accompanist
implementation("com.google.accompanist:accompanist-systemuicontroller:0.31.4-beta")

//Paging 3
// Paging 3
implementation("androidx.paging:paging-runtime:3.3.0")
implementation("androidx.paging:paging-compose:3.3.0")

//Room
// Room
implementation("androidx.room:room-runtime:2.6.1")
kapt("androidx.room:room-compiler:2.6.1")
implementation("androidx.room:room-ktx:2.6.1")
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package info.octera.droidstorybox

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
Expand All @@ -21,4 +19,4 @@ class ExampleInstrumentedTest {
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.example.newsapp", appContext.packageName)
}
}
}
7 changes: 3 additions & 4 deletions app/src/main/java/info/octera/droidstorybox/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.material3.MaterialTheme
import androidx.compose.ui.Modifier
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import dagger.hilt.android.AndroidEntryPoint
import info.octera.droidstorybox.presentation.navgraph.NavGraph
import info.octera.droidstorybox.ui.theme.NewsAppTheme
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
Expand All @@ -22,17 +22,16 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
enableEdgeToEdge()


installSplashScreen().apply {
setKeepOnScreenCondition {
viewModel.splashCondition
}
}
actionBar?.hide();
actionBar?.hide()
setContent {
NewsAppTheme {
Box(
modifier = Modifier.background(MaterialTheme.colorScheme.background)
modifier = Modifier.background(MaterialTheme.colorScheme.background),
) {
val startDestination = viewModel.startDestination
NavGraph(startDestination = startDestination)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class MainApplication : Application() {
}
class MainApplication : Application()
41 changes: 21 additions & 20 deletions app/src/main/java/info/octera/droidstorybox/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,36 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import info.octera.droidstorybox.domain.usecases.app_entry.AppEntryUseCases
import info.octera.droidstorybox.presentation.navgraph.Route
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import javax.inject.Inject

@HiltViewModel
class MainViewModel @Inject constructor(
private val appEntryUseCases: AppEntryUseCases
) :
class MainViewModel
@Inject
constructor(
private val appEntryUseCases: AppEntryUseCases,
) :
ViewModel() {
var splashCondition by mutableStateOf(true)
private set

var splashCondition by mutableStateOf(true)
private set

var startDestination by mutableStateOf(Route.AppStartNavigation.route)
private set
var startDestination by mutableStateOf(Route.AppStartNavigation.route)
private set

init {
appEntryUseCases.readAppEntry().onEach { shouldStartFromHomeScreen ->
if (shouldStartFromHomeScreen) {
startDestination = Route.NewsNavigation.route
} else {
startDestination = Route.AppStartNavigation.route
}
delay(300)
splashCondition = false
}.launchIn(viewModelScope)
init {
appEntryUseCases.readAppEntry().onEach { shouldStartFromHomeScreen ->
if (shouldStartFromHomeScreen) {
startDestination = Route.NewsNavigation.route
} else {
startDestination = Route.AppStartNavigation.route
}
delay(300)
splashCondition = false
}.launchIn(viewModelScope)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ import androidx.room.Query
import info.octera.droidstorybox.domain.model.Article
import kotlinx.coroutines.flow.Flow


@Dao
interface NewsDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun upsert(article: Article)

Expand All @@ -23,6 +21,4 @@ interface NewsDao {

@Query("SELECT * FROM Article WHERE url=:url")
suspend fun getArticle(url: String): Article?


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import info.octera.droidstorybox.domain.model.Article

@Database(entities = [Article::class],version = 1,)
@Database(entities = [Article::class], version = 1)
@TypeConverters(NewsTypeConverter::class)
abstract class NewsDatabase : RoomDatabase() {

abstract val newsDao: NewsDao

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,17 @@ import androidx.room.ProvidedTypeConverter
import androidx.room.TypeConverter
import info.octera.droidstorybox.domain.model.Source


@ProvidedTypeConverter
class NewsTypeConverter {


@TypeConverter
fun sourceToString(source: Source): String{
fun sourceToString(source: Source): String {
return "${source.id},${source.name}"
}

@TypeConverter
fun stringToSource(source: String): Source{
fun stringToSource(source: String): Source {
return source.split(',').let { sourceArray ->
Source(id = sourceArray[0], name = sourceArray[1])
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

class LocalUserManagerImpl(
private val context: Context
private val context: Context,
) : LocalUserManager {
override suspend fun saveAppEntry() {
context.dataStore.edit { setting ->
Expand All @@ -26,8 +26,9 @@ class LocalUserManagerImpl(
}
}
}
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = Constants.USER_SETTINGS)

private object PreferencesKeys {
val APP_ENTRY = booleanPreferencesKey(name = Constants.APP_ENTRY)
}
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = Constants.USER_SETTINGS)

private object PreferencesKeys {
val APP_ENTRY = booleanPreferencesKey(name = Constants.APP_ENTRY)
}
Loading

0 comments on commit 2209d5a

Please sign in to comment.