Skip to content

chore(release): finish the 0.19.2 pin sweep (drift gate fix) - #534

Merged
arcaputo3 merged 1 commit into
mainfrom
chore/release-0.19.2-pins
Aug 8, 2026
Merged

chore(release): finish the 0.19.2 pin sweep (drift gate fix)#534
arcaputo3 merged 1 commit into
mainfrom
chore/release-0.19.2-pins

Conversation

@arcaputo3

Copy link
Copy Markdown
Contributor

Fixes the examples CI failure on main (✗ Version drift: examples/project.scala pins 0.19.1 but build.mill falls back to 0.19.2) and sweeps every remaining com.tjclp::xl:0.19.1 dep string: examples, scripting reference docs, both release-packaged skills, the scripting scaladoc header, plus the WorkbookMetadata.appVersion default that gets stamped into written files. Historical 0.19.1 mentions stay.

The in-flight v0.19.2 release run was cancelled before its Maven-publish step; after this merges the tag moves to the fixed commit and the release re-runs cleanly.

🤖 Generated with Claude Code

…s, packaged skills, metadata appVersion

The 0.19.2 bump (#533) missed the dep-pin strings outside README/QUICK-START:
examples/project.scala (the CI version-drift gate caught this on main),
examples/README.md, docs/reference/scripting.md, both packaged skills
(xl-scripting SKILL/RECIPES), the scripting.scala scaladoc header, and the
WorkbookMetadata.appVersion default stamped into written files. Historical
mentions (roadmap, LIMITATIONS, rule-introduction annotations) stay.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@arcaputo3
arcaputo3 merged commit b7b3163 into main Aug 8, 2026
4 checks passed
@claude

claude Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review: chore(release): finish the 0.19.2 pin sweep (drift gate fix)

Mechanical and correct as far as it goes — every substitution in the diff is the right one, and I verified the two CI gates this PR is meant to satisfy now pass:

  • examples drift guard (scripts/test-examples.sh:14-29): examples/project.scala0.19.2 matches the build.mill:17 PUBLISH_VERSION fallback 0.19.2. ✅
  • release scripting-skill gate (.github/workflows/release.yml:350-360): the stale-pin grep over plugin/skills/xl-scripting/ now returns exactly one line, com.tjclp::xl:0.19.2. ✅ It would have hard-failed the 0.19.2 release before this.
  • the appVersion bump is inert for tests: no test or fixture asserts the literal. DocPropsSpec:103-119 only asserts docProps/app.xml presence, and WorkbookEquivalence:103 compares expected-vs-actual symmetrically. XlsxReader:1482 propagates the read AppVersion, so round-trip byte-identity on pre-existing files is untouched — the default only applies to freshly constructed WorkbookMetadata.
  • Repo-wide, the only remaining 0.19.1 mentions are correctly historical: CHANGELOG.md, docs/STATUS.md:24, docs/LIMITATIONS.md:232, plugin/skills/xl-cli/SKILL.md:118 (rule-introduction annotation). Leaving those is right.

One gap and a few structural notes.


1. plugin/.claude-plugin/plugin.json is still 0.19.1 — please bump it here

It still reads "version": "0.19.1". This is item 3 of the release-prep checklist, which carries its own warning:

  1. plugin/.claude-plugin/plugin.json (the "version" field)
    • Update the plugin marketplace version. Do not skip this — it has drifted in past releases (was stale at 0.7.0) because it was missing from this list.

It is not a com.tjclp::xl: dep string, so it sits just outside the scope stated in the PR body — but the title says finish the pin sweep, this is the PR that unblocks re-tagging, and grepping .github/ and scripts/ for plugin.json / claude-plugin returns nothing, so no gate will catch it. Bumping it here costs one line and avoids a third follow-up.


2. Root cause: the pin checklist is 8 items, CI gates 2 of them

build.mill is the source of truth, but seven locations hand-copy it and only two are mechanically checked. Ungated today: WorkbookMetadata.appVersion, plugin.json, docs/reference/scripting.md, examples/README.md, the xl/src/com/tjclp/xl/scripting.scala scaladoc, README.md, docs/QUICK-START.md. This checklist has now failed twice (0.7.0 plugin.json, then #533 → this PR), which is the signal that it wants to be code rather than prose. A ~15-line scripts/check-version-pins.sh wired into the main CI workflow would close it:

  V="<PUBLISH_VERSION fallback parsed out of build.mill>"
  fail=0
  check() { grep -q "$2" "$1" || { echo "FAIL: $1 does not pin $V"; fail=1; }; }
  check examples/project.scala             "com.tjclp::xl:$V"
  check examples/README.md                 "com.tjclp::xl:$V"
  check README.md                          "$V"
  check docs/QUICK-START.md                "$V"
  check plugin/.claude-plugin/plugin.json  "\"version\": \"$V\""
  check xl-core/src/com/tjclp/xl/workbooks/WorkbookMetadata.scala "Some(\"$V\")"
  exit $fail

...plus a check that no stale com.tjclp::xl:<other> survives outside CHANGELOG and docs history. Given the guiding principle in CLAUDE.md, "the release cannot be tagged with a stale pin" is better expressed as a gate than as a checklist item a human (or an agent) has to remember.


3. A stronger fix for appVersion specifically

appVersion is the one entry that gets stamped into every file users write, and it is the one with no gate at all. Deriving it from a generated BuildInfo instead of a hand-maintained literal in xl-core would make drift structurally impossible. Caveat worth thinking through first: PUBLISH_VERSION is env-driven in CI, so BuildInfo would stamp the tag version into released artifacts (arguably more correct than today) and the build.mill fallback locally — the same observable behavior as now, minus the staleness. Non-blocking; a follow-up issue.


4. Not this PR, but directly relevant to the re-run it enables

Inside the release job the steps run in this order:

  • .github/workflows/release.yml:265Publish to Maven Central
  • .github/workflows/release.yml:350 — the xl-scripting pin gate

So the gate runs after the irreversible publish, in the same job. On the 0.19.2 attempt it could only have reported the stale pin once artifacts were already on Central. Moving the pin checks into a pre-publish step, or into a separate gating job that release declares in needs:, would make it an actual gate. Worth doing before the re-tag, since that is the failure mode this whole PR chain is cleaning up after.


Notes

  • I did not run ./mill __.compile or ./mill __.test (the sandbox declined the build). The only Scala changes are a string literal in a default argument and a scaladoc comment, so compile risk is nil and CI covers it.
  • Style and conventions: nothing to flag — no purity, totality, or formatting surface touched.

Verdict: approve once plugin.json is bumped to 0.19.2. Items 2-4 are follow-ups, not blockers for this PR.

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