From 11d7150b5af3055fbf036c4d9847ccdf228898dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 5 Mar 2026 17:03:45 +0100 Subject: [PATCH 1/8] ci: dedupe yarn.lock in Dependabot PR workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 Signed-off-by: Fredrik Adelöw --- .github/workflows/sync_dependabot-changesets.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/sync_dependabot-changesets.yml b/.github/workflows/sync_dependabot-changesets.yml index fb51949fd1..ef0efe04f9 100644 --- a/.github/workflows/sync_dependabot-changesets.yml +++ b/.github/workflows/sync_dependabot-changesets.yml @@ -25,6 +25,15 @@ jobs: run: | git config --global user.email noreply@backstage.io git config --global user.name 'Github changeset workflow' + - name: Setup Node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 20 + - name: Dedupe lockfile + run: | + corepack enable + yarn dedupe + git add yarn.lock - name: Generate changeset uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: From 85fcc10e80e493ae427ebaad75dca0ea7b024e3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 5 Mar 2026 17:06:29 +0100 Subject: [PATCH 2/8] ci: dedupe all lockfiles conditionally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only dedupe each lockfile if it was actually changed by Dependabot. Covers root (Yarn 4) and docs-ui/microsite (Yarn Classic) lockfiles. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Fredrik Adelöw --- .../workflows/sync_dependabot-changesets.yml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sync_dependabot-changesets.yml b/.github/workflows/sync_dependabot-changesets.yml index ef0efe04f9..2974407872 100644 --- a/.github/workflows/sync_dependabot-changesets.yml +++ b/.github/workflows/sync_dependabot-changesets.yml @@ -29,11 +29,23 @@ jobs: uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: 20 - - name: Dedupe lockfile + - name: Dedupe lockfiles run: | corepack enable - yarn dedupe - git add yarn.lock + + # Root lockfile (Yarn 4) + if git diff --name-only HEAD~1 | grep -q '^yarn\.lock$'; then + yarn dedupe + git add yarn.lock + fi + + # Subdirectory lockfiles (Yarn Classic) + for dir in docs-ui microsite; do + if git diff --name-only HEAD~1 | grep -q "^${dir}/yarn.lock$"; then + npx yarn-deduplicate "$dir/yarn.lock" + git add "$dir/yarn.lock" + fi + done - name: Generate changeset uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: From b3076be06b82baac30b78e0b5bf8f6061cdc9c8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 5 Mar 2026 17:10:23 +0100 Subject: [PATCH 3/8] ci: use node 22 for consistency with other workflows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 Signed-off-by: Fredrik Adelöw --- .github/workflows/sync_dependabot-changesets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync_dependabot-changesets.yml b/.github/workflows/sync_dependabot-changesets.yml index 2974407872..a94f745f89 100644 --- a/.github/workflows/sync_dependabot-changesets.yml +++ b/.github/workflows/sync_dependabot-changesets.yml @@ -28,7 +28,7 @@ jobs: - name: Setup Node uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 20 + node-version: 22 - name: Dedupe lockfiles run: | corepack enable From 619f6d37cbb2b5e846b19f0070ddbfd8898db388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 5 Mar 2026 17:14:54 +0100 Subject: [PATCH 4/8] ci: split dedupe/changeset/commit into separate steps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each step sets an output only if it actually modified files. The dedupe step checks git diff after running to avoid staging unchanged lockfiles. A final step commits and pushes only if either step made changes. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Fredrik Adelöw --- .../workflows/sync_dependabot-changesets.yml | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/.github/workflows/sync_dependabot-changesets.yml b/.github/workflows/sync_dependabot-changesets.yml index a94f745f89..750cdd3bb3 100644 --- a/.github/workflows/sync_dependabot-changesets.yml +++ b/.github/workflows/sync_dependabot-changesets.yml @@ -30,23 +30,34 @@ jobs: with: node-version: 22 - name: Dedupe lockfiles + id: dedupe run: | corepack enable + changed=false # Root lockfile (Yarn 4) if git diff --name-only HEAD~1 | grep -q '^yarn\.lock$'; then yarn dedupe - git add yarn.lock + if ! git diff --quiet yarn.lock; then + git add yarn.lock + changed=true + fi fi # Subdirectory lockfiles (Yarn Classic) for dir in docs-ui microsite; do if git diff --name-only HEAD~1 | grep -q "^${dir}/yarn.lock$"; then npx yarn-deduplicate "$dir/yarn.lock" - git add "$dir/yarn.lock" + if ! git diff --quiet "$dir/yarn.lock"; then + git add "$dir/yarn.lock" + changed=true + fi fi done + + echo "changed=$changed" >> "$GITHUB_OUTPUT" - name: Generate changeset + id: changeset uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: | @@ -100,5 +111,9 @@ jobs: const { stdout: commitMessage } = await exec.getExecOutput('git show --pretty=format:%s -s HEAD'); await createChangeset(fileName, commitMessage, packageNames); await exec.exec('git', ['add', fileName]); - await exec.exec('git commit -C HEAD --amend --no-edit'); - await exec.exec('git push --force'); + core.setOutput('changed', 'true'); + - name: Commit and push + if: steps.dedupe.outputs.changed == 'true' || steps.changeset.outputs.changed == 'true' + run: | + git commit -C HEAD --amend --no-edit + git push --force From 51a36847ae5533c02342d4d43fe80d63b629e489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 5 Mar 2026 17:45:45 +0100 Subject: [PATCH 5/8] ci: use yarn dedupe for all lockfiles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All lockfiles in the repo use Yarn 4, so use `yarn --cwd dedupe` uniformly instead of npx yarn-deduplicate for subdirectories. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Fredrik Adelöw --- .../workflows/sync_dependabot-changesets.yml | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/.github/workflows/sync_dependabot-changesets.yml b/.github/workflows/sync_dependabot-changesets.yml index 750cdd3bb3..2a48c09d15 100644 --- a/.github/workflows/sync_dependabot-changesets.yml +++ b/.github/workflows/sync_dependabot-changesets.yml @@ -35,21 +35,12 @@ jobs: corepack enable changed=false - # Root lockfile (Yarn 4) - if git diff --name-only HEAD~1 | grep -q '^yarn\.lock$'; then - yarn dedupe - if ! git diff --quiet yarn.lock; then - git add yarn.lock - changed=true - fi - fi - - # Subdirectory lockfiles (Yarn Classic) - for dir in docs-ui microsite; do - if git diff --name-only HEAD~1 | grep -q "^${dir}/yarn.lock$"; then - npx yarn-deduplicate "$dir/yarn.lock" - if ! git diff --quiet "$dir/yarn.lock"; then - git add "$dir/yarn.lock" + for dir in . docs-ui microsite; do + if [ "$dir" = "." ]; then lockfile=yarn.lock; else lockfile="$dir/yarn.lock"; fi + if git diff --name-only HEAD~1 | grep -q "^${lockfile}$"; then + yarn --cwd "$dir" dedupe + if ! git diff --quiet "$lockfile"; then + git add "$lockfile" changed=true fi fi From 5e9e97af08c5cc61c38e985dc5efe79e76ad40c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 5 Mar 2026 17:47:07 +0100 Subject: [PATCH 6/8] ci: use node-version 22.x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 Signed-off-by: Fredrik Adelöw --- .github/workflows/sync_dependabot-changesets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync_dependabot-changesets.yml b/.github/workflows/sync_dependabot-changesets.yml index 2a48c09d15..e174058f25 100644 --- a/.github/workflows/sync_dependabot-changesets.yml +++ b/.github/workflows/sync_dependabot-changesets.yml @@ -28,7 +28,7 @@ jobs: - name: Setup Node uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 22 + node-version: 22.x - name: Dedupe lockfiles id: dedupe run: | From dda57bdf3d934ef93f80b1603132e7c8d965a605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 5 Mar 2026 17:47:48 +0100 Subject: [PATCH 7/8] ci: update actions/setup-node to v6.2.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 Signed-off-by: Fredrik Adelöw --- .github/workflows/sync_dependabot-changesets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync_dependabot-changesets.yml b/.github/workflows/sync_dependabot-changesets.yml index e174058f25..4f9c90a363 100644 --- a/.github/workflows/sync_dependabot-changesets.yml +++ b/.github/workflows/sync_dependabot-changesets.yml @@ -26,7 +26,7 @@ jobs: git config --global user.email noreply@backstage.io git config --global user.name 'Github changeset workflow' - name: Setup Node - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: 22.x - name: Dedupe lockfiles From cc6c57994581d439c5558257c32d7b27b1cdef95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 5 Mar 2026 19:08:22 +0100 Subject: [PATCH 8/8] ci: add upfront dependabot branch check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the branch verification to a separate step right after checkout, and gate all subsequent steps on its output. Removes the redundant branch check from inside the changeset generation script. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Fredrik Adelöw --- .../workflows/sync_dependabot-changesets.yml | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/workflows/sync_dependabot-changesets.yml b/.github/workflows/sync_dependabot-changesets.yml index 4f9c90a363..4f3bbee376 100644 --- a/.github/workflows/sync_dependabot-changesets.yml +++ b/.github/workflows/sync_dependabot-changesets.yml @@ -21,15 +21,27 @@ jobs: fetch-depth: 2 ref: ${{ github.head_ref }} token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} + - name: Verify Dependabot branch + id: verify + run: | + if git branch --show-current | grep -q '^dependabot/'; then + echo "is_dependabot=true" >> "$GITHUB_OUTPUT" + else + echo "Not a dependabot branch, skipping" + echo "is_dependabot=false" >> "$GITHUB_OUTPUT" + fi - name: Configure Git + if: steps.verify.outputs.is_dependabot == 'true' run: | git config --global user.email noreply@backstage.io git config --global user.name 'Github changeset workflow' - name: Setup Node + if: steps.verify.outputs.is_dependabot == 'true' uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version: 22.x - name: Dedupe lockfiles + if: steps.verify.outputs.is_dependabot == 'true' id: dedupe run: | corepack enable @@ -48,6 +60,7 @@ jobs: echo "changed=$changed" >> "$GITHUB_OUTPUT" - name: Generate changeset + if: steps.verify.outputs.is_dependabot == 'true' id: changeset uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: @@ -73,12 +86,6 @@ jobs: await fs.writeFile(fileName, body); } - const branch = await exec.getExecOutput('git branch --show-current'); - if (!branch.stdout.startsWith('dependabot/')) { - console.log('Not a dependabot branch, skipping'); - return; - } - const diffOutput = await exec.getExecOutput('git diff --name-only HEAD~1'); const diffFiles = diffOutput.stdout.split('\n'); @@ -104,7 +111,7 @@ jobs: await exec.exec('git', ['add', fileName]); core.setOutput('changed', 'true'); - name: Commit and push - if: steps.dedupe.outputs.changed == 'true' || steps.changeset.outputs.changed == 'true' + if: steps.verify.outputs.is_dependabot == 'true' && (steps.dedupe.outputs.changed == 'true' || steps.changeset.outputs.changed == 'true') run: | git commit -C HEAD --amend --no-edit git push --force