Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 158 additions & 0 deletions .github/actions/create-release-pr/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
name: Create Release Pull Request
description: 'Creates a release pull request for the specified platform (mobile or extension).'

inputs:
checkout-base-branch:
required: true
description: 'The base branch, tag, or SHA for git operations.'
release-pr-base-branch:
required: true
description: 'The base branch, tag, or SHA for the release pull request.'
semver-version:
required: true
description: 'A semantic version, e.g.: "x.y.z".'
mobile-build-version:
required: false
description: 'The build version for the mobile platform.'
previous-version-ref:
required: true
description: 'Previous release version branch name, tag or commit hash (e.g., release/7.7.0, v7.7.0, or 76fbc500034db9779e9ff7ce637ac5be1da0493d). For hotfix releases, pass the literal string "null".'
mobile-template-sheet-id:
required: false
description: 'The Mobile testing sheet template id.'
default: '1012668681' # prod sheet template
extension-template-sheet-id:
required: false
description: 'The Extension testing sheet template id.'
default: '295804563' # prod sheet template
test-only:
required: false
description: 'If true, the release will be marked as a test release.'
default: 'false'
release-sheet-google-document-id:
required: false
description: 'The Google Document ID for the release notes.'
default: '1tsoodlAlyvEUpkkcNcbZ4PM9HuC9cEM80RZeoVv5OCQ' # Prod Release Document
platform:
required: true
description: 'The platform for which the release PR is being created. Must be one of: mobile, extension.'
git-user-name:
description: 'Git user name for commits. Defaults to metamaskbot.'
default: 'metamaskbot'
git-user-email:
description: 'Git user email for commits. Defaults to metamaskbot@users.noreply.github.com.'
default: 'metamaskbot@users.noreply.github.com'
github-token:
description: 'GitHub token used for authentication.'
required: true
google-application-creds-base64:
description: 'Google application credentials base64 encoded.'
required: true
github-tools-repository:
description: 'The GitHub repository containing the GitHub tools. Defaults to the GitHub tools action repositor, and usually does not need to be changed.'
required: false
default: ${{ github.action_repository }}
github-tools-ref:
description: 'The SHA of the action to use. Defaults to the current action ref, and usually does not need to be changed.'
required: false
default: ${{ github.action_ref }}

runs:
using: composite
steps:
# Step 1: Checkout invoking repository (metamask-mobile | metamask-extension )
- name: Checkout invoking repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ inputs.checkout-base-branch }}
token: ${{ inputs.github-token }}

# Step 2: Checkout github-tools repository
- name: Checkout github-tools repository
uses: actions/checkout@v4
with:
repository: ${{ inputs.github-tools-repository }}
ref: ${{ inputs.github-tools-ref }}
path: github-tools

# Step 3: Setup environment
- name: Checkout and setup environment
uses: MetaMask/action-checkout-and-setup@v2
with:
is-high-risk-environment: true

# Step 4: Print Input Values
- name: Print Input Values
env:
PLATFORM: ${{ inputs.platform }}
CHECKOUT_BASE_BRANCH: ${{ inputs.checkout-base-branch }}
RELEASE_PR_BASE_BRANCH: ${{ inputs.release-pr-base-branch }}
SEMVER_VERSION: ${{ inputs.semver-version }}
PREVIOUS_VERSION_REF: ${{ inputs.previous-version-ref }}
TEST_ONLY: ${{ inputs.test-only }}
MOBILE_BUILD_VERSION: ${{ inputs.mobile-build-version }}
MOBILE_TEMPLATE_SHEET_ID: ${{ inputs.mobile-template-sheet-id }}
EXTENSION_TEMPLATE_SHEET_ID: ${{ inputs.extension-template-sheet-id }}
RELEASE_SHEET_GOOGLE_DOCUMENT_ID: ${{ inputs.release-sheet-google-document-id }}
GIT_USER_NAME: ${{ inputs.git-user-name }}
GIT_USER_EMAIL: ${{ inputs.git-user-email }}
shell: bash
run: |
echo "Input Values:"
echo "-------------"
echo "Platform: $PLATFORM"
echo "Checkout Base Branch: $CHECKOUT_BASE_BRANCH"
echo "Release PR Base Branch: $RELEASE_PR_BASE_BRANCH"
echo "Semver Version: $SEMVER_VERSION"
echo "Previous Version Reference: $PREVIOUS_VERSION_REF"
echo "Test Only Mode: $TEST_ONLY"
if [[ "$PLATFORM" == "mobile" ]]; then
echo "Mobile Build Version: $MOBILE_BUILD_VERSION"
fi
echo "Mobile Template Sheet ID: $MOBILE_TEMPLATE_SHEET_ID"
echo "Extension Template Sheet ID: $EXTENSION_TEMPLATE_SHEET_ID"
echo "Release Sheet Google Document ID: $RELEASE_SHEET_GOOGLE_DOCUMENT_ID"
echo "Git User Name: $GIT_USER_NAME"
echo "Git User Email: $GIT_USER_EMAIL"
echo "-------------"

# Step 5: Create Release PR
- name: Create Release PR
id: create-release-pr
shell: bash
env:
GITHUB_TOKEN: ${{ inputs.github-token }}
BASE_BRANCH: ${{ inputs.release-pr-base-branch }}
GITHUB_REPOSITORY_URL: '${{ github.server_url }}/${{ github.repository }}'
TEST_ONLY: ${{ inputs.test-only }}
GOOGLE_DOCUMENT_ID: ${{ inputs.release-sheet-google-document-id }}
GOOGLE_APPLICATION_CREDENTIALS_BASE64: ${{ inputs.google-application-creds-base64 }}
NEW_VERSION: ${{ inputs.semver-version }}
MOBILE_TEMPLATE_SHEET_ID: ${{ inputs.mobile-template-sheet-id }}
EXTENSION_TEMPLATE_SHEET_ID: ${{ inputs.extension-template-sheet-id }}
PLATFORM: ${{ inputs.platform }}
PREVIOUS_VERSION_REF: ${{ inputs.previous-version-ref }}
SEMVER_VERSION: ${{ inputs.semver-version }}
MOBILE_BUILD_VERSION: ${{ inputs.mobile-build-version }}
GIT_USER_NAME: ${{ inputs.git-user-name }}
GIT_USER_EMAIL: ${{ inputs.git-user-email }}
working-directory: ${{ github.workspace }}
run: |
# Execute the script from github-tools
./github-tools/.github/scripts/create-platform-release-pr.sh \
"$PLATFORM" \
"$PREVIOUS_VERSION_REF" \
"$SEMVER_VERSION" \
"$MOBILE_BUILD_VERSION" \
"$GIT_USER_NAME" \
"$GIT_USER_EMAIL"

# Step 6: Upload commits.csv as artifact (if generated)
- name: Upload commits.csv artifact
if: ${{ hashFiles('commits.csv') != '' }}
uses: actions/upload-artifact@v4
with:
name: commits-csv
path: commits.csv
if-no-files-found: error
71 changes: 71 additions & 0 deletions .github/actions/post-merge-validation/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Post Merge Validation
description: 'Tracks PRs merged to main and updates a Google Spreadsheet with validation status.'

inputs:
repo:
description: 'The repo owner/name to process (e.g. MetaMask/metamask-extension)'
required: true
start-hour-utc:
description: 'The hour of the day (UTC) to start processing the PRs merged in main'
required: true
spreadsheet-id:
description: 'Google Spreadsheet ID to update'
required: false
default: '1tsoodlAlyvEUpkkcNcbZ4PM9HuC9cEM80RZeoVv5OCQ'
lookback-days:
description: 'Number of days to look back for PRs'
required: false
default: '1'
github-token:
description: 'GitHub token with repo access'
required: true
google-application-creds-base64:
description: 'Base64 encoded Google service account credentials'
required: true
github-tools-repository:
description: 'The GitHub repository containing the GitHub tools. Defaults to the GitHub tools action repositor, and usually does not need to be changed.'
required: false
default: ${{ github.action_repository }}
github-tools-ref:
description: 'The SHA of the action to use. Defaults to the current action ref, and usually does not need to be changed.'
required: false
default: ${{ github.action_ref }}

runs:
using: composite
steps:
- name: Checkout GitHub tools repository
uses: actions/checkout@v5
with:
repository: ${{ inputs.github-tools-repository }}
ref: ${{ inputs.github-tools-ref }}
path: ./github-tools

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version-file: ./github-tools/.nvmrc
cache-dependency-path: ./github-tools/yarn.lock
cache: yarn

- name: Enable Corepack
shell: bash
run: corepack enable
working-directory: ./github-tools

- name: Install dependencies
working-directory: ./github-tools
shell: bash
run: yarn --immutable

- name: Run post-merge-validation script
working-directory: ./github-tools
env:
SHEET_ID: ${{ inputs.spreadsheet-id }}
START_HOUR_UTC: ${{ inputs.start-hour-utc }}
LOOKBACK_DAYS: ${{ inputs.lookback-days }}
REPO: ${{ inputs.repo }}
GITHUB_TOKEN: ${{ inputs.github-token }}
GOOGLE_APPLICATION_CREDENTIALS_BASE64: ${{ inputs.google-application-creds-base64 }}
shell: bash
run: node .github/scripts/post-merge-validation-tracker.mjs
145 changes: 145 additions & 0 deletions .github/actions/stable-sync/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
name: Stable Sync
description: 'An action to sync the release branch to main for a given semantic version.'

inputs:
semver-version:
required: true
description: 'The semantic version to use for the sync (e.g., x.x.x)'
repo-type:
required: false
description: 'Type of repository (mobile or extension)'
default: 'mobile'
stable-branch-name:
required: false
description: 'The name of the stable branch to sync to (e.g., stable, main)'
default: 'stable'
github-token:
description: 'GitHub token used for authentication.'
required: true
github-tools-repository:
description: 'The GitHub repository containing the GitHub tools. Defaults to the GitHub tools action repositor, and usually does not need to be changed.'
required: false
default: ${{ github.action_repository }}
github-tools-ref:
description: 'The SHA of the action to use. Defaults to the current action ref, and usually does not need to be changed.'
required: false
default: ${{ github.action_ref }}

runs:
using: composite
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Checkout GitHub tools repository
uses: actions/checkout@v5
with:
repository: ${{ inputs.github-tools-repository }}
ref: ${{ inputs.github-tools-ref }}
path: ./github-tools

- name: Setup Node.js Mobile
if: ${{ inputs.repo-type == 'mobile' }}
uses: actions/setup-node@v6
with:
node-version: '18'

- name: Setup Node.js Extension
if: ${{ inputs.repo-type == 'extension' }}
uses: actions/setup-node@v6
with:
node-version: '22.15'

- name: Prepare Yarn
if: ${{ inputs.repo-type == 'extension' }}
shell: bash
run: corepack prepare yarn@4.5.1 --activate

- name: Prepare Yarn - Enable corepack
if: ${{ inputs.repo-type == 'extension' }}
shell: bash
run: corepack enable

- name: Check if PR exists
id: check-pr
uses: actions/github-script@v7
with:
script: |
const { data: prs } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
head: `${context.repo.owner}:stable-main-${process.env.SEMVER_VERSION}`,
base: 'main'
});
return prs.length > 0;
env:
SEMVER_VERSION: ${{ inputs.semver-version }}

- name: Set Git user and email
shell: bash
run: |
git config --global user.name "metamaskbot"
git config --global user.email "metamaskbot@users.noreply.github.com"

- name: Run stable sync
id: run-stable-sync
# if: steps.check-pr.outputs.result != 'true'
env:
CREATE_BRANCH: 'false' # let the script handle the branch creation
REPO: ${{ inputs.repo-type }} # Default to 'mobile' if not specified
BASE_BRANCH: ${{ inputs.stable-branch-name }}
SEMVER_VERSION: ${{ inputs.semver-version }}
shell: bash
run: |
# Ensure github-tools is in .gitignore to prevent it from being committed
if ! grep -q "^github-tools/" .gitignore 2>/dev/null; then
echo "github-tools/" >> .gitignore
echo "Added github-tools/ to .gitignore"
fi

# Execute the script from github-tools
node ./github-tools/.github/scripts/stable-sync.js "stable-main-$SEMVER_VERSION"
BRANCH_NAME="stable-main-$SEMVER_VERSION"
if git ls-remote --heads origin "$BRANCH_NAME" | grep -q "$BRANCH_NAME"; then
echo "Branch $BRANCH_NAME exists remotely, force pushing to overwrite"
git push origin "$BRANCH_NAME" --force
else
echo "Branch $BRANCH_NAME doesn't exist remotely, pushing with --set-upstream"
git push --set-upstream origin "$BRANCH_NAME"
fi

- name: Create Pull Request
if: steps.check-pr.outputs.result != 'true'
env:
GITHUB_TOKEN: ${{ inputs.github-token }}
BRANCH_NAME: stable-main-${{ inputs.semver-version }}
VERSION: ${{ inputs.semver-version }}
shell: bash
run: |
# Create PR using GitHub CLI
gh pr create \
--title "release: sync stable to main for version $VERSION" \
--body "This PR syncs the stable branch to main for version $VERSION.

*Synchronization Process:*

- Fetches the latest changes from the remote repository
- Resets the branch to match the stable branch
- Attempts to merge changes from main into the branch
- Handles merge conflicts if they occur

*File Preservation:*

Preserves specific files from the stable branch:
- CHANGELOG.md
- bitrise.yml
- android/app/build.gradle
- ios/MetaMask.xcodeproj/project.pbxproj
- package.json

Indicates the next version candidate of main to $VERSION" \
--base main \
--head "$BRANCH_NAME"
#--label "sync" \
#--label "stable"
Loading
Loading