Version each publish leg against its own branch; validate at entry - #215
Merged
Conversation
Fixes #213. On a publish dispatched from the default branch, NBGV derives PublicRelease from the runner's GITHUB_REF (= refs/heads/main for every matrix leg), so the develop leg loses its -g<sha> prerelease suffix and its NuGet package is published as a stable version (isPrerelease=false). - get-version-task.yml gains an optional `branch` input that pins the GITHUB_REF/GITHUB_REF_NAME NBGV reads to the leg being versioned, with a github.ref fallback when empty. Threaded from all five callers (build-release-task + the four build-*-task files). - Replace the late, main-only "Verify public release version" step with a single `validate-release` entry job that the build jobs needs:, checking branch<->version consistency both directions (main must have no prerelease suffix; every other branch must have one) and failing fast before builds. - Codify the validate-input/state-consistency-at-entry pattern in AGENTS.md "Workflow YAML Conventions". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a release-pipeline versioning bug where publish-release.yml runs from main but builds a main+develop matrix, causing NBGV to classify the develop leg as a public release and publish stable NuGet versions.
Changes:
- Add an optional
branchinput toget-version-task.ymland pinGITHUB_REF/GITHUB_REF_NAMEfor the NBGV step to the leg being versioned. - Thread
branchthrough all reusable-workflow callers ofget-version-task.ymlso every target versions against its intended branch. - Replace the late, one-directional main-only version check with an early
validate-releasejob that enforces branch<->prerelease consistency for bothmainand non-mainlegs.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| AGENTS.md | Documents the “validate invariants at entry, fail fast” workflow convention with concrete examples. |
| .github/workflows/get-version-task.yml | Adds branch input and pins env so NBGV classifies the correct leg branch during matrix publishes. |
| .github/workflows/build-release-task.yml | Threads branch into versioning and adds an entry validate-release job gating downstream build/release jobs. |
| .github/workflows/build-pypilibrary-task.yml | Passes inputs.branch to the shared get-version workflow. |
| .github/workflows/build-nugetlibrary-task.yml | Passes inputs.branch to the shared get-version workflow (fixing the mislabel root cause for NuGet). |
| .github/workflows/build-executable-task.yml | Passes inputs.branch to the shared get-version workflow. |
| .github/workflows/build-docker-task.yml | Passes inputs.branch to the shared get-version workflow. |
This was referenced Jun 26, 2026
ptr727
added a commit
that referenced
this pull request
Jun 27, 2026
## Problem Closes #219. The `validate-release` entry gate (added in #213/#215) runs **unconditionally**, including in PR **smoke** builds. A smoke build checks out the PR head in detached HEAD, so NBGV always computes a prerelease version (`X.Y.Z-g<sha>`). On a **main-base** PR — a `develop → main` promotion carrying a build target — the gate's `branch == 'main'` arm fails: ``` ::error::Public (main) release version 'X.Y.Z-g<sha>' carries a prerelease suffix; refusing to publish. ``` `validate-release` fails → `build` is skipped → the required `Check pull request workflow status` fails. **Every clean `develop → main` promotion PR that includes a build-target change is blocked by its own smoke build** (masked only when merged via admin bypass). ## Fix Skip the gate for smoke builds — they never publish — keeping the job in the graph as a **success** so `build-*`'s `needs: [get-version, validate-release]` stays satisfied: ```yaml SMOKE: ${{ inputs.smoke }} ... if [[ "$SMOKE" == "true" ]]; then echo "Smoke build; skipping release version validation." exit 0 fi ``` Real publishes (`smoke: false`) still get both-direction validation. ## Verification - `actionlint` (Docker, shellcheck-bundled) clean; CRLF preserved. - Per the issue's push-probe: a `smoke: true` invocation passes for both `branch: main` (Release) and `branch: develop` (Debug) with `github-release` skipped; real publishes unaffected. Found via end-to-end CI flow validation during the #213/#214 downstream re-sync. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ptr727
added a commit
that referenced
this pull request
Jun 27, 2026
…ride (#222) ## Problem Closes #221; supersedes the mechanism from #215. The #213 fix (PR #215) restored the develop leg's prerelease tag by overriding `GITHUB_REF` in the nbgv step `env:`. **It doesn't work.** `GITHUB_REF` is GitHub-reserved — a step-level `env:` can't reliably override it (the runner re-injects the dispatch ref). NBGV's GitHub Actions cloud-build provider reads `GITHUB_REF` for `BuildingRef`, so on a publish dispatched from `main` the develop leg was still classified public and would publish a **clean (stable)** version. CI evidence from the first real publish after #215: ``` GITHUB_REF: refs/heads/develop # the step-env override (as configured) "BuildingRef": "refs/heads/main" # NBGV still saw the dispatch ref "PublicRelease": true "SemVer2": "1.4.2" # clean, no -g suffix ``` (The `validate-release` gate correctly blocked the bad publish, so nothing shipped — but the develop prerelease leg never publishes.) ## Fix NBGV versions from the **checked-out branch** unless its cloud provider overrides with `GITHUB_REF`. Each matrix leg already checks out its own branch, so set NBGV's own `IGNORE_GITHUB_REF=true` to make it ignore the CI ref: ```yaml - name: Run Nerdbank.GitVersioning tool step id: nbgv uses: dotnet/nbgv@master env: IGNORE_GITHUB_REF: true ``` - Removed the ineffective `GITHUB_REF`/`GITHUB_REF_NAME` override. - Dropped the now-useless `branch` input from `get-version-task.yml` and its threading from all five callers (`build-release-task` + the four `build-*-task`). - `validate-release` entry gate (from #213/#215, smoke-skip from #219) **stays** as the backstop. NBGV source confirms the knob: `BuildingRef => IgnoreGitHubRef ? null : env GITHUB_REF`. ## Verification - `actionlint` (Docker) clean on all six changed workflows; CRLF preserved. - Per the issue's CI probe (real `dotnet/nbgv`): `develop` checkout + `IGNORE_GITHUB_REF=true` → `PublicRelease=False`, `1.4.2-g…`; `main` → `True`, `1.4.3`; `main` without the flag reproduces the bug. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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)
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.
Problem
Closes #213.
publish-release.ymldispatched frommainbuilds a matrix of bothmainanddevelop. NBGV derivesPublicReleasefrom the runner'sGITHUB_REF, which isrefs/heads/mainfor every leg regardless of the ref each leg checks out. So thedevelopleg is classified public, NBGV strips its-g<sha>prerelease suffix, and the develop NuGet package is published as a stable version (isPrerelease=false) — consumers can resolve a develop build as if stable. The GitHub release object staysprerelease:true, masking the bug.Fix
get-version-task.yml: optionalbranchinput pins theGITHUB_REF/GITHUB_REF_NAMENBGV reads to the leg being versioned (fallback togithub.refwhen empty). The mislabel originates inbuild-nugetlibrary-task's own get-version call, sobranchis threaded from all five callers (build-release-task+ the fourbuild-*-taskfiles).github-release) is replaced by a singlevalidate-releasejob that the build jobsneeds:. It checks branch↔version consistency both directions —mainmust carry no prerelease-; every other branch must carry one (the Publish matrix mislabels the develop leg as a public release: NBGV drops the prerelease tag, NuGet package published as stable #213 regression guard) — and fails fast before the expensive builds.AGENTS.md"Workflow YAML Conventions", generalizing the existingpublish-docker-readme-task.yml"Validate inputs step".Verification
actionlint(Docker) clean on all six changed workflows; markdownlint clean onAGENTS.md; CRLF preserved.publish-releasefrommain, confirm the develop leg'sSemVer2regains-g<sha>and the NuGet package isisPrerelease=true;validate-releasefails a clean-X.Y.Zdevelop version.🤖 Generated with Claude Code