Skip to content

Split Docker builds: fast PR smoke tests and cron-only publishing - #398

Merged
ptr727 merged 13 commits into
developfrom
ci-split-builds
Jun 3, 2026
Merged

Split Docker builds: fast PR smoke tests and cron-only publishing#398
ptr727 merged 13 commits into
developfrom
ci-split-builds

Conversation

@ptr727

@ptr727 ptr727 commented Jun 3, 2026

Copy link
Copy Markdown
Owner

Problem

Every PR built the full 36-image matrix (each amd64+arm64), so feedback took hours, and every merge to main/develop republished the matching images regardless of what changed. Auto-merged Dependabot/codegen PRs therefore triggered full rebuilds and pushed no-op image updates to Docker Hub consumers. Codegen (Sun) and the weekly cron (Mon) also double-built the same content within ~24h.

Changes

  • Fast PR feedbacktest-pull-request.yml runs unit tests + a path-gated smoke build (NxMeta + NxMeta-LSIO, amd64 only, no push) that only runs when image files (Docker/**, Make/Matrix.json, Make/Version.json) change. Non-image PRs get unit-tests only. check-workflow-status keeps its name and treats skipped as pass.
  • Cron-only publishing, both branchespublish-release.yml is now the sole publisher (schedule + manual dispatch). It builds the base images once, then builds and pushes the full matrix for both main and develop in one run, plus the GitHub release, Docker Hub readme, and date badge. The push: trigger is gone, so merges no longer build/publish.
  • Parameterized build taskbuild-docker-task.yml gains smoke/ref/build_base inputs and branch-scoped matrix filtering; build-base-images-task.yml and get-version-task.yml gain platforms/ref inputs.
  • Removed: publish-periodic-docker-release.yml, build-release-task.yml. Trimmed: test-release-task.yml to unit-tests/style only.
  • Cadence: codegen schedule → daily to match Dependabot.
  • Docs: README build/publishing section, HISTORY (v2.12), version.json, AGENTS.md + copilot-instructions.md CI sections, and the stale merge-bot comment.

Net behavior

Trigger Before After
PR: Actions/NuGet bump full matrix unit tests only
PR: image/code change full matrix unit tests + 2-image amd64 smoke
Merge (any) rebuild + republish silent commit
Scheduled / manual publish main only (18 pushed, 18 wasted) both branches (36 pushed)

Verification

  • All 11 workflows parse; actionlint clean (also fixed a pre-existing SC2086 in build-datebadge-task.yml).
  • jq matrix filters validated against Make/Matrix.json: smoke→2 rows, main→18, develop→18.
  • Post-merge: confirm a non-image PR skips the smoke build; an image PR runs it; a manual workflow_dispatch of the publisher produces both :stable and :develop-stable tags. Verify branch protection still requires check-workflow-status.

🤖 Generated with Claude Code

PRs no longer build the full 36-image matrix. test-pull-request.yml now
runs unit tests plus a path-gated smoke build (NxMeta + NxMeta-LSIO,
amd64 only, no push) that only runs when image files change, giving fast
PR feedback.

Publishing moves to schedule/manual only. publish-release.yml becomes the
sole publisher: it builds the base images once and then builds and pushes
the full matrix for both the main and develop branches in one run, plus
the GitHub release, Docker Hub readme, and date badge. The push-triggered
publish (old publish-release.yml) and the separate weekly publisher
(publish-periodic-docker-release.yml) are removed, and build-release-task.yml
is retired. Merges to main/develop no longer build or publish images, so
auto-merged Dependabot and codegen PRs stop producing no-op image updates
for consumers; the next scheduled publish picks them up.

build-docker-task.yml gains smoke/ref/build_base inputs and branch-scoped
matrix filtering; build-base-images-task.yml and get-version-task.yml gain
platforms/ref inputs. Codegen schedule changed to daily to match Dependabot.
Docs (README, HISTORY, AGENTS, copilot-instructions) and version updated.

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

Copilot AI left a comment

Copy link
Copy Markdown

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 restructures the GitHub Actions CI/CD pipeline to drastically shorten pull-request feedback loops (unit tests + a small smoke build only when image-related files change) and to move all Docker publishing into a single scheduled/manual workflow run that publishes both main and develop tags together.

Changes:

  • PR workflow now runs unit tests always and conditionally runs a small amd64-only smoke build when Docker/matrix inputs change.
  • Publishing no longer happens on merges; a weekly scheduled/manual publish-release.yml run is the sole publisher and builds both main and develop in one run.
  • Reusable build workflows were parameterized (smoke/ref/platform filtering), and legacy publishing workflows/tasks were removed.

Reviewed changes

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

Show a summary per file
File Description
version.json Bumps repo/tooling version to 2.12.
README.md Updates documentation to describe PR smoke builds and schedule/manual-only publishing for both branches.
HISTORY.md Adds 2.12 release notes describing the CI pipeline rework.
AGENTS.md Updates agent guidance to reflect the new CI/publishing model and expectations.
.github/copilot-instructions.md Documents new CI pipeline behavior for contributors/agents.
.github/workflows/test-release-task.yml Removes the full “build release” job so this workflow is unit-tests only.
.github/workflows/test-pull-request.yml Adds path-based change detection + conditional smoke build and keeps a single required status check job.
.github/workflows/run-periodic-codegen-pull-request.yml Changes codegen cadence from weekly to daily.
.github/workflows/publish-release.yml Converts to schedule/manual-only “sole publisher”, building base once and publishing both branches in one run.
.github/workflows/publish-periodic-docker-release.yml Removes legacy weekly publishing workflow.
.github/workflows/merge-bot-pull-request.yml Updates comments to reflect that merges no longer trigger publishing.
.github/workflows/get-version-task.yml Adds a ref input and uses it during checkout for version computation.
.github/workflows/build-release-task.yml Removes legacy reusable “build release” workflow.
.github/workflows/build-docker-task.yml Adds smoke/ref/build_base inputs and matrix filtering to support smoke and multi-branch publishing.
.github/workflows/build-datebadge-task.yml Fixes shell quoting when writing to $GITHUB_OUTPUT.
.github/workflows/build-base-images-task.yml Adds configurable platforms input for smoke vs full builds.
Comments suppressed due to low confidence (1)

.github/workflows/build-base-images-task.yml:54

  • The Docker Hub login step runs even when push is false (e.g., PR smoke builds). For PRs from forks, Docker Hub secrets are unavailable, so this step will fail even though pushing isn't needed. Gate the login on inputs.push so non-publishing builds can still run.
      - name: Login to Docker Hub step
        uses: docker/login-action@v4
        with:
          registry: docker.io
          username: ${{ secrets.DOCKER_HUB_USERNAME }}

Comment thread .github/workflows/get-version-task.yml Outdated
Comment thread .github/workflows/build-docker-task.yml Outdated
Comment thread .github/workflows/build-docker-task.yml Outdated
Comment thread .github/workflows/build-docker-task.yml
Comment thread .github/workflows/test-pull-request.yml
Comment thread .github/workflows/build-docker-task.yml Outdated
Comment thread .github/workflows/publish-release.yml Outdated
Comment thread .github/workflows/publish-release.yml
- Checkout steps fall back to github.ref when inputs.ref is empty
  (get-version-task, build-docker-task x2, build-base-images-task).
- Gate Docker Hub login on inputs.push so non-publishing/smoke builds
  (and forked PRs without secrets) don't require credentials
  (build-docker-task, build-base-images-task).
- Pass the branch ref to jq via --arg instead of string interpolation
  (build-docker-task), with a shellcheck SC2016 directive documenting
  that $ref is a jq variable.
- Add a ref input to build-base-images-task and call it with ref: main
  from publish-release so a develop dispatch can't overwrite the shared
  nx-base tag.
- Use a single global concurrency group for publish-release so dispatches
  on different refs can't race on shared tags/readme/badge.
- changes job: add contents: read + checkout so paths-filter works on
  non-PR triggers (workflow_dispatch).

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

Copilot AI left a comment

Copy link
Copy Markdown

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 16 out of 16 changed files in this pull request and generated 3 comments.

Comment thread .github/workflows/publish-release.yml
Comment thread .github/workflows/publish-release.yml
Comment thread .github/workflows/test-pull-request.yml
…check

- publish-release: compute the version from main (get-version ref: main)
  and check out main for the GitHub release, so release metadata/assets
  match the main publish regardless of the dispatch ref; set prerelease
  false accordingly.
- publish-release: github-release now needs both build-main and
  build-develop, so no release is published when develop is still
  building or has failed.
- test-pull-request: check-workflow-status now needs the changes job and
  fails if it fails/cancels, so a paths-filter failure can't let an
  image-changing PR merge with the smoke build silently skipped.

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

Copilot AI left a comment

Copy link
Copy Markdown

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 16 out of 16 changed files in this pull request and generated 1 comment.

Comment thread .github/workflows/build-base-images-task.yml
build-base-images-task pushed and wrote caches only when github.ref_name
was main/develop, but the publisher now builds the shared base from
ref: main and may be dispatched from another branch. Drop the ref_name
guard so push is controlled by the caller (inputs.push), and scope the
cache to the built ref (inputs.ref) instead of github.ref_name.

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

Copilot AI left a comment

Copy link
Copy Markdown

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 16 out of 16 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

.github/workflows/build-datebadge-task.yml:21

  • build-datebadge-task.yml only executes the badge update step when github.ref_name == 'main'. Since this workflow is invoked via workflow_call, github.ref_name is inherited from the caller (e.g., publish-release.yml). If the publisher is manually dispatched from develop (which the new design explicitly supports), the badge step will be skipped and the byob.yarr.is/.../lastbuild badge will not update.
          echo "date=$(date)" >> "$GITHUB_OUTPUT"

      - name: Build BYOB date badge step
        if: ${{ github.ref_name == 'main' }}
        uses: RubbaBoy/BYOB@v1

Comment thread .github/workflows/publish-release.yml
Comment thread .github/workflows/publish-release.yml
- publish-docker-readme-task: add a ref input and check out that ref; the
  publisher passes ref: main so published Docker Hub readmes and the repo
  list track main content, consistent with the pinned version/release.
- build-datebadge-task: drop the github.ref_name == 'main' gate. The sole
  caller (publish-release) runs it only after a successful publish and may
  be dispatched from any ref, so the Last Build badge should always update.

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

Copilot AI left a comment

Copy link
Copy Markdown

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 17 out of 17 changed files in this pull request and generated 1 comment.

Comment thread .github/workflows/test-pull-request.yml
The PR smoke product build pulls the published base from Docker Hub, so
building the base on every image-changing PR was wasted work. Add a base
paths-filter (Docker/NxBase*.Dockerfile) and pass build_base to the smoke
build only when a base Dockerfile changed, so a base bump is still
compile-validated while ordinary product/version PRs skip the base build.

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

Copilot AI left a comment

Copy link
Copy Markdown

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 17 out of 17 changed files in this pull request and generated 1 comment.

Comment thread .github/workflows/test-pull-request.yml
dorny/paths-filter falls back to git diff for non-PR triggers
(workflow_dispatch); the default shallow checkout can miss the history it
needs. Use fetch-depth: 0 so those runs are deterministic. PRs use the API
and are unaffected.

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

Copilot AI left a comment

Copy link
Copy Markdown

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 17 out of 17 changed files in this pull request and generated 2 comments.

Comment thread .github/workflows/test-pull-request.yml
Comment thread .github/workflows/publish-release.yml Outdated
Set publish-release concurrency cancel-in-progress: false so a manual
dispatch during an in-flight (scheduled or manual) publish queues rather
than cancelling it, avoiding a partially pushed set of shared tags.

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

Copilot AI left a comment

Copy link
Copy Markdown

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 17 out of 17 changed files in this pull request and generated 1 comment.

Comment thread .github/workflows/publish-release.yml
action-gh-release tags against the run commit (github.sha) unless
target_commitish is set; since the publisher is dispatchable from any ref,
set target_commitish: main so the release tag lands on main, consistent
with the main-pinned version and assets.

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

Copilot AI left a comment

Copy link
Copy Markdown

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 17 out of 17 changed files in this pull request and generated 2 comments.

Comment thread .github/workflows/build-docker-task.yml Outdated
Comment thread README.md
…rsion

- build-docker-task smoke filter: de-dup by [.Name, .Branch] instead of
  .Name, so the smoke build covers NxMeta/NxMeta-LSIO for both main and
  develop (4 amd64 builds), and a develop-targeted PR validates the
  develop rows/args rather than only the main rows.
- README: bump the Release Notes header to 2.12 with a CI-rework summary
  to match version.json / HISTORY.md, and drop the now-unused
  nxpackage-link / nxvmsdockerfile-link reference definitions.

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

Copilot AI left a comment

Copy link
Copy Markdown

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 17 out of 17 changed files in this pull request and generated no new comments.

…nsions

Add .vscode/extensions.json recommending linters for every structured file
type the repo uses -- C# (Roslyn + CSharpier), Markdown (markdownlint),
YAML (Red Hat schema), Dockerfiles/Compose (Docker), and GitHub Actions
(GitHub Actions extension) -- so a fresh clone gets editor linting for all
of them rather than singling out workflows or adding a CI lint job.

Document the approach in AGENTS.md (new "Linting structured files" section)
and copilot-instructions.md; actionlint remains the deeper CLI check for
workflow edits.

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

Copilot AI left a comment

Copy link
Copy Markdown

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 18 out of 18 changed files in this pull request and generated no new comments.

@ptr727
ptr727 merged commit e8048ce into develop Jun 3, 2026
8 checks passed
@ptr727
ptr727 deleted the ci-split-builds branch June 3, 2026 17:01
@ptr727 ptr727 mentioned this pull request Jun 3, 2026
ptr727 added a commit that referenced this pull request Jun 3, 2026
Promotes the current `develop` integration branch to `main`.

## Included

- **Split Docker builds: fast PR smoke tests and cron-only publishing
(#398)** — PRs run unit tests + a path-gated amd64 smoke build instead
of the full matrix; publishing moves to a schedule/manual-only
`publish-release.yml` that builds the base once and publishes the full
matrix for both branches in one run; merges no longer build/publish;
codegen runs daily; adds `.vscode/extensions.json` workspace linters and
documents the CI/review model. Version bumped to 2.12.
- **Update codegen files (#394)** — refreshed `Make/Version.json` /
`Make/Matrix.json`.
- **NuGet dependency bumps (#390, #392).**

## Notes

- This PR targets `main`, so per the repo ruleset it should be merged
with a **merge commit** (not squash), keeping `develop` forward-only.
- The develop→main diff touches `Make/Matrix.json` /
`Make/Version.json`, so the PR's smoke build will run (real end-to-end
exercise of the new PR pipeline).

🤖 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