Migrate to branch-scoped triggered-Docker CI/CD (2.15) - #461
Merged
Conversation
Rework the CI/CD workflows to the branch-scoped self-publishing model. - publish-release.yml: triggered-Docker, one branch per run (weekly schedule on main, path-scoped push on Make/Matrix.json to main, and dispatch). Single get-version -> build-base (main only) -> build-docker -> github-release (main only) -> docker-readme (main only, folded) -> cleanup chain. Removes the two-leg build-main/build-develop run and the date-badge job; NBGV classifies natively (no IGNORE_GITHUB_REF). - build-docker-task.yml: drop the nested get-version; accept the threaded semver2 as LABEL_VERSION so one NBGV classification feeds every product leg. - test-pull-request.yml: trigger on push to every branch + dispatch; replace dorny/paths-filter with an inline git-diff change-gate; add !github.event.deleted guards; rename the aggregator to Check pull request workflow status job; smoke branch is github.ref_name; call validate-task.yml. - validate-task.yml: rename of test-release-task.yml (Validate job: Husky lint + dotnet test). - merge-bot-pull-request.yml: add --delete-branch to both merge jobs. - Delete build-datebadge-task.yml and publish-docker-readme-task.yml. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port the branch-ruleset, settings, and secret configuration-as-code from the canonical reference: configure.sh (apply/check, the hardened 5D audit helpers), the develop and main rulesets (squash+linear vs merge, required check Check pull request workflow status job, signed commits, copilot review), settings.json, and a retargeted README enumerating the 12 NxWitness Docker Hub repositories derived from Make/Matrix.json. Required secrets in both stores: DOCKER_HUB_USERNAME, DOCKER_HUB_ACCESS_TOKEN, CODEGEN_APP_CLIENT_ID, CODEGEN_APP_PRIVATE_KEY. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add WORKFLOW.md, the canonical CI/CD contract (model, glossary, architecture, the D0-D10 behavioral guarantees, the 5-test methodology, and section 6 repo configuration), adapted for the triggered-Docker one-branch publisher, the multi-product shared-base build layer, the dual-target codegen seam, the forward-only version guard, and the folded docker-readme. D9.1 documents the sole nbgv@master action-pinning exception; D10 ties config-as-code to repo-config. Converge AGENTS.md with the canonical shared sections: the Where-rules-live lead-in, references to WORKFLOW.md and repo-config, a Documentation Style Conventions section (Markdown, Comments, Character Set, Line Endings, Quantitative Claims), the nbgv@master rule, and a refreshed CI Pipeline and Template adaptations describing the one-branch publisher, folded docker-readme, dropped date badge, threaded semver2, and validate-task rename. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- NxWitness.slnx: rebuild to the real file set (current workflows incl. validate-task.yml, minus the deleted datebadge/docker-readme and the stale nonexistent template-shaped names; add repo-config and WORKFLOW.md as solution items). - version.json: bump the NBGV floor 2.14 -> 2.15 to mark the CI/CD overhaul and exercise the publish path (a deliberate maintainer-directed infra bump). - README.md: strip the BYOB "Last Build" date badge and its reference link; sweep the one em-dash. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ng repos) Add a validate job (validate-task: lint + dotnet test) to publish-release.yml that gates build-docker, so a schedule/push/dispatch publish can never ship a tree that would fail the same gate CI enforces on push - matching ESPHome/PlexCleaner whose publishers validate before building. Update WORKFLOW.md D2.1/D4.6 to describe the in-publisher re-validation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Migrates NxWitness CI/CD to a triggered-Docker, one-run-one-branch workflow model, aligning release behavior with sibling repos while preserving the repo’s codegen-driven multi-product Docker matrix and shared base images.
Changes:
- Add a canonical CI/CD contract in
WORKFLOW.mdand updateAGENTS.mdto delegate workflow rules/docs accordingly. - Rework GitHub Actions workflows to: run CI on
pushfor all branches; publish only on schedule /mainmatrix-pin push / dispatch; and thread a single computed NBGV version into Docker builds (no nested versioning). - Add
repo-config/configuration-as-code (rulesets, settings, required secrets audit) and update supporting docs/solution items.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| WORKFLOW.md | New canonical workflow contract/specification for CI, publishing, versioning, and repo configuration. |
| version.json | Bump NBGV version floor from 2.14 to 2.15. |
| repo-config/settings.json | Config-as-code for repo-level merge/auto-merge settings. |
| repo-config/ruleset-main.json | Config-as-code for main branch ruleset (merge method, required check, signatures, Copilot review rule). |
| repo-config/ruleset-develop.json | Config-as-code for develop branch ruleset (squash + linear history, required check, signatures, Copilot review rule). |
| repo-config/README.md | Documentation for applying/auditing repo configuration, including required-check lockstep guidance. |
| repo-config/configure.sh | Script to apply/check rulesets, settings, security toggles, and secret-name presence. |
| README.md | Remove “Last Build” badge and normalize punctuation in a licensing note. |
| NxWitness.slnx | Refresh solution item list to reflect current workflow/docs/config files. |
| AGENTS.md | Update canonical pointers (WORKFLOW.md / repo-config / CODESTYLE.md) and revise CI/CD and doc-style guidance. |
| .github/workflows/validate-task.yml | New reusable validation gate (Husky lint + tests) used by CI and publisher. |
| .github/workflows/test-release-task.yml | Remove older validation workflow superseded by validate-task.yml. |
| .github/workflows/test-pull-request.yml | Switch CI trigger to push (all branches), add inline change-gate, rename required aggregator job. |
| .github/workflows/publish-release.yml | Convert publisher to one-run-one-branch model with schedule + path-scoped push + dispatch; fold Docker Hub README publishing. |
| .github/workflows/publish-docker-readme-task.yml | Remove standalone reusable Docker Hub README publisher (folded into publish-release.yml). |
| .github/workflows/merge-bot-pull-request.yml | Add --delete-branch to merge-bot merges to clean up bot branches explicitly. |
| .github/workflows/build-docker-task.yml | Remove nested get-version, accept threaded semver2 input for image LABEL_VERSION. |
| .github/workflows/build-datebadge-task.yml | Remove BYOB date-badge workflow (and associated README badge usage). |
…oke label - test-pull-request smoke now maps the branch to main or develop (a feature-branch ref matched no Make/Matrix.json .Branch row, producing an empty smoke matrix that failed the build). - the change-gate falls back to building everything if the push `before` SHA is not in the fetched history (e.g. a force-push that rewrote it), instead of erroring on `git diff`. - build-docker-task semver2 input defaults to '0.0.0-smoke' so smoke images get a non-empty LABEL_VERSION. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove the inputs.push gate on the Docker Hub login so smoke builds also authenticate (higher pull/cache rate limits against the branch-scoped registry buildcache), converging with ESPHome/PlexCleaner. This makes the "Docker Hub creds in both secret stores" rationale accurate: a Dependabot-triggered push CI smoke build now logs in, so the creds must be in the Dependabot store too. Add set -euo pipefail to the tags/args step so a jq/sed failure fails loudly instead of emitting empty build-args. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
get-version computes the version from the trigger branch tip; build-base, validate, docker-readme-repos and docker-readme now pin their checkout to that GitCommitId on main (build-docker already did), so the whole publish run operates on one commit even if main advances mid-run. develop (no versioned release) keeps the moving ref. validate-task's checkout falls back to github.ref when no ref is passed, matching the repo's other workflows. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ecrets) validate-task runs only lint + dotnet test and consumes no secrets, so least-privilege: do not pass the repo secrets to it. smoke-build/build-docker keep secrets: inherit (Docker Hub login). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A -task.yml is invoked only via uses: (WORKFLOW.md: never triggered directly), and the canonical validate-task workflows are workflow_call-only. Drop the workflow_dispatch trigger carried over from the old test-release-task. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The smoke-build needs: [changes, validate] and its if carries no always(), so GitHub skips it when validate fails (implicit needs-success). Reword the comment to make that mechanism explicit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment on lines
+240
to
+242
| - **D1.4 Smoke never publishes and never uploads a release asset.** Output: a smoke build compiles the image | ||
| subset but makes no GitHub release and no Docker push (`push: false`, `smoke: true`). The Docker login step | ||
| is gated on `push`, so smoke needs no Docker Hub secrets (forked-PR-safe). |
ptr727
added a commit
that referenced
this pull request
Aug 30, 2026
The last audit class: eleven `readme-structure` findings. Audit run `2026-08-30T03:26:30Z | hub a378121`. Stacked on #551, so this PR is based on `resync/docs-split` and will retarget as its parents merge. ## The eleven findings | Finding | Fix | | --- | --- | | H1 is not the repo name | `# NxWitness` | | Tagline carries Markdown links | Link-free plain text, one sentence, 72 chars. The original sentence survives as the free prose below it, where links are allowed. | | No `## Questions or Issues` | Added. Carries the support routing moved out of `## Troubleshooting`, which keeps its own subsections. | | No `## 3rd Party Tools` | Added. The fleet's fixed lead line, then 23 entries alphabetized. | | No `### Releases` | Added under Build and Distribution, with the base class's GitHub release and pre-release shields plus the 40 Docker version shields moved up from the old `## Releases`. | | `[license-link]` points at a repo path | `[license]`, bare, since an in-repo path takes no suffix. | | Ten `[hub<name>-link]` references | Renamed to `<target>-docker-hub-link`, the shape that covers a repo shipping one image and one shipping ten. | | 161 definitions ungrouped | Grouped under the five declared headers in spec order, sorted by label within each. | The tagline is also mirrored into `HISTORY.md`, which the spec requires and which the old pair could never satisfy at once, since the shared sentence carried a Markdown link. Its now-orphaned `networkoptix-link` definition goes with it. For the tool list, every tool the hub catalogs uses the catalog's link and description verbatim; the rest are described as what the tool is rather than as what this repo does with it. ## Defects found while restructuring - The NxGo-LSIO install bullet linked the **Nx Witness** LSIO image. - The Products list linked **Wisenet WAVE** at `dwspectrum.com`. - A display filename read `Test.yaml` where the file is `Test.yml`. - `./LSIO/etc/s6-overlay/s6-rc.d/init-nx-relocate/run` resolved to nothing. Fixing the README alone would have been a symptom fix: `CreateMatrix/Dockerfile.cs` emits that comment into every LSIO Dockerfile, so the next codegen run reproduces it. The generator and the five generated files now name `Docker/s6-overlay/...`. Those files carry only that comment change; the upstream version bump a full regeneration also produces belongs to the codegen bot. - `Docker/README.md`, the Docker Hub overview, still opened with the retired title and tagline, so it disagreed with every other surface about the project's name. - A spaced hyphen joining two clauses, which the character-set rule bans in the same terms as an em dash. ## A correction to #549's stated verification `OPERATIONS.md` asserted that the local test command is plain `dotnet test`. That is unverified and false on at least one machine: a pristine checkout of the migration commit reports `Zero tests ran` and exit 5 there, while CI runs the same command on the same SDK (10.0.400, runtime 10.0.11) and reports 21 passed. My earlier local "21/21" came from a build tree still carrying state from the coverlet configuration it replaced. The configuration is correct, and CI is the evidence. The runbook now states the invocation CI actually runs as the one to reproduce locally, says that an MTP run discovering nothing exits 5 rather than passing silently so the count is what to read, and names the direct `dotnet CreateMatrixTests/bin/Debug/net10.0/CreateMatrixTests.dll` run as the way to separate a driver problem from a test-project problem. The `net10.0` versus `net10.0|x64` target string is the tell. Filed upstream as ptr727/ProjectTemplate#1122, since D1.6 governs this for the whole fleet and the remaining dotnet repos will hit it. ## Verification - Every label has a definition and every definition is used, 161 of 161, no duplicates. Every relative target exists, every in-page anchor resolves, the five group headers appear in spec order with labels sorted within each. - The Table of Contents matches the actual headings one for one, in order. - The ten image names match `Make/Matrix.json`; the base images match the two base Dockerfiles. - Build clean, markdownlint (48 files), cspell, editorconfig-checker and actionlint clean, no new cspell word needed. ## The 2.15 release is now documented This started as "reported, not fixed", and changed after the maintainer ruled on it. Recording the sequence, because the PR title does not suggest a release-notes change. `version.json` has declared 2.15 since 2026-06-29 and releases 2.15.43 through 2.15.59 have published since 2026-07-27, but neither `HISTORY.md` nor the README's Release Notes ever gained an entry, so both still described 2.14 as current. The bump came from #461, a large CI/CD migration that listed `version floor 2.14 -> 2.15` as one line item and added no changelog entry. The entry is derived rather than invented. Reading every merge between the 2.14 entry and now, 2.15 is the branch-scoped triggered-Docker CI/CD migration, the Codecov upload, multi-arch on `main` only, the lint-architecture standardization, and workflow hygiene. Nothing in it changes a published image, and the entry says exactly that rather than dressing infrastructure work up as a product release: ```text - Version 2.15: - Build, CI, and repository tooling changes only. No functional change to the published images. ``` **The floor is not rolled back**, per the maintainer: forward only once a release is cut. That is also the only mechanically safe answer, since NBGV derives the patch from git height, so a lower floor would generate versions sorting below what is already published. #437 could revert a bump cleanly because nothing had shipped at it; that window is closed here. The wider question, that agents have moved this repo's floor five times under a develop-leads-main cadence the fleet has since retired, is filed as ptr727/ProjectTemplate#1124 rather than addressed here. ## Reported, not fixed - The GitHub About description still carries the retired sentence. It feeds the Docker Hub short description through the docker-readme task, so that surface will disagree with the README until it is set by hand. `registry/repos.json` declares no `description` for this repo, so `configure.sh apply` cannot write it. - `HISTORY.md`'s 2.11 entry carries a lowercase `docker` in prose. It is a shipped changelog record rather than current prose, so it was left rather than edited for casing. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Expanded setup, installation, image variants, release channels, publishing, build workflows, troubleshooting, and support guidance. * Clarified supported NxWitness and OEM-branded VMS products. * Added testing, diagnostics, architecture checks, and coverage instructions. * Updated release history for version 2.15, corrected links, and removed an obsolete reference. * **Chores** * Updated documentation references for relocated runtime initialization paths. * Improved spell-check dictionary consistency. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Migrate NxWitness to the branch-scoped, triggered-Docker one-run-one-branch CI/CD model, converging it with
the sibling repos while keeping the repo-specific codegen + multi-product Docker matrix.
Release model (triggered-Docker, one run = one branch)
workflow_dispatch+ weeklyschedule(main) + path-scopedpushon main whenMake/Matrix.jsonchanges (codegen commits a new matrix -> publish the new product versions at once).Single
get-versionthreaded assemver2to every product leg (no nested NBGV -> no:SemVer2collision); main-only
build-base(develop dispatch reuses it viabuild_base: false); avalidatejobre-runs lint +
dotnet testbefore building;github-release+ foldeddocker-readmeare main-only. Theold two-leg build-main/build-develop run is removed (one-branch = native NBGV classification, no
IGNORE_GITHUB_REF). The D2.2 main-version backstop stays.push: ['**']+ dispatch (droppull_request/dorny); inlinegit diffchange-gate; deletion guards; aggregator renamed to
Check pull request workflow status job.Convergence
New
WORKFLOW.md(D0-D10 incl. the codegen + multi-image D-guarantees),repo-config/(5D audit), foldeddocker-readme(manifest-jq overMake/Matrix.json), merge-bot--delete-branch,dotnet/nbgv@master(theWORKFLOW.md D9.1 exception),
.slnxrebuilt to the real file set, version floor2.14 -> 2.15. Codegen +Dependabot stay dual-target main+develop. No NuGet publish (the .NET is the matrix generator only).
configure.sh applywill run in lockstep so the renamed required check resolves.