Skip to content

Conversation

@Mrtenz
Copy link
Member

@Mrtenz Mrtenz commented Nov 11, 2025

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

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, highlighting breaking changes as necessary
  • I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes

Note

Adds a composite action and workflow job to block release PRs (including merge queue) when releasing packages that conflict with upstream changes.

  • CI/Workflows:
    • Enable merge_group trigger in .github/workflows/main.yml.
    • Add check-release job for PRs/merge groups using MetaMask/action-is-release to detect releases and invoking ./.github/actions/check-release; included in all-jobs-complete needs.
  • New composite action:
    • ./.github/actions/check-release/action.yml compares package versions at MERGE_BASE vs HEAD to find released packages, checks files changed between before..MERGE_BASE, and fails with an error if changes touch those package directories.

Written by Cursor Bugbot for commit 2f0340c. This will update automatically on new commits. Configure here.

needs: check-workflows
runs-on: ubuntu-latest
steps:
- name: Check if the commit or pull request is a release
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered reusing the is-release job below, but it adds a little bit of complexity around the conditionals, and we don't need the extra options below for merged commits.

Copy link
Member

@Gudahtt Gudahtt Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We could maybe skip this for push events? Just because it wouldn't be relevant anymore for push, and this might make it a bit more clear why we have to similarly-named jobs

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could skip the individual steps on push, but not the job itself, since that would cause all-jobs-complete to be skipped.

uses: MetaMask/action-is-release@d063725cd15ee145d7e795a2e77db31a3e3f2c92
with:
commit-starts-with: 'Release [version],Release v[version],Release/[version],Release/v[version],Release `[version]`'
commit-message: ${{ github.event.pull_request.title }}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used so we can determine if an unmerged pull request is a release pull request. github.event.pull_request.title is not defined for other events (push and merge_group), so doesn't affect those.

with:
commit-starts-with: 'Release [version],Release v[version],Release/[version],Release/v[version],Release `[version]`'
commit-message: ${{ github.event.pull_request.title }}
before: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before }}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

github.event.before is only defined on push, not on pull_request or merge_group, so I had to add this.

Copy link
Member

@Gudahtt Gudahtt Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

base.sha doesn't seem correct here.

In the action-is-release action, we used github.event.before to get the diff of what changed in a given commit, to check whether the version number had changed. For the push event, the diff betweeen github.event.before and the current commit would only include changes from that push event.

Whereas base.sha refers to the commit on the base branch that the PR was originally branched from. It does not get updated when the branch is updated with a merge commit. That means if a core release goes out while a PR is open, github.event.pull_request.base.sha..HEAD will include a version bump from the unrelated core release on main.

Instead I think we need the merge-base here, between the base branch and the current commit

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either that, or get the merge-base in action-is-release instead

needs: check-workflows
uses: ./.github/workflows/lint-build-test.yml

check-release:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't add a conditional here, but only to the step below. This way we can add check-release as dependency to all-jobs-complete. Otherwise, if check-release (the job) is skipped, all-jobs-complete would be skipped too.

done
# Get all files changed ahead of this PR.
git diff --name-only "$BEFORE..$(git merge-base HEAD refs/remotes/origin/main)" > changed-files.txt
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding, git merge-base HEAD refs/remotes/origin/main finds the common ancestor between HEAD (i.e., the current commit), and origin/main. We can then diff $BEFORE with that to find any differences on main not included in the current branch.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an action rather than a workflow to support the uses syntax in a step, rather than as a job. It's related to this comment.

@Mrtenz Mrtenz marked this pull request as ready for review November 12, 2025 14:40
@Mrtenz Mrtenz requested a review from a team as a code owner November 12, 2025 14:40
@Mrtenz Mrtenz force-pushed the mrtenz/merge-queue-release-validation branch from d677951 to 56f08cb Compare November 12, 2025 14:40
# Get all packages being released in this PR
for package in "${PACKAGES[@]}"; do
MAIN_VERSION=$(git show "refs/remotes/origin/main:$package" | jq -r .version)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comparison doesn't seem quite right. We're using origin/main as the "before the current commit" comparison point, but there might be more changes in-between origin/main and the current commit. e.g. if there is a release PR queued before the current one

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if: github.event_name != 'push' && steps.is-release.outputs.IS_RELEASE == 'true'
uses: ./.github/actions/check-release
with:
before: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha }}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Merge Queue Conflict Blind Spot

Using github.event.pull_request.base.sha or github.event.merge_group.base_sha as the before parameter doesn't capture changes from other PRs in the merge queue. These values represent the base branch commit when the PR was created, not the current state including queued changes. This means the release conflict check won't detect conflicts with other PRs ahead in the merge queue, defeating the purpose of checking merge queue conflicts.

Fix in Cursor Fix in Web

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor didn't explain this super well, but, I think this comment is at least partially accurate.

If you didn't use any merge commits, base.sha is exactly what we want here I think (at least for the pull_request event, not 100% sure on merge_group), but merges break that assumption.

Essentially what we want to compare in check-release is the previous merge base with the current merge base. We want to compare a merge base for both sides of the comparison.

Copy link
Member

@Gudahtt Gudahtt Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the merge_group event, would base.sha refer to the previous commit in the queue itself? Even the merge-base of base.sha might not refer to the correct commit if that's the case.

We might need to consider something like.... grab the PR number from the merge-queue branch name, fetch the branch for that PR, then get the merge-base of that branch.

I found a discussion where someone talked about how to get the PR number from the merge queue branch name: https://github.com/orgs/community/discussions/120203
(in service of a different goal, of skipping the queue for PRs that were already up-to-date, which also would be pretty neat)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants