From 8acf9643b90450af8b81f7debd0173e3aace62c6 Mon Sep 17 00:00:00 2001 From: Salah-Eddine Saakoun Date: Mon, 14 Sep 2026 19:23:36 +0200 Subject: [PATCH 1/5] feat: repair Dependabot pull requests automatically --- .github/dependabot.yml | 1 + .../repair-dependabot-pull-requests.yml | 115 ++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 .github/workflows/repair-dependabot-pull-requests.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f6e3a1dc2fd..d03ec0e2662 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -11,6 +11,7 @@ updates: default-days: 3 allow: - dependency-name: '@metamask/*' + - dependency-name: '@lavamoat/*' versioning-strategy: 'increase' - package-ecosystem: 'github-actions' diff --git a/.github/workflows/repair-dependabot-pull-requests.yml b/.github/workflows/repair-dependabot-pull-requests.yml new file mode 100644 index 00000000000..2adecbf6df3 --- /dev/null +++ b/.github/workflows/repair-dependabot-pull-requests.yml @@ -0,0 +1,115 @@ +name: Repair Dependabot pull requests + +# Dependabot opens pull requests that cannot merge on their own: +# +# - Its security updates walk manifests one at a time rather than treating the +# Yarn workspace as one project, so they leave a dependency's version range +# disagreeing between packages and fail `yarn constraints`. +# - It does not deduplicate `yarn.lock`, so `yarn lint:dependencies` fails. +# - It does not write changelog entries, so `Check changelog` fails. +# +# All three are mechanical, so this repairs them and pushes the result back to +# the pull request rather than asking a human to do it by hand. + +on: + pull_request: + # Deliberately not `synchronize`: this workflow pushes to the pull request + # branch, and reacting to our own push would loop. + types: + - opened + - reopened + +permissions: + contents: read + +jobs: + repair: + name: Repair constraints, lockfile and changelogs + # The trigger above already rules out reacting to our own push; the actor + # check is a second line of defence. `[dependabot skip]` on the commit below + # is what stops Dependabot rebasing over this work. + if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' && github.actor != 'metamaskbot' }} + runs-on: ubuntu-latest + environment: default-branch + permissions: + contents: read + id-token: write + steps: + # Runs triggered by Dependabot get a read-only `GITHUB_TOKEN` and no + # access to repository secrets, so the push has to be authorised by an + # OIDC token exchange instead. + - name: Get access token + id: get-token + uses: MetaMask/github-tools/.github/actions/get-token@v1 + with: + token-exchange-url: ${{ vars.TOKEN_EXCHANGE_URL }} + permissions: | + contents: write + pull_requests: write + + - name: Check out the pull request branch + uses: actions/checkout@v7 + with: + ref: ${{ github.event.pull_request.head.ref }} + fetch-depth: 0 + persist-credentials: false + + - name: Configure Git + run: | + git config user.name 'MetaMask Bot' + git config user.email 'metamaskbot@users.noreply.github.com' + + - name: Get merge base + id: merge-base + env: + BASE_REF: ${{ github.event.pull_request.base.ref }} + run: | + set -euo pipefail + echo "merge-base=$(git merge-base HEAD "refs/remotes/origin/$BASE_REF")" >> "$GITHUB_OUTPUT" + + - name: Set up environment + uses: MetaMask/action-checkout-and-setup@v3 + with: + is-high-risk-environment: false + + # Aligns any dependency whose range Dependabot left disagreeing between + # packages. Opted into here and nowhere else, so that routine use of + # `yarn lint:fix` cannot fold a dependency bump into unrelated work. + - name: Align dependency ranges + env: + ALIGN_DEPENDENCY_RANGES: 'true' + run: yarn constraints --fix + + # Aligning ranges rewrites manifests but not the lockfile, so it has to be + # resolved again before deduplicating. + - name: Resolve the lockfile + run: yarn install --no-immutable + + - name: Deduplicate the lockfile + run: yarn dedupe + + - name: Write changelog entries for the bumped dependencies + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + MERGE_BASE: ${{ steps.merge-base.outputs.merge-base }} + CHANGELOG_BASE_REF: ${{ steps.merge-base.outputs.merge-base }} + run: yarn changelog:validate --checkDeps --fix --currentPr "$PR_NUMBER" --fromRef "$MERGE_BASE" + # Changelogs may be written even when other validation errors remain, and + # we still want to commit what was written. + continue-on-error: true + + - name: Commit and push the repairs + env: + PR_HEAD_REF: ${{ github.event.pull_request.head.ref }} + TOKEN: ${{ steps.get-token.outputs.token }} + run: | + set -euo pipefail + + if git diff --quiet; then + echo 'Nothing to repair.' + exit 0 + fi + + git add -- '**/package.json' package.json yarn.lock '**/CHANGELOG.md' + git commit -m '[dependabot skip] chore: align dependency ranges, deduplicate lockfile and update changelogs' + git push "https://x-access-token:${TOKEN}@github.com/${GITHUB_REPOSITORY}.git" "HEAD:$PR_HEAD_REF" From 0c720771b00e737dc773998a57184fa521087bb6 Mon Sep 17 00:00:00 2001 From: Salah-Eddine Saakoun Date: Mon, 14 Sep 2026 20:01:47 +0200 Subject: [PATCH 2/5] chore: unwrap workflow comments --- .../repair-dependabot-pull-requests.yml | 31 ++++--------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/.github/workflows/repair-dependabot-pull-requests.yml b/.github/workflows/repair-dependabot-pull-requests.yml index 2adecbf6df3..d9742564fd9 100644 --- a/.github/workflows/repair-dependabot-pull-requests.yml +++ b/.github/workflows/repair-dependabot-pull-requests.yml @@ -1,20 +1,10 @@ name: Repair Dependabot pull requests -# Dependabot opens pull requests that cannot merge on their own: -# -# - Its security updates walk manifests one at a time rather than treating the -# Yarn workspace as one project, so they leave a dependency's version range -# disagreeing between packages and fail `yarn constraints`. -# - It does not deduplicate `yarn.lock`, so `yarn lint:dependencies` fails. -# - It does not write changelog entries, so `Check changelog` fails. -# -# All three are mechanical, so this repairs them and pushes the result back to -# the pull request rather than asking a human to do it by hand. +# Dependabot leaves dependency ranges disagreeing between packages, does not deduplicate `yarn.lock`, and does not write changelog entries. All three are mechanical, so repair them and push the result back. on: pull_request: - # Deliberately not `synchronize`: this workflow pushes to the pull request - # branch, and reacting to our own push would loop. + # Deliberately not `synchronize`: this job pushes to the pull request branch, and reacting to its own push would loop. types: - opened - reopened @@ -25,9 +15,6 @@ permissions: jobs: repair: name: Repair constraints, lockfile and changelogs - # The trigger above already rules out reacting to our own push; the actor - # check is a second line of defence. `[dependabot skip]` on the commit below - # is what stops Dependabot rebasing over this work. if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' && github.actor != 'metamaskbot' }} runs-on: ubuntu-latest environment: default-branch @@ -35,9 +22,7 @@ jobs: contents: read id-token: write steps: - # Runs triggered by Dependabot get a read-only `GITHUB_TOKEN` and no - # access to repository secrets, so the push has to be authorised by an - # OIDC token exchange instead. + # Dependabot runs get a read-only `GITHUB_TOKEN` and no repository secrets, so the push is authorised by an OIDC exchange instead. - name: Get access token id: get-token uses: MetaMask/github-tools/.github/actions/get-token@v1 @@ -72,16 +57,13 @@ jobs: with: is-high-risk-environment: false - # Aligns any dependency whose range Dependabot left disagreeing between - # packages. Opted into here and nowhere else, so that routine use of - # `yarn lint:fix` cannot fold a dependency bump into unrelated work. + # Opted into here and nowhere else, so that routine use of `yarn lint:fix` cannot fold a dependency bump into unrelated work. - name: Align dependency ranges env: ALIGN_DEPENDENCY_RANGES: 'true' run: yarn constraints --fix - # Aligning ranges rewrites manifests but not the lockfile, so it has to be - # resolved again before deduplicating. + # Aligning ranges rewrites manifests but not the lockfile, so it has to be resolved again before deduplicating. - name: Resolve the lockfile run: yarn install --no-immutable @@ -94,8 +76,7 @@ jobs: MERGE_BASE: ${{ steps.merge-base.outputs.merge-base }} CHANGELOG_BASE_REF: ${{ steps.merge-base.outputs.merge-base }} run: yarn changelog:validate --checkDeps --fix --currentPr "$PR_NUMBER" --fromRef "$MERGE_BASE" - # Changelogs may be written even when other validation errors remain, and - # we still want to commit what was written. + # Entries may be written even when other validation errors remain, and we still want to commit those. continue-on-error: true - name: Commit and push the repairs From 3f2ea68d054e3f18f968ad4260cb238d67d47689 Mon Sep 17 00:00:00 2001 From: Salah-Eddine Saakoun Date: Mon, 14 Sep 2026 20:04:42 +0200 Subject: [PATCH 3/5] chore: drop redundant workflow comments --- .github/workflows/repair-dependabot-pull-requests.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/repair-dependabot-pull-requests.yml b/.github/workflows/repair-dependabot-pull-requests.yml index d9742564fd9..45886b67853 100644 --- a/.github/workflows/repair-dependabot-pull-requests.yml +++ b/.github/workflows/repair-dependabot-pull-requests.yml @@ -1,7 +1,5 @@ name: Repair Dependabot pull requests -# Dependabot leaves dependency ranges disagreeing between packages, does not deduplicate `yarn.lock`, and does not write changelog entries. All three are mechanical, so repair them and push the result back. - on: pull_request: # Deliberately not `synchronize`: this job pushes to the pull request branch, and reacting to its own push would loop. @@ -57,7 +55,6 @@ jobs: with: is-high-risk-environment: false - # Opted into here and nowhere else, so that routine use of `yarn lint:fix` cannot fold a dependency bump into unrelated work. - name: Align dependency ranges env: ALIGN_DEPENDENCY_RANGES: 'true' @@ -76,7 +73,7 @@ jobs: MERGE_BASE: ${{ steps.merge-base.outputs.merge-base }} CHANGELOG_BASE_REF: ${{ steps.merge-base.outputs.merge-base }} run: yarn changelog:validate --checkDeps --fix --currentPr "$PR_NUMBER" --fromRef "$MERGE_BASE" - # Entries may be written even when other validation errors remain, and we still want to commit those. + # Entries can be written even when other validation errors remain, and those are still worth committing. continue-on-error: true - name: Commit and push the repairs From 67b5b17d56697d79e4e8e310c81ddfe407bad2ce Mon Sep 17 00:00:00 2001 From: Salah-Eddine Saakoun Date: Mon, 14 Sep 2026 21:24:38 +0200 Subject: [PATCH 4/5] chore: address review feedback on the repair workflow --- .../workflows/repair-dependabot-pull-requests.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/repair-dependabot-pull-requests.yml b/.github/workflows/repair-dependabot-pull-requests.yml index 45886b67853..63c14d1139c 100644 --- a/.github/workflows/repair-dependabot-pull-requests.yml +++ b/.github/workflows/repair-dependabot-pull-requests.yml @@ -13,9 +13,8 @@ permissions: jobs: repair: name: Repair constraints, lockfile and changelogs - if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' && github.actor != 'metamaskbot' }} + if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' && github.actor != 'metamask-ci[bot]' }} runs-on: ubuntu-latest - environment: default-branch permissions: contents: read id-token: write @@ -39,8 +38,8 @@ jobs: - name: Configure Git run: | - git config user.name 'MetaMask Bot' - git config user.email 'metamaskbot@users.noreply.github.com' + git config user.name 'metamask-ci[bot]' + git config user.email '271559518+metamask-ci[bot]@users.noreply.github.com' - name: Get merge base id: merge-base @@ -60,11 +59,11 @@ jobs: ALIGN_DEPENDENCY_RANGES: 'true' run: yarn constraints --fix - # Aligning ranges rewrites manifests but not the lockfile, so it has to be resolved again before deduplicating. - - name: Resolve the lockfile + # `--no-immutable` because the step above changed ranges, so this install has to be allowed to rewrite the lockfile. Without it Yarn fails with YN0028 in CI. + - name: Apply dependency range updates run: yarn install --no-immutable - - name: Deduplicate the lockfile + - name: Deduplicate dependency tree run: yarn dedupe - name: Write changelog entries for the bumped dependencies From c90706dc3a3462dd8c3357e3f3ab787a9cc18941 Mon Sep 17 00:00:00 2001 From: Salah-Eddine Saakoun Date: Mon, 14 Sep 2026 21:59:59 +0200 Subject: [PATCH 5/5] chore: drop redundant actor check --- .github/workflows/repair-dependabot-pull-requests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/repair-dependabot-pull-requests.yml b/.github/workflows/repair-dependabot-pull-requests.yml index 63c14d1139c..ac032ad096a 100644 --- a/.github/workflows/repair-dependabot-pull-requests.yml +++ b/.github/workflows/repair-dependabot-pull-requests.yml @@ -13,7 +13,7 @@ permissions: jobs: repair: name: Repair constraints, lockfile and changelogs - if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' && github.actor != 'metamask-ci[bot]' }} + if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' }} runs-on: ubuntu-latest permissions: contents: read