Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions .github/workflows/CD.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: CD

on:
push:
tags:
- 'v*.*.*'

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: 17

- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v3

- name: Set release version
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV

- name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

- name: chmod cache key
run: chmod +x ./scripts/checksum.sh

- name: Generate cache key
run: ./scripts/checksum.sh app checksum.txt

- name: Cache Gradle
uses: actions/cache@v3
with:
path: |
~/.gradle/caches/modules-*
~/.gradle/caches/jars-*
~/.gradle/caches/build-cache-*
~/.gradle/wrapper/
~/.gradle/caches/transforms-*
key: gradle-${{ hashFiles('checksum.txt') }}
restore-keys: |
gradle-

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3

- name: Build Release APK
run: ./gradlew assembleRelease --no-daemon --stacktrace

- name: Prepare APK for Release
run: |
mkdir -p release
cp app/build/outputs/apk/release/app-release.apk release/BreakingBad-${{ env.RELEASE_VERSION }}.apk

- name: Generate changelog
id: changelog
uses: metcalfc/changelog-generator@v4.1.0
with:
myToken: ${{ secrets.GITHUB_TOKEN }}

- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: release/BreakingBad-${{ env.RELEASE_VERSION }}.apk
name: Release ${{ env.RELEASE_VERSION }}
body: |
${{ steps.changelog.outputs.changelog }}
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Delete checksum.txt after build
if: always()
run: rm -f checksum.txt
67 changes: 49 additions & 18 deletions .github/workflows/Build.yaml → .github/workflows/CI.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build
name: CI

on:
pull_request:
Expand All @@ -10,10 +10,9 @@ concurrency:
cancel-in-progress: true

jobs:
build:
spotless:
runs-on: ubuntu-latest
timeout-minutes: 30

timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down Expand Up @@ -42,21 +41,60 @@ jobs:
~/.gradle/caches/modules-*
~/.gradle/caches/jars-*
~/.gradle/caches/build-cache-*
~/.gradle/wrapper/
~/.gradle/caches/transforms-*
key: gradle-${{ hashFiles('checksum.txt') }}
restore-keys: |
gradle-

- name: Setup Gradle
uses: gradle/gradle-build-action@v3
uses: gradle/actions/setup-gradle@v3

- name: Check Spotless
run: ./gradlew spotlessCheck --init-script gradle/init.gradle.kts --no-configuration-cache --stacktrace
run: ./gradlew spotlessCheck --init-script gradle/init.gradle.kts --no-configuration-cache --no-daemon --stacktrace

tests:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: 17

- name: chmod cache key
run: chmod +x ./scripts/checksum.sh

- name: Generate cache key
run: ./scripts/checksum.sh app checksum.txt

- uses: actions/cache@v3
with:
path: |
~/.gradle/caches/modules-*
~/.gradle/caches/jars-*
~/.gradle/caches/build-cache-*
~/.gradle/wrapper/
~/.gradle/caches/transforms-*
key: gradle-${{ hashFiles('checksum.txt') }}
restore-keys: |
gradle-

- name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3

- name: UnitTest
run: |
./gradlew testDebugUnitTest --stacktrace
run: ./gradlew testDebugUnitTest --no-daemon --stacktrace

- name: Check Kover
run: |
./gradlew koverXmlReportDebug
run: ./gradlew koverXmlReportDebug --no-daemon

- name: Display local test coverage
uses: madrapps/jacoco-report@v1.6.1
Expand All @@ -69,11 +107,4 @@ jobs:
continue-on-error: false
paths: |
${{ github.workspace }}/feature/**/build/reports/kover/reportDebug.xml
token: ${{ secrets.GITHUB_TOKEN }}

- name: Upload lint reports
if: always()
uses: actions/upload-artifact@v3
with:
name: build-reports
path: app/build/reports
token: ${{ secrets.GITHUB_TOKEN }}
684 changes: 684 additions & 0 deletions app/src/main/assets/character.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions build-logic/convention/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
Expand All @@ -12,8 +13,8 @@ java {
targetCompatibility = JavaVersion.VERSION_17
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
compilerOptions {
jvmTarget.set(JvmTarget.JVM_17)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ extensions.configure<ApplicationExtension> {

buildTypes {
getByName("debug") {
isDebuggable = false
isDebuggable = true
}

getByName("release") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ internal fun Project.configureAndroidCompose() {
}

extensions.configure<ComposeCompilerGradlePluginExtension> {
enableStrongSkippingMode = true
includeSourceInformation = true
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2025 shinhyo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.shinhyo.brba.core.network

import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.shinhyo.brba.core.network.model.CharacterResponse
import kotlinx.coroutines.delay
import kotlinx.serialization.json.Json
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton

/**
* NOTE: This is a sample app.
* The actual network implementation can be replaced with a local data source
* for testing or demo purposes without real network calls.
*/
@Singleton
class LocalDataSource @Inject constructor(
@ApplicationContext private val context: Context,
) : NetworkDataSource {
private val jsonParser = Json { ignoreUnknownKeys = true }

override suspend fun getCharacter(): List<CharacterResponse> {
simulateNetworkDelay()
return readCharactersFromAsset()
}

override suspend fun getCharacter(id: Long): List<CharacterResponse> {
simulateNetworkDelay()
return readCharactersFromAsset().filter { it.charId == id }
}

private suspend fun simulateNetworkDelay() {
// Simulate random network delay (up to 500ms) for sample app
delay((0..500).random().toLong())
}

private fun readCharactersFromAsset(): List<CharacterResponse> {
val assetManager = context.assets
val inputStream = assetManager.open("character.json")
val json = inputStream.bufferedReader().use { it.readText() }
return try {
jsonParser.decodeFromString(json)
} catch (e: Exception) {
Timber.e(e, "Failed to parse character.json")
emptyList()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,26 @@ import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import io.github.shinhyo.brba.core.network.LocalDataSource
import io.github.shinhyo.brba.core.network.NetworkDataSource
import io.github.shinhyo.brba.core.network.retrofit.RetrofitNetwork

@Module
@InstallIn(SingletonComponent::class)
interface NetworkModule {

/**
* NOTE: This is a sample app.
*
* The actual network implementation can be replaced with a local data source
* for testing or demo purposes without real network calls.
*/
// @Binds
// fun bindNetworkDataSource(
// network: RetrofitNetwork,
// ): NetworkDataSource

@Binds
fun bindNetworkDataSource(
network: RetrofitNetwork,
network: LocalDataSource,
): NetworkDataSource
}
36 changes: 18 additions & 18 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
[versions]
versionCode = "1"
versionName = "1.0.0"
compileSdkVer = "34"
targetSdkVer = "34"
compileSdkVer = "35"
targetSdkVer = "35"
minSdkVer = "28"

androidGradlePlugin = "8.5.2"
androidTools = "31.6.0"
androidGradlePlugin = "8.10.0"
androidTools = "31.10.0"

# https://github.com/JetBrains/kotlin/releases
kotlin = "2.0.20"
kotlin = "2.1.21"
# https://github.com/google/ksp/releases
ksp = "2.0.20-1.0.25"
androidDesugarJdkLibs = "2.1.2"
ksp = "2.1.21-2.0.1"
androidDesugarJdkLibs = "2.1.5"

kotlinxCoroutines = "1.8.1"
kotlinxCoroutines = "1.10.1"
kotlinxSerializationJson = "1.7.1"

androidxCore = "1.13.1"
androidxCore = "1.16.0"
androidxCoreSplashscreen = "1.0.1"
androidxAppCompat = "1.7.0"
androidxActivity = "1.9.2"
androidxStartup = "1.1.1"
androidxActivity = "1.10.1"
androidxStartup = "1.2.0"
androidxHiltNavigationCompose = "1.2.0"
androidxLifecycle = "2.8.5"
androidxDataStore = "1.1.1"
androidxLifecycle = "2.9.0"
androidxDataStore = "1.1.7"

androidxComposeBom = "2024.09.00"
androidxComposeBom = "2025.05.01"
androidxComposeMaterial3 = "1.1.2"

hilt = "2.51.1"
hilt = "2.56"
hiltExt = "1.0.0"

androidxNavigation = "2.8.0"
androidxNavigation = "2.9.0"

junit4 = "4.13.2"
androidxTestCore = "1.6.1"
Expand All @@ -45,13 +45,13 @@ timber = "5.0.1"
okhttp = "4.12.0"
retrofit = "2.11.0"
retrofitKotlinxSerializationJson = "1.0.0"
room = "2.6.1"
room = "2.7.1"
turbine = "1.1.0"
junit = "1.2.1"
material = "1.12.0"
haze = "0.7.2"
mockk = "1.13.9"
kover = "0.8.3"
kover = "0.9.1"

[libraries]

Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Tue Jun 25 15:56:57 KST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading