Skip to content

Restore HEAD sentinel in scm tag - #1044

Merged
shnapz merged 1 commit into
masterfrom
akabas/fix-scm-tag
Sep 23, 2026
Merged

shnapz merged 1 commit into
masterfrom
akabas/fix-scm-tag

Conversation

@shnapz

@shnapz shnapz commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

maven-release-plugin rewrites <scm><tag> during release:prepare, then restores it from pom.xml.releaseBackup in the development phase. The restore replays whatever the tree held before prepare ran rather than computing a correct value, so the field behaves as a loop: whatever master holds, master keeps holding.

Master currently holds v0.10.29 — two releases stale.

How it broke

Release cycle prepare release prepare for next dev
v0.10.27 v0.10.27 HEAD ✅
v0.10.28 v0.10.28 HEAD ✅
v0.10.29 (early attempt, 4212693) v0.10.29 HEAD ✅
v0.10.29 (final, 558b87a) v0.10.29 v0.10.29 ❌
v0.10.30 (e655bb2) v0.10.30 v0.10.29 ❌

The loop ran correctly on the HEAD sentinel for years. It broke during the v0.10.29 cycle: the cleanup commits (#1009, #1011) reverted master to a tree that still carried the release-time value v0.10.29 instead of the development-time sentinel, and the loop has replayed that stale literal ever since — including through v0.10.30, which restored v0.10.29 rather than HEAD.

Why it is worth fixing now

Nothing published is affected: the v0.10.30 prepare commit set v0.10.30 correctly, and dbeam-parent-0.10.30.pom on Maven Central carries <tag>v0.10.30</tag>. This is master's working state only.

The exposure is a standalone release:perform. Its checkout URL falls back to release.properties and then to the POM's own <scm> section, including <tag>. In the normal release:prepare release:perform invocation release.properties exists with the right scm.tag and the POM value is never consulted — but retrying a failed deploy after release:clean, splitting prepare and perform into separate CI jobs, or performing from a fresh checkout would resolve the tag from the POM, check out v0.10.29, and try to redeploy an already-published version.

The pointer is wrong twice over: the v0.10.29 tag itself points at e032ae1, while the published 0.10.29 artifacts were built from 558b87a (the Central pom contains central-publishing-maven-plugin, which only landed in 05add13 / #1012).

Restoring HEAD is self-healing — the development phase will back up HEAD and restore HEAD from here on. Worth landing before 0.10.31 is cut, so that cycle does not re-bake the stale value.

Also

release.properties and pom.xml.releaseBackup are now gitignored. They are cleaned on a successful release:perform but linger after a failed one, where they can be committed by accident — plausibly how the value got baked in originally.

Test plan

  • xmllint --noout pom.xml — well-formed
  • <scm><tag> is the only occurrence in the tree; dbeam-core and dbeam-bom have no <scm> block and inherit from the parent
  • CI green
  • Next release (0.10.31) leaves <tag>HEAD</tag> on master after the development-phase commit

🤖 Generated with Claude Code

maven-release-plugin rewrites <scm><tag> during release:prepare and then
restores it from pom.xml.releaseBackup in the development phase. It
replays whatever the tree held before prepare ran rather than computing a
correct value, so the field is a loop: whatever master holds, master
keeps holding.

Through v0.10.28 and the first v0.10.29 attempt the loop ran on the HEAD
sentinel. The v0.10.29 cleanup commits (#1009, #1011) reverted master to
a tree that still carried the release-time value v0.10.29, and the loop
has replayed that stale literal ever since -- including through the
v0.10.30 release, which restored v0.10.29 instead of HEAD.

Left alone this is self-perpetuating, and it is a live footgun for a
standalone release:perform: without release.properties the plugin
resolves the checkout from the POM's <scm> section, so it would check out
v0.10.29 and try to redeploy an already-published version. The stale
pointer is wrong twice over, since the v0.10.29 tag itself points at
e032ae1 rather than 558b87a, the commit the published 0.10.29 artifacts
were built from.

Restoring HEAD is self-healing: the development phase will back up HEAD
and restore HEAD from now on.

Also gitignore release.properties and pom.xml.releaseBackup. They are
cleaned on a successful release:perform but linger after a failed one,
where they can be committed by accident -- plausibly how the value got
baked in originally.

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

codecov Bot commented Sep 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.87%. Comparing base (ca54576) to head (f9020cc).

Additional details and impacted files
@@            Coverage Diff            @@
##             master    #1044   +/-   ##
=========================================
  Coverage     91.87%   91.87%           
  Complexity      288      288           
=========================================
  Files            27       27           
  Lines          1034     1034           
  Branches         90       90           
=========================================
  Hits            950      950           
  Misses           55       55           
  Partials         29       29           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@shnapz shnapz mentioned this pull request Sep 23, 2026
2 of 3 tasks
@shnapz
shnapz merged commit 14045f5 into master Sep 23, 2026
9 checks passed
@shnapz
shnapz deleted the akabas/fix-scm-tag branch September 23, 2026 18:17
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