Skip to content

Commit af8b97b

Browse files
authored
ci: Check if any changes made ahead of PR affect a release to support merge queue (#7114)
## Explanation This adds the `merge_group` target and adds a check for releases, so we can safely enable the merge queue. The release check will check for any differences on `main` or in the merge queue compared to the release branch. If any conflicts are detected, the release will be rejected from the merge queue, and will need to be updated with the latest changes first. ## References <!-- Are there any issues that this pull request is tied to? Are there other links that reviewers should consult to understand these changes better? Are there client or consumer pull requests to adopt any breaking changes? For example: * Fixes #12345 * Related to #67890 --> ## Checklist - [ ] I've updated the test suite for new or updated code as appropriate - [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [ ] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/core/tree/main/docs/contributing.md#updating-changelogs), highlighting breaking changes as necessary - [ ] I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Add merge queue support and a release-conflict check action integrated into the main workflow for release PRs. > > - **CI/Workflows**: > - Add `merge_group` trigger to `.github/workflows/main.yml`. > - Introduce `check-release` job to detect PR/merge-queue releases and run conflict checks. > - Uses `MetaMask/action-is-release` to detect release PRs and extracts PR number (supports merge queue refs). > - Wires results into overall job dependencies (`all-jobs-complete` now needs `check-release`). > - **New Composite Action**: > - Add `.github/actions/check-release/action.yml` to detect release conflicts across packages. > - Identifies packages with version bumps vs `main`, computes changed files ahead of the PR/merge group target, and errors on conflicts. > - Supports `pull_request` and `merge_group` events; fetches PR branch via `gh` and compares against calculated target. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit babd67a. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent c459156 commit af8b97b

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: Check release
2+
description: Check for conflicts in packages being released in this PR.
3+
4+
inputs:
5+
pull-request:
6+
description: 'The pull request number to get changed files from.'
7+
required: true
8+
9+
runs:
10+
using: composite
11+
steps:
12+
- name: Checkout repository
13+
uses: actions/checkout@v4
14+
with:
15+
fetch-depth: 0
16+
17+
- name: Get target reference
18+
id: get-target
19+
shell: bash
20+
env:
21+
EVENT_NAME: ${{ github.event_name }}
22+
run: |
23+
if [ "$EVENT_NAME" = "pull_request" ]; then
24+
echo "TARGET=$(git merge-base HEAD refs/remotes/origin/main)" >> "$GITHUB_OUTPUT"
25+
elif [ "$EVENT_NAME" = "merge_group" ]; then
26+
echo "TARGET=$(git rev-parse HEAD^)" >> "$GITHUB_OUTPUT"
27+
else
28+
echo "::error::This action only supports \`pull_request\` and \`merge_group\` events."
29+
exit 1
30+
fi
31+
32+
- name: Check commits for changes in released packages
33+
shell: bash
34+
env:
35+
GH_TOKEN: ${{ github.token }}
36+
PULL_REQUEST: ${{ inputs.pull-request }}
37+
TARGET: ${{ steps.get-target.outputs.TARGET }}
38+
run: |
39+
set -euo pipefail
40+
git fetch origin main
41+
42+
mapfile -t PACKAGES < <(find packages -maxdepth 2 -name "package.json" -not -path "*/node_modules/*")
43+
RELEASED_PACKAGES=()
44+
45+
# Get all packages being released in this PR
46+
MERGE_BASE=$(git merge-base HEAD refs/remotes/origin/main)
47+
for package in "${PACKAGES[@]}"; do
48+
MAIN_VERSION=$(git show "$MERGE_BASE:$package" | jq -r .version)
49+
HEAD_VERSION=$(jq -r .version "$package")
50+
51+
if [ "$HEAD_VERSION" != "$MAIN_VERSION" ]; then
52+
package_name=$(jq -r ".name" "$package")
53+
echo "📦 Package \`$package_name\` is being released (version \`$MAIN_VERSION\` -> \`$HEAD_VERSION\`)"
54+
RELEASED_PACKAGES+=("$package")
55+
fi
56+
done
57+
58+
# Fetch the pull request branch to compare changes.
59+
PULL_REQUEST_BRANCH=$(gh pr view "$PULL_REQUEST" --json headRefName --template "{{ .headRefName }}")
60+
echo "🔍 Checking for release conflicts with files changed ahead of PR branch \`$PULL_REQUEST_BRANCH\`..."
61+
git fetch origin "$PULL_REQUEST_BRANCH"
62+
63+
# Get all files changed ahead of this PR.
64+
BEFORE=$(git merge-base "refs/remotes/origin/main" "origin/$PULL_REQUEST_BRANCH")
65+
git diff --name-only "$BEFORE..$TARGET" > changed-files.txt
66+
67+
CONFLICTS=()
68+
for package in "${RELEASED_PACKAGES[@]}"; do
69+
package_directory=$(dirname "$package")
70+
if grep -q "^$package_directory/" changed-files.txt; then
71+
CONFLICTS+=("$package_directory")
72+
fi
73+
done
74+
75+
if [ ${#CONFLICTS[@]} -ne 0 ]; then
76+
mapfile -t CONFLICTS < <(printf "%s\n" "${CONFLICTS[@]}" | sort -u)
77+
fi
78+
79+
if [ ${#CONFLICTS[@]} -ne 0 ]; then
80+
for conflict in "${CONFLICTS[@]}"; do
81+
package_name=$(jq -r ".name" "$conflict/package.json")
82+
echo "::error::Release conflict detected in \`$package_name\`. This package is being released in this PR, but files in the package were also modified ahead of this PR. Please ensure that all changes are included in the release."
83+
done
84+
exit 1
85+
else
86+
echo "✅ No release conflicts detected."
87+
fi

.github/workflows/main.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
push:
55
branches: [main]
66
pull_request:
7+
merge_group:
78

89
concurrency:
910
group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.sha || github.ref }}
@@ -62,6 +63,59 @@ jobs:
6263
needs: check-workflows
6364
uses: ./.github/workflows/lint-build-test.yml
6465

66+
check-release:
67+
name: Check release
68+
needs: check-workflows
69+
runs-on: ubuntu-latest
70+
steps:
71+
- name: Checkout repository
72+
uses: actions/checkout@v4
73+
with:
74+
fetch-depth: 0
75+
76+
- name: Get merge base
77+
id: merge-base
78+
if: github.event_name != 'push'
79+
env:
80+
BASE_REF: ${{ github.event.pull_request.base.ref || github.event.merge_group.base_ref }}
81+
run: |
82+
echo "MERGE_BASE=$(git merge-base HEAD "refs/remotes/origin/$BASE_REF")" >> "$GITHUB_OUTPUT"
83+
84+
- name: Check if the commit or pull request is a release
85+
id: is-release
86+
if: github.event_name != 'push'
87+
uses: MetaMask/action-is-release@d063725cd15ee145d7e795a2e77db31a3e3f2c92
88+
with:
89+
commit-starts-with: 'Release [version],Release v[version],Release/[version],Release/v[version],Release `[version]`'
90+
commit-message: ${{ github.event.pull_request.title }}
91+
before: ${{ steps.merge-base.outputs.MERGE_BASE }}
92+
93+
- name: Get pull request number
94+
if: github.event_name != 'push'
95+
id: pr-number
96+
env:
97+
EVENT_NAME: ${{ github.event_name }}
98+
PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
99+
MERGE_GROUP_HEAD_REF: ${{ github.event.merge_group.head_ref }}
100+
run: |
101+
if [ "$EVENT_NAME" = "pull_request" ]; then
102+
echo "PR_NUMBER=$PULL_REQUEST_NUMBER" >> "$GITHUB_OUTPUT"
103+
elif [ "$EVENT_NAME" = "merge_group" ]; then
104+
PR_NUMBER_REGEX='/pr-([0-9]+)-'
105+
if [[ "$MERGE_GROUP_HEAD_REF" =~ $PR_NUMBER_REGEX ]]; then
106+
echo "PR_NUMBER=${BASH_REMATCH[1]}" >> "$GITHUB_OUTPUT"
107+
else
108+
echo "::error::Could not extract PR number from merge group head ref: $MERGE_GROUP_HEAD_REF."
109+
exit 1
110+
fi
111+
fi
112+
113+
- name: Check release
114+
if: github.event_name != 'push' && steps.is-release.outputs.IS_RELEASE == 'true'
115+
uses: ./.github/actions/check-release
116+
with:
117+
pull-request: ${{ steps.pr-number.outputs.PR_NUMBER }}
118+
65119
is-release:
66120
name: Determine whether this is a release merge commit
67121
needs: lint-build-test
@@ -99,6 +153,7 @@ jobs:
99153
runs-on: ubuntu-latest
100154
needs:
101155
- analyse-code
156+
- check-release
102157
- lint-build-test
103158
outputs:
104159
passed: ${{ steps.set-output.outputs.passed }}

0 commit comments

Comments
 (0)