From b44bf5f401bf9adfe22cf3e76fe0b253a86d3607 Mon Sep 17 00:00:00 2001 From: darken Date: Sun, 24 Jul 2022 13:38:14 +0200 Subject: [PATCH] Setup CI for testing, gplay release and foss release. --- .../{android.yml => code-checks.yml} | 20 ++- .github/workflows/release-tag.yml | 153 ++++++++++++++++++ app/build.gradle | 85 ++++++---- fastlane/Appfile | 4 +- fastlane/Fastfile | 30 ++-- fastlane/remove_unsupported_languages.sh | 1 + 6 files changed, 247 insertions(+), 46 deletions(-) rename .github/workflows/{android.yml => code-checks.yml} (50%) create mode 100644 .github/workflows/release-tag.yml diff --git a/.github/workflows/android.yml b/.github/workflows/code-checks.yml similarity index 50% rename from .github/workflows/android.yml rename to .github/workflows/code-checks.yml index 442e4f12..99c13075 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/code-checks.yml @@ -1,4 +1,4 @@ -name: Android CI +name: Code tests & eval on: push: @@ -7,13 +7,13 @@ on: branches: [ main ] jobs: - build: + build-and-test: name: Build and test runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: set up JDK 11 + - name: Set up JDK 11 uses: actions/setup-java@v2 with: java-version: '11' @@ -22,7 +22,13 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - - name: Build with Gradle - run: ./gradlew assembleDebug - - name: Run tests - run: ./gradlew testGplayDebugUnitTest testFossDebugUnitTest \ No newline at end of file + + - name: Build FOSS variant + run: ./gradlew assembleFossDebug + - name: Test FOSS variant + run: ./gradlew testFossDebugUnitTest + + - name: Build Google Play variant + run: ./gradlew assembleGplayDebug + - name: Test Google Play variant + run: ./gradlew testGplayDebugUnitTest diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml new file mode 100644 index 00000000..8864c7e4 --- /dev/null +++ b/.github/workflows/release-tag.yml @@ -0,0 +1,153 @@ +name: Tagged releases + +on: + push: + tags: + - 'v*' + +jobs: + release-github: + name: Create GitHub release + runs-on: ubuntu-latest + environment: foss-production + steps: + - name: Decode Keystore + env: + ENCODED_KEYSTORE: ${{ secrets.SIGNING_KEYSTORE_BASE64 }} + run: | + TMP_KEYSTORE_DIR_PATH="${RUNNER_TEMP}"/keystore + mkdir -p "${TMP_KEYSTORE_DIR_PATH}" + TMP_KEYSTORE_FILE_PATH="${TMP_KEYSTORE_DIR_PATH}"/keystore.jks + echo $ENCODED_KEYSTORE | base64 -di > "${TMP_KEYSTORE_FILE_PATH}" + echo "STORE_PATH=$(echo $TMP_KEYSTORE_FILE_PATH)" >> $GITHUB_ENV + + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Get the version + id: tagger + uses: jimschubert/query-tag-action@v2 + with: + skip-unshallow: 'true' + abbrev: false + commit-ish: HEAD + + - name: Install JDK ${{ matrix.java_version }} + uses: actions/setup-java@v3 + with: + distribution: 'adopt' + java-version: 11 + + - name: Assemble beta APK + if: contains(steps.tagger.outputs.tag, '-beta') + run: ./gradlew assembleFossBeta + env: + VERSION: ${{ github.ref }} + STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }} + KEY_ALIAS: ${{ secrets.KEY_ALIAS }} + KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} + BUGSNAG_API_KEY: ${{ secrets.BUGSNAG_API_KEY }} + + - name: Assemble production APK + if: "!contains(steps.tagger.outputs.tag, '-beta')" + run: ./gradlew assembleFossRelease + env: + VERSION: ${{ github.ref }} + STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }} + KEY_ALIAS: ${{ secrets.KEY_ALIAS }} + KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} + BUGSNAG_API_KEY: ${{ secrets.BUGSNAG_API_KEY }} + + - name: Create pre-release + if: contains(steps.tagger.outputs.tag, '-beta') + uses: softprops/action-gh-release@v1 + with: + prerelease: true + tag_name: ${{ steps.tagger.outputs.tag }} + name: ${{ steps.tagger.outputs.tag }} + generate_release_notes: true + files: app/build/outputs/apk/beta/*.apk + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create release + if: "!contains(steps.tagger.outputs.tag, '-beta')" + uses: softprops/action-gh-release@v1 + with: + prerelease: false + tag_name: ${{ steps.tagger.outputs.tag }} + name: ${{ steps.tagger.outputs.tag }} + generate_release_notes: true + files: app/build/outputs/apk/release/*.apk + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + release-gplay: + name: Create Google Play release + runs-on: ubuntu-latest + environment: gplay-production + steps: + - name: Decode Keystore + env: + ENCODED_KEYSTORE: ${{ secrets.SIGNING_KEYSTORE_BASE64 }} + run: | + TMP_KEYSTORE_DIR_PATH="${RUNNER_TEMP}"/keystore + mkdir -p "${TMP_KEYSTORE_DIR_PATH}" + TMP_KEYSTORE_FILE_PATH="${TMP_KEYSTORE_DIR_PATH}"/keystore.jks + echo $ENCODED_KEYSTORE | base64 -di > "${TMP_KEYSTORE_FILE_PATH}" + echo "STORE_PATH=$(echo $TMP_KEYSTORE_FILE_PATH)" >> $GITHUB_ENV + + - name: Decode Google Play service account key + env: + ENCODED_SERVICE_KEY: ${{ secrets.GPLAY_SERVICE_ACCOUNT_KEY_JSON_BASE64 }} + run: | + TMP_SERVICEKEY_DIR="${RUNNER_TEMP}"/gplaykey + mkdir -p "${TMP_SERVICEKEY_DIR}" + TMP_SERVICEKEY_FILE_PATH="${TMP_SERVICEKEY_DIR}"/service_account.json + echo $ENCODED_SERVICE_KEY | base64 -di > "${TMP_SERVICEKEY_FILE_PATH}" + echo "SUPPLY_JSON_KEY=$(echo $TMP_SERVICEKEY_FILE_PATH)" >> $GITHUB_ENV + + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Get the version + id: tagger + uses: jimschubert/query-tag-action@v2 + with: + skip-unshallow: 'true' + abbrev: false + commit-ish: HEAD + + - name: Install JDK ${{ matrix.java_version }} + uses: actions/setup-java@v3 + with: + distribution: 'adopt' + java-version: 11 + + - name: Set up ruby env + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.7.6 + bundler-cache: true + + - name: Assemble beta and upload to Google Play + if: contains(steps.tagger.outputs.tag, '-beta') + run: bundle exec fastlane beta + env: + STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }} + KEY_ALIAS: ${{ secrets.KEY_ALIAS }} + KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} + BUGSNAG_API_KEY: ${{ secrets.BUGSNAG_API_KEY }} + + - name: Assemble production and upload to Google Play + if: "!contains(steps.tagger.outputs.tag, '-beta')" + run: bundle exec fastlane production + env: + STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }} + KEY_ALIAS: ${{ secrets.KEY_ALIAS }} + KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} + BUGSNAG_API_KEY: ${{ secrets.BUGSNAG_API_KEY }} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 397b9648..b196b203 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,10 +16,6 @@ android { compileSdkVersion buildConfig.compileSdk - Properties bugsnagProps = new Properties() - def bugsnagPropsFile = new File(System.properties['user.home'], ".appconfig/${packageName}/bugsnag.properties") - if (bugsnagPropsFile.canRead()) bugsnagProps.load(new FileInputStream(bugsnagPropsFile)) - defaultConfig { applicationId "${packageName}" @@ -38,22 +34,55 @@ android { } signingConfigs { - release {} + releaseFoss {} + releaseGplay {} } - def signingPropFile = new File(System.properties['user.home'], ".appconfig/${packageName}/signing.properties") - if (signingPropFile.canRead()) { - Properties signingProps = new Properties() - signingProps.load(new FileInputStream(signingPropFile)) - signingConfigs { - release { - storeFile new File(signingProps['release.storePath']) - keyAlias signingProps['release.keyAlias'] - storePassword signingProps['release.storePassword'] - keyPassword signingProps['release.keyPassword'] + + signingConfigs { + releaseFoss { + def signingFossPropFile = new File(System.properties['user.home'], ".appconfig/${packageName}/signing-foss.properties") + Properties signingPropsFoss = new Properties() + if (signingFossPropFile.canRead()) signingPropsFoss.load(new FileInputStream(signingFossPropFile)) + String keyStorePathFoss = System.getenv("STORE_PATH") ?: signingPropsFoss["release.storePath"] + File keyStoreFoss = keyStorePathFoss ? new File(keyStorePathFoss) : null + if (keyStoreFoss?.canRead()) { + storeFile keyStoreFoss + storePassword System.getenv("STORE_PASSWORD") ?: signingPropsFoss['release.storePassword'] + keyAlias System.getenv("KEY_ALIAS") ?: signingPropsFoss['release.keyAlias'] + keyPassword System.getenv("KEY_PASSWORD") ?: signingPropsFoss['release.keyPassword'] + } + } + + releaseGplay { + def signingGplayPropFile = new File(System.properties['user.home'], ".appconfig/${packageName}/signing-gplay.properties") + Properties signingPropsGplay = new Properties() + if (signingGplayPropFile.canRead()) signingPropsGplay.load(new FileInputStream(signingGplayPropFile)) + String keyStorePathGplay = System.getenv("STORE_PATH") ?: signingPropsGplay["release.storePath"] + File keyStoreGplay = keyStorePathGplay ? new File(keyStorePathGplay) : null + if (keyStoreGplay?.canRead()) { + storeFile keyStoreGplay + storePassword System.getenv("STORE_PASSWORD") ?: signingPropsGplay['release.storePassword'] + keyAlias System.getenv("KEY_ALIAS") ?: signingPropsGplay['release.keyAlias'] + keyPassword System.getenv("KEY_PASSWORD") ?: signingPropsGplay['release.keyPassword'] } } } + flavorDimensions "version" + productFlavors { + foss { + signingConfig signingConfigs.releaseFoss + } + gplay { + signingConfig signingConfigs.releaseGplay + } + } + + Properties bugsnagProps = new Properties() + def bugsnagPropsFile = new File(System.properties['user.home'], ".appconfig/${packageName}/bugsnag.properties") + if (bugsnagPropsFile.canRead()) bugsnagProps.load(new FileInputStream(bugsnagPropsFile)) + String bugSnagApiKey = System.getenv("BUGSNAG_API_KEY") ?: bugsnagProps.getProperty("bugsnag.apikey", "") + buildTypes { def proguardRulesRelease = fileTree(dir: "../proguard", include: ["*.pro"]).asList().toArray() debug { @@ -62,10 +91,9 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt') proguardFiles proguardRulesRelease proguardFiles 'proguard-rules-debug.pro' - manifestPlaceholders = [bugsnagApiKey: bugsnagProps.getProperty("bugsnag.apikey", "")] + manifestPlaceholders = [bugsnagApiKey: bugSnagApiKey] } - release { - signingConfig signingConfigs.release + beta { lintOptions { abortOnError true fatal 'StopShip' @@ -74,17 +102,18 @@ android { shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt') proguardFiles proguardRulesRelease - manifestPlaceholders = [bugsnagApiKey: bugsnagProps.getProperty("bugsnag.apikey", "")] + manifestPlaceholders = [bugsnagApiKey: bugSnagApiKey] } - } - - flavorDimensions "version" - productFlavors { - gplay { - - } - foss { - + release { + lintOptions { + abortOnError true + fatal 'StopShip' + } + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt') + proguardFiles proguardRulesRelease + manifestPlaceholders = [bugsnagApiKey: bugSnagApiKey] } } diff --git a/fastlane/Appfile b/fastlane/Appfile index dbe8a58a..51b31fd2 100644 --- a/fastlane/Appfile +++ b/fastlane/Appfile @@ -1,2 +1,2 @@ -json_key_file "~/.fastlaneconfig/androiddev-console-darken_development-4f6965ff0eda.json" # Path to the json secret file - Follow https://github.com/fastlane/supply#setup to get one -package_name "eu.darken.capod" # e.g. com.krausefx.app +json_key_file "~/.appconfig/eu.darken.capod/gplay-capod-ci_api.json" +package_name "eu.darken.capod" diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 5bf16110..38530e72 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -11,7 +11,7 @@ # This is the minimum version number required. # Update this, if you use features of a newer version -fastlane_version "2.204.3" +fastlane_version "2.175.0" default_platform :android @@ -21,17 +21,29 @@ platform :android do end lane :beta do - ensure_git_branch(branch: 'dev') - git_pull - gradle(task: 'clean assembleRelease') - supply(track: 'beta') + gradle(task: 'clean assembleGplayBeta') + sh "bash ./remove_unsupported_languages.sh" + supply( + track: 'beta', + skip_upload_changelogs: 'false', + skip_upload_images: 'true', + skip_upload_screenshots: 'true', + skip_upload_aab: 'true', + skip_upload_metadata: 'true', + ) end lane :production do - ensure_git_branch(branch: 'master') - git_pull - gradle(task: 'clean assembleRelease') - supply(track: 'rollout', rollout: '0.1') + gradle(task: 'clean assembleGplayRelease') + sh "bash ./remove_unsupported_languages.sh" + supply( + track: 'beta', + skip_upload_changelogs: 'false', + skip_upload_images: 'true', + skip_upload_screenshots: 'true', + skip_upload_aab: 'true', + skip_upload_metadata: 'true', + ) end lane :listing_only do diff --git a/fastlane/remove_unsupported_languages.sh b/fastlane/remove_unsupported_languages.sh index 67fe750f..19d483b5 100644 --- a/fastlane/remove_unsupported_languages.sh +++ b/fastlane/remove_unsupported_languages.sh @@ -11,5 +11,6 @@ rm -rv ./metadata/android/ku-TR rm -rv ./metadata/android/kmr-TR rm -rv ./metadata/android/ur-IN rm -rv ./metadata/android/zu +rm -rv ./metadata/android/si-LK find ./metadata/android -empty -type d -delete exit 0 \ No newline at end of file