Skip to content

Shared node-repo workflows: mint the stage-repo token from a GitHub App (#2249) - #2310

Merged
rbuergi merged 2 commits into
mainfrom
fix/2249-satellite-app-token
Aug 26, 2026
Merged

rbuergi merged 2 commits into
mainfrom
fix/2249-satellite-app-token

Conversation

@rbuergi

@rbuergi rbuergi commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Platform half of #2249. The satellite callers follow in their own PRs, together with their pin bump.

The cause is a store split, not a missing value

Every dependabot PR in MeshWeaver.SocialMedia and MeshWeaver.Reinsurance is permanently red, so the automated bumps of these very workflows' pins can never merge. GitHub hands a dependabot-triggered run the Dependabot secret store, never the Actions one — MESHWEAVER_REPO_TOKEN exists for push runs and is simply absent for dependabot ones.

The preflight is behaving correctly and is not changed to skip. A dependency bump is precisely when you want the compile gate to run.

Why not just copy the PAT into the second store

That fixes today and rots tomorrow. It is the same credential class that left Chart Drift at HTTP 401 for nine consecutive runs while reporting a missing secret (#1709). So the credential stops being stored:

before after
secret stage-repo-token (PAT) stage-repo-app-id + stage-repo-app-private-key
lifetime until someone notices it died one hour, minted per run
scope whatever the PAT was scoped to owner/repositories = the stage repo alone, permission-contents: read
dependabot runs absent → red forever resolves, because the pair is provisioned in both stores

MESHWEAVER_APP_ID / MESHWEAVER_APP_PRIVATE_KEY are provisioned in the Actions and Dependabot stores of SocialMedia, Reinsurance and Plugins.

One diagnostic added

The bake preflight still fails RED when stage-modules is set and the credentials are absent. It now also says, when the actor is dependabot, that the secret source for this run was the Dependabot store — the fact the last person had to infer from a bare 'not provisioned'.

Scope note

The issue lists Plugins among the affected repos. It is not affected by this mechanism: Plugins does not pass stage-repo-token and its ci.yml records that it no longer checks out the private core repo. Its one open dependabot PR (#629, actions/setup-node 6→7) is unrelated.

Safety of landing this alone

Callers are SHA-pinned, so nothing moves until a caller bumps — and the currently-open bump PRs are red and cannot merge, so there is no window in which a caller lands on this workflow while still passing the old secret name.

Verified: UpstreamBuildGateGuard 4/4 passed against the edited workflow (fresh trx); both files parse as YAML.

What's New: skipped — CI credential plumbing, no user-visible effect.

…pp (#2249)

Every dependabot PR in MeshWeaver.SocialMedia and MeshWeaver.Reinsurance is
permanently RED, so the automated bumps of these very workflows' pins can never
merge. The preflight is behaving correctly and must not be "fixed" with a
dependabot exemption — that would reintroduce the skip-trapdoor, and a
dependency bump is precisely when you want the compile gate to run.

The cause is a store split, not a missing value: GitHub hands a
dependabot-triggered run the DEPENDABOT secret store, never the Actions one.
`MESHWEAVER_REPO_TOKEN` exists for normal runs and is simply absent for
dependabot ones.

Copying the PAT into the second store would fix today and rot tomorrow — the
same PAT class that left Chart Drift at HTTP 401 for nine consecutive runs
(#1709). So the credential stops being a stored token:

  - `stage-repo-token` is replaced by `stage-repo-app-id` +
    `stage-repo-app-private-key`.
  - Both workflows mint an installation token per run, scoped by
    `owner`/`repositories` to the stage repo alone with
    `permission-contents: read` — narrower than the PAT it replaces.
  - The App id + private key are provisioned in BOTH stores of every calling
    repo, so a dependabot run resolves them exactly like a push run.

The bake preflight keeps asserting RED when `stage-modules` is set and the
credentials are absent, and now adds the one line that turns a confusing red
into an actionable one: if the run's actor is dependabot, it says the secret
source was the Dependabot store. That is the fact the last person had to infer.

Callers are SHA-pinned, so this lands without touching them; the satellite
callers switch to the new secrets in the same change set as their pin bump.

Category: none — CI credential plumbing, no user-visible effect.
Copilot AI lite review requested due to automatic review settings August 26, 2026 06:16

Copilot AI left a comment

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.

Pull request overview

This PR updates the shared reusable node-repo CI workflows to stop relying on a long-lived PAT for staging cross-repo modules, and instead mint a short-lived, repo-scoped installation token via a GitHub App—addressing the Dependabot secret-store split described in #2249 and reducing credential-rot risk.

Changes:

  • Replace stage-repo-token (PAT) with stage-repo-app-id + stage-repo-app-private-key inputs on the reusable workflows.
  • Mint a per-run installation token using actions/create-github-app-token@v2, scoped to the configured stage repo, and use it for the staging checkout.
  • Add an additional Dependabot-focused diagnostic warning in the publish-bake preflight when stage-module staging is enabled.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
.github/workflows/node-repo-publish-bake.yml Switches staging checkout auth from PAT to GitHub App installation token; updates workflow-call secret contract and preflight diagnostics accordingly.
.github/workflows/node-repo-gate.yml Switches staging checkout auth from PAT to GitHub App installation token; updates workflow-call secret contract accordingly.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/node-repo-publish-bake.yml Outdated
Comment thread .github/workflows/node-repo-gate.yml
@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

    9 files  ±0      9 suites  ±0   6m 8s ⏱️ -3s
1 827 tests ±0  1 823 ✅ ±0  4 💤 ±0  0 ❌ ±0 
2 370 runs  +1  2 366 ✅ +1  4 💤 ±0  0 ❌ ±0 

Results for commit 61103d0. ± Comparison against base commit b53aed0.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

   10 files  ±0     10 suites  ±0   6m 22s ⏱️ - 1m 5s
1 310 tests ±0  1 309 ✅ ±0  1 💤 ±0  0 ❌ ±0 
1 311 runs  ±0  1 310 ✅ ±0  1 💤 ±0  0 ❌ ±0 

Results for commit 61103d0. ± Comparison against base commit b53aed0.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

1 202 tests  ±0   1 202 ✅ ±0   16m 56s ⏱️ +34s
    9 suites ±0       0 💤 ±0 
    9 files   ±0       0 ❌ ±0 

Results for commit 61103d0. ± Comparison against base commit b53aed0.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

2 122 tests  ±0   1 822 ✅ ±0   12m 0s ⏱️ -9s
    9 suites ±0     300 💤 ±0 
    9 files   ±0       0 ❌ ±0 

Results for commit 61103d0. ± Comparison against base commit b53aed0.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

1 815 tests  ±0   1 815 ✅ ±0   9m 6s ⏱️ -15s
   10 suites ±0       0 💤 ±0 
   10 files   ±0       0 ❌ ±0 

Results for commit 61103d0. ± Comparison against base commit b53aed0.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

3 438 tests  ±0   3 438 ✅ ±0   9m 23s ⏱️ -9s
    8 suites ±0       0 💤 ±0 
    8 files   ±0       0 ❌ ±0 

Results for commit 61103d0. ± Comparison against base commit b53aed0.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

    55 files  ±0      55 suites  ±0   59m 57s ⏱️ - 1m 8s
11 714 tests ±0  11 409 ✅ ±0  305 💤 ±0  0 ❌ ±0 
12 258 runs  +1  11 953 ✅ +1  305 💤 ±0  0 ❌ ±0 

Results for commit 61103d0. ± Comparison against base commit b53aed0.

♻️ This comment has been updated with latest results.

@rbuergi

rbuergi commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

CI red here is not this PR — filed as #2319 and investigated before re-running, not after.

LiveQueryHandoffDropTest.A_notification_snapshotted_before_Initial_and_delivered_after_still_reaches_the_query failed on shard 2. This PR changes exactly two files — node-repo-gate.yml and node-repo-publish-bake.yml — reusable workflows consumed only by satellite repos. They are not referenced by this repo's own CI and cannot reach MeshWeaver.Hosting.Test.

Control: #2312, same base, unrelated diff, passed the identical shard 2 (run 32938049737).

Worth reading #2319 rather than treating it as noise: the test's own docstring says a red there is "a permanent miss dressed as a timeout, which is why raising a budget could never fix it" — so by its author's reasoning this is a residual hole in the early→live handoff fix (b74277304, merged ~6.5 h earlier), not a slow runner.

Re-running the failed jobs now to unblock this unrelated change. The defect is tracked in #2319, not buried here.

…before minting

Two findings from the automatic review, both real.

1. The Dependabot-store hint fired whenever `missing[]` was non-empty — including for a
   missing acr-password or azure-tenant-id. A hint that names ONE cause must only fire
   for the input that has that cause; otherwise it sends the next person to the wrong
   settings page while the actual missing secret sits in the list above it. Now gated on
   a `stage_missing` flag set only by the two stage-repo credential checks.

2. node-repo-gate.yml minted the token with no assertion on its inputs, so a missing
   app-id, a missing private key, or a malformed stage-repo surfaced as an opaque
   create-github-app-token or checkout failure two steps later. It now carries the same
   shape publish-bake has: fail RED naming exactly what to provision, plus the
   dependabot-store line when the actor is dependabot.

Both `if:`s are on the declared INPUT `stage-modules` — whether staging was requested at
all — never on whether a secret happens to be set. That distinction is the whole point of
AGENTS.md's "a gate NEVER tests its own inputs": an input-shaped `if:` renders a skipped
job identically to a passed one, and these two must fail loudly instead.

Category: none — CI credential plumbing, no user-visible effect.
@rbuergi
rbuergi merged commit a727426 into main Aug 26, 2026
26 checks passed
@rbuergi
rbuergi deleted the fix/2249-satellite-app-token branch August 28, 2026 08:56
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.

2 participants