From 77ed44c1fd0cbe7bf07cee8faba65e763d9f160b Mon Sep 17 00:00:00 2001 From: Angela Cortecchia Date: Wed, 11 Mar 2026 10:13:41 +0100 Subject: [PATCH 01/10] feat(ci): add apk and abb in release # Conflicts: # .github/workflows/build-and-deploy.yml --- .github/workflows/build-and-deploy.yml | 70 +++++++++++++++----------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 0c2285f..51e72a9 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -1,7 +1,8 @@ - name: CI/CD Process on: - workflow_call: + push: + tags: + - 'v*' workflow_dispatch: concurrency: @@ -10,18 +11,15 @@ concurrency: jobs: build-android: - name: Compile Android + name: Build Android (APK & AAB) runs-on: ubuntu-latest - concurrency: - group: build-android-${{ github.workflow }}-${{ github.event.number || github.ref }} - cancel-in-progress: true steps: - name: Checkout uses: actions/checkout@v6.0.2 - + - name: Grant execute permission for gradlew run: chmod +x gradlew - + - name: Validate Gradle wrapper uses: gradle/actions/wrapper-validation@v5 with: @@ -35,18 +33,24 @@ jobs: java-version: '17' cache: 'gradle' - - name: Run ktlint - run: ./gradlew ktlintCheck - - - name: Compile Android Kotlin - run: ./gradlew composeApp:compileDebugKotlinAndroid + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + # Generate APK (test/GitHub) and AAB (Google Play) + - name: Build Release Artifacts + run: ./gradlew :composeApp:assembleRelease :composeApp:bundleRelease + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: android-release + path: | + composeApp/build/outputs/apk/release/*.apk + composeApp/build/outputs/bundle/release/*.aab build-ios: name: Compile iOS runs-on: macos-latest - concurrency: - group: build-ios-${{ github.workflow }}-${{ github.event.number || github.ref }} - cancel-in-progress: true steps: - name: Checkout uses: actions/checkout@v6.0.2 @@ -57,23 +61,29 @@ jobs: distribution: 'temurin' java-version: '17' cache: 'gradle' - - name: Grant execute permission for gradlew run: chmod +x gradlew - - name: Compile iOS Kotlin - run: ./gradlew composeApp:compileKotlinIosSimulatorArm64 + run: ./gradlew :composeApp:compileKotlinIosSimulatorArm64 - success: + create-release: + name: Create GitHub Release + needs: [build-android, build-ios] runs-on: ubuntu-latest - needs: - - build-android - - build-ios - if: >- - always() && ( - contains(join(needs.*.result, ','), 'failure') - || !contains(join(needs.*.result, ','), 'cancelled') - ) + if: startsWith(github.ref, 'refs/tags/') steps: - - name: Verify that there were no failures - run: ${{ !contains(join(needs.*.result, ','), 'failure') }} \ No newline at end of file + - name: Download Android Artifacts + uses: actions/download-artifact@v4 + with: + name: android-release + + - name: Release + uses: softprops/action-gh-release@v2 + with: + files: | + **/*.apk + **/*.aab + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 80350f56dd2fc76797192a3b3d5772cc56c1252d Mon Sep 17 00:00:00 2001 From: Angela Cortecchia Date: Wed, 11 Mar 2026 11:41:54 +0100 Subject: [PATCH 02/10] feat(ci): add setup for gh and play store release --- .github/workflows/build-and-deploy.yml | 153 +++++++++++++++++++++---- composeApp/build.gradle.kts | 22 +++- fastlane/Fastfile | 70 ++++++----- 3 files changed, 191 insertions(+), 54 deletions(-) diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 51e72a9..9b774e3 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -17,15 +17,12 @@ jobs: - name: Checkout uses: actions/checkout@v6.0.2 - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - name: Validate Gradle wrapper uses: gradle/actions/wrapper-validation@v5 with: allow-snapshots: false min-wrapper-count: 1 - + - name: Set up JDK 17 uses: actions/setup-java@v5 with: @@ -33,20 +30,52 @@ jobs: java-version: '17' cache: 'gradle' + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '4.0' + bundler-cache: true + - name: Grant execute permission for gradlew run: chmod +x gradlew - # Generate APK (test/GitHub) and AAB (Google Play) - - name: Build Release Artifacts - run: ./gradlew :composeApp:assembleRelease :composeApp:bundleRelease + - name: Extract version from tag + if: startsWith(github.ref, 'refs/tags/') + run: | + TAG="${GITHUB_REF#refs/tags/v}" + VERSION_CODE=$(echo "$TAG" | sed 's/[^0-9]//g' | cut -c1-9) + echo "VERSION_NAME=$TAG" >> $GITHUB_ENV + echo "VERSION_CODE=${VERSION_CODE:-1}" >> $GITHUB_ENV + + - name: Decode Keystore + if: env.KEYSTORE_BASE64 != '' + env: + KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} + run: | + echo "$KEYSTORE_BASE64" | base64 -d > ${{ github.workspace }}/release.keystore + echo "KEYSTORE_FILE=${{ github.workspace }}/release.keystore" >> $GITHUB_ENV + + - name: Build Release APK & AAB (Fastlane) + env: + KEYSTORE_FILE: ${{ env.KEYSTORE_FILE }} + KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} + KEY_ALIAS: ${{ secrets.KEY_ALIAS }} + KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} + VERSION_NAME: ${{ env.VERSION_NAME }} + VERSION_CODE: ${{ env.VERSION_CODE }} + run: bundle exec fastlane android release + + - name: Upload APK + uses: actions/upload-artifact@v4 + with: + name: android-apk + path: composeApp/build/outputs/apk/release/*.apk - - name: Upload Artifacts + - name: Upload AAB uses: actions/upload-artifact@v4 with: - name: android-release - path: | - composeApp/build/outputs/apk/release/*.apk - composeApp/build/outputs/bundle/release/*.aab + name: android-aab + path: composeApp/build/outputs/bundle/release/*.aab build-ios: name: Compile iOS @@ -54,36 +83,118 @@ jobs: steps: - name: Checkout uses: actions/checkout@v6.0.2 - + - name: Set up JDK 17 uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: '17' cache: 'gradle' + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '4.0' + bundler-cache: true + - name: Grant execute permission for gradlew run: chmod +x gradlew - - name: Compile iOS Kotlin - run: ./gradlew :composeApp:compileKotlinIosSimulatorArm64 + + - name: Compile iOS Kotlin (Fastlane) + run: bundle exec fastlane ios build create-release: name: Create GitHub Release needs: [build-android, build-ios] runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/') + permissions: + contents: write steps: - - name: Download Android Artifacts + - name: Download APK uses: actions/download-artifact@v4 with: - name: android-release + name: android-apk + path: artifacts/apk - - name: Release + - name: Download AAB + uses: actions/download-artifact@v4 + with: + name: android-aab + path: artifacts/aab + + - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: files: | - **/*.apk - **/*.aab + artifacts/apk/*.apk + body: | + ## Release ${{ github.ref_name }} + + ### Downloads + - **Android APK**: scarica dagli assets qui sotto draft: false prerelease: false + generate_release_notes: true env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # ────────────────────────────────────────────────────────────── + # Google Play Store deployment via Fastlane + # ────────────────────────────────────────────────────────────── + # todo: + # 1. Create service account Google Play, download JSON key + # → https://developers.google.com/android-publisher/getting_started + # 2. Save JSON key as GitHub secret: PLAY_STORE_JSON_KEY + # 3. Save keystore (base64) as secret: KEYSTORE_BASE64 + # 4. Save keystore credentials: KEYSTORE_PASSWORD, KEY_ALIAS, KEY_PASSWORD + # 5. use this job + # ────────────────────────────────────────────────────────────── + + # deploy-play-store: + # name: Deploy to Google Play Store + # needs: [build-android] + # runs-on: ubuntu-latest + # if: startsWith(github.ref, 'refs/tags/') + # steps: + # - name: Checkout + # uses: actions/checkout@v6.0.2 + # + # - name: Set up JDK 17 + # uses: actions/setup-java@v5 + # with: + # distribution: 'temurin' + # java-version: '17' + # cache: 'gradle' + # + # - name: Set up Ruby + # uses: ruby/setup-ruby@v1 + # with: + # ruby-version: '4.0' + # bundler-cache: true + # + # - name: Grant execute permission for gradlew + # run: chmod +x gradlew + # + # - name: Decode Keystore + # env: + # KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} + # run: | + # echo "$KEYSTORE_BASE64" | base64 -d > ${{ github.workspace }}/release.keystore + # echo "KEYSTORE_FILE=${{ github.workspace }}/release.keystore" >> $GITHUB_ENV + # + # - name: Decode Play Store JSON key + # env: + # PLAY_STORE_JSON_KEY: ${{ secrets.PLAY_STORE_JSON_KEY }} + # run: | + # echo "$PLAY_STORE_JSON_KEY" > ${{ github.workspace }}/play-store-key.json + # echo "SUPPLY_JSON_KEY=${{ github.workspace }}/play-store-key.json" >> $GITHUB_ENV + # + # - name: Deploy to Play Store (Fastlane) + # env: + # KEYSTORE_FILE: ${{ env.KEYSTORE_FILE }} + # KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} + # KEY_ALIAS: ${{ secrets.KEY_ALIAS }} + # KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} + # SUPPLY_JSON_KEY: ${{ env.SUPPLY_JSON_KEY }} + # run: bundle exec fastlane android deploy diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index eae6184..7d59f34 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -82,8 +82,20 @@ android { applicationId = "it.unibo.collektive.echo" minSdk = libs.versions.android.minSdk.get().toInt() targetSdk = libs.versions.android.targetSdk.get().toInt() - versionCode = 1 - versionName = "1.0" + versionCode = System.getenv("VERSION_CODE")?.toIntOrNull() ?: 1 + versionName = System.getenv("VERSION_NAME") ?: "1.0" + } + + signingConfigs { + create("release") { + val keystoreFilePath = System.getenv("KEYSTORE_FILE") + if (keystoreFilePath != null) { + storeFile = file(keystoreFilePath) + storePassword = System.getenv("KEYSTORE_PASSWORD") + keyAlias = System.getenv("KEY_ALIAS") + keyPassword = System.getenv("KEY_PASSWORD") + } + } } packaging { @@ -95,6 +107,12 @@ android { buildTypes { release { isMinifyEnabled = false + val keystoreFilePath = System.getenv("KEYSTORE_FILE") + signingConfig = if (keystoreFilePath != null) { + signingConfigs.getByName("release") + } else { + signingConfigs.getByName("debug") + } } } diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 8b782fb..a01b757 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -1,4 +1,5 @@ platform :android do + lane :lint do gradle( task: "ktlintCheck", @@ -12,56 +13,63 @@ platform :android do project_dir: "./" ) end - + + # Build signed release APK + AAB lane :release do gradle( - task: "composeApp:bundleRelease", + task: "composeApp:assembleRelease composeApp:bundleRelease", project_dir: "./" ) end + # ────────────────────────────────────────────────────────────── + # Deploy AAB to Google Play Store (internal track) + # ────────────────────────────────────────────────────────────── + # todo: + # 1. Create service account Google Play, download json key + # 2. set path to JSON key in ENV variable SUPPLY_JSON_KEY, e.g.: + # export SUPPLY_JSON_KEY="/path/to/your/service-account.json" + # or pass is as parameter + # 3. Exec: bundle exec fastlane android deploy + # ────────────────────────────────────────────────────────────── lane :deploy do + release # build APK + AAB + + upload_to_play_store( + package_name: "it.unibo.collektive.echo", + aab: "composeApp/build/outputs/bundle/release/composeApp-release.aab", + track: "internal", # Options: internal, alpha, beta, production + release_status: "draft", # Options: completed, draft, halted, inProgress + skip_upload_metadata: true, + skip_upload_images: true, + skip_upload_screenshots: true + ) end end platform :ios do + lane :build do gradle( task: "composeApp:linkDebugFrameworkIosArm64", project_dir: "./" ) - end - lane :ios_release do - gradle( - task: "composeApp:linkReleaseFrameworkIosArm64", - project_dir: "./" - ) - build_app( - project: './iosApp/iosApp.xcodeproj', - scheme: "iosApp", - configuration: "Release", - destination: "generic/platform=iOS" - ) - - end - - lane :release do - gradle( - task: "composeApp:linkReleaseFrameworkIosArm64", - project_dir: "./" - ) - - build_app( - project: './iosApp/iosApp.xcodeproj', - scheme: 'iosApp', - configuration: 'Release', - destination: 'generic/platform=iOS', - allowProvisioningUpdates: true - ) - end + lane :release do + gradle( + task: "composeApp:linkReleaseFrameworkIosArm64", + project_dir: "./" + ) + build_app( + project: "./iosApp/iosApp.xcodeproj", + scheme: "iosApp", + configuration: "Release", + destination: "generic/platform=iOS", + allowProvisioningUpdates: true + ) + end end From 9c3d2fc7ac0e148632124eeccdbb21e95527de6f Mon Sep 17 00:00:00 2001 From: Angela Cortecchia Date: Mon, 16 Mar 2026 11:46:35 +0100 Subject: [PATCH 03/10] build(fastlane): update release and deploy lanes for Android --- fastlane/Fastfile | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index a01b757..113429f 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -1,5 +1,4 @@ platform :android do - lane :lint do gradle( task: "ktlintCheck", @@ -14,38 +13,27 @@ platform :android do ) end - # Build signed release APK + AAB lane :release do + # Builds the APK used for the GitHub Release + gradle( + task: "composeApp:assembleRelease", + project_dir: "./" + ) + # Builds the Android App Bundle (AAB) used for the Play Store gradle( - task: "composeApp:assembleRelease composeApp:bundleRelease", + task: "composeApp:bundleRelease", project_dir: "./" ) end - # ────────────────────────────────────────────────────────────── - # Deploy AAB to Google Play Store (internal track) - # ────────────────────────────────────────────────────────────── - # todo: - # 1. Create service account Google Play, download json key - # 2. set path to JSON key in ENV variable SUPPLY_JSON_KEY, e.g.: - # export SUPPLY_JSON_KEY="/path/to/your/service-account.json" - # or pass is as parameter - # 3. Exec: bundle exec fastlane android deploy - # ────────────────────────────────────────────────────────────── lane :deploy do - release # build APK + AAB - + # Uploads the generated AAB to Google Play Console upload_to_play_store( - package_name: "it.unibo.collektive.echo", - aab: "composeApp/build/outputs/bundle/release/composeApp-release.aab", - track: "internal", # Options: internal, alpha, beta, production - release_status: "draft", # Options: completed, draft, halted, inProgress - skip_upload_metadata: true, - skip_upload_images: true, - skip_upload_screenshots: true + track: 'production', # ['internal', 'production', 'beta'] + aab: 'composeApp/build/outputs/bundle/release/composeApp-release.aab', + json_key_data: ENV['PLAY_STORE_JSON_KEY_DATA'] ) end - end platform :ios do From 9ab4c926dccb0ca5589ac16cf19efc4fd27b5b36 Mon Sep 17 00:00:00 2001 From: Angela Cortecchia Date: Mon, 16 Mar 2026 11:46:49 +0100 Subject: [PATCH 04/10] chore(release): update assets to Android APK and remove docker commands --- release.config.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/release.config.js b/release.config.js index ef02b14..6ae4eb4 100644 --- a/release.config.js +++ b/release.config.js @@ -2,10 +2,8 @@ var prepareCmd = ` echo version=\${nextRelease.version} > gradle.properties echo VERSION="\${nextRelease.version}" > .env echo PROJECT_NAME=$(grep -Po 'rootProject\\s*\\.\\s*name\\s*=\\s*"\\K[\\w-]+(?=")' settings.gradle.kts) >> .env -docker compose build ` var publishCmd = ` -docker compose push git add gradle.properties .env git commit -m "chore(release): update gradle.properties .env versions to \${nextRelease.version} [skip ci]" git push @@ -18,9 +16,9 @@ config.plugins.push( }], ["@semantic-release/github", { "assets": [ - { "path": "charts.tar.zst" }, + { "path": "composeApp/build/outputs/apk/release/*.apk", "label": "Android Release APK" } ] }], "@semantic-release/git", ) -module.exports = config \ No newline at end of file +module.exports = config From e22f88d926105fb2089220508fcbec3b773c27b0 Mon Sep 17 00:00:00 2001 From: Angela Cortecchia Date: Mon, 16 Mar 2026 11:47:02 +0100 Subject: [PATCH 05/10] ci: refactor build and deploy workflow to use workflow_call and semantic-release --- .github/workflows/build-and-deploy.yml | 248 ++++++++++--------------- 1 file changed, 93 insertions(+), 155 deletions(-) diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 9b774e3..9d03ef5 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -1,200 +1,138 @@ name: CI/CD Process on: - push: - tags: - - 'v*' + workflow_call: workflow_dispatch: -concurrency: - group: ${{ github.workflow }}-${{ github.event.number || github.ref }} - cancel-in-progress: true - jobs: - build-android: - name: Build Android (APK & AAB) - runs-on: ubuntu-latest + build-ios: + name: Build iOS + runs-on: macos-latest + concurrency: + group: ios-${{ github.workflow }}-${{ github.event.number || github.ref }} + cancel-in-progress: true steps: - name: Checkout uses: actions/checkout@v6.0.2 - - name: Validate Gradle wrapper uses: gradle/actions/wrapper-validation@v5 with: allow-snapshots: false min-wrapper-count: 1 - - name: Set up JDK 17 - uses: actions/setup-java@v5 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '17' cache: 'gradle' - - - name: Set up Ruby + - name: Set up Ruby & Fastlane uses: ruby/setup-ruby@v1 with: - ruby-version: '4.0' bundler-cache: true - - name: Grant execute permission for gradlew run: chmod +x gradlew + - name: Build iOS via Fastlane + run: bundle exec fastlane ios build - - name: Extract version from tag - if: startsWith(github.ref, 'refs/tags/') - run: | - TAG="${GITHUB_REF#refs/tags/v}" - VERSION_CODE=$(echo "$TAG" | sed 's/[^0-9]//g' | cut -c1-9) - echo "VERSION_NAME=$TAG" >> $GITHUB_ENV - echo "VERSION_CODE=${VERSION_CODE:-1}" >> $GITHUB_ENV - - - name: Decode Keystore - if: env.KEYSTORE_BASE64 != '' - env: - KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} - run: | - echo "$KEYSTORE_BASE64" | base64 -d > ${{ github.workspace }}/release.keystore - echo "KEYSTORE_FILE=${{ github.workspace }}/release.keystore" >> $GITHUB_ENV - - - name: Build Release APK & AAB (Fastlane) - env: - KEYSTORE_FILE: ${{ env.KEYSTORE_FILE }} - KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} - KEY_ALIAS: ${{ secrets.KEY_ALIAS }} - KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} - VERSION_NAME: ${{ env.VERSION_NAME }} - VERSION_CODE: ${{ env.VERSION_CODE }} - run: bundle exec fastlane android release - - - name: Upload APK - uses: actions/upload-artifact@v4 - with: - name: android-apk - path: composeApp/build/outputs/apk/release/*.apk - - - name: Upload AAB - uses: actions/upload-artifact@v4 - with: - name: android-aab - path: composeApp/build/outputs/bundle/release/*.aab - - build-ios: - name: Compile iOS - runs-on: macos-latest + build-android: + name: Compile Android + runs-on: ubuntu-latest + concurrency: + group: android-${{ github.workflow }}-${{ github.event.number || github.ref }} + cancel-in-progress: true steps: - name: Checkout uses: actions/checkout@v6.0.2 - + - name: Validate Gradle wrapper + uses: gradle/actions/wrapper-validation@v5 + with: + allow-snapshots: false + min-wrapper-count: 1 - name: Set up JDK 17 uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: '17' cache: 'gradle' - - - name: Set up Ruby + - name: Set up Ruby w/Fastlane uses: ruby/setup-ruby@v1 with: - ruby-version: '4.0' bundler-cache: true - - name: Grant execute permission for gradlew run: chmod +x gradlew + - name: Run lint through Fastlane + run: bundle exec fastlane lint + - name: Decode Keystore + env: + ENCODED_STRING: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} + run: | + echo $ENCODED_STRING | base64 -di > composeApp/keystore.jks + - name: Build Android Release (APK & AAB) via Fastlane + run: bundle exec fastlane android release + env: # for gradle + KEYSTORE_FILE: "keystore.jks" + KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} + KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} + KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} + - name: Upload Android APK artifact + uses: actions/upload-artifact@v4 + with: + name: echo-app-apk + path: composeApp/build/outputs/apk/release/*.apk + - name: Upload Android AAB artifact + uses: actions/upload-artifact@v4 + with: + name: echo-app-aab + path: composeApp/build/outputs/bundle/release/*.aab - - name: Compile iOS Kotlin (Fastlane) - run: bundle exec fastlane ios build - - create-release: - name: Create GitHub Release - needs: [build-android, build-ios] + release: + name: GitHub Release runs-on: ubuntu-latest - if: startsWith(github.ref, 'refs/tags/') - permissions: - contents: write + needs: + - build-ios + - build-android + concurrency: + # Only one release job at a time per branch, as only master releases. + group: release-${{ github.event.number || github.ref }} steps: - - name: Download APK - uses: actions/download-artifact@v4 + - name: Checkout repository + uses: actions/checkout@v4 with: - name: android-apk - path: artifacts/apk - - - name: Download AAB + fetch-depth: 0 + - name: Download Android APK artifact uses: actions/download-artifact@v4 with: - name: android-aab - path: artifacts/aab - - - name: Create GitHub Release - uses: softprops/action-gh-release@v2 + name: android-release-apk + path: composeApp/build/outputs/apk/release/ + - name: Install Node + uses: actions/setup-node@v6.3.0 with: - files: | - artifacts/apk/*.apk - body: | - ## Release ${{ github.ref_name }} - - ### Downloads - - **Android APK**: scarica dagli assets qui sotto - draft: false - prerelease: false - generate_release_notes: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - # ────────────────────────────────────────────────────────────── - # Google Play Store deployment via Fastlane - # ────────────────────────────────────────────────────────────── - # todo: - # 1. Create service account Google Play, download JSON key - # → https://developers.google.com/android-publisher/getting_started - # 2. Save JSON key as GitHub secret: PLAY_STORE_JSON_KEY - # 3. Save keystore (base64) as secret: KEYSTORE_BASE64 - # 4. Save keystore credentials: KEYSTORE_PASSWORD, KEY_ALIAS, KEY_PASSWORD - # 5. use this job - # ────────────────────────────────────────────────────────────── - - # deploy-play-store: - # name: Deploy to Google Play Store - # needs: [build-android] - # runs-on: ubuntu-latest - # if: startsWith(github.ref, 'refs/tags/') - # steps: - # - name: Checkout - # uses: actions/checkout@v6.0.2 - # - # - name: Set up JDK 17 - # uses: actions/setup-java@v5 - # with: - # distribution: 'temurin' - # java-version: '17' - # cache: 'gradle' - # - # - name: Set up Ruby - # uses: ruby/setup-ruby@v1 - # with: - # ruby-version: '4.0' - # bundler-cache: true - # - # - name: Grant execute permission for gradlew - # run: chmod +x gradlew - # - # - name: Decode Keystore - # env: - # KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} - # run: | - # echo "$KEYSTORE_BASE64" | base64 -d > ${{ github.workspace }}/release.keystore - # echo "KEYSTORE_FILE=${{ github.workspace }}/release.keystore" >> $GITHUB_ENV - # - # - name: Decode Play Store JSON key - # env: - # PLAY_STORE_JSON_KEY: ${{ secrets.PLAY_STORE_JSON_KEY }} - # run: | - # echo "$PLAY_STORE_JSON_KEY" > ${{ github.workspace }}/play-store-key.json - # echo "SUPPLY_JSON_KEY=${{ github.workspace }}/play-store-key.json" >> $GITHUB_ENV - # - # - name: Deploy to Play Store (Fastlane) - # env: - # KEYSTORE_FILE: ${{ env.KEYSTORE_FILE }} - # KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} - # KEY_ALIAS: ${{ secrets.KEY_ALIAS }} - # KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} - # SUPPLY_JSON_KEY: ${{ env.SUPPLY_JSON_KEY }} - # run: bundle exec fastlane android deploy + node-version: ${{ steps.node-version.outputs.version }} + - name: Semantic Release +# env: +# GITHUB_TOKEN: ${{ secrets.DEPLOYMENT_TOKEN }} + run: | + npm install + npx semantic-release + +###### remove comment when ready to deploy on play store +# deploy-play-store: +# name: Deploy to Play Store +# runs-on: ubuntu-latest +# needs: release +# if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' +# steps: +# - name: Checkout repository +# uses: actions/checkout@v4 +# - name: Download Android AAB artifact +# uses: actions/download-artifact@v4 +# with: +# name: android-release-aab +# path: composeApp/build/outputs/bundle/release/ +# - name: Set up Ruby & Fastlane for Play Store Deploy +# uses: ruby/setup-ruby@v1 +# with: +# bundler-cache: true +# - name: Deploy to Google Play Store via Fastlane +# #env: +# # PLAY_STORE_JSON_KEY_DATA: ${{ secrets.PLAY_STORE_JSON_KEY }} +# run: bundle exec fastlane android deploy \ No newline at end of file From efe47c40a6e2d7c7880c7c085ce2445d95ffeb60 Mon Sep 17 00:00:00 2001 From: Angela Cortecchia Date: Mon, 16 Mar 2026 11:58:52 +0100 Subject: [PATCH 06/10] chore(deps): add ruby version file --- .ruby-version | 1 + Gemfile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 .ruby-version diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..cc868b6 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +4.0.1 \ No newline at end of file diff --git a/Gemfile b/Gemfile index 11e0778..a705a83 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,3 @@ source "https://rubygems.org" -ruby '4.0.1' +ruby file: '.ruby-version' gem "fastlane" From d526d4294ce6623efebf577cb307d7fdf3805706 Mon Sep 17 00:00:00 2001 From: Angela Cortecchia Date: Mon, 16 Mar 2026 12:01:32 +0100 Subject: [PATCH 07/10] chore: update Gemfile.lock for ruby version --- Gemfile.lock | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 87eb440..3798efb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -328,5 +328,8 @@ CHECKSUMS xcpretty (0.4.1) sha256=b14c50e721f6589ee3d6f5353e2c2cfcd8541fa1ea16d6c602807dd7327f3892 xcpretty-travis-formatter (1.0.1) sha256=aacc332f17cb7b2cba222994e2adc74223db88724fe76341483ad3098e232f93 +RUBY VERSION + ruby 4.0.1 + BUNDLED WITH 4.0.3 From 406ebcffe35879977527c23f7ce1d503ab29330d Mon Sep 17 00:00:00 2001 From: Angela Cortecchia Date: Mon, 16 Mar 2026 12:06:55 +0100 Subject: [PATCH 08/10] fix(ci): linter run invocation --- .github/workflows/build-and-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 9d03ef5..640bc82 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -60,7 +60,7 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Run lint through Fastlane - run: bundle exec fastlane lint + run: bundle exec fastlane android lint - name: Decode Keystore env: ENCODED_STRING: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} From 763802b48dab4e88c15b63c0ac824c559c9e2961 Mon Sep 17 00:00:00 2001 From: Angela Cortecchia Date: Mon, 16 Mar 2026 13:45:09 +0100 Subject: [PATCH 09/10] fix(ci): get env variables --- .github/workflows/build-and-deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 640bc82..1296486 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -108,8 +108,8 @@ jobs: with: node-version: ${{ steps.node-version.outputs.version }} - name: Semantic Release -# env: -# GITHUB_TOKEN: ${{ secrets.DEPLOYMENT_TOKEN }} + env: + GITHUB_TOKEN: ${{ secrets.DEPLOYMENT_TOKEN }} run: | npm install npx semantic-release From ece2ac7cb9a446d69a429c20774abe8734333dd9 Mon Sep 17 00:00:00 2001 From: Angela Cortecchia Date: Mon, 16 Mar 2026 14:00:02 +0100 Subject: [PATCH 10/10] fix(ci): add missing success job --- .github/workflows/build-and-deploy.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 1296486..4bd2ff0 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -135,4 +135,20 @@ jobs: # - name: Deploy to Google Play Store via Fastlane # #env: # # PLAY_STORE_JSON_KEY_DATA: ${{ secrets.PLAY_STORE_JSON_KEY }} -# run: bundle exec fastlane android deploy \ No newline at end of file +# run: bundle exec fastlane android deploy + + success: + runs-on: ubuntu-latest + needs: + - build-android + - build-ios + - release + #- deploy-play-store + if: >- + always() && ( + contains(join(needs.*.result, ','), 'failure') + || !contains(join(needs.*.result, ','), 'cancelled') + ) + steps: + - name: Verify that there were no failures + run: ${{ !contains(join(needs.*.result, ','), 'failure') }} \ No newline at end of file