diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6c0823072dd1..ac6c903ebc44 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -50,7 +50,6 @@ scripts/build.sh @MetaMask/mobile-pla fingerprint.config.js @MetaMask/mobile-platform builds.yml @MetaMask/mobile-platform .github/workflows/generate-build-version.yml @MetaMask/mobile-platform -.github/workflows/commit-build-version.yml @MetaMask/mobile-platform .github/workflows/push-eas-update.yml @MetaMask/mobile-admins .github/workflows/build-and-upload-to-testflight.yml @MetaMask/mobile-admins .github/workflows/upload-to-testflight.yml @MetaMask/mobile-admins diff --git a/.github/workflows/auto-rc-ota-build-core.yml b/.github/workflows/auto-rc-ota-build-core.yml index 5abd58ba7649..10ee31998d78 100644 --- a/.github/workflows/auto-rc-ota-build-core.yml +++ b/.github/workflows/auto-rc-ota-build-core.yml @@ -43,6 +43,11 @@ on: required: false type: boolean default: true + build_number: + description: 'Build number from generate-build-version.yml to apply locally at build time' + required: false + type: string + default: '' outputs: semantic_version: description: 'package.json version at the built commit (empty when OTA bump skips the build)' @@ -76,6 +81,7 @@ jobs: build_name: ${{ inputs.build_name }} platform: ${{ inputs.platform }} source_branch: ${{ inputs.source_branch || github.ref_name }} + build_number: ${{ inputs.build_number }} upload_to_sentry: true secrets: inherit diff --git a/.github/workflows/build-rc-auto.yml b/.github/workflows/build-rc-auto.yml index 2c9a86d4ff05..e5cd3b7dd305 100644 --- a/.github/workflows/build-rc-auto.yml +++ b/.github/workflows/build-rc-auto.yml @@ -7,8 +7,9 @@ # in-progress run of this workflow for that branch is cancelled (one branch + one # workflow at a time). # -# Version bump: generate-build-version → commit-build-version, then iOS and Android -# builds are triggered in parallel via auto-rc-ota-build-core.yml (bump commit passed as source_branch). +# Version bump: generate-build-version, then iOS and Android builds are triggered in parallel +# via auto-rc-ota-build-core.yml with the generated number applied locally at build time. +# Both platforms pin source_branch to github.sha so they build the same commit. # # The RC build comment includes an AI-generated test plan (inline with collapsible sections). # @@ -31,8 +32,8 @@ concurrency: cancel-in-progress: true permissions: - contents: write pull-requests: write + contents: read actions: write id-token: write @@ -62,7 +63,7 @@ jobs: echo "branch-name=$BRANCH_NAME" >> "$GITHUB_OUTPUT" # Validate branch matches release/x.y.z or release/x.y.z-ota (OTA hotfix) format - if [[ "$BRANCH_NAME" =~ ^release/[0-9]+\.[0-9]+\.[0-9]+(-ota)?$ ]]; then + if [[ "$BRANCH_NAME" =~ ^release/[0-9]+\.[0-9]+\.[0-9]+(-(ota|test))?$ ]]; then VERSION="${BRANCH_NAME#release/}" # Strip `-ota` suffix: it is a branch-name convention only. Downstream consumers # (build-announce display "RC X.Y.Z", test-plan artifact name) expect strict X.Y.Z. @@ -116,28 +117,19 @@ jobs: needs: validate-and-find-pr if: needs.validate-and-find-pr.outputs.has-pr == 'true' && needs.validate-and-find-pr.outputs.rc-frozen != 'true' - update_rc_build_version: - name: Commit RC build version - uses: ./.github/workflows/commit-build-version.yml - needs: [validate-and-find-pr, generate_rc_build_version] - if: needs.validate-and-find-pr.outputs.has-pr == 'true' && needs.validate-and-find-pr.outputs.rc-frozen != 'true' - permissions: - contents: write - id-token: write - with: - base-branch: ${{ needs.validate-and-find-pr.outputs.branch-name }} - build_number: ${{ needs.generate_rc_build_version.outputs.build-version }} - trigger-ios-rc-build: name: Trigger iOS RC Build uses: ./.github/workflows/auto-rc-ota-build-core.yml needs: - validate-and-find-pr - - update_rc_build_version + - generate_rc_build_version if: needs.validate-and-find-pr.outputs.has-pr == 'true' && needs.validate-and-find-pr.outputs.rc-frozen != 'true' with: platform: ios - source_branch: ${{ needs.update_rc_build_version.outputs.commit-hash }} + # Pin to the triggering commit so iOS and Android build the same SHA even if + # cherry-picks land on the release branch while the two jobs are in flight. + source_branch: ${{ github.sha }} + build_number: ${{ needs.generate_rc_build_version.outputs.build-version }} distribute_external: true secrets: inherit @@ -146,11 +138,12 @@ jobs: uses: ./.github/workflows/auto-rc-ota-build-core.yml needs: - validate-and-find-pr - - update_rc_build_version + - generate_rc_build_version if: needs.validate-and-find-pr.outputs.has-pr == 'true' && needs.validate-and-find-pr.outputs.rc-frozen != 'true' with: platform: android - source_branch: ${{ needs.update_rc_build_version.outputs.commit-hash }} + source_branch: ${{ github.sha }} + build_number: ${{ needs.generate_rc_build_version.outputs.build-version }} secrets: inherit post-rc-build-comment: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6b1b13ac8cf0..96ee77b43c74 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,9 +24,7 @@ on: build_number: description: >- Optional (workflow_call only). From generate-build-version.yml. When non-empty, each matrix - build runner applies scripts/set-build-version.sh locally before building. Omit when - source_branch already contains the desired build number (e.g. commit-hash from - commit-build-version.yml). + build runner applies scripts/set-build-version.sh locally before building. required: false type: string default: '' diff --git a/.github/workflows/commit-build-version.yml b/.github/workflows/commit-build-version.yml deleted file mode 100644 index 1621d5752749..000000000000 --- a/.github/workflows/commit-build-version.yml +++ /dev/null @@ -1,64 +0,0 @@ -############################################################################################## -# -# Commit Build Version (reusable) -# -# Applies a caller-supplied build number to version files, commits, and pushes to base-branch. -# Does not generate the number — use generate-build-version.yml first. -# -############################################################################################## -name: Commit Build Version - -on: - workflow_call: - inputs: - base-branch: - description: 'Branch, tag, or SHA to checkout and push the version bump to' - required: true - type: string - build_number: - description: 'Build number from generate-build-version.yml outputs.build-version' - required: true - type: string - outputs: - commit-hash: - description: 'Commit SHA with build version bumped' - value: ${{ jobs.commit.outputs.commit-hash }} - -permissions: - id-token: write - -jobs: - commit: - runs-on: ubuntu-latest - outputs: - commit-hash: ${{ steps.bump-build-version.outputs.commit-hash }} - steps: - - name: Get token - id: get-token - uses: MetaMask/github-tools/.github/actions/get-token@v1 - with: - token-exchange-url: ${{ vars.TOKEN_EXCHANGE_URL }} - permissions: | - contents: write - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - ref: ${{ inputs.base-branch }} - token: ${{ steps.get-token.outputs.token }} - - name: Bump build version - id: bump-build-version - shell: bash - env: - BUILD_NUMBER: ${{ inputs.build_number }} - HEAD_REF: ${{ inputs.base-branch }} - run: | - ./scripts/set-build-version.sh "$BUILD_NUMBER" - git diff - git config user.name metamaskbot - git config user.email metamaskbot@users.noreply.github.com - git add package.json - git add ios/MetaMask.xcodeproj/project.pbxproj - git add android/app/build.gradle - git commit -m "[skip ci] Bump version number to ${BUILD_NUMBER}" - git push origin HEAD:"$HEAD_REF" --force-with-lease - echo "commit-hash=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/create-release-pr.yml b/.github/workflows/create-release-pr.yml index 4b83b603551d..eda27f1f1cbc 100644 --- a/.github/workflows/create-release-pr.yml +++ b/.github/workflows/create-release-pr.yml @@ -93,15 +93,33 @@ jobs: run: | .github/scripts/resolve-previous-ref.sh - generate-build-version: + resolve-build-version: + name: Resolve current build number needs: resolve-bases if: needs.resolve-bases.outputs.is_ota != 'true' - uses: ./.github/workflows/generate-build-version.yml + runs-on: ubuntu-latest + outputs: + build-version: ${{ steps.meta.outputs.ios_version_code }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{ needs.resolve-bases.outputs.checkout_base }} + fetch-depth: 1 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + + - name: Read build number from version files + id: meta + run: ./scripts/get-build-metadata.sh --ci create-release-pr: - needs: [resolve-bases, resolve-previous-ref, generate-build-version] - # When generate-build-version is skipped (OTA), this job must still run; see https://docs.github.com/en/actions/using-jobs/using-jobs-in-a-workflow#handling-skipped-dependent-jobs - if: always() && needs.resolve-bases.result == 'success' && needs.resolve-previous-ref.result == 'success' && (needs.generate-build-version.result == 'success' || needs.generate-build-version.result == 'skipped') + needs: [resolve-bases, resolve-previous-ref, resolve-build-version] + # When resolve-build-version is skipped (OTA), this job must still run; see https://docs.github.com/en/actions/using-jobs/using-jobs-in-a-workflow#handling-skipped-dependent-jobs + if: always() && needs.resolve-bases.result == 'success' && needs.resolve-previous-ref.result == 'success' && (needs.resolve-build-version.result == 'success' || needs.resolve-build-version.result == 'skipped') name: Create Release Pull Request using Github Tools runs-on: ubuntu-latest steps: @@ -132,7 +150,9 @@ jobs: release-pr-base-branch: ${{ needs.resolve-bases.outputs.release_base }} semver-version: ${{ inputs.semver-version }} previous-version-ref: ${{ needs.resolve-previous-ref.outputs.previous_ref }} - mobile-build-version: ${{ needs.generate-build-version.outputs.build-version }} + # github-tools requires this input for mobile, but only bumps semver on the release branch. + # Build numbers are applied locally at build time (see build.yml build_number input). + mobile-build-version: ${{ needs.resolve-build-version.outputs.build-version }} github-token: ${{ steps.get-token.outputs.token }} google-application-creds-base64: ${{ github.event_name == 'workflow_dispatch' && secrets.GCP_RLS_SHEET_ACCOUNT_BASE64 || secrets.google-application-creds-base64 }} diff --git a/.github/workflows/runway-production-builds.yml b/.github/workflows/runway-production-builds.yml index 37ed85b82861..d5932cb0ad7b 100644 --- a/.github/workflows/runway-production-builds.yml +++ b/.github/workflows/runway-production-builds.yml @@ -3,9 +3,9 @@ # Runway Production Builds # # Triggered from Runway to build the production iOS + Android binaries in one run. -# Bumps the build version once, then dispatches build.yml with platform: both so iOS and Android -# build in parallel against the same bumped commit. Finishes by uploading the iOS IPA to -# TestFlight. +# Generates the build number once, then dispatches build.yml with platform: both so iOS and Android +# apply the same number locally at build time (no version-bump commit). Finishes by uploading the +# iOS IPA to TestFlight. # # This workflow only produces fresh native binaries — OTA updates are handled by the separate # runway-ota-production.yml workflow. @@ -24,7 +24,7 @@ on: type: string permissions: - contents: write # required by commit-build-version.yml + contents: read pull-requests: read actions: write id-token: write # required by build.yml @@ -34,24 +34,17 @@ jobs: name: Generate build version uses: ./.github/workflows/generate-build-version.yml - commit-build-version: - name: Commit build version - needs: generate-build-version - uses: ./.github/workflows/commit-build-version.yml - permissions: - id-token: write - with: - base-branch: ${{ inputs.source_branch || github.ref_name }} - build_number: ${{ needs.generate-build-version.outputs.build-version }} - build: name: Build iOS + Android (main-prod) - needs: commit-build-version + needs: generate-build-version uses: ./.github/workflows/build.yml with: build_name: main-prod platform: both - source_branch: ${{ needs.commit-build-version.outputs.commit-hash }} + # Prefer an explicit input; otherwise pin to the dispatch SHA so iOS and + # Android do not race a moving branch tip under one build number. + source_branch: ${{ inputs.source_branch || github.sha }} + build_number: ${{ needs.generate-build-version.outputs.build-version }} upload_to_sentry: true secrets: inherit diff --git a/.github/workflows/runway-rc-builds.yml b/.github/workflows/runway-rc-builds.yml index 939448bc317f..9d5b1a923d0e 100644 --- a/.github/workflows/runway-rc-builds.yml +++ b/.github/workflows/runway-rc-builds.yml @@ -3,9 +3,9 @@ # Runway RC Builds # # Triggered from Runway to build the release-candidate iOS + Android binaries in one run. -# Bumps the build version once, then dispatches build.yml with platform: both so iOS and Android -# build in parallel against the same bumped commit. Uploads the iOS IPA to TestFlight and posts -# a Slack notification with the resulting build numbers. +# Generates the build number once, then dispatches build.yml with platform: both so iOS and Android +# apply the same number locally at build time (no version-bump commit). Uploads the iOS IPA to +# TestFlight and posts a Slack notification with the resulting build numbers. # # This workflow only produces fresh native binaries — OTA updates are handled by the separate # runway-ota-rc.yml workflow. @@ -24,7 +24,7 @@ on: type: string permissions: - contents: write # required by commit-build-version.yml + contents: read pull-requests: read actions: write id-token: write # required by build.yml @@ -34,24 +34,17 @@ jobs: name: Generate build version uses: ./.github/workflows/generate-build-version.yml - commit-build-version: - name: Commit build version - needs: generate-build-version - uses: ./.github/workflows/commit-build-version.yml - permissions: - id-token: write - with: - base-branch: ${{ inputs.source_branch || github.ref_name }} - build_number: ${{ needs.generate-build-version.outputs.build-version }} - build: name: Build iOS + Android (main-rc) - needs: commit-build-version + needs: generate-build-version uses: ./.github/workflows/build.yml with: build_name: main-rc platform: both - source_branch: ${{ needs.commit-build-version.outputs.commit-hash }} + # Prefer an explicit input; otherwise pin to the dispatch SHA so iOS and + # Android do not race a moving branch tip under one build number. + source_branch: ${{ inputs.source_branch || github.sha }} + build_number: ${{ needs.generate-build-version.outputs.build-version }} upload_to_sentry: true secrets: inherit diff --git a/scripts/create-release-pr.sh b/scripts/create-release-pr.sh index 3a4f021ba829..d09b6e61fe85 100755 --- a/scripts/create-release-pr.sh +++ b/scripts/create-release-pr.sh @@ -6,7 +6,6 @@ set -o pipefail PREVIOUS_VERSION="${1}" NEW_VERSION="${2}" -NEW_VERSION_NUMBER="${3}" RELEASE_BRANCH_PREFIX="release/" if [[ -z $NEW_VERSION ]]; then @@ -49,16 +48,15 @@ git checkout "${RELEASE_BRANCH_NAME}" echo "Release Branch Checked Out" echo "Running version update scripts.." -# Bump versions for the release +# Bump semver for the release (build numbers are applied at build time) ./scripts/set-semvar-version.sh "${NEW_VERSION}" -./scripts/set-build-version.sh "${NEW_VERSION_NUMBER}" echo "Adding and committing changes.." # Track our changes git add package.json android/app/build.gradle ios/MetaMask.xcodeproj/project.pbxproj # Generate a commit -git commit -m "bump semvar version to ${NEW_VERSION} && build version to ${NEW_VERSION_NUMBER}" +git commit -m "bump semvar version to ${NEW_VERSION}" echo "Pushing changes to the remote.." git push --set-upstream origin "${RELEASE_BRANCH_NAME}"