From da4496243bfc7cbdc35c89e107e8212cc55db6b7 Mon Sep 17 00:00:00 2001 From: Andrew Rowson Date: Tue, 13 Sep 2022 14:51:31 +0100 Subject: [PATCH] Store oss/gms apks after publish, consolidate release workflows to pull apks --- .circleci/continue-config.yml | 27 ++++++++---- .github/workflows/beta.yml | 76 --------------------------------- .github/workflows/fetch-apks.sh | 32 ++++++++++++++ .github/workflows/release.yml | 65 ++++++++++++++-------------- 4 files changed, 83 insertions(+), 117 deletions(-) delete mode 100644 .github/workflows/beta.yml create mode 100755 .github/workflows/fetch-apks.sh diff --git a/.circleci/continue-config.yml b/.circleci/continue-config.yml index efd95fa243..97c844d684 100644 --- a/.circleci/continue-config.yml +++ b/.circleci/continue-config.yml @@ -96,22 +96,27 @@ jobs: - checkout - android/accept-licenses - restore-gradle-cache + - run: + name: Set credentials + command: | + echo -n $GOOGLE_CLOUD_SERVICE_ACCOUNT_CREDENTIALS_BASE64 | base64 -d > project/app/owntracks-android-gcloud-creds.json + echo -n $KEYSTORE_BASE64 | base64 -d > project/owntracks.release.keystore.jks - run: name: Build command: | - ./project/gradlew -p ./project assembleDebug assembleAndroidTest assembleGmsReleaseUnitTest :app:compileOssReleaseSources :app:packageGmsReleaseBundle app:assembleGmsDebugAndroidTest app:assembleOssDebugAndroidTest --scan + ./project/gradlew -p ./project assembleDebug assembleRelease assembleAndroidTest assembleGmsReleaseUnitTest :app:compileOssReleaseSources :app:packageGmsReleaseBundle app:assembleGmsDebugAndroidTest app:assembleOssDebugAndroidTest --scan - save-gradle-cache - persist_to_workspace: - root: project/app/build/outputs/apk/oss/debug/ + root: project/app/build/outputs/apk/ paths: - - app-oss-debug.apk + - "**" fdroid-scanner: executor: android-docker resource_class: small steps: - checkout - attach_workspace: - at: project/app/build/outputs/apk/oss/debug/ + at: project/app/build/outputs/apk/ - run: name: Fdroid Scanner command: | @@ -246,13 +251,18 @@ jobs: command: | echo -n $GOOGLE_CLOUD_SERVICE_ACCOUNT_CREDENTIALS_BASE64 | base64 -d > project/app/owntracks-android-gcloud-creds.json echo -n $KEYSTORE_BASE64 | base64 -d > project/owntracks.release.keystore.jks + - attach_workspace: + at: project/app/build/outputs/apk/ - run: name: Build command: | - ./project/gradlew -p ./project assembleRelease publishGmsReleaseBundle --scan + ./project/gradlew -p ./project publishGmsReleaseBundle --scan + - store_artifacts: + path: project/app/build/outputs/apk/gms/release/app-gms-release.apk + destination: gms-apk - store_artifacts: - path: project/app/build/outputs - destination: build-outputs + path: project/app/build/outputs/apk/oss/release/app-oss-release.apk + destination: oss-apk workflows: evaluate-oss-contribution: @@ -276,7 +286,8 @@ workflows: when: not: << pipeline.parameters.oss-contribution-flow >> jobs: - - build + - build: + context: Android Deploy Credentials - fdroid-scanner: requires: - build diff --git a/.github/workflows/beta.yml b/.github/workflows/beta.yml deleted file mode 100644 index 489483c196..0000000000 --- a/.github/workflows/beta.yml +++ /dev/null @@ -1,76 +0,0 @@ -# This flow is designed to be used to update the beta track on the Play store. It does this by promoting the internal track build to beta, triggered by the creation of a beta tag. -# Crucially, it assumes that whatever is the current internal track build is the correct candidate for sending to beta - it does *not* rebuild and publish. Therefore, if changes -# are made and a new beta tag created at the same time, those changes will *not* be included in the build that the beta track ends up pointing at. I get around this by -# making sure changes are published to internal first, then creating / pushing the beta tag in order to promote. I should also fix this at some point. -name: Android CI Beta release - -on: - push: - tags: - - v[0-9]+.[0-9]+.[0-9]+-beta[0-9]+ - -jobs: - promote: - name: Create GH release and promote Play store internal to Beta - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Create release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - body_path: ./CHANGELOG.md - release_name: ${{ github.ref }} - draft: true - prerelease: true - - name: set up JDK 11 - uses: actions/setup-java@v3 - with: - distribution: "temurin" - java-version: 11 - - uses: actions/cache@v3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }} - restore-keys: | - ${{ runner.os }}-gradle- - - name: Decrypt secrets - env: - GOOGLE_CLOUD_SERVICE_ACCOUNT_CREDENTIALS: ${{ secrets.GOOGLE_CLOUD_SERVICE_ACCOUNT_CREDENTIALS }} - KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} - run: | - echo -n $GOOGLE_CLOUD_SERVICE_ACCOUNT_CREDENTIALS > project/app/owntracks-android-gcloud-creds.json - echo -n $KEYSTORE_BASE64 | base64 -d > project/owntracks.release.keystore.jks - - name: Build APK - run: ./gradlew clean :app:getLatestVersionCodeMinusOne assembleRelease - working-directory: project - env: - KEYSTORE_PASSPHRASE: ${{ secrets.KEYSTORE_PASSPHRASE }} - ORG_GRADLE_PROJECT_google_maps_api_key: ${{ secrets.GOOGLE_MAPS_API_KEY }} - MAKE_APK_SAME_VERSION_CODE_AS_GOOGLE_PLAY: yes - - name: Upload GMS Release Asset - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: ./project/app/build/outputs/apk/gms/release/app-gms-release.apk - asset_name: owntracks-release-gms.apk - asset_content_type: application/vnd.android.package-archive - - name: Upload OSS Release Asset - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: ./project/app/build/outputs/apk/oss/release/app-oss-release.apk - asset_name: owntracks-release-oss.apk - asset_content_type: application/vnd.android.package-archive - - name: Promote play store beta from internal - run: ./gradlew promoteArtifact --from-track internal --promote-track beta --release-status completed - working-directory: project diff --git a/.github/workflows/fetch-apks.sh b/.github/workflows/fetch-apks.sh new file mode 100755 index 0000000000..03544d30f2 --- /dev/null +++ b/.github/workflows/fetch-apks.sh @@ -0,0 +1,32 @@ +#!/bin/bash +echo "Commit Sha: $GITHUB_SHA" +PIPELINE_OUTPUT=$(curl -s -u ${CIRCLE_CI_TOKEN}: https://circleci.com/api/v2/project/gh/owntracks/android/pipeline) +echo "Found $(echo $PIPELINE_OUTPUT | jq '.items | length') pipelines" +MATCHING_PIPELINE_ID=$(echo $PIPELINE_OUTPUT | jq -r '.items[] | select(.vcs.revision == env.GITHUB_SHA and .vcs.branch == "master") |.id') +echo "Pipeline ID that matches git rev $GITHUB_SHA is $MATCHING_PIPELINE" +if [ -z "$MATCHING_PIPELINE_ID" ]; then exit 1; fi + +WORKFLOW_OUTPUT=$(curl -s -u ${CIRCLE_CI_TOKEN}: https://circleci.com/api/v2/pipeline/$MATCHING_PIPELINE_ID/workflow) +WORKFLOW_ID=$(echo $WORKFLOW_OUTPUT | jq -r '.items[] | select(.name=="build-and-test" and .status=="success") |.id') +echo "This pipeline has $(echo $WORKFLOW_OUTPUT | jq '.items | length') workflows" +echo "Workflow ID that matches 'build-and-test' is $WORKFLOW_ID" +if [ -z "$WORKFLOW_ID" ]; then exit 1; fi + +JOB_OUTPUT=$(curl -s -u ${CIRCLE_CI_TOKEN}: https://circleci.com/api/v2/workflow/$WORKFLOW_ID/job) +echo "This workflow has $(echo $JOB_OUTPUT | jq '.items | length') jobs" +JOB_ID=$(echo $JOB_OUTPUT | jq -r '.items[] | select (.name == "publish-to-play-store" and .status=="success") | .id') +echo "Job ID that matches 'publish-to-play-store' is $JOB_ID" +if [ -z "$JOB_ID" ]; then exit 1; fi + +MINIMUM_SIZE_KB_CHECK=1000 + +echo "Fetching OSS APK" +curl -s -L -o oss.apk https://output.circle-artifacts.com/output/job/$JOB_ID/artifacts/0/oss-apk +du -h oss.apk +OSS_SIZE_KB=$(du -k oss.apk | cut -f1) +if [ "$OSS_SIZE_KB" -lt "$MINIMUM_SIZE_KB_CHECK" ]; then exit 1; fi +echo "Fetching GMS APK" +curl -s -L -o gms.apk https://output.circle-artifacts.com/output/job/$JOB_ID/artifacts/0/gms-apk +du -h gms.apk +GMS_SIZE_KB=$(du -k oss.apk | cut -f1) +if [ "$GMS_SIZE_KB" -lt "$MINIMUM_SIZE_KB_CHECK" ]; then exit 1; fi diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 11ad18216b..6408d2a357 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,11 +1,12 @@ -# This flow is designed to be used to update the production track on the Play store. It does this by promoting the beta track build to production, triggered by the creation of a release tag. +# This flow is designed to be used to update the production and beta tracks on the Play store. It does this by promoting the beta track build to production, triggered by the creation of a release tag. # As per the beta build, this does not actually do a build / upload, it simply promotes whatever's in beta to production. Best to create the -name: Android CI production release +name: Android Release on: push: tags: - v[0-9]+.[0-9]+.[0-9]+ + - v[0-9]+.[0-9]+.[0-9]+-beta[0-9]+ jobs: release: @@ -13,6 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + - uses: octokit/request-action@v2.x name: Find beta tags id: get_beta_tags @@ -29,51 +31,43 @@ jobs: export LENGTH=$(echo $labels | jq '. | length') echo $LENGTH echo "::set-output name=beta_tag_count::$LENGTH" - - name: Create release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - body_path: ./CHANGELOG.md - release_name: ${{ github.ref }} - draft: true - prerelease: false + - name: set up JDK 11 uses: actions/setup-java@v3 with: java-version: 11 distribution: "temurin" - - uses: actions/cache@v3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }} - restore-keys: | - ${{ runner.os }}-gradle- + - name: Decrypt secrets env: GOOGLE_CLOUD_SERVICE_ACCOUNT_CREDENTIALS: ${{ secrets.GOOGLE_CLOUD_SERVICE_ACCOUNT_CREDENTIALS }} - KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} run: | echo -n $GOOGLE_CLOUD_SERVICE_ACCOUNT_CREDENTIALS > project/app/owntracks-android-gcloud-creds.json - echo -n $KEYSTORE_BASE64 | base64 -d > project/owntracks.release.keystore.jks - - name: Build APK - run: ./gradlew clean :app:getLatestVersionCodeMinusOne assembleRelease - working-directory: project + + - name: Fetch APK from CircleCI + run: .github/workflows/fetch-apks.sh + env: + CIRCLE_CI_TOKEN: "${{ secrets.CIRCLE_CI_TOKEN }}" + + - name: Create release + id: create_release + uses: actions/create-release@v1 env: - KEYSTORE_PASSPHRASE: ${{ secrets.KEYSTORE_PASSPHRASE }} - ORG_GRADLE_PROJECT_google_maps_api_key: ${{ secrets.GOOGLE_MAPS_API_KEY }} - MAKE_APK_SAME_VERSION_CODE_AS_GOOGLE_PLAY: yes + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + body_path: ./CHANGELOG.md + release_name: ${{ github.ref }} + draft: true + prerelease: ${{ contains(github.ref, 'beta') }} + - name: Upload GMS Release Asset uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: ./project/app/build/outputs/apk/gms/release/app-gms-release.apk + asset_path: ./gms.apk asset_name: owntracks-release-gms.apk asset_content_type: application/vnd.android.package-archive - name: Upload OSS Release Asset @@ -82,14 +76,19 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: ./project/app/build/outputs/apk/oss/release/app-oss-release.apk + asset_path: ./oss.apk asset_name: owntracks-release-oss.apk asset_content_type: application/vnd.android.package-archive + + - name: Promote play store beta from internal + run: ./gradlew promoteGmsReleaseArtifact --from-track internal --promote-track beta --release-status completed + working-directory: project + if: ${{ contains(github.ref, 'beta') }} - name: Promote play store production from beta run: ./gradlew promoteArtifact --from-track beta --promote-track production --release-status completed working-directory: project - if: ${{ steps.tagCount.outputs.beta_tag_count > 0 }} + if: ${{ !contains(github.ref, 'beta') && steps.tagCount.outputs.beta_tag_count > 0 }} - name: Promote play store production from internal run: ./gradlew promoteArtifact --from-track internal --promote-track production --release-status completed working-directory: project - if: ${{ steps.tagCount.outputs.beta_tag_count == 0 }} + if: ${{ !contains(github.ref, 'beta') && steps.tagCount.outputs.beta_tag_count == 0 }}