Release #60
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| date: | |
| description: "Build date (e.g., $(date +'%Y%m%d%H%M%S'))" | |
| required: true | |
| type: string | |
| version: | |
| description: "Version number (e.g., 1.0.0)" | |
| required: true | |
| type: string | |
| env: | |
| GRADLE_MAVEN_REPOSITORIES: "https://maven.google.com/,https://repo.maven.apache.org/maven2/,https://plugins.gradle.org/m2/,https://maven.mozilla.org/maven2/" | |
| MOZ_BUILD_DATE: "${{ inputs.date }}" | |
| SENTRY_TOKEN: "${{ secrets.SENTRY_TOKEN }}" | |
| SIGNING_KEY_ALIAS: "${{ secrets.SIGNING_KEY_ALIAS }}" | |
| SIGNING_KEY_PASSWORD: "${{ secrets.SIGNING_KEY_PASSWORD }}" | |
| SIGNING_KEY_STORE_BASE64: "${{ secrets.SIGNING_KEY_STORE_BASE64 }}" | |
| SIGNING_STORE_PASSWORD: "${{ secrets.SIGNING_STORE_PASSWORD }}" | |
| EXPECTED_RELEASE_CERT_SHA1: "B2:C9:03:22:84:A6:46:EA:B1:6C:36:5C:5C:71:DB:33:32:69:7D:6D" | |
| jobs: | |
| build-geckoview: | |
| concurrency: | |
| group: "${{ github.ref }}-${{ matrix.arch }}-geckoview" | |
| cancel-in-progress: true | |
| env: | |
| MOZCONFIG: ".mozconfig-${{ matrix.arch }}" | |
| name: Build GeckoView | |
| runs-on: namespace-profile-linux-md | |
| strategy: | |
| matrix: | |
| arch: | |
| - arm-linux-androideabi | |
| - aarch64-linux-android | |
| - x86_64-linux-android | |
| steps: | |
| - name: β Checkout repository | |
| uses: namespacelabs/nscloud-checkout-action@v8 | |
| with: | |
| submodules: recursive | |
| - name: βοΈ Setup Java | |
| uses: actions/setup-java@v5 | |
| with: | |
| java-version: 17 | |
| distribution: temurin | |
| - name: πΎ Set up Gradle dependency cache | |
| uses: namespacelabs/nscloud-cache-action@v1 | |
| with: | |
| cache: gradle | |
| - name: πΎ Set up Gradle build cache | |
| run: | | |
| mkdir -p "$HOME/.gradle/init.d" | |
| nsc cache gradle setup --init-gradle "$HOME/.gradle/init.d/namespace-cache.gradle" | |
| - name: π§ Setup deps | |
| run: | | |
| curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y | |
| . "$HOME/.cargo/env" | |
| if [ "${{ matrix.arch }}" = "arm-linux-androideabi" ]; then | |
| rustup target add thumbv7neon-linux-androideabi | |
| else | |
| rustup target add ${{ matrix.arch }} | |
| fi | |
| - name: π Generate local.properties | |
| run: | | |
| NDK_VERSION=$(sed -n 's/^NDK_VERSION = "\(.*\)"/\1/p' python/mozboot/mozboot/android.py) | |
| NDK_DIR="$HOME/.mozbuild/android-ndk-$NDK_VERSION" | |
| cat > local.properties << EOF | |
| localProperties.dependencySubstitutions.geckoviewTopobjdir=objdir | |
| sdk.dir=$HOME/.mozbuild/android-sdk-linux | |
| ndk.dir=$NDK_DIR | |
| EOF | |
| cat > glean/local.properties << EOF | |
| sdk.dir=$HOME/.mozbuild/android-sdk-linux | |
| ndk.dir=$NDK_DIR | |
| EOF | |
| - name: π©Ή Apply local patches | |
| run: | | |
| chmod +x patches/apply-local-patches.sh | |
| ./patches/apply-local-patches.sh | |
| - name: π Write Sentry DSN token file | |
| run: | | |
| printf "%s" "$SENTRY_TOKEN" > .sentry_token | |
| chmod 600 .sentry_token | |
| - name: π¦Ύ Fetch clang-22 toolchain | |
| run: | | |
| chmod +x scripts/fetch-clang-22.sh | |
| ./scripts/fetch-clang-22.sh | |
| - name: π¨ Build Gecko | |
| run: | | |
| unset ANDROID_HOME | |
| unset ANDROID_NDK | |
| unset ANDROID_NDK_HOME | |
| unset ANDROID_NDK_LATEST_HOME | |
| unset ANDROID_NDK_ROOT | |
| unset ANDROID_SDK_ROOT | |
| echo $MOZ_BUILD_DATE | |
| ./mach build | |
| ./mach package | |
| export GRADLE_INVOKED_WITHIN_MACH_BUILD=1 | |
| ./mach gradle :geckoview:assembleRelease | |
| - name: Create Maven zip | |
| run: | | |
| set -euo pipefail | |
| OBJDIR="obj-${{ matrix.arch }}" | |
| GRADLE_DIR="$OBJDIR/gradle" | |
| export GRADLE_INVOKED_WITHIN_MACH_BUILD=1 | |
| ./mach gradle :geckoview:publishReleasePublicationToMavenRepository | |
| python3 scripts/create-maven-zip.py --objdir "$OBJDIR" --include-snapshots --require-aar | |
| test -f "$GRADLE_DIR/target.maven.zip" | |
| - name: π Upload GeckoView Artifact | |
| uses: namespace-actions/upload-artifact@v1 | |
| with: | |
| name: geckoview-${{ matrix.arch }}-${{ github.run_id }} | |
| path: | | |
| ./obj-${{ matrix.arch }}/gradle/target.maven.zip | |
| retention-days: 1 | |
| build-app: | |
| name: Build App | |
| needs: | |
| - build-geckoview | |
| runs-on: namespace-profile-linux-md | |
| steps: | |
| - name: β Checkout repository | |
| uses: namespacelabs/nscloud-checkout-action@v8 | |
| with: | |
| submodules: recursive | |
| - name: βοΈ Setup Java | |
| uses: actions/setup-java@v5 | |
| with: | |
| java-version: 17 | |
| distribution: temurin | |
| - name: πΎ Set up Gradle dependency cache | |
| uses: namespacelabs/nscloud-cache-action@v1 | |
| with: | |
| cache: gradle | |
| - name: πΎ Set up Gradle build cache | |
| run: | | |
| mkdir -p "$HOME/.gradle/init.d" | |
| nsc cache gradle setup --init-gradle "$HOME/.gradle/init.d/namespace-cache.gradle" | |
| - name: β¬οΈ Download GeckoView ARMEABI_V7A Artifact | |
| uses: namespace-actions/download-artifact@v2 | |
| with: | |
| name: geckoview-arm-linux-androideabi-${{ github.run_id }} | |
| path: obj-arm-linux-androideabi/ | |
| - name: β¬οΈ Download GeckoView ARM64_V8A Artifact | |
| uses: namespace-actions/download-artifact@v2 | |
| with: | |
| name: geckoview-aarch64-linux-android-${{ github.run_id }} | |
| path: obj-aarch64-linux-android/ | |
| - name: β¬οΈ Download GeckoView X86_64 Artifact | |
| uses: namespace-actions/download-artifact@v2 | |
| with: | |
| name: geckoview-x86_64-linux-android-${{ github.run_id }} | |
| path: obj-x86_64-linux-android/ | |
| - name: π Display structure of artifact files | |
| run: | | |
| ls -R obj-arm-linux-androideabi | |
| ls -R obj-aarch64-linux-android | |
| ls -R obj-x86_64-linux-android | |
| - name: π§ Setup deps | |
| run: | | |
| curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y | |
| . "$HOME/.cargo/env" | |
| rustup target add x86_64-linux-android | |
| - name: π Generate local.properties | |
| run: | | |
| NDK_VERSION=$(sed -n 's/^NDK_VERSION = "\(.*\)"/\1/p' python/mozboot/mozboot/android.py) | |
| NDK_DIR="$HOME/.mozbuild/android-ndk-$NDK_VERSION" | |
| cat > local.properties << EOF | |
| localProperties.dependencySubstitutions.geckoviewTopobjdir=objdir | |
| sdk.dir=$HOME/.mozbuild/android-sdk-linux | |
| ndk.dir=$NDK_DIR | |
| branchBuild.waterfox.version=${{ inputs.version }} | |
| EOF | |
| cat > glean/local.properties << EOF | |
| sdk.dir=$HOME/.mozbuild/android-sdk-linux | |
| ndk.dir=$NDK_DIR | |
| EOF | |
| - name: π©Ή Apply local patches | |
| run: | | |
| chmod +x patches/apply-local-patches.sh | |
| ./patches/apply-local-patches.sh | |
| - name: π Write Sentry DSN token file | |
| run: | | |
| printf "%s" "$SENTRY_TOKEN" > .sentry_token | |
| chmod 600 .sentry_token | |
| - name: π¦Ύ Fetch clang-22 toolchain | |
| run: | | |
| chmod +x scripts/fetch-clang-22.sh | |
| ./scripts/fetch-clang-22.sh | |
| - name: π¨ Build Gecko | |
| run: | | |
| unset ANDROID_HOME | |
| unset ANDROID_NDK | |
| unset ANDROID_NDK_HOME | |
| unset ANDROID_NDK_LATEST_HOME | |
| unset ANDROID_NDK_ROOT | |
| unset ANDROID_SDK_ROOT | |
| export MOZ_ANDROID_FAT_AAR_ARMEABI_V7A="$(pwd)/obj-arm-linux-androideabi/target.maven.zip" | |
| export MOZ_ANDROID_FAT_AAR_ARM64_V8A="$(pwd)/obj-aarch64-linux-android/target.maven.zip" | |
| export MOZ_ANDROID_FAT_AAR_X86_64="$(pwd)/obj-x86_64-linux-android/target.maven.zip" | |
| ./mach build | |
| - name: π Decode Keystore | |
| run: | | |
| echo "${{ secrets.SIGNING_KEY_STORE_BASE64 }}" | base64 --decode > mobile/android/fenix/app/keystore.jks | |
| - name: π¨ Build Release APKs | |
| run: | | |
| unset ANDROID_HOME | |
| unset ANDROID_NDK | |
| unset ANDROID_NDK_HOME | |
| unset ANDROID_NDK_LATEST_HOME | |
| unset ANDROID_NDK_ROOT | |
| unset ANDROID_SDK_ROOT | |
| export GRADLE_INVOKED_WITHIN_MACH_BUILD=1 | |
| ./mach gradle :fenix:assembleWaterfoxRelease | |
| - name: π¦ Build Release AAB | |
| run: | | |
| unset ANDROID_HOME | |
| unset ANDROID_NDK | |
| unset ANDROID_NDK_HOME | |
| unset ANDROID_NDK_LATEST_HOME | |
| unset ANDROID_NDK_ROOT | |
| unset ANDROID_SDK_ROOT | |
| export GRADLE_INVOKED_WITHIN_MACH_BUILD=1 | |
| ./mach gradle :fenix:bundleWaterfoxRelease | |
| - name: Verify release AAB signing fingerprint | |
| run: | | |
| EXPECTED_SHA1="$(echo "${EXPECTED_RELEASE_CERT_SHA1}" | tr '[:lower:]' '[:upper:]' | tr -d '[:space:]')" | |
| AAB_PATH=$(find objdir/gradle/build/mobile/android/fenix/app/outputs/bundle/waterfoxRelease -name '*.aab' -type f | head -n 1) | |
| if [ -z "${AAB_PATH}" ]; then | |
| echo "No AAB artifact found to verify." | |
| exit 1 | |
| fi | |
| ACTUAL_SHA1=$(keytool -printcert -jarfile "${AAB_PATH}" | sed -n 's/^.*SHA1: //p' | head -n 1 | tr '[:lower:]' '[:upper:]' | tr -d '[:space:]') | |
| if [ -z "${ACTUAL_SHA1}" ]; then | |
| echo "Unable to read signing fingerprint from ${AAB_PATH}." | |
| exit 1 | |
| fi | |
| echo "Expected AAB signing SHA1: ${EXPECTED_SHA1}" | |
| echo "Actual AAB signing SHA1: ${ACTUAL_SHA1}" | |
| if [ "${ACTUAL_SHA1}" != "${EXPECTED_SHA1}" ]; then | |
| echo "Release AAB is signed with an unexpected certificate." | |
| exit 1 | |
| fi | |
| - name: π Upload Build Artifacts | |
| uses: namespace-actions/upload-artifact@v1 | |
| with: | |
| name: build-artifacts-${{ github.run_id }} | |
| path: | | |
| objdir/gradle/build/mobile/android/fenix/app/outputs/bundle/waterfoxRelease/*.aab | |
| objdir/gradle/build/mobile/android/fenix/app/outputs/apk/waterfox/release/*.apk | |
| objdir/gradle/build/mobile/android/fenix/app/outputs/apk/waterfox/release/output-metadata.json | |
| retention-days: 7 | |
| - name: π§Ή Clean up | |
| run: rm -f mobile/android/fenix/app/keystore.jks | |
| release: | |
| name: Create GitHub Release | |
| needs: | |
| - build-app | |
| runs-on: namespace-profile-linux-sm | |
| permissions: | |
| contents: write | |
| environment: release | |
| concurrency: | |
| group: release | |
| cancel-in-progress: false | |
| steps: | |
| - name: β¬οΈ Download Build Artifacts | |
| uses: namespace-actions/download-artifact@v2 | |
| with: | |
| name: build-artifacts-${{ github.run_id }} | |
| path: artifacts | |
| - name: π Display structure of downloaded files | |
| run: ls -R artifacts | |
| - name: π Create Release | |
| continue-on-error: true | |
| env: | |
| GH_REPO: ${{ github.repository }} | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| VERSION_NAME=$(jq -r '.elements[0].versionName' artifacts/apk/waterfox/release/output-metadata.json) | |
| VERSION_CODE=$(jq -r '.elements[0].versionCode' artifacts/apk/waterfox/release/output-metadata.json) | |
| RELEASE_NAME="$VERSION_NAME ($VERSION_CODE)" | |
| gh release create "$VERSION_NAME-$VERSION_CODE" \ | |
| --draft \ | |
| --title "$RELEASE_NAME" \ | |
| artifacts/apk/waterfox/release/*.apk |