Skip to content

Target 1.1.0, fix the release-tag pattern, and report the version in CI - #222

Merged
mgravell merged 5 commits into
mainfrom
release-1-1-0
Sep 11, 2026
Merged

Target 1.1.0, fix the release-tag pattern, and report the version in CI#222
mgravell merged 5 commits into
mainfrom
release-1-1-0

Conversation

@mgravell

@mgravell mgravell commented Sep 11, 2026

Copy link
Copy Markdown
Member

Three things, all in service of cutting 1.1.0 cleanly.

1. Land on 1.1.0

versionHeightOffset goes -1-3.

The offset is a fixed shift, not a pin: height counts commits since the version property changed, and two more have landed since it opened (#221, plus this commit). Editing versionHeightOffset does not reset the height — verified, it stays at 3 — so the offset has to absorb the drift:

height + offset version
-1 (current) 3 2… wait, 1 1.1.1
-3 3 0 1.1.0

Confirmed locally: {'VersionHeight': 3, 'BuildNumber': 0, 'NuGetPackageVersion': '1.1.0-…'}. The -g suffix there is only because a branch isn't a public-release ref; main will compute a clean 1.1.0, since a squash-merge puts exactly one commit on top of 78f0fc7 — the same height I measured.

2. Fix the release-tag pattern — it has never worked

publicReleaseRefSpec requires ^refs/tags/v\d+\.\d+, but every tag this repo has ever cut is unprefixed: 1.0.52, 1.0.48, 1.0.45, … The regex cannot match any of them.

Demonstrated on real history — checking out the actual 1.0.52 tag and asking nbgv:

{'NuGetPackageVersion': '1.0.52-g7a36975e31', 'PublicRelease': False}

So a tag-triggered build has always produced a -g-suffixed version; the packages that actually shipped must have come from main builds instead, which is why this was never noticed. Relaxed to v? so both spellings work — at an unprefixed 1.1.0 tag nbgv now reports a clean 1.1.0, PublicRelease: True.

Same fix, same reason, as StackExchange.Redis 611e478 — which also had to bump the offset in the same commit, for the same "one more commit" reason.

3. Report the computed version in CI

Modelled on StackExchange.Redis's CI.yml:

- name: Report computed version
  run: |
    $version = nbgv get-version --variable NuGetPackageVersion
    "### Computed package version: ``$version``" >> $env:GITHUB_STEP_SUMMARY
    Write-Output "Computed package version: $version"

Placed before restore/build, so the version stays legible even when a later step fails. Cutting a release then means reading that line off a green main build and tagging with exactly it.

Checking this PR's own run

Two things to eyeball when CI goes green here:

  • the step summary should read 1.1.0-g<hash> — the -g is expected on a PR branch, and becomes clean 1.1.0 on main;
  • the step working at all confirms nbgv is on PATH after the dotnet/nbgv action (its README says it installs the CLI, but this is the first step to depend on that).

4. Add release.yml (second commit)

There was no release workflow at alldotnet.yml pushes to MyGet on main, and nothing publishes to nuget.org, so every release to date must have been pushed by hand. That is also why the broken tag pattern above went unnoticed for so long.

Triggered by a published GitHub Release, with workflow_dispatch as a dry run that does everything except the tag check and the push — so the pipeline can be proven, and the packages inspected via the run artifact, without cutting a release.

The guard is the point. nbgv computes the version from version.json + commit height, so the tag name does not set it; a mistyped tag would otherwise ship a package that disagrees with its release. The step compares the two and fails loudly instead. A leading v is stripped, matching the v? pattern fixed above.

Publishes both packages — Dapper.AOT and Dapper.Advisor are both on nuget.org at 1.0.52, and both set GeneratePackageOnBuild for Release, so a Release build produces the pair and the collect step gathers them with the same glob dotnet.yml already uses. They upload as a run artifact before the push, so a failed push doesn't cost the build.

Setup needed outside this repo (also recorded in the file header)

  • a GitHub environment named release;
  • a NUGET_USER repository secret holding the nuget.org profile to publish as;
  • a Trusted Publishing policy on nuget.org for each of the two packages — Repository Owner DapperLib, Repository DapperAOT, Workflow File release.yml, Environment release.

No further offset delta needed

Adding a second commit to this branch does not need another versionHeightOffset change: the repo squash-merges, so this lands as one commit on main regardless. Simulated it rather than assuming — squash-merging this branch onto main gives:

{'VersionHeight': 3, 'BuildNumber': 0, 'NuGetPackageVersion': '1.1.0-…'}

-3 still computes 1.1.0. (The -g suffix is only because the simulation branch isn't main.)

Three things, all in service of cutting 1.1.0 cleanly.

**Land on 1.1.0.** versionHeightOffset goes -1 -> -3. The offset is a fixed shift,
not a pin: height counts commits since the `version` property changed, and two more
have landed since (#221, and this one), so -1 would compute 1.1.1. Editing
versionHeightOffset does *not* reset the height - verified, height stays 3 - so the
offset has to absorb the drift. -3 puts this commit at exactly 1.1.0, which is what
main will compute once this squash-merges (one commit on top of 78f0fc7 either way).

**Fix the release-tag pattern**, which has never worked. publicReleaseRefSpec requires
`^refs/tags/v\d+\.\d+`, but every tag this repo has ever cut is unprefixed - 1.0.52,
1.0.48, 1.0.45 and so on - so the regex cannot match any of them. Checking out the
real 1.0.52 tag and asking nbgv gives `1.0.52-g7a36975e31`, PublicRelease False: a
tag-triggered build has always produced a -g suffixed version, and the packages that
shipped must have come from main builds instead. Relaxed to `v?`, so both spellings
work; at an unprefixed 1.1.0 tag nbgv now reports a clean 1.1.0, PublicRelease True.
Same fix, same reason, as StackExchange.Redis 611e478.

**Report the computed version in CI**, modelled on StackExchange.Redis's CI.yml: a
step that writes the NuGetPackageVersion to the job summary and the log, placed before
restore/build so it stays legible when a later step fails. Cutting a release then means
reading that line off a green main build and tagging with exactly it.
There was no release workflow at all - dotnet.yml pushes to MyGet on main, and
nothing publishes to nuget.org, so every release to date must have been pushed by
hand. That is also why the broken tag pattern went unnoticed.

Triggered by a published GitHub Release, with workflow_dispatch as a dry run that
does everything except the tag check and the push, so the pipeline can be proven
without cutting a release.

The guard is the point: nbgv computes the version from version.json plus commit
height, so the tag name does not set it and a mistyped tag would otherwise ship a
package that disagrees with its release. The step compares the two and fails loudly
instead. A leading "v" is stripped, matching the v? pattern this PR also fixes.

Publishes **both** packages: Dapper.AOT and Dapper.Advisor are both on nuget.org at
1.0.52, and both set GeneratePackageOnBuild for Release, so a Release build produces
the pair and the collect step gathers them with the same glob dotnet.yml already
uses. They are uploaded as a run artifact before the push, so a failed push does not
cost the build.

Auth is Trusted Publishing (OIDC) - no long-lived key in the repo. That needs setup
outside this file, recorded in the header comment: a GitHub environment named
"release", a NUGET_USER secret, and a trusted-publishing policy on nuget.org for
*each* of the two packages.

No further versionHeightOffset delta: the repo squash-merges, so this lands as one
commit on main regardless of how many are on the branch, and -3 still computes 1.1.0.
release.yml now publishes to nuget.org on a tagged release, so the MyGet push on
every main build is both redundant and a second, unversioned place for packages to
appear. Removed, along with the Pack and Purge steps that existed only to feed it -
packaging is still exercised on every build, because both src projects set
GeneratePackageOnBuild for Release, so a broken nuspec still fails CI.

That also retires the MYGETAPIKEY secret; nothing references it now.

Badges: there were none at all, so this adds rather than updates - build status, and
current nuget.org versions for both published packages. Worth having now that a
release actually lands on nuget.org by a route anyone can see.
The new net48 CI step caught this on its first real outing, which is exactly what it
was added for: CommandDefinitionOverloads.output.netfx.txt still claimed "2 skipped
silently" and carried no DAP057, because #220 was developed on Linux and only the
.output.* goldens can be regenerated there - the .output.netfx.* twins need an actual
net48 run.

Swept the rest rather than fixing just the one that failed: comparing every
.output.txt against its .output.netfx.txt, this is the *only* pair whose diagnostic
ids differ, and the only one whose scorecard buckets disagree. The other scorecard
differences are legitimate - netfx genuinely has fewer call-sites (15 of 15 vs 17 of
17, and so on), and DateOnly.net6 is gated off netfx entirely.

The generated-code goldens are untouched: #220 added diagnostics, not code, and the
handled count is 1 of 3 on both sides either way.
The first real run printed `1.1.4-g90538b49e3` on this PR, which is correct and
misleading at once: a PR builds refs/pull/N/merge, whose height includes every branch
commit plus the merge, so it is not the number that will ship. Squash-merged onto
main the same work computes 1.1.0.

Since the whole point of this step is "read this, tag with it", that gap is a live
mis-tag waiting to happen. On main the summary now says to tag with exactly that
value; anywhere else it says, in the summary itself, that the number is not the one
that would ship and to read it off a main run instead. The log line carries the ref
either way.

release.yml's guard would catch the resulting mismatch, but not hitting it beats
being caught by it.
@mgravell
mgravell merged commit b5194b4 into main Sep 11, 2026
2 checks passed
@mgravell
mgravell deleted the release-1-1-0 branch September 11, 2026 14:16
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.

1 participant