diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..11324ca4d --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +# AWS credentials for S3 build cache +AWS_ACCESS_KEY_ID=your_access_key_id +AWS_SECRET_ACCESS_KEY=your_secret_access_key diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 746b4ebc6..ab952adb8 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -18,8 +18,12 @@ jobs: with: java-version: 17 distribution: 'temurin' - - name: Clean build - run: ./gradlew clean + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ap-northeast-2 - name: Setup google-services.json (Live) run: | mkdir -p ./app/src/live @@ -85,8 +89,12 @@ jobs: with: java-version: 17 distribution: 'temurin' - - name: Clean build - run: ./gradlew clean + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ap-northeast-2 - name: Setup google-services.json (Staging) run: | mkdir -p ./app/src/staging diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ecf21b802..e05f96b0e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,18 +8,13 @@ on: branches: - 'develop' -jobs: - cancel-workflow: - runs-on: ubuntu-latest - steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.6.0 - with: - access_token: ${{ github.token }} +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true - static-check: +jobs: + build: runs-on: ubuntu-latest - needs: cancel-workflow steps: - name: Checkout uses: actions/checkout@v4 @@ -28,9 +23,13 @@ jobs: with: java-version: 17 distribution: 'adopt' - - name: Clean build - run: ./gradlew clean - - name: Run ktlintDebug + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ap-northeast-2 + - name: Run ktlint run: ./gradlew ktlintMainSourceSetCheck - name: Upload ktlint report uses: actions/upload-artifact@v4 @@ -38,20 +37,6 @@ jobs: with: name: ktlint-result path: ./**/build/reports/ktlint/**/*.html - - build: - runs-on: ubuntu-latest - needs: static-check - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Setup Java - uses: actions/setup-java@v4 - with: - java-version: 17 - distribution: 'adopt' - - name: Clean build - run: ./gradlew clean - name: Setup google-services.json (Staging) run: | mkdir -p ./app/src/staging @@ -71,4 +56,4 @@ jobs: ${{ secrets.secrets_xml_staging_core_network }} EOF - name: Build debug APK - run: ./gradlew assembleStagingDebug --stacktrace \ No newline at end of file + run: ./gradlew assembleStagingDebug --stacktrace diff --git a/.github/workflows/manual_deploy.yml b/.github/workflows/manual_deploy.yml index a194fde81..7bca980af 100644 --- a/.github/workflows/manual_deploy.yml +++ b/.github/workflows/manual_deploy.yml @@ -32,8 +32,12 @@ jobs: with: java-version: 17 distribution: 'adopt' - - name: Clean build - run: ./gradlew clean + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ap-northeast-2 - name: Setup google-services.json (Live) if: startsWith(github.event.inputs.variant, 'live') run: | @@ -109,7 +113,7 @@ jobs: SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }} SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }} - name: Upload artifact to Firebase App Distribution (Live) - if: ${{ github.event.inputs.firebase == 'true' && startsWith(github.event.inputs.variant, 'Live') }} + if: ${{ github.event.inputs.firebase == 'true' && startsWith(github.event.inputs.variant, 'live') }} run: ./gradlew appDistributionUploadLiveRelease - name: Upload artifact to Firebase App Distribution (Staging) if: ${{ github.event.inputs.firebase == 'true' && startsWith(github.event.inputs.variant, 'staging') }} @@ -141,4 +145,4 @@ jobs: file_path: './app/build/outputs/apk/staging/release/app-staging-release.apk' file_name: 'app-staging-release.apk' file_type: 'apk' - initial_comment: 'staging-release APK' \ No newline at end of file + initial_comment: 'staging-release APK' diff --git a/.gitignore b/.gitignore index 8d77a8811..c8dae52b7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ /app/src/live/ /app/src/staging/ +# Environment variables +.env + # Created by https://www.toptal.com/developers/gitignore/api/androidstudio # Edit at https://www.toptal.com/developers/gitignore?templates=androidstudio diff --git a/README.md b/README.md index 09e49b394..e3903aa71 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,23 @@ Please request these files from the maintainer if needed. ``` 3. Build and run the project using JDK 17. +### Build Cache + +CI 빌드 속도 향상을 위해 S3 기반 원격 빌드 캐시를 사용합니다. + +**로컬에서 캐시 업로드:** + +1. `.env` 파일에 AWS 자격 증명 설정: + ``` + AWS_ACCESS_KEY_ID=your_access_key_id + AWS_SECRET_ACCESS_KEY=your_secret_access_key + ``` + +2. 캐시 업로드 실행: + ```bash + ./gradlew warmCache + ``` + ### Deployment 1. Create a `release-${version-code}` branch and modify the version code in `version.properties`. diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 95ecbd6cc..1edbd8632 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -120,6 +120,10 @@ android { } } +kotlin { + jvmToolchain(17) +} + dependencies { // Testing testImplementation(libs.junit) @@ -185,3 +189,8 @@ dependencies { // Desugaring coreLibraryDesugaring(libs.desugar.jdk.libs) } + +tasks.register("warmCache") { + description = "CI용 빌드 캐시를 S3에 업로드합니다." + dependsOn("ktlintMainSourceSetCheck", "assembleStagingDebug") +} diff --git a/gradle.properties b/gradle.properties index 3bbd832e9..35e9ad703 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,4 +18,7 @@ # org.gradle.parallel=true org.gradle.jvmargs=-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 android.enableJetifier=true -android.useAndroidX=true \ No newline at end of file +android.useAndroidX=true + +# Build Cache +org.gradle.caching=true \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index b1cf6a9d7..80a739d93 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,6 +6,38 @@ pluginManagement { } } +plugins { + id("com.github.burrunan.s3-build-cache") version "1.8.1" +} + +// Load .env file if exists +val envFile = file(".env") +if (envFile.exists()) { + envFile.readLines() + .filter { it.isNotBlank() && !it.startsWith("#") } + .forEach { line -> + val (key, value) = line.split("=", limit = 2) + System.setProperty(key.trim(), value.trim()) + } +} + +fun envOrNull(name: String): String? = System.getenv(name) ?: System.getProperty(name) + +buildCache { + local { + isEnabled = true + } + remote { + region = "ap-northeast-2" + bucket = "snutt-android-build-cache" + prefix = "cache/" + isPush = gradle.startParameter.taskNames.any { it.contains("warmCache") } + lookupDefaultAwsCredentials = true + envOrNull("AWS_ACCESS_KEY_ID")?.let { awsAccessKeyId = it } + envOrNull("AWS_SECRET_ACCESS_KEY")?.let { awsSecretKey = it } + } +} + dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories {