Skip to content
Open
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
61175c2
feat: adopt auto-changelog v6 --checkDeps for dependency bump validation
cryptodev-2s Apr 13, 2026
a83983a
fix: correct --checkDeps usage and handle main branch
cryptodev-2s Apr 13, 2026
02fd302
fix: trigger fix-changelogs via @metamaskbot check-deps PR comment
cryptodev-2s Apr 13, 2026
14d0298
revert: remove --checkDeps from validate-changelog.sh
cryptodev-2s Apr 13, 2026
9c0924f
fix: use env vars to prevent code injection in fix-changelogs workflow
cryptodev-2s Apr 13, 2026
f3192c6
fix: skip fix-changelogs workflow on fork PRs
cryptodev-2s Apr 13, 2026
925ca11
fix: address code review findings in fix-changelogs workflow
cryptodev-2s Apr 13, 2026
a62d2ee
fix: address review feedback for fix-changelogs workflow
cryptodev-2s Apr 13, 2026
b6cf542
fix: remove unnecessary yarn changelog:update step
cryptodev-2s Apr 13, 2026
b516c86
fix: move reaction step first and report push failures in comment
cryptodev-2s Apr 13, 2026
455620a
fix: remove unnecessary checkout from fork detection job
cryptodev-2s Apr 13, 2026
9069a65
feat: auto-trigger fix-changelogs on release PR open
cryptodev-2s Apr 14, 2026
5a137b1
fix: rename workflow to update-changelogs
cryptodev-2s Apr 14, 2026
61a4b9e
fix: add job timeout and defensive git add separator
cryptodev-2s Apr 14, 2026
f4aabbb
fix: address remaining review findings
cryptodev-2s Apr 14, 2026
e8bd7be
fix: fetch origin/main for --checkDeps base branch comparison
cryptodev-2s Apr 15, 2026
30eec0c
fix: use full git history and hide previous bot comments
cryptodev-2s Apr 15, 2026
b20f53e
fix: improve bot comment hiding reliability
cryptodev-2s Apr 15, 2026
29a5a04
feat: use CHANGELOG_UPDATE_TOKEN for git push to trigger CI
cryptodev-2s Apr 15, 2026
d29dc62
fix: rename secret to UPDATE_CHANGELOG_TOKEN
cryptodev-2s Apr 15, 2026
567a53b
fix: use actions/checkout with PAT directly
cryptodev-2s Apr 15, 2026
0959ecc
fix: address review findings - dead code, regex, token cleanup
cryptodev-2s Apr 15, 2026
bbac608
fix: use github.token for reactions and comments, PAT only for git push
cryptodev-2s Apr 15, 2026
aa78ed8
fix: add continue-on-error to reaction step
cryptodev-2s Apr 16, 2026
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
125 changes: 125 additions & 0 deletions .github/workflows/update-changelogs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
name: Update Changelogs

on:
issue_comment:
types: [created]
pull_request:
branches: [main]
types: [opened]

concurrency:
group: update-changelogs-${{ github.event.issue.number || github.event.pull_request.number }}
cancel-in-progress: true

permissions:
contents: write
pull-requests: write

jobs:
is-fork-pull-request:
name: Determine whether this PR is from a fork
if: >
(github.event_name == 'pull_request' && startsWith(github.head_ref, 'release/')) ||
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Release branches aren't required to start with release/. We used to check for release branches this way, but now we have a more sophisticated check. You should be able to use the is-release action to determine this. See how we do this in main.yml:

is-release:
name: Determine whether this is a release merge commit
needs: lint-build-test
if: github.event_name == 'push'
runs-on: ubuntu-latest
outputs:
IS_RELEASE: ${{ steps.is-release.outputs.IS_RELEASE }}
steps:
- id: is-release
uses: MetaMask/action-is-release@v2
with:
commit-starts-with: 'Release [version],Release v[version],Release/[version],Release/v[version],Release `[version]`'

(Maybe we want to extract this step to a separate internal action so we don't have to repeat the list of commit patterns?)

(github.event.issue.pull_request && contains(github.event.comment.body, '@metamaskbot update-changelogs'))
Comment thread
cryptodev-2s marked this conversation as resolved.
runs-on: ubuntu-latest
outputs:
IS_FORK: ${{ steps.is-fork.outputs.IS_FORK }}
steps:
- name: Determine whether this PR is from a fork
id: is-fork
run: |
IS_FORK=$(gh pr view --json isCrossRepository --jq '.isCrossRepository' "$PR_NUMBER" --repo "$GITHUB_REPOSITORY")
echo "IS_FORK=$IS_FORK" >> "$GITHUB_OUTPUT"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }}

update-changelogs:
name: Update changelogs
needs: is-fork-pull-request
if: ${{ needs.is-fork-pull-request.outputs.IS_FORK == 'false' }}
runs-on: ubuntu-latest
timeout-minutes: 30
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I thought jobs automatically timed out? I see that you borrowed this from the extension repo, but we haven't been specifying timeouts in this repo so I'm curious if it's really necessary.

Suggested change
timeout-minutes: 30

env:
GITHUB_TOKEN: ${{ secrets.UPDATE_CHANGELOG_TOKEN }}
PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }}
steps:
- name: React to comment
if: github.event_name == 'issue_comment'
continue-on-error: true
run: gh api "repos/${GITHUB_REPOSITORY}/issues/comments/${COMMENT_ID}/reactions" -f content='+1'
env:
GH_TOKEN: ${{ github.token }}
COMMENT_ID: ${{ github.event.comment.id }}
Comment thread
cursor[bot] marked this conversation as resolved.

- name: Checkout repository
uses: actions/checkout@v4
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We should use v5:

Suggested change
uses: actions/checkout@v4
uses: actions/checkout@v5

with:
# Use PAT to ensure the push triggers subsequent CI workflows
token: ${{ secrets.UPDATE_CHANGELOG_TOKEN }}
fetch-depth: 0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it necessary to pull all history? We don't do this for the publish-preview workflow in github-tools, nor does this happen in the update-lavamoat-policies workflow in extension.

Suggested change
fetch-depth: 0

Besides, in the "Setup environment" step below we already check out the repo with fetch-depth: 0 by default.


- name: Checkout pull request
run: gh pr checkout "$PR_NUMBER"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not really sure why we have to check out the PR specifically, but I guess we do this elsewhere, so there must be a reason 🤔


- name: Setup environment
uses: MetaMask/action-checkout-and-setup@v2
with:
is-high-risk-environment: false
cache-node-modules: true
node-version: 22.x
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We shouldn't specify the Node version if we don't have to. If we ever upgrade Node we would want this to use the latest version. I believe we can leave this off and that way .nvmrc will be used:

Suggested change
node-version: 22.x

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Setup action re-checkouts, overwriting PR branch

High Severity

MetaMask/action-checkout-and-setup@v2 is a composite action that internally runs actions/checkout, which will re-checkout the default ref and overwrite the PR branch obtained by gh pr checkout in the previous step. Every other workflow in the repo uses this action as the first and only checkout step. After this action runs, all subsequent steps (changelog validation, commit, push) operate on the wrong branch — the default branch for issue_comment events or the merge commit for pull_request events — making the workflow non-functional and potentially pushing changes directly to main.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit aa78ed8. Configure here.


- name: Hide previous bot comments
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe we should only do this once we've confirmed that we need to post a new comment?

continue-on-error: true
run: |
COMMENT_IDS=$(gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" --paginate \
--jq '[.[] | select(.user.login == "github-actions[bot]" and (.body | test("^(✅|⚠️|❌)"))) | .node_id] | .[]')
for NODE_ID in $COMMENT_IDS; do
gh api graphql -f query='mutation { minimizeComment(input: {subjectId: "'"$NODE_ID"'", classifier: OUTDATED}) { clientMutationId } }'
done
env:
GH_TOKEN: ${{ github.token }}

- name: Validate and fix dependency bump entries
id: validate
Comment on lines +83 to +84
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Should we use a more descriptive name?

Suggested change
- name: Validate and fix dependency bump entries
id: validate
- name: Ensure required dependency bump entries exist across all changelogs
id: update-changelogs

run: >
yarn workspaces foreach --all --no-private --parallel --interlaced --verbose
run changelog:validate --checkDeps --fix --currentPr "$PR_NUMBER"
Comment on lines +85 to +87
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we reuse the package script in the root?

Suggested change
run: >
yarn workspaces foreach --all --no-private --parallel --interlaced --verbose
run changelog:validate --checkDeps --fix --currentPr "$PR_NUMBER"
run: >
yarn changelog:validate --checkDeps --fix --currentPr "$PR_NUMBER"

continue-on-error: true

- name: Commit and push if changed
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Should we use a more descriptive name?

Suggested change
- name: Commit and push if changed
- name: Commit and push updated changelogs

id: commit
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Should we use a more descriptive step ID?

Suggested change
id: commit
id: push-changes

run: |
if git diff --quiet; then
Comment thread
mcmire marked this conversation as resolved.
echo "changed=false" >> "$GITHUB_OUTPUT"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The name of this output seems to indicate that tracks whether there were changes, but this is inaccurate. This tracks not only whether there were changes, but also whether they were pushed. Maybe this should be:

Suggested change
echo "changed=false" >> "$GITHUB_OUTPUT"
echo "changes_pushed=false" >> "$GITHUB_OUTPUT"

exit 0
fi
git diff --stat
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
Comment on lines +98 to +99
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this necessary? I thought using the token to check out the repo automatically sets the user name and email.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes — actions/checkout with a token sets up git credentials for push (auth), but not user.name/user.email for commit authorship. Without these, git commit would fail or use the runner's default identity.

git add -- '**/CHANGELOG.md'
git commit -m "chore: auto-fix dependency bump changelog entries"
git push
echo "changed=true" >> "$GITHUB_OUTPUT"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
echo "changed=true" >> "$GITHUB_OUTPUT"
echo "changes_pushed=true" >> "$GITHUB_OUTPUT"


- name: Comment result
if: always()
run: |
if [ "$CHANGED" = "true" ] && [ "$VALIDATE_OUTCOME" = "failure" ]; then
gh pr comment "$PR_NUMBER" --body "⚠️ Changelogs updated and pushed, but some validation errors remain. Check the [workflow run]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID) for details."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I wonder how this could happen 🤔 This would seem to indicate that changes were pushed when they were not supposed to be.

elif [ "$CHANGED" = "true" ]; then
gh pr comment "$PR_NUMBER" --body "✅ Changelogs updated and pushed."
elif [ "$COMMIT_OUTCOME" = "failure" ]; then
gh pr comment "$PR_NUMBER" --body "❌ Failed to push changelog fixes. Check the [workflow run]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID) for details."
elif [ "$VALIDATE_OUTCOME" = "failure" ]; then
gh pr comment "$PR_NUMBER" --body "❌ Changelog validation failed. Check the [workflow run]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID) for details."
elif [ "$VALIDATE_OUTCOME" = "skipped" ] || [ "$COMMIT_OUTCOME" = "skipped" ]; then
gh pr comment "$PR_NUMBER" --body "❌ Workflow failed before changelog validation. Check the [workflow run]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID) for details."
else
gh pr comment "$PR_NUMBER" --body "✅ No changelog changes needed."
fi
Comment thread
cursor[bot] marked this conversation as resolved.
env:
GH_TOKEN: ${{ github.token }}
CHANGED: ${{ steps.commit.outputs.changed }}
COMMIT_OUTCOME: ${{ steps.commit.outcome }}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Should we use a more descriptive name for this step?

Suggested change
COMMIT_OUTCOME: ${{ steps.commit.outcome }}
PUSH_CHANGES_OUTCOME: ${{ steps.push-changes.outcome }}

VALIDATE_OUTCOME: ${{ steps.validate.outcome }}
Comment thread
cursor[bot] marked this conversation as resolved.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Should we use a more descriptive name for this step?

Suggested change
VALIDATE_OUTCOME: ${{ steps.validate.outcome }}
UPDATE_CHANGELOGS_OUTCOME: ${{ steps.update-changelogs.outcome }}

Loading