Skip to content

fix: align the version with the 1.57.0 tag and add a CI guard so the mismatch cannot recur - #1706

Merged
laurentiu021 merged 2 commits into
mainfrom
fix/align-version-with-1-57-0
Aug 5, 2026
Merged

fix: align the version with the 1.57.0 tag and add a CI guard so the mismatch cannot recur#1706
laurentiu021 merged 2 commits into
mainfrom
fix/align-version-with-1-57-0

Conversation

@laurentiu021

Copy link
Copy Markdown
Owner

The v1.57.0 release failed at Extract release notes from CHANGELOG, leaving a pushed tag with no published release.

Root cause — mine, not the pipeline's

I titled #1704 feat:, so auto-release computed a minor bump and tagged v1.57.0. But I had hand-written the csproj version and the CHANGELOG header as 1.56.15, assuming a patch bump. release.yml then looked for a ## [1.57.0] section, found nothing, and correctly refused rather than publishing a release with placeholder notes.

The guard did its job. The inputs were wrong.

The fix

Move the version to what the tag actually says:

  • Version / FileVersion / AssemblyVersion1.57.0
  • CHANGELOG header renamed 1.56.151.57.0

The notes themselves are untouched and already describe exactly what shipped. Those feature additions are also what justify a minor bump, so 1.57.0 is the correct number and 1.56.15 was the mistake. Nothing about the release is rewritten: the tag stays as-is, and merging this lets the release be re-dispatched against it.

Why this can't happen again

Nothing in the repo verified version consistency — that absence is why the drift reached a published tag. CI now cross-checks on every PR that:

  1. Version, FileVersion and AssemblyVersion agree with each other, and
  2. the newest CHANGELOG header matches the csproj version.

Caught on the PR, where it costs one edit, instead of after the tag is pushed.

The check was proven, not assumed

Run against three fixtures with the real PowerShell host:

Fixture Expected Result
Corrected tree (1.57.0 everywhere) pass exit 0
The actual bug (csproj 1.56.15 vs CHANGELOG 1.57.0) reject exit 1, ...disagree
Partial edit (Version bumped, FileVersion left behind) reject exit 1, FileVersion (1.56.15.0) does not match Version (1.57.0)

Red before, green after.

Notes

  • No CHANGELOG entry for this commit: it corrects the version of an entry that is already there, and adding a second section for the same release would be wrong.
  • Leak scan against all 32 patterns: zero hits.

…mismatch cannot recur

The v1.57.0 release failed at "Extract release notes from CHANGELOG", leaving a pushed tag with no
published release.

Root cause is mine, not the pipeline's. I titled #1704 feat:, so auto-release computed a MINOR bump
and tagged v1.57.0 — while I had hand-written the csproj version and the CHANGELOG header as
1.56.15, assuming a patch. release.yml then looked for a "## [1.57.0]" section, found none, and
correctly refused rather than publishing a release with placeholder notes. The guard did its job;
the inputs were wrong.

Fixed by moving the version to what the tag actually says: csproj Version/FileVersion/
AssemblyVersion to 1.57.0, and the CHANGELOG header renamed. The notes themselves are unchanged and
already describe exactly what shipped — the feature additions are also what justify a minor bump,
so 1.57.0 is the correct number and 1.56.15 was the mistake. Nothing about the release is
rewritten: the tag stays, and pushing this lets the release be re-dispatched against it.

Turned the failure into a mechanical rule rather than a resolution to remember. CI now cross-checks,
on every PR, that Version/FileVersion/AssemblyVersion agree with each other and that the newest
CHANGELOG header matches — the exact drift that reached a published tag today, caught where it costs
one edit instead of a stuck release. Nothing in the repo verified this before; that absence is why
it got through.

The check was proven, not assumed. Run against three fixtures with the real PowerShell host:
the corrected tree passes; the actual bug (csproj 1.56.15 vs CHANGELOG 1.57.0) exits 1 with
"disagree"; and a partial edit that updates Version but leaves FileVersion behind exits 1 with
"FileVersion (1.56.15.0) does not match Version (1.57.0)". Red before, green after.
… chart buffers

CI failed with "Collection was modified; enumeration operation may not execute" thrown from
LiveCharts' CollectionDeepObserver. A real concurrency bug in the history feature I added in #1704,
not a test artifact.

The poll loop appends to _downBuffer/_upBuffer every second while ReloadHistoryAsync rebuilds those
same buffers with ReplaceWith, and LiveCharts observes both. The existing guard tested
ShowingHistory, which is only assigned AFTER the load's await completes — so the window between
entering the reload and that assignment was unguarded. In the app both run on the UI dispatcher and
interleave harmlessly; a test host has no dispatcher, so ConfigureAwait(true) resumes on the thread
pool and the two genuinely overlap. Now gated on a _historyOwnsChart flag claimed BEFORE the first
await and released on the cancellation path, so a cancelled load cannot leave the live chart
permanently frozen.

I was wrong about the cause first. My initial diagnosis was that ReplaceWith let a Reset subscriber
observe the collection mid-rebuild — plausible, and it matched the stack trace's shape, but the
harness disproved it: those assertions passed against the UNFIXED helper, because notification
suppression already means the Reset fires after the rebuild. The stack trace says OnItemsAdded, an
Add notification, which is the poll loop, not the replace. Corrected the fix and the comment rather
than shipping a rationale that reads convincingly and is false.

Investigating it did surface two genuine ReplaceWith defects, both now fixed and pinned: passing the
collection as its own source emptied it (Items.Clear() runs before anything is added back, and the
lazy source was that same collection), and a source that threw part-way left the collection
half-replaced while still bound to the UI. Both are red against the old code and green against the
new one — 20 call sites pass a lazy LINQ query, so the shape was reachable.

What is NOT claimed: the harness does not reproduce the race. 60 reload cycles with the poll loop
live pass against the unfixed code too, so that check is labelled a smoke test, not a red/green
proof. The race has only ever been observed on CI, so CI is where this fix has to be judged.

All four projects build with 0 warnings and 0 errors.
@laurentiu021
laurentiu021 merged commit 1b5b6d3 into main Aug 5, 2026
4 checks passed
@laurentiu021
laurentiu021 deleted the fix/align-version-with-1-57-0 branch August 5, 2026 12:53
laurentiu021 added a commit that referenced this pull request Aug 5, 2026
…efore the notes exist (#1707)

Unblocks two stranded tags and removes the cause, in a chore: commit so this cannot itself tag a
third version.

v1.57.0 and v1.57.1 are both pushed with no published release. The cause is a process defect I hit
three times: auto-release computes the version from the commit type AND the previous tag, then pushes
the tag — and only afterwards does release.yml check that CHANGELOG.md has a section for it. So a
version I could not know in advance gets tagged, the release fails on the missing section, and the
next fix: merge (including one meant to repair this) tags another one. Patching the number by hand
could never converge.

Two changes:

1. The 1.57.1 entry the release needs, describing the Bandwidth Monitor chart crash fixed in #1706,
   and csproj moved to 1.57.1 to match. That is the tag whose release will be re-dispatched;
   v1.57.0's content is already inside 1.57.1, so nothing shipped is lost or rewritten.

2. auto-release now verifies the CHANGELOG entry exists and is non-empty BEFORE creating the tag.
   A missing entry now costs a workflow re-run instead of stranding a version. The error message
   states the exact header to add and the bump it came from, because the author genuinely cannot
   compute that number locally — treating it as author carelessness would be the wrong fix.

Verified against six fixtures rather than assumed: an entry that is present and non-empty accepts; a
missing one rejects (the actual failure); a present-but-empty section rejects, since it would publish
a release with no notes; an older entry still resolves; and the escaped dots mean 1.5.71 cannot match
a 1.57.1 header. Also re-ran the csproj/CHANGELOG consistency check added in #1706 against this tree
so the two guards agree rather than contradicting each other.

Note that release.yml checks out the TAG, not main — so this entry only reaches a release for tags
created after it. That is exactly why the guard belongs in auto-release, before the tag is cut.

Co-authored-by: laurentiu021 <laurentiu021@users.noreply.github.com>
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