From 303d76ffda69b49c6a1ef8d1c5fde40fea95c84b Mon Sep 17 00:00:00 2001 From: Rob Lemley Date: Thu, 3 Oct 2024 17:01:52 -0400 Subject: [PATCH] [CI] Add github publishing --- .github/workflows/shippable_builds.yml | 58 +++++++++++++++++++++++++ docs/CI/Release_Automation.md | 31 ++++++++++++- docs/CI/publish_hold.png | Bin 0 -> 10530 bytes 3 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 docs/CI/publish_hold.png diff --git a/.github/workflows/shippable_builds.yml b/.github/workflows/shippable_builds.yml index 1a629eacaee..f3eeb3cdcd3 100644 --- a/.github/workflows/shippable_builds.yml +++ b/.github/workflows/shippable_builds.yml @@ -154,3 +154,61 @@ jobs: path: | uploads/*-signed.apk uploads/*.aab + + pre_publish: + # This is a holding job meant to require approval before proceeding with the publishing jobs below + # The environment has a deployment protection rule requiring approval from a set of named reviewers + # before proceeding. + environment: publish_hold + needs: [sign_mobile] + runs-on: ubuntu-latest + steps: + - name: Approval + shell: bash + run: | + true + + github_release: + runs-on: ubuntu-latest + needs: [ pre_publish, dump_config ] + environment: gh-releases + env: + APP_NAME: ${{ needs.dump_config.outputs.appName }} + RELEASE_TYPE: ${{ needs.dump_config.outputs.releaseType }} + PACKAGE_FORMAT: "apk" + PACKAGE_FLAVOR: "foss" + UPLOADS: "uploads" + steps: + - uses: actions/download-artifact@v4 + with: + # The artifact name is the APK FOSS package for Github releases + name: signed-${{ env.APP_NAME }}-${{ env.PACKAGE_FORMAT }}-${{ env.PACKAGE_FLAVOR }} + path: ${{ env.UPLOADS }}/ + + - name: Get Version -> Tag Name + ## This obviously is quite incorrect. Need a way to extract versionName from gradle + shell: bash + run: | + APKANALYZER="${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/apkanalyzer" + APK_FILE="${APP_NAME}-${PACKAGE_FLAVOR}-${RELEASE_TYPE}-signed.apk" + _version=$(${APKANALYZER} manifest version-name "${UPLOADS}/${APK_FILE}") + _tag="${APP_NAME}-${_version}" + echo "TAG_NAME=${_tag}" >> $GITHUB_ENV + echo "APK_FILE=${APK_FILE}" >> $GITHUB_ENV + + - name: App Token Generate + uses: actions/create-github-app-token@v1 + id: app-token + with: + app-id: ${{ vars.RELEASER_APP_CLIENT_ID }} + private-key: ${{ secrets.RELEASER_APP_PRIVATE_KEY }} + + - name: Publish + uses: softprops/action-gh-release@v2 + with: + token: ${{ steps.app-token.outputs.token }} + target_commitish: ${{ github.sha }} + tag_name: ${{ env.TAG_NAME }} + fail_on_unmatched_files: true + files: | + ${{ env.UPLOADS }}/${{ env.APK_FILE }} diff --git a/docs/CI/Release_Automation.md b/docs/CI/Release_Automation.md index 5074904b5bd..e10cdaf0ac9 100644 --- a/docs/CI/Release_Automation.md +++ b/docs/CI/Release_Automation.md @@ -8,7 +8,7 @@ and release type. The environment is selected when triggering the workflow. You also select the appropriate branch to run the workflow on. The environments are only accessible by the branch they are associated with -**Environments** +## Build Environments - thunderbird_beta - thunderbird_daily @@ -30,9 +30,13 @@ The variables set in these environments are non-sensitive and are used by the bu ``` That would build `bundleFullBeta` and `assembleFossBeta`. +## Signing Environments + There are also "secret" environments that are used by the signing job. -An "upload" secret environment and a "signing" secret environment are needed. Currently the environment names are based on the appName, releaseType, and packageFlavor. So `app-thunderbird_beta_full` which would have the upload signing configuration for Thunderbird Beta set up. This could be improved. +An "upload" secret environment and a "signing" secret environment are needed. Currently the environment names are based +on the appName, releaseType, and packageFlavor. So `app-thunderbird_beta_full` which would have the upload +signing configuration for Thunderbird Beta set up. This could be improved. The secrets themselves are from https://github.com/noriban/sign-android-release: ```yaml @@ -41,3 +45,26 @@ alias: ${{ secrets.KEY_ALIAS }} keyPassword: ${{ secrets.KEY_PASSWORD }} keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }} ``` + +## Publishing Hold Environment + +The "publish_hold" is shared by all application variants and is used by the "pre_publish" job. +It has no secrets or variables, but "Required Reviewers" is set to trusted team members who oversee releases. The +effect is that after package signing completes, the publishing jobs that depend on it will not run until released +manually. + +![publish hold](publish_hold.png) + +## Github Releases Environment + +"gh_releases" contains the Client Id and Private Key for a Github App that's used by the "actions/create-github-app-token' +to generate a token with the appropriate permissions to create and tag a Github release. + +| | Name | Description | +| -------- | ------------------------ | ------------------------------- | +| Variable | RELEASER_APP_CLIENT_ID | The Client ID of the github app | +| Secret | RELEASER_APP_PRIVATE_KEY | The private key of the app | + +### App Permissions + +**TODO** diff --git a/docs/CI/publish_hold.png b/docs/CI/publish_hold.png new file mode 100644 index 0000000000000000000000000000000000000000..343e489d88210bca70f9c63227cc432a76e79286 GIT binary patch literal 10530 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 literal 0 HcmV?d00001