Skip to content

docs(skills): add releasing-struts, and configure the release plugin in the pom - #1844

Merged
lukaszlenart merged 4 commits into
mainfrom
docs/releasing-struts-skill
Aug 14, 2026
Merged

docs(skills): add releasing-struts, and configure the release plugin in the pom#1844
lukaszlenart merged 4 commits into
mainfrom
docs/releasing-struts-skill

Conversation

@lukaszlenart

@lukaszlenart lukaszlenart commented Aug 14, 2026

Copy link
Copy Markdown
Member

#1843 has merged, so this now targets main directly.

Why

The only end-to-end description of the release process is the cwiki page Building Struts 2 — Normal release, last revised in 2017. It is still right about JIRA, the release plugin, Nexus and dist.apache.org, and wrong about everything downstream:

It says Reality
Branches develop / master main and support/struts-6-x-x
Tag STRUTS_2_3_x STRUTS_X_Y_Z
Export the wiki to /docs No longer part of the site
Docker Jekyll, commit content/, svn co .../production/struts The site builds from a PR to apache/struts-site
people.apache.org, announce.md, downloads.html Dead host; files are announce-YYYY.md and download.cgi

The four existing skills cover the paperwork. Nothing covered the mechanics, the ordering, or the last mile — the GA [ANN] mail, CVE registration, the site update, post-release follow-through.

The skill

releasing-struts/SKILL.md — seven phases, each with a gate someone other than the release manager can verify, cross-referencing creating-version-notes, creating-release-vote-mail and creating-security-bulletins rather than restating them.

releasing-struts/release-runbook.md — the commands, each marked ✔ verified against the 7.3.0 / 6.11.0 run or ⚠ carried over from the cwiki and unconfirmed. Still ⚠: the Nexus close/release clicks, the release:perform fallback, and whether the omnibus JIRA ticket is still practice.

releasing-struts/scripts/ — phases 3 and 5 were already automated in a local toolbox that exists on one machine. Ported so the skill is self-contained: stage-assemblies.sh (closed staging repo → dist/dev, renamed and re-hashed) and promote-dist.sh (dist/devdist/release). Behaviour unchanged; deviations listed in each header — set -eu, a required $VERSION, tolerant md5/sha1 cleanup, a printed file list before the commit, and an explicit -m so the svn move does not open $EDITOR.

.gitignore — a blanket *.sh silently swallowed both scripts on the first push. Negated for .claude/skills/**/scripts/*.sh only.

The pom change

The release ran on remembered command-line flags. Both move into the pom:

  • autoVersionSubmodules onto maven-release-plugin. Verified against the effective pom that it merges with, rather than replaces, the ASF parent's useReleaseProfile=false, goals=deploy and releaseProfiles=apache-release.
  • retryFailedDeploymentCount=10 onto maven-deploy-plugin in pluginManagement — the only place it can work. release:perform forks a fresh Maven build, and the fork does not inherit -D from the outer invocation, so mvn release:perform -DretryFailedDeploymentCount=10 was never reaching the deploy at all.

The SCM tag stays interactive: tagNameFormat only interpolates @{project.version} and has no string functions, so the closest it gets to STRUTS_7_3_0 is STRUTS_7.3.0. Noted in the pom so nobody retries it.

Both runbook commands lose their flags to match. Only 7.x is changed — support/struts-6-x-x needs the same edit on its own branch.

Corrections found while verifying

  • Releases are cut on a release/X.Y.Z-RC1 branch off the line, not on main. The [maven-release-plugin] commits live on release/7.3.0-RC1 and release/6.11.0-RC1; main still reads 7.2.2-SNAPSHOT after 7.3.0 shipped. A failed vote is a deleted branch, not a revert.
  • The BOM needs no version syncbom/pom.xml inherits through <parent>, and the struts-version.version property the cwiki tells you to check no longer exists.
  • The GA [ANN] mail goes To: user@ with Cc: announce@, announcements@strutsdev@ is not on it.

Follow-up

The cwiki page should be trimmed to a pointer at this skill, so there aren't two documents that disagree. Not done here — that's a wiki edit, not a repo change.

🤖 Generated with Claude Code

@lukaszlenart
lukaszlenart force-pushed the docs/releasing-struts-skill branch from 0aaf29d to 137cb06 Compare August 14, 2026 09:28
Base automatically changed from docs/plain-text-list-mail-in-skills to main August 14, 2026 09:29
lukaszlenart and others added 2 commits August 14, 2026 11:29
The only end-to-end description of the release process was the cwiki
page "Building Struts 2 - Normal release", last revised in 2017. It is
still right about JIRA, the release plugin, Nexus and dist.apache.org,
and wrong about everything downstream: branches develop/master, tag
STRUTS_2_3_x, exporting the wiki to /docs, building the site with
Docker Jekyll and committing content/ into an svn production repo, and
publishing via people.apache.org. Following it today publishes to a
repository that no longer serves the site.

The four existing skills cover the paperwork -- Version Notes, the
[VOTE] mail, bulletins, report triage. Nothing covered the mechanics,
the ordering, or the last mile: the GA [ANN] mail, CVE registration,
the site update, and post-release follow-through.

releasing-struts is the spine: seven phases, each with a gate that
someone else can verify, cross-referencing the existing skills rather
than restating them. release-runbook.md holds the commands, with every
step marked as verified against the 7.3.0/6.11.0 run or as carried over
from the cwiki page and still unconfirmed, so the next release manager
knows which is which.

Three things the cwiki got wrong that were verified here:

- Releases are cut on a release/X.Y.Z-RC1 branch off the line, not on
  main. The [maven-release-plugin] commits never reach main, which is
  why the root pom still read 7.2.2-SNAPSHOT after 7.3.0 shipped -- and
  why the pom is worthless as a source for the release number.
- The BOM needs no version sync; bom/pom.xml inherits through <parent>
  and the struts-version.version property no longer exists.
- The GA [ANN] mail goes To user@ with Cc announce@ and
  announcements@struts, not to dev@.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Phases 3 and 5 were automated all along, in the release manager's local
toolbox at ~/Projects/Apache/minatour/bin. The runbook pointed at a
directory that only exists on one machine, which is how those steps came
to be marked unverified in the first place.

Ported both into scripts/, so the skill is self-contained:

  stage-assemblies.sh  closed staging repo -> dist/dev, renamed, re-hashed
  promote-dist.sh      dist/dev -> dist/release

Behaviour is unchanged. The deviations, listed in each script's header:
set -eu so a failed step cannot commit a partial set, a required $VERSION
so an unset variable cannot create an empty directory or move the whole
dev tree, tolerant md5/sha1 cleanup, a printed file list before the
commit, and an explicit -m so the svn move does not open $EDITOR.

.gitignore carries a blanket *.sh, which silently swallowed both files on
the first attempt. Negated for .claude/skills/**/scripts/*.sh only -- a
skill that ships a tool has to be able to ship it.

The toolbox's third script, update-struts2-draft-docs.sh, exports
Confluence into the retired svn production site. Deliberately not ported,
and called out as dead so nobody runs it.

Both phases are now marked verified. The remaining unverified steps are
the Nexus close/release clicks, the release:perform fallback, and whether
the omnibus JIRA ticket is still practice.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@lukaszlenart
lukaszlenart force-pushed the docs/releasing-struts-skill branch from 137cb06 to d700c5e Compare August 14, 2026 09:29
…ommand line

The release ran on remembered flags: release:prepare needed
-DautoVersionSubmodules=true and release:perform -DretryFailedDeploymentCount=10,
neither recorded anywhere but a 2017 wiki page. A flag that has to be
remembered is a flag that will eventually be forgotten, and forgetting
autoVersionSubmodules means answering a version prompt once per module.

autoVersionSubmodules moves onto maven-release-plugin. Verified against
the effective pom that it merges with, rather than replaces, the three
settings inherited from the ASF parent: useReleaseProfile=false,
goals=deploy, releaseProfiles=apache-release.

retryFailedDeploymentCount moves onto maven-deploy-plugin in
pluginManagement, which is the only place it can work: release:perform
forks a new Maven build and the fork does not inherit -D properties from
the outer invocation, so the flag on the command line was never reaching
the deploy.

The SCM tag stays interactive. Our tags are STRUTS_X_Y_Z and
tagNameFormat can only interpolate @{project.version}, which would give
STRUTS_7.3.0. Noted in the pom so the next reader does not retry it.

Both commands in the runbook lose their flags to match.

Only the 7.x line is changed here; support/struts-6-x-x needs the same
edit on its own branch.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@lukaszlenart lukaszlenart changed the title docs(skills): add releasing-struts, the end-to-end release runbook docs(skills): add releasing-struts, and configure the release plugin in the pom Aug 14, 2026
Comment thread .claude/skills/releasing-struts/SKILL.md Outdated
Comment thread .claude/skills/releasing-struts/release-runbook.md Outdated
Comment thread .claude/skills/releasing-struts/release-runbook.md Outdated
Comment thread .claude/skills/releasing-struts/release-runbook.md
Comment thread .claude/skills/releasing-struts/release-runbook.md Outdated
Review comments:

- creating-security-bulletins is not "phase 7". A bulletin is written
  when the report is triaged, often months before a release carries the
  fix, and plenty are handled with no release in flight. Phase 7 is only
  the reverse dependency: if this release carries a security fix, follow
  that skill once phase 6 is done.
- Dropped every reference to the minatour toolbox, including the note
  about its dead draft-docs script. The scripts live here now.
- Phase 1 checks the JDK before building. 7.x builds on 17 and 6.x on 8,
  and whichever JDK is active in the shell is the one that produces the
  release. On a mismatch the instruction is to stop and ask how to
  switch: jenv, SDKMAN, asdf and a hand-set JAVA_HOME all differ, and
  .java-version is gitignored, so there is nothing safe to infer from.
- Closing the Nexus staging repository is the release manager's action
  in a web UI behind an ASF login. Now written as hand over, wait for
  confirmation, then verify the group URL yourself.

Review findings:

- The site checklist named source/download.cgi, a six-line wrapper
  around mirrors.cgi with no release content, and omitted
  source/releases.md, which holds the release table and which both
  August 2026 site PRs changed. Following it shipped an incomplete PR --
  as PR #323 did earlier today.
- promote-dist.sh only rejected an empty VERSION while its header
  claimed an unset variable could not move the whole dev directory.
  svn resolves a "." path element rather than rejecting it (".." is
  rejected, "." is not), so VERSION="." moved dist/dev/struts wholesale
  in one irreversible commit. Both scripts now require a version-shaped
  value.
- set -eu had silently dropped the original's unconditional cleanup, so
  a failed run left an svn working copy with $VERSION already added; a
  later run for a different version would have committed the stale tree
  alongside the new one. Restored via trap, and struts-dev is now
  guarded up front like $VERSION.
- The phase 3 gate listed five assemblies. There are six: min-lib was
  missed by a [a-z]+ pattern that cannot match a hyphen. 24 files.
- The default tag would be struts2-project-X.Y.Z; the root artifactId is
  struts2-project, not struts2-parent.
- The "is the staging repository closed?" diagnostic was unreachable in
  the case it described: under set -e a 404 killed wget first. Wrapped.
- The rename glob had been widened from *2-assembly*.zip* to
  *2-assembly*, which forced a compensating change to the .pom cleanup
  and was not in the header's deviation list. Restored to the original
  pair, with a comment noting the two lines are coupled.
- Documented invocation ran in the repository tree, creating ./$VERSION
  and an svn working copy there. Now cd "$(mktemp -d)" first.

Guards exercised: empty, ".", "..", "abc" all rejected by both scripts;
the wget failure path prints its diagnostic and leaves no working copy.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@lukaszlenart
lukaszlenart merged commit f6fef73 into main Aug 14, 2026
12 checks passed
@lukaszlenart
lukaszlenart deleted the docs/releasing-struts-skill branch August 14, 2026 10:39
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