Skip to content

ci(wave): the platform bake reads Plugins with an App credential, and ONE fan-out fires after the Plugins publication - #2705

Merged
rbuergi merged 2 commits into
mainfrom
ci/content-checkout-token
Aug 29, 2026
Merged

rbuergi merged 2 commits into
mainfrom
ci/content-checkout-token

Conversation

@rbuergi

@rbuergi rbuergi commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

What broke (main-cd run 33276813173, the first push-driven wave)

  1. plugins-modules died at checkout — fatal: repository 'https://github.com/Systemorph/MeshWeaver.Plugins/' not found. The reusable node-repo-module-pack.yml / node-repo-publish-bake.yml check out content-repository with the calling run's GITHUB_TOKEN, which cannot read the private Plugins repo.
  2. Two fan-outs — the inline dispatch-dependents job (ci: the release wave is a GitHub Actions trigger — platform + plugins built together, dependents dispatched, packages cascade #2696) and the reusable notify-dependents.yml (built in parallel). The reusable fired right after promote, before the Plugins bake, so every woken satellite would seed a Plugins publication that was not sealed yet — and its payload was {version, reason}, which Manufacturing refuses (no sha256: digest) and Education cannot bake from (no client_payload.image).
  3. The verdict went RED correctly (plugins-modules=failure … dispatch-dependents=skipped).

What this does

  • Both reusable workflows take content-app-id / content-app-private-key; when content-repository is set they assert the credential RED, mint a Contents: Read installation token scoped to that one repo, and check out with it. Node repos calling them with no content-repository are byte-identical to before.
  • main-cd passes the dispatch App (installed on Plugins) as the content credential to plugins-modules and plugins-bake.
  • One fan-out: notify-dependents now needs: plugins-bake (+ plugins-bake-image), runs only on plugins-bake == success, and carries sha, image, digest, source: platform, chain: [platform, plugins] — asserted RED for reason: platform. The inline job is deleted; the verdict's LEGS name notify-dependents.
  • PlatformReleaseNotifyGuard pins: a single job (no dispatch-dependents: key can come back), the gate on plugins-bake, the payload fields, and the reusable's collected-then-exit 1 failure handling.

Verified locally

  • check-workflow-shell.py: 0 live findings. YAML parses.
  • MeshWeaver.Documentation.Test builds -c Release -warnaserror (0 errors); PlatformReleaseNotifyGuard + UpstreamBuildGateGuard + workflow-shell guards: 10/10 passed.

Not in scope

The satellite gates' bake consumption: N DECLINED (module MVID skew, #2698) is a Plugins-side convergence; the wave PRs in the satellites stay red on that until it lands.

🤖 Generated with Claude Code

… ONE fan-out fires after the Plugins publication

The first push-driven release wave (main-cd run 33276813173) failed three ways at once:

- plugins-modules died at checkout: 'repository Systemorph/MeshWeaver.Plugins not found'.
  The reusable module-pack and publish-bake checked out content-repository with the
  run's GITHUB_TOKEN, which is scoped to the calling repo. Both now take
  content-app-id / content-app-private-key, assert them RED when content-repository is
  set, mint a Contents:Read installation token and check out with it. main-cd passes
  the dispatch App (installed on Plugins) as that credential.
- Two fan-outs existed: an inline dispatch-dependents job (#2696) and the reusable
  notify-dependents.yml built in parallel. The reusable fired straight after promote —
  BEFORE the Plugins bake — with a payload of {version, reason} that the receivers
  cannot use (Manufacturing refuses without a sha256: digest; Education bakes against
  client_payload.image). The inline job is deleted; notify-dependents now needs
  plugins-bake success and carries sha/image/digest/source/chain, asserted RED for a
  platform release.
- The verdict's LEGS name notify-dependents; PlatformReleaseNotifyGuard pins the
  single job, its gate on plugins-bake, the payload, and the reusable's RED-on-failure.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 29, 2026 22:24

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 hardens the release “wave” in GitHub Actions so the platform run can (1) bake Plugins content from a private repo using an App-scoped token and (2) notify downstream repos exactly once, only after the Plugins publication is sealed, with a payload that downstream gates can consume.

Changes:

  • Add an App-credentialed “content repository” checkout path to the reusable node-repo-module-pack and node-repo-publish-bake workflows (so MeshWeaver.Plugins can be read from platform CD).
  • Make main-cd use a single reusable fan-out (notify-dependents) gated on plugins-bake success, and remove the prior inline fan-out job.
  • Extend notify-dependents.yml payload to include sha, image, and digest, and update the guard test + WhatsNew entry to pin the intended shape.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/MeshWeaver.Documentation.Test/PlatformReleaseNotifyGuard.cs Updates the CI-shape guard to enforce one fan-out and validate the reusable workflow’s structure.
src/MeshWeaver.Documentation/Data/WhatsNew/2026-08-30-a-platform-release-wakes-the-fleet-once-and-after-plugins.md Adds a changelog entry describing the fixed wave semantics and credentialing.
.github/workflows/notify-dependents.yml Adds sha/image/digest inputs, validates platform payload completeness, and posts JSON payloads to subscribers.
.github/workflows/node-repo-publish-bake.yml Adds App-based token minting for cross-repo content checkout when content-repository is set.
.github/workflows/node-repo-module-pack.yml Adds App-based token minting for cross-repo content checkout for both select and pack jobs.
.github/workflows/main-cd.yml Wires the new content credential into Plugins jobs and gates a single downstream notify job on Plugins bake completion.

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

Comment thread .github/workflows/notify-dependents.yml Outdated
…s release is not a platform event

release-packages.yml calls the same reusable with reason: packages; hard-coding
source:"platform" / chain:[platform, plugins] would label a NuGet release as an image
release and seed the receivers' cycle guard with a Plugins publication that was never
made. source is now the reason, and only a platform release carries Plugins in its chain.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

689 tests  ±0   497 ✅ ±0   3m 53s ⏱️ - 1m 0s
  5 suites ±0   192 💤 ±0 
  5 files   ±0     0 ❌ ±0 

Results for commit 7f0a118. ± Comparison against base commit a9b3483.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

941 tests  ±0   941 ✅ ±0   5m 3s ⏱️ +17s
  6 suites ±0     0 💤 ±0 
  6 files   ±0     0 ❌ ±0 

Results for commit 7f0a118. ± Comparison against base commit a9b3483.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

1 528 tests  ±0   1 528 ✅ ±0   5m 52s ⏱️ -17s
    8 suites ±0       0 💤 ±0 
    8 files   ±0       0 ❌ ±0 

Results for commit 7f0a118. ± Comparison against base commit a9b3483.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

   10 files  ±0     10 suites  ±0   5m 36s ⏱️ -7s
3 453 tests +1  3 453 ✅ +1  0 💤 ±0  0 ❌ ±0 
4 087 runs  +1  4 087 ✅ +1  0 💤 ±0  0 ❌ ±0 

Results for commit 7f0a118. ± Comparison against base commit a9b3483.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

913 tests  +658   913 ✅ +659   5m 44s ⏱️ + 5m 29s
  6 suites ±  0     0 💤 ±  0 
  6 files   ±  0     0 ❌  -   1 

Results for commit 7f0a118. ± Comparison against base commit a9b3483.

This pull request removes 1 and adds 659 tests. Note that renamed tests count towards both.
MeshWeaver.PluginCatalog.Test ‑ HOST_CRASHED
MeshWeaver.PluginCatalog.Test.AdoptedBuildSourceStampTest ‑ AdoptedTypeWithSources_IsNotDirty_AndTheNextReleaseRequestIsSatisfied
MeshWeaver.PluginCatalog.Test.AdoptedBuildSourceStampTest ‑ AdoptionAfterTheSnapshotIsAlreadyPublished_IsStillStamped
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ AClaimedNodeSurvivesAnUpdateUntouched
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ AClaimedNodeSurvivesThePrune
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ AGreenBuildThatChangedNothingInTheModuleFetchesNothing
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ AGreenBuildThatChangedTheModuleFetchesOnlyTheChangedFiles
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ AnOptedInRecordStaysOptedInThroughAnUpdate
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ ReminderIsTheDefault_AutoUpdateIsAnExplicitOptIn
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ TheBuildNodePathIsStableAndAnchoredInTheAdminPartition
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ TheDeploymentDefaultSeedsFreshInstalls_TheRecordsOwnChoiceWinsThereafter
…

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

788 tests  ±0   784 ✅ ±0   7m 21s ⏱️ -8s
  6 suites ±0     4 💤 ±0 
  6 files   ±0     0 ❌ ±0 

Results for commit 7f0a118. ± Comparison against base commit a9b3483.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results

   41 files  ±  0     41 suites  ±0   33m 31s ⏱️ + 4m 14s
8 312 tests +659  8 116 ✅ +660  196 💤 ±0  0 ❌  - 1 
8 946 runs  +659  8 750 ✅ +660  196 💤 ±0  0 ❌  - 1 

Results for commit 7f0a118. ± Comparison against base commit a9b3483.

This pull request removes 1 and adds 660 tests. Note that renamed tests count towards both.
MeshWeaver.PluginCatalog.Test ‑ HOST_CRASHED
MeshWeaver.Persistence.Test.DocumentationCodeBlockCompilationTest ‑ ExecutedCsharpBlocks_MustCompile(embeddedResourceName: \"MeshWeaver.Documentation.Data.WhatsNew.2026-08-30-\"···)
MeshWeaver.PluginCatalog.Test.AdoptedBuildSourceStampTest ‑ AdoptedTypeWithSources_IsNotDirty_AndTheNextReleaseRequestIsSatisfied
MeshWeaver.PluginCatalog.Test.AdoptedBuildSourceStampTest ‑ AdoptionAfterTheSnapshotIsAlreadyPublished_IsStillStamped
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ AClaimedNodeSurvivesAnUpdateUntouched
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ AClaimedNodeSurvivesThePrune
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ AGreenBuildThatChangedNothingInTheModuleFetchesNothing
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ AGreenBuildThatChangedTheModuleFetchesOnlyTheChangedFiles
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ AnOptedInRecordStaysOptedInThroughAnUpdate
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ ReminderIsTheDefault_AutoUpdateIsAnExplicitOptIn
MeshWeaver.PluginCatalog.Test.BuildCompletionSubscriptionTest ‑ TheBuildNodePathIsStableAndAnchoredInTheAdminPartition
…

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