Skip to content

Template convergence barrier: absorb pins, generic release + docker-readme, carry-whole-file - #207

Merged
ptr727 merged 29 commits into
developfrom
template-convergence
Jun 25, 2026
Merged

Template convergence barrier: absorb pins, generic release + docker-readme, carry-whole-file#207
ptr727 merged 29 commits into
developfrom
template-convergence

Conversation

@ptr727

@ptr727 ptr727 commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Phase-0 of the template-to-downstream convergence sweep: the template absorbs everything downstream repos had reinvented, so derived repos can take the carried artifacts verbatim with zero hand-rolling. Builds on #205 (orchestration personas) and #206 (per-PR merge-bot concurrency), which this branch incorporates. Held for end-gate review; not to be merged midway.

What this PR does

  • Absorbs downstream-led action pins (template now leads per Lead action pins; affirm pattern-based artifact handoff (#203) #204): dependabot/fetch-metadata v2.5.0 -> v3.1.0 and softprops/action-gh-release v2.6.2 -> v3.0.1, the SHAs the downstreams already run.
  • Generalizes the release model + adds a loud guard. Every release is a tag on the built commit plus an auto source zip, README, and LICENSE; targets amend it by uploading release-asset-<branch>-* artifacts (binaries/packages) or pushing elsewhere (image/registry). github-release collects assets by the release-asset-<branch>-* pattern so the job is target-agnostic and carries verbatim.
  • Makes the Docker README + date badge main-only, caller-gated. Neither has per-branch context, so both move out of the publisher branch matrix into single jobs gated on main being published. publish-docker-readme-task.yml is rebuilt generic: a matrix over a repositories input (or a manifest-derived list), a caller-passed ref, and an optional transform step (e.g. m4) to render the README before pushing.
  • Adopts the carry-whole-file rule. Replaces "drop the sections you don't ship": derived repos carry each shared file in full (an inert [*.cs] block or unused-language CODESTYLE.md section costs nothing), so every re-sync is a clean overwrite, not a partial merge. CODESTYLE.md is genericized into a self-contained drop-in (no demo-project names, no template-onboarding pointers) and carries both the .NET and Python sections whole. Only per-language .vscode/tasks.json task definitions still track the repo's language.

All carried files stay self-contained (no template/demo/cross-project references except the sanctioned upstream-drift pointer). Workflow YAML and Markdown remain CRLF per the line-ending governance. Validated with actionlint and markdownlint-cli2 (clean).

Documented adaptations (for review)

These are the genuine, intentional deviations the maintainer should review at the end gate. Each is a sanctioned exception with its rationale recorded inline in the artifact; nothing here is accidental drift.

  • fail_on_unmatched_files: true on github-release - a promised release-asset-* that goes missing or is misnamed fails the release loudly; a Docker-only / no-file-target repo is the one case that relaxes it (no release asset to attach).
  • merge-bot-pull-request.yml concurrency: per-PR group, cancel-in-progress: false - under pull_request_target github.ref is the base branch, which would serialize every bot PR against that base, so the group keys on the PR number; cancellation would leave auto-merge in an inconsistent state, so events queue and each runs to completion.
  • publish-release.yml concurrency: global ref-independent group, cancel-in-progress: false - it publishes shared ref-independent artifacts (both branches' Docker tags/caches and GitHub releases) regardless of the triggering ref, so a ref-scoped group would let a scheduled run and a manual dispatch double-push; cancelling mid-flight can leave a partial tag set or half-created release.
  • dotnet/nbgv consumed via @master (no SHA pin) - the upstream tag stream lags master substantially and Dependabot's tag-tracking would propose a downgrade; this is the one documented no-SHA-pin exception.
  • Ruleset-bound job name kept verbatim (no "job" suffix) - Check pull request workflow status in test-pull-request.yml is referenced as a required-status-check context: in the branch ruleset; renaming it to fit the "every job name ends in job" convention would silently break required-status-check enforcement.

🤖 Generated with Claude Code

ptr727 and others added 7 commits June 23, 2026 22:12
Re-syncing the downstream fleet from the hub needs a durable, committed
playbook (per-machine memory is lost on a machine switch). Add an
"Orchestrated Re-Sync: Hub and Downstream Personas" subsection defining
the hub/orchestrator vs downstream/derived separation of duties, and make
the full-replacement rule explicit in "Staying in Sync": carried
artifacts are replaced whole, never partially hand-merged, and re-syncing
is not an occasion to add or grow comments. Guards the two recurring
downstream regressions (partial carries, comment accretion); the
orchestrator validates each result by diffing against the template.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The pull_request_target switch (#201) changed github.ref from the PR
merge ref to the base branch, so the concurrency group serialized every
bot PR against a base into one queue - delaying auto-merge/disable when
multiple Dependabot/codegen PRs are open. Key on github.event.pull_request.number
so each PR's events still process in arrival order while different PRs run
concurrently. Surfaced by Copilot on the NxWitness re-sync (#448).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lead the pins downstream already run: dependabot/fetch-metadata v2.5.0->v3.1.0
and softprops/action-gh-release v2.6.2->v3.0.1. Adopt PlexCleaner's
fail_on_unmatched_files guard on github-release so a promised release-asset
that goes missing/misnamed fails loudly; document that a no-file-target
(Docker-only) repo relaxes it, and frame the generic release model (tag +
source zip + README + LICENSE, targets amend).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…task

The Docker Hub overview and build badge have no per-branch context - only main
should update them. Move both out of the publisher's branch matrix into single
jobs gated on main being published (caller-gated), dropping the per-leg self-gate
and the branch input. Rebuild publish-docker-readme as a generic task: matrix over
a repositories input (single- or multi-image), caller-passed ref, and an optional
transform step (e.g. m4) to render the readme before pushing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the 'drop the sections/blocks you don't ship' guidance with a
carry-whole-file rule: an inert [*.cs] editorconfig block or an unused-language
CODESTYLE.md section costs nothing, and keeping it makes every re-sync a clean
wholesale overwrite instead of an error-prone partial merge. Only per-language
.vscode/tasks.json definitions still track the repo's own language, since the
template ships only the task groups it uses.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 24, 2026 15:22

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

Phase-0 template-to-downstream convergence changes, focusing on making the template the source of truth for action pins and a more generic release + Docker README + date badge publishing model so derived repos can re-sync with minimal bespoke edits.

Changes:

  • Update action pins used by core workflows (Dependabot metadata fetch and GitHub release creation).
  • Refactor publish-release so the date badge and Docker Hub README publish once (caller-gated to main being published), rather than per-branch matrix legs.
  • Generalize the reusable Docker README publishing workflow to support multiple repositories and an optional README transform step.

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
AGENTS.md Document the "carry whole shared file" re-sync rule and add the hub/downstream persona playbook for fleet-wide re-syncs.
.github/workflows/publish-release.yml Gate date badge and Docker README publishing on main being included in the publish plan (single job, not per-branch matrix).
.github/workflows/publish-docker-readme-task.yml Generalize Docker Hub README publishing (multi-repo matrix + optional transform step + caller-provided ref).
.github/workflows/merge-bot-pull-request.yml Key concurrency by PR number under pull_request_target and bump dependabot/fetch-metadata pin.
.github/workflows/build-release-task.yml Bump softprops/action-gh-release pin and enable fail_on_unmatched_files for release file patterns.
.github/workflows/build-datebadge-task.yml Remove internal branch gating and rely on the caller to invoke only when main is being published.

Comment thread .github/workflows/publish-docker-readme-task.yml Outdated
ptr727 and others added 3 commits June 24, 2026 08:35
…otection

A CRLF shebang breaks execution, and a broad normalization pass already swept
extensionless s6 service scripts to CRLF (since .editorconfig can't match a file
with no extension and '* -text' enforces nothing). Add '*.sh text eol=lf' as a
carried pin and document that any repo shipping extensionless executables (s6
init, hooks) adds an explicit path pin like 'Docker/s6-overlay/** text eol=lf' so
git holds them at LF on checkout and --renormalize. Also fold the stale
'[*.cs] is .NET-only' note into the carry-whole-file rule.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CRLF in a Dockerfile breaks RUN heredocs and line continuations. Add LF pins for
Dockerfile/*.Dockerfile in .gitattributes and .editorconfig, and renormalize the
template's own Docker/Dockerfile (was CRLF) to LF.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The s6 service-script case is one instance of a general pattern: a file class
the .editorconfig extension rules and '* -text' don't cover needs an explicit
.gitattributes pin matching its tool's native ending. Call out husky/git hook
scripts (.husky/pre-commit) alongside s6, and extend the rule to tool-owned
formats like KiCad project/footprint/3D files (*.kicad_mod/*.kicad_sym/*.step,
LF) so a sweep can't churn them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 24, 2026 15:57

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

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

Comment thread .github/workflows/publish-docker-readme-task.yml Outdated
Comment thread AGENTS.md Outdated
ptr727 and others added 5 commits June 24, 2026 09:09
…rule

The two workflows rewritten in Phase 0 came out LF while every other workflow is
CRLF per .editorconfig - normalize them back to CRLF (EOL-only). Document the
decision rule the fan-out surfaced: CRLF is the default, LF only where a type
requires it or CRLF breaks consumption (scripts/shebangs, Dockerfiles, KiCad);
YAML stays CRLF (Actions tolerates it; yamllint defers via new-lines: disable).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… transform

Eliminate the per-repo glue the fan-out surfaced: a multi-image repo passes
manifest + manifest-jq (a get-repos job derives the matrix from e.g. Matrix.json)
instead of hand-rolling its own derivation in the caller, and a render that needs
a build artifact passes transform-artifact (downloaded before transform-run)
instead of smuggling gh run download into the command. repositories stays
supported for single-image repos. Also add the carried-file self-containment rule
to AGENTS.md (no template/demo/cross-project references).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The 'never names a build job' rule is about the download step (pattern, not
artifact-ids); the producing build jobs still appear in needs for sequencing -
spell that out so it isn't misread as dropping needs. And exempt the sanctioned
upstream-drift-report pointer from the no-cross-repo-references rule.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…, precise EOL wording

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 24, 2026 17:32

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

Copilot reviewed 9 out of 10 changed files in this pull request and generated 5 comments.

Comment thread CODESTYLE.md Outdated
Comment thread CODESTYLE.md Outdated
Comment thread AGENTS.md
Comment thread .github/workflows/publish-docker-readme-task.yml
Comment thread .github/workflows/build-release-task.yml
Reword the .NET/Python section intros and the Quick Start so they say
carry the file whole and ignore unused sections, not drop them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ptr727
ptr727 requested a review from Copilot June 24, 2026 17:42
Copilot stopped reviewing on behalf of ptr727 due to an error June 24, 2026 18:02

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

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

Comment thread .github/workflows/publish-docker-readme-task.yml
Comment thread .github/workflows/publish-docker-readme-task.yml
Comment thread .github/workflows/publish-docker-readme-task.yml
Comment thread .github/workflows/publish-docker-readme-task.yml
Comment thread .github/workflows/publish-docker-readme-task.yml
Comment thread .github/workflows/publish-release.yml Outdated
Comment thread .gitattributes Outdated
Comment thread .gitattributes
Comment thread .gitattributes
… pins

The header read "Leave line endings alone" while the file pins LF for
scripts/Dockerfiles; state the default-plus-exceptions policy accurately.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 25, 2026 00:30
Copilot stopped reviewing on behalf of ptr727 due to an error June 25, 2026 00:50

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

Copilot reviewed 9 out of 10 changed files in this pull request and generated 4 comments.

Comment thread .github/workflows/publish-docker-readme-task.yml
Comment thread .github/workflows/publish-docker-readme-task.yml
Comment thread .github/workflows/publish-docker-readme-task.yml
Comment thread .editorconfig
…ce tasks)

CODESTYLE no longer enumerates the convenience/project tasks; clarify that only the
clean-compile task names are CODESTYLE-owned, the rest are the repo's adapt zone.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…mage

Per the issue #208 decisions: SHA-pinning covers repo-owned build-layer leaves too
(Dependabot bumps SHA pins), and a multi-image repo uses a per-image registry
buildcache tag rather than type=gha. Close the ambiguity so downstreams stop
flagging these as drift.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 25, 2026 02: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

Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.

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

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

Comment thread .github/workflows/publish-docker-readme-task.yml
From the Copilot re-review of the convergence PRs:
- .gitattributes header: state that .editorconfig guides the editor while
  the eol=lf pins are git's own enforcement (git does not read .editorconfig).
- CODESTYLE.md: make the .NET/Python section intros conditional ("any ...
  project(s)") so they no longer contradict the carry-whole "ignore if absent"
  preamble.
- AGENTS.md: generalize "merging is not releasing" so the publish step covers
  an opted-in publish-on-merge trigger, not only scheduled/manual dispatch.
- build-datebadge-task.yml: pin RubbaBoy/BYOB to the v1.3.0 release SHA
  (24f4642) per the action-pinning rule; the floating "# v1" violated it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

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

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

Comment thread .github/workflows/publish-docker-readme-task.yml
Comment thread .github/workflows/publish-docker-readme-task.yml

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.

The job was not started because a GitHub Actions budget is preventing further Actions use.

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

Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.

@ptr727
ptr727 merged commit 9eb242a into develop Jun 25, 2026
15 checks passed
@ptr727
ptr727 deleted the template-convergence branch June 25, 2026 14:48
ptr727 added a commit that referenced this pull request Jul 4, 2026
Promote the accumulated `develop` work to `main`. Twelve changes since
the last promotion:

- Add `WORKFLOW.md`: workflow style, architecture, behavioral contract,
test methodology (#223)
- Use NBGV `IGNORE_GITHUB_REF` instead of the ineffective `GITHUB_REF`
override (#222)
- Skip validate-release on smoke builds (#220)
- Gate asset delete on the release create/refresh condition (#218)
- Ship branch rulesets as versioned JSON in the re-sync / drift loop
(#212)
- Clean up transfer artifacts surgically at consumption, not
blanket-delete (#216)
- Version each publish leg against its own branch; validate at entry
(#215)
- Consolidate workspace configurations into a unified ProjectTemplate
workspace (#210)
- Template convergence barrier: absorb pins, generic release +
docker-readme, carry-whole-file (#207)
- Key merge-bot concurrency on PR number, not `github.ref` (#206)
- Codify orchestrated re-sync personas and full-replacement rule (#205)
- Lead action pins; affirm pattern-based artifact handoff (#204)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
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