Skip to content

Commit b80fa5d

Browse files
authored
fix(release-script): install root artifact before ShowcaseSync to prevent cut abort (#83)
cut-release.ps1 Step 4 (ShowcaseSync) aborted during the v1.6.5 cut with "Could not find artifact io.github.demchaav:graphcompose:jar:1.6.5": after Step 1 bumped the four pom.xml files to 1.6.5, the examples module's graphcompose:\${project.version} dependency had no matching artifact in local ~/.m2 (only the previous 1.6.4 was there) and Step 4 had no install gate. The cut had to finish by hand — install root, re-run ShowcaseSync, verify, commit, tag, push. Run-ShowcaseSync now executes ./mvnw -B -ntp -DskipTests install -pl . immediately before exec:java, in both Release and PostReleaseOnly modes. The dry-run preview now lists both steps so the install is visible before any cut. Also relaxes the Step 0 pre-flight branch / clean / sync gates for -DryRun so the script can be previewed from a feature branch while iterating on it. Live cuts still fail the gates loudly. Lesson captured in docs/contributing/release-process.md section 4.
1 parent 83fcd6a commit b80fa5d

2 files changed

Lines changed: 48 additions & 19 deletions

File tree

docs/contributing/release-process.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ Each learning maps to a check above.
136136
- **v1.6.0 prep** — slimming the README to a marketing landing renamed the canonical `DocumentSession document = …` example variable to `doc`, which silently broke `DocumentationCoverageTest.readmeShouldUseCanonicalDslAndAvoidLegacyApis` because the test asserts the literal string `document.pageFlow(` is present. *Mitigation*: any rewrite of the README "Hello world" snippet must keep `DocumentSession document` as the variable name and `document.pageFlow(`, `document.buildPdf()`, `GraphCompose.document(` as the literal canonical fingerprints the guard scans for. Renaming the variable is a guard-test break, not a stylistic preference.
137137
- **v1.6.0 post-release** — the `examples-generation` CI job introduced after v1.6.0 went red on the first run because `examples/pom.xml` and `benchmarks/pom.xml` declare a `<graphcompose.version>` property used by their `graphcompose` dependency, and `cut-release.ps1` was only flipping the project's own `<version>` tag (the first `<version>` in each file). The subordinate POMs kept `<graphcompose.version>1.6.0-beta.1</graphcompose.version>` after the release commit; CI couldn't resolve a `1.6.0-beta.1` artifact (it never existed on any registry), so `mvnw -f examples/pom.xml clean compile` failed at dependency resolution. *Mitigation*: `Update-PomVersion` in `cut-release.ps1` now flips both the first `<version>` tag *and* a `<graphcompose.version>...</graphcompose.version>` property if present, in the same call. Future agents need not touch this — running the script handles both.
138138
- **v1.6.5 prep** — the subordinate-POM `<graphcompose.version>` property flip from the v1.6.0 lesson above is now **superseded**: `examples/` and `benchmarks/` were converted to a reactor under a non-published `aggregator/pom.xml`, so they inherit their version from `graphcompose-build` and declare `<graphcompose.version>${project.version}</graphcompose.version>` instead of a literal. The library `pom.xml` stays standalone, so JitPack coordinates never change. Version drift is now structurally impossible *and* caught by `VersionConsistencyGuardTest` (wired into CI's guard job and the section 0.B gate). `cut-release.ps1` bumps the library pom, the aggregator, both inherited parent refs, and the README install snippets in one commit; `.github/workflows/release.yml` then gates the tag on `verify` and publishes the GitHub Release automatically. *Mitigation*: section 0.D verifies all four version sites agree; the guard fails the verify gate if any hand-edit leaves them out of sync.
139+
- **v1.6.5 cut**`cut-release.ps1` Step 4 (`ShowcaseSync`) aborted with `Could not find artifact io.github.demchaav:graphcompose:jar:1.6.5 in central` after Step 1 bumped the four pom.xml files to `1.6.5`: the examples module depends on `graphcompose:${project.version}`, the previous release (`1.6.4`) was the only version in the local `~/.m2`, and Step 4 had no install gate to put the just-bumped version there first. Cut had to be finished by hand — install root, re-run ShowcaseSync, verify, commit, tag, push. *Mitigation*: `Run-ShowcaseSync` now runs `./mvnw -B -ntp -DskipTests install -pl .` immediately before `exec:java`, in both Release and PostReleaseOnly modes; the dry-run preview shows both steps. Pre-flight branch / clean / sync gates are now relaxed for `-DryRun` so the script can be previewed from a feature branch while iterating on it.
139140

140141
---
141142

scripts/cut-release.ps1

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,30 @@ function Run-ShowcaseSync {
271271
# as a single literal argument.
272272
$execProp = '"-Dexec.mainClass=com.demcha.examples.support.ShowcaseSync"'
273273
if ($DryRun) {
274+
Write-Host " [DRY RUN] $mvnw -B -ntp -DskipTests install -pl ." -ForegroundColor Yellow
274275
Write-Host " [DRY RUN] $mvnw -f examples/pom.xml exec:java $execProp" -ForegroundColor Yellow
275276
return
276277
}
277278
Push-Location $repoRoot
278279
try {
280+
# ShowcaseSync runs from the examples module, which depends on
281+
# io.github.demchaav:graphcompose:${project.version}. After Step 1
282+
# bumps the four pom.xml files to the new release version, that
283+
# artifact is not yet in the local m2 cache — only the previous
284+
# release is — so exec:java fails dependency resolution with
285+
# "Could not find artifact ...:graphcompose:jar:<new-version>".
286+
# Install the root artifact first so the examples module can
287+
# resolve it. Bug surfaced during v1.6.5 cut: Step 4 aborted with
288+
# exit 1; we had to install by hand and resume manually.
289+
Write-Host " > $mvnw -B -ntp -DskipTests install -pl ." -ForegroundColor DarkGray
290+
& $mvnw -B -ntp -DskipTests install -pl . 2>&1 | ForEach-Object {
291+
if ($_ -match 'BUILD SUCCESS|BUILD FAILURE|ERROR') {
292+
Write-Host " $_" -ForegroundColor DarkGray
293+
}
294+
}
295+
if ($LASTEXITCODE -ne 0) {
296+
throw "Install root artifact failed (exit $LASTEXITCODE)"
297+
}
279298
& $mvnw -f examples/pom.xml exec:java $execProp 2>&1 | ForEach-Object {
280299
if ($_ -match 'Synced|Wrote manifest|BUILD SUCCESS|BUILD FAILURE|ERROR') {
281300
Write-Host " $_" -ForegroundColor DarkGray
@@ -337,28 +356,37 @@ try {
337356

338357
Step 0 "Pre-flight checks"
339358

340-
# 1. On develop branch?
359+
# In -DryRun mode the script never mutates anything, so the branch /
360+
# working-tree / origin-sync gates are relaxed: a maintainer can preview
361+
# what a release cut would do from a feature branch (e.g. while iterating
362+
# on the script itself) without having to switch to develop and back.
363+
# Live cuts still fail these gates loudly.
341364
$branch = (git rev-parse --abbrev-ref HEAD).Trim()
342-
if ($branch -ne 'develop') {
343-
throw "Not on develop branch (currently on $branch). Switch to develop first."
344-
}
345-
Note "branch: develop OK"
365+
if ($DryRun) {
366+
Note "branch: $branch (gate relaxed for -DryRun)"
367+
} else {
368+
# 1. On develop branch?
369+
if ($branch -ne 'develop') {
370+
throw "Not on develop branch (currently on $branch). Switch to develop first."
371+
}
372+
Note "branch: develop OK"
346373

347-
# 2. Working tree clean?
348-
$status = git status --porcelain
349-
if ($status) {
350-
throw "Working tree has uncommitted changes. Commit or stash first."
351-
}
352-
Note "working tree: clean OK"
353-
354-
# 3. In sync with origin?
355-
git fetch origin develop --quiet
356-
$local = (git rev-parse develop).Trim()
357-
$remote = (git rev-parse origin/develop).Trim()
358-
if ($local -ne $remote) {
359-
throw "Local develop ($local) is not in sync with origin/develop ($remote). Pull/push first."
374+
# 2. Working tree clean?
375+
$status = git status --porcelain
376+
if ($status) {
377+
throw "Working tree has uncommitted changes. Commit or stash first."
378+
}
379+
Note "working tree: clean OK"
380+
381+
# 3. In sync with origin?
382+
git fetch origin develop --quiet
383+
$local = (git rev-parse develop).Trim()
384+
$remote = (git rev-parse origin/develop).Trim()
385+
if ($local -ne $remote) {
386+
throw "Local develop ($local) is not in sync with origin/develop ($remote). Pull/push first."
387+
}
388+
Note "in sync with origin/develop OK"
360389
}
361-
Note "in sync with origin/develop OK"
362390

363391
# 4. Tag doesn't already exist?
364392
$existingTag = git tag -l $tag

0 commit comments

Comments
 (0)