diff --git a/.agents/skills/eco-ci-selfcheck/SKILL.md b/.agents/skills/eco-ci-selfcheck/SKILL.md index 184094b5..fe69796f 100644 --- a/.agents/skills/eco-ci-selfcheck/SKILL.md +++ b/.agents/skills/eco-ci-selfcheck/SKILL.md @@ -228,14 +228,14 @@ The table cell can't carry a real list. Markdown table cells flatten newlines, a Table column order and stack order: ```markdown -| Stack | Status | Run | Created | Notes | -| -------- | -------------- | --------------------------------------------------------------------------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------- | +| Stack | Status | Run | Created | Notes | +| -------- | -------------- | --------------------------------------------------------------------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------- | | rsbuild | ✅ OK | [26557329578](https://github.com/rstackjs/rstack-ecosystem-ci/actions/runs/26557329578) | 2026-05-28 05:50 UTC | modernjs prepare lifecycle crashed: rsbuild#7773 (async templateParameters) ↔ modernjs hook not awaited — see details | -| rsdoctor | ✅ OK | [26018807250](…) | 2026-05-18 07:07 UTC | rsbuild suite: 4 vitest tests failed — see details | -| rslib | ✅ OK | [26382662636](…) | 2026-05-25 04:07 UTC | all suites passed | -| rspack | 🛑 ECO-CI SELF | [26384019463](…) | 2026-05-25 04:57 UTC | 1 framework failure (`_selftest`); 6 sibling jobs surfaced real upstream↔consumer breakage — see details | -| rspress | ✅ OK | [26381920989](…) | 2026-05-25 03:40 UTC | all suites passed | -| rstest | ✅ OK | [26382680571](…) | 2026-05-25 04:08 UTC | all suites passed | +| rsdoctor | ✅ OK | [26018807250](…) | 2026-05-18 07:07 UTC | rsbuild suite: 4 vitest tests failed — see details | +| rslib | ✅ OK | [26382662636](…) | 2026-05-25 04:07 UTC | all suites passed | +| rspack | 🛑 ECO-CI SELF | [26384019463](…) | 2026-05-25 04:57 UTC | 1 framework failure (`_selftest`); 6 sibling jobs surfaced real upstream↔consumer breakage — see details | +| rspress | ✅ OK | [26381920989](…) | 2026-05-25 03:40 UTC | all suites passed | +| rstest | ✅ OK | [26382680571](…) | 2026-05-25 04:08 UTC | all suites passed | ``` Followed by: @@ -275,7 +275,7 @@ There is no `✅ OK (test failed)` sub-state any more. Tests-passed-but-vitest-r **`## Details` section** — the actual evidence chain, written as proper Markdown lists where renderers naturally break each item onto its own line. - One `### ` heading per non-pure-passing row in the table. -- Underneath each heading, a real Markdown ordered list. Prefix each item with its per-job verdict so the reader can sort framework-bugs from ecosystem-signals at a glance: `1. **🛑 \`\`** — .Root cause: .` or `1. **✅ \`\` — real ecosystem signal** — …`. +- Underneath each heading, a real Markdown ordered list. Prefix each item with its per-job verdict so the reader can sort framework-bugs from ecosystem-signals at a glance: `1. **🛑 \`\`** — .Root cause: .`or`1. **✅ \`\` — real ecosystem signal\*\* — …`. - One list item per _distinct_ root cause. Mixed runs put the 🛑 framework-failure items first and the ✅ ecosystem-signal items after, so the user sees "what we have to fix in this repo" before "what we have to ping the owners about." - Quote ≤80 chars of any verbatim error per item. Never paste log lines longer than one screen line. Always cite the file path + line + SHA / package version that backs the root-cause claim so the user can re-verify in two clicks. For every non-vitest ecosystem signal, also cite the first-bad upstream commit from Step 5 sub-step 6. - The list items are real Markdown — they MUST start with `1.` `2.` `3.` … on their own line, NOT be jammed onto one line separated by HTML. diff --git a/.github/actions/ecosystem_ci_per_commit/action.yaml b/.github/actions/ecosystem_ci_per_commit/action.yaml index 8c4171d1..0d76b834 100644 --- a/.github/actions/ecosystem_ci_per_commit/action.yaml +++ b/.github/actions/ecosystem_ci_per_commit/action.yaml @@ -56,24 +56,6 @@ runs: ref: 'main' client_payload: ${{ inputs.client-payload }} - - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - fetch-depth: 1 - # checkout@v6 persists credentials via includeIf gitdir, which leaks - # GITHUB_TOKEN auth into the worktree later created by - # JamesIves/github-pages-deploy-action and overrides the PAT in `token`, - # causing 403 on cross-repo push. - # See https://github.com/JamesIves/github-pages-deploy-action/issues/1928 - persist-credentials: false - - - name: Setup Node.js - if: steps.eco_ci.outcome == 'failure' - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 - with: - node-version: 22.22.3 - package-manager-cache: false - - name: Get CI Result id: eco-ci-result uses: rstackjs/rstack-ecosystem-ci/.github/actions/ecosystem-ci-result@3cbb84659edaf3713e10831715d39de0d5c02df7 # main @@ -96,39 +78,3 @@ runs: repo: '${{ inputs.ecosystem-repo }}', body: process.env.SUMMARY }) - - - name: Checkout ecosystem-ci repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - repository: rstackjs/rstack-ecosystem-ci - ref: main - path: ecosystem-ci-repo - fetch-depth: 1 - persist-credentials: false - - - name: Update Ecosystem History - id: update-history - shell: bash - env: - CLIENT_PAYLOAD: ${{ inputs.client-payload }} - SUMMARY_MARKDOWN: ${{ steps.eco-ci-result.outputs.summary }} - RESULTS_JSON: ${{ steps.eco-ci-result.outputs.results }} - WORKFLOW_FILE: ${{ inputs.workflow-file }} - HISTORY_REPOSITORY: rstackjs/rstack-ecosystem-ci - OUTPUT_DIR: data-artifacts - GITHUB_TOKEN: ${{ inputs.github-token }} - run: | - node "$GITHUB_WORKSPACE/ecosystem-ci-repo/scripts/update-ecosystem-history.mjs" - - - name: Publish History - if: ${{ steps.update-history.outcome == 'success' }} - uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4 - with: - branch: data - folder: data-artifacts - clean: false - target-folder: . - token: ${{ inputs.github-token }} - repository-name: rstackjs/rstack-ecosystem-ci - git-config-name: github-actions[bot] - git-config-email: github-actions[bot]@users.noreply.github.com diff --git a/.github/workflows/rsbuild-ecosystem-ci-from-commit.yml b/.github/workflows/rsbuild-ecosystem-ci-from-commit.yml index ddb7a247..10875fc9 100644 --- a/.github/workflows/rsbuild-ecosystem-ci-from-commit.yml +++ b/.github/workflows/rsbuild-ecosystem-ci-from-commit.yml @@ -105,3 +105,50 @@ jobs: run-suites --stack rsbuild ${{ matrix.suite }} + + update-history: + name: Update Ecosystem History + needs: [execute-all] + if: ${{ always() && inputs.suite == '-' }} + runs-on: ubuntu-latest + permissions: + contents: write + actions: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22.22.3 + package-manager-cache: false + - name: Get CI Result + id: eco-ci-result + uses: ./.github/actions/ecosystem-ci-result + with: + heading: rsbuild + workflow-output: '{"workflow_id": "${{ github.run_id }}"}' + - name: Update Ecosystem History + id: update-history + env: + STACK: rsbuild + SOURCE_REPO: ${{ inputs.repo }} + SOURCE_COMMIT: ${{ inputs.commitSHA }} + SUMMARY_MARKDOWN: ${{ steps.eco-ci-result.outputs.summary }} + RESULTS_JSON: ${{ steps.eco-ci-result.outputs.results }} + HISTORY_REPOSITORY: ${{ github.repository }} + OUTPUT_DIR: data-artifacts + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: node scripts/update-ecosystem-history.mjs + - name: Publish History + if: ${{ steps.update-history.outcome == 'success' }} + uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4 + with: + branch: data + folder: data-artifacts + clean: false + target-folder: . + token: ${{ secrets.GITHUB_TOKEN }} + repository-name: ${{ github.repository }} + git-config-name: github-actions[bot] + git-config-email: github-actions[bot]@users.noreply.github.com diff --git a/.github/workflows/rsdoctor-ecosystem-ci-from-commit.yml b/.github/workflows/rsdoctor-ecosystem-ci-from-commit.yml index d6fe33b4..dbf9fa4b 100644 --- a/.github/workflows/rsdoctor-ecosystem-ci-from-commit.yml +++ b/.github/workflows/rsdoctor-ecosystem-ci-from-commit.yml @@ -90,3 +90,50 @@ jobs: run-suites --stack rsdoctor ${{ matrix.suite }} + + update-history: + name: Update Ecosystem History + needs: [execute-all] + if: ${{ always() && inputs.suite == '-' }} + runs-on: ubuntu-latest + permissions: + contents: write + actions: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22.22.3 + package-manager-cache: false + - name: Get CI Result + id: eco-ci-result + uses: ./.github/actions/ecosystem-ci-result + with: + heading: rsdoctor + workflow-output: '{"workflow_id": "${{ github.run_id }}"}' + - name: Update Ecosystem History + id: update-history + env: + STACK: rsdoctor + SOURCE_REPO: ${{ inputs.repo }} + SOURCE_COMMIT: ${{ inputs.commitSHA }} + SUMMARY_MARKDOWN: ${{ steps.eco-ci-result.outputs.summary }} + RESULTS_JSON: ${{ steps.eco-ci-result.outputs.results }} + HISTORY_REPOSITORY: ${{ github.repository }} + OUTPUT_DIR: data-artifacts + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: node scripts/update-ecosystem-history.mjs + - name: Publish History + if: ${{ steps.update-history.outcome == 'success' }} + uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4 + with: + branch: data + folder: data-artifacts + clean: false + target-folder: . + token: ${{ secrets.GITHUB_TOKEN }} + repository-name: ${{ github.repository }} + git-config-name: github-actions[bot] + git-config-email: github-actions[bot]@users.noreply.github.com diff --git a/.github/workflows/rslib-ecosystem-ci-from-commit.yml b/.github/workflows/rslib-ecosystem-ci-from-commit.yml index 5ea6b03a..ef448bde 100644 --- a/.github/workflows/rslib-ecosystem-ci-from-commit.yml +++ b/.github/workflows/rslib-ecosystem-ci-from-commit.yml @@ -106,3 +106,50 @@ jobs: run-suites --stack rslib ${{ matrix.suite }} + + update-history: + name: Update Ecosystem History + needs: [execute-all] + if: ${{ always() && inputs.suite == '-' }} + runs-on: ubuntu-latest + permissions: + contents: write + actions: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22.22.3 + package-manager-cache: false + - name: Get CI Result + id: eco-ci-result + uses: ./.github/actions/ecosystem-ci-result + with: + heading: rslib + workflow-output: '{"workflow_id": "${{ github.run_id }}"}' + - name: Update Ecosystem History + id: update-history + env: + STACK: rslib + SOURCE_REPO: ${{ inputs.repo }} + SOURCE_COMMIT: ${{ inputs.commitSHA }} + SUMMARY_MARKDOWN: ${{ steps.eco-ci-result.outputs.summary }} + RESULTS_JSON: ${{ steps.eco-ci-result.outputs.results }} + HISTORY_REPOSITORY: ${{ github.repository }} + OUTPUT_DIR: data-artifacts + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: node scripts/update-ecosystem-history.mjs + - name: Publish History + if: ${{ steps.update-history.outcome == 'success' }} + uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4 + with: + branch: data + folder: data-artifacts + clean: false + target-folder: . + token: ${{ secrets.GITHUB_TOKEN }} + repository-name: ${{ github.repository }} + git-config-name: github-actions[bot] + git-config-email: github-actions[bot]@users.noreply.github.com diff --git a/.github/workflows/rspack-ecosystem-ci-from-commit.yml b/.github/workflows/rspack-ecosystem-ci-from-commit.yml index 5b84be06..7523dc40 100644 --- a/.github/workflows/rspack-ecosystem-ci-from-commit.yml +++ b/.github/workflows/rspack-ecosystem-ci-from-commit.yml @@ -222,3 +222,50 @@ jobs: --stack rspack \ "${suite_ref_args[@]}" \ ${{ matrix.suite }} + + update-history: + name: Update Ecosystem History + needs: [execute-all] + if: ${{ always() && inputs.suite == '-' }} + runs-on: ubuntu-latest + permissions: + contents: write + actions: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22.22.3 + package-manager-cache: false + - name: Get CI Result + id: eco-ci-result + uses: ./.github/actions/ecosystem-ci-result + with: + heading: rspack + workflow-output: '{"workflow_id": "${{ github.run_id }}"}' + - name: Update Ecosystem History + id: update-history + env: + STACK: rspack + SOURCE_REPO: ${{ inputs.repo }} + SOURCE_COMMIT: ${{ inputs.commitSHA }} + SUMMARY_MARKDOWN: ${{ steps.eco-ci-result.outputs.summary }} + RESULTS_JSON: ${{ steps.eco-ci-result.outputs.results }} + HISTORY_REPOSITORY: ${{ github.repository }} + OUTPUT_DIR: data-artifacts + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: node scripts/update-ecosystem-history.mjs + - name: Publish History + if: ${{ steps.update-history.outcome == 'success' }} + uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4 + with: + branch: data + folder: data-artifacts + clean: false + target-folder: . + token: ${{ secrets.GITHUB_TOKEN }} + repository-name: ${{ github.repository }} + git-config-name: github-actions[bot] + git-config-email: github-actions[bot]@users.noreply.github.com diff --git a/.github/workflows/rspress-ecosystem-ci-from-commit.yml b/.github/workflows/rspress-ecosystem-ci-from-commit.yml index a214f744..9f8519f4 100644 --- a/.github/workflows/rspress-ecosystem-ci-from-commit.yml +++ b/.github/workflows/rspress-ecosystem-ci-from-commit.yml @@ -106,3 +106,50 @@ jobs: run-suites --stack rspress ${{ matrix.suite }} + + update-history: + name: Update Ecosystem History + needs: [execute-all] + if: ${{ always() && inputs.suite == '-' }} + runs-on: ubuntu-latest + permissions: + contents: write + actions: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22.22.3 + package-manager-cache: false + - name: Get CI Result + id: eco-ci-result + uses: ./.github/actions/ecosystem-ci-result + with: + heading: rspress + workflow-output: '{"workflow_id": "${{ github.run_id }}"}' + - name: Update Ecosystem History + id: update-history + env: + STACK: rspress + SOURCE_REPO: ${{ inputs.repo }} + SOURCE_COMMIT: ${{ inputs.commitSHA }} + SUMMARY_MARKDOWN: ${{ steps.eco-ci-result.outputs.summary }} + RESULTS_JSON: ${{ steps.eco-ci-result.outputs.results }} + HISTORY_REPOSITORY: ${{ github.repository }} + OUTPUT_DIR: data-artifacts + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: node scripts/update-ecosystem-history.mjs + - name: Publish History + if: ${{ steps.update-history.outcome == 'success' }} + uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4 + with: + branch: data + folder: data-artifacts + clean: false + target-folder: . + token: ${{ secrets.GITHUB_TOKEN }} + repository-name: ${{ github.repository }} + git-config-name: github-actions[bot] + git-config-email: github-actions[bot]@users.noreply.github.com diff --git a/.github/workflows/rstest-ecosystem-ci-from-commit.yml b/.github/workflows/rstest-ecosystem-ci-from-commit.yml index f1224364..ee559230 100644 --- a/.github/workflows/rstest-ecosystem-ci-from-commit.yml +++ b/.github/workflows/rstest-ecosystem-ci-from-commit.yml @@ -108,3 +108,50 @@ jobs: run-suites --stack rstest ${{ matrix.suite }} + + update-history: + name: Update Ecosystem History + needs: [execute-all] + if: ${{ always() && inputs.suite == '-' }} + runs-on: ubuntu-latest + permissions: + contents: write + actions: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 22.22.3 + package-manager-cache: false + - name: Get CI Result + id: eco-ci-result + uses: ./.github/actions/ecosystem-ci-result + with: + heading: rstest + workflow-output: '{"workflow_id": "${{ github.run_id }}"}' + - name: Update Ecosystem History + id: update-history + env: + STACK: rstest + SOURCE_REPO: ${{ inputs.repo }} + SOURCE_COMMIT: ${{ inputs.commitSHA }} + SUMMARY_MARKDOWN: ${{ steps.eco-ci-result.outputs.summary }} + RESULTS_JSON: ${{ steps.eco-ci-result.outputs.results }} + HISTORY_REPOSITORY: ${{ github.repository }} + OUTPUT_DIR: data-artifacts + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: node scripts/update-ecosystem-history.mjs + - name: Publish History + if: ${{ steps.update-history.outcome == 'success' }} + uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4 + with: + branch: data + folder: data-artifacts + clean: false + target-folder: . + token: ${{ secrets.GITHUB_TOKEN }} + repository-name: ${{ github.repository }} + git-config-name: github-actions[bot] + git-config-email: github-actions[bot]@users.noreply.github.com diff --git a/AGENTS.md b/AGENTS.md index 76d5d684..4a28624d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -110,7 +110,7 @@ flowchart TD ### from-commit -Automatically triggered by upstream CI on each push to main; posts a commit comment on failure and feeds successful runs into the website's `data` branch. +Automatically triggered by upstream CI on each push to main; posts a commit comment on failure and feeds runs into the website's `data` branch. The `data`-branch push runs **inside the downstream workflow** (`update-history` job, only when `suite == '-'`) using the downstream repo's own `GITHUB_TOKEN` (`contents: write` + `actions: read`). The consumer's dispatch token therefore only needs **Actions read/write** — never `Contents`. ```mermaid flowchart TD @@ -151,6 +151,16 @@ flowchart TD rspackPrepareBindingPathB --> checkoutEcoCi checkoutEcoCi --> buildStackAction --> pnpmInstall --> rspackVerdaccioPublish --> runSuites pnpmInstall -. non-rspack or rspack _selftest: skip rspackVerdaccioPublish .-> runSuites + + %% update-history job (runs only when suite == '-'): summarize THIS run + %% and push the data payload to the data branch with the downstream + %% GITHUB_TOKEN (contents: write + actions: read). No consumer PAT here — + %% this is why the consumer token only needs Actions RW, not Contents RW. + ecoCiResultDown["ecosystem-ci-result: fetch THIS run's jobs, build summary"] + updateHistory["update-ecosystem-history.mjs: build data-artifacts payload"] + publishHistory["JamesIves/github-pages-deploy-action
push artifacts to the data branch via GITHUB_TOKEN (feeds website/)
(guarded: if steps.update-history.outcome == 'success')"] + runSuites -. "all suites finished (suite == '-')" .-> ecoCiResultDown + ecoCiResultDown --> updateHistory -- "succeeded" --> publishHistory end %% Fork at dispatch: rspack goes through prepare-binding first, @@ -159,18 +169,13 @@ flowchart TD dispatchWorkflow -. other stacks .-> checkoutEcoCi %% ======================================================================== - %% BACK IN UPSTREAM — commit comment on failure + push to data branch + %% BACK IN UPSTREAM — commit comment on failure only (data push moved + %% downstream, so the consumer PAT no longer needs Contents RW) %% ======================================================================== subgraph result["Back in upstream"] ecoCiResult["ecosystem-ci-result: fetch downstream jobs, build summary"] createCommitComment["createCommitComment on the upstream commit
(guarded: if steps.eco_ci.outcome == 'failure')"] - updateHistory["update-ecosystem-history.mjs: build data-artifacts payload from results JSON"] - publishHistory["JamesIves/github-pages-deploy-action
push artifacts to rstackjs/rstack-ecosystem-ci data branch (feeds website/)
(guarded: if steps.update-history.outcome == 'success')"] - historyFailedEnd(["update-history failed: data branch not updated for this run"]) ecoCiResult -- "downstream failed" --> createCommitComment - ecoCiResult --> updateHistory - updateHistory -- "update-history succeeded" --> publishHistory - updateHistory -. update-history failed: skip publishHistory .-> historyFailedEnd end runSuites -. run finished .-> ecoCiResult @@ -185,6 +190,6 @@ flowchart TD After any change under `.github/`, classify the touched paths and tell the user the required follow-up. Do not parameterize `ref: main` in `trigger-workflow-and-wait` — it is the bridge that makes the third bucket auto-propagate. -- **`.github/actions/ecosystem_ci_dispatch/**` or `ecosystem_ci_per_commit/**`** — upstream stack repos pin these by SHA. Bump `version` in `package.json`, dispatch `release.yml` to cut a new tag, then bump the two `@` pins in every upstream stack repo (Renovate normally opens these PRs). -- **`.github/actions/ecosystem-ci-result/**`** — pinned by SHA inside the two actions above. First land a digest bump (Renovate or manual) of `ecosystem-ci-result@` in both `ecosystem_ci_dispatch` and `ecosystem_ci_per_commit`, then run the release flow above. A merge to `main` alone never reaches consumers. +- **`.github/actions/ecosystem_ci_dispatch/**`or`ecosystem_ci_per_commit/**`** — upstream stack repos pin these by SHA. Bump `version` in `package.json`, dispatch `release.yml` to cut a new tag, then bump the two `@` pins in every upstream stack repo (Renovate normally opens these PRs). +- **`.github/actions/ecosystem-ci-result/**`** — pinned by SHA inside the two actions above. First land a digest bump (Renovate or manual) of `ecosystem-ci-result@`in both`ecosystem_ci_dispatch`and`ecosystem_ci_per_commit`, then run the release flow above. A merge to `main` alone never reaches consumers. - **Everything else** (workflows, `build-*` / `prepare-rspack-binding` / `publish-rspack-to-verdaccio` actions, `ecosystem-ci.ts`, `utils.ts`, `tests/**`, lockfiles, configs) — auto-tracked by `ref: main`. No SHA work; next dispatch picks it up.