| name | documenting-struts-release |
| description | Use when a new Apache Struts version has been released and you need to audit its release notes (JIRA / Version Notes) and update the website's feature/behavior documentation to match, including spotting breaking / backward-incompatible changes that need migration notes. For the GA announcement mechanics (announce-YYYY, _config.yml, releases.md, [ANN] email) use announcing-struts-release instead. |
Documenting a Struts Release
Overview
A new release ships bug fixes, improvements, and new features. Some of them
change documented behavior or add new configuration; many do not. This skill is
the content audit: map each release-note item to the page that documents it,
and update only the real gaps. It is separate from the release announcement
(see announcing-struts-release).
Core principle: find the gap, don't re-document. Most items are either already
documented by an earlier PR or have no doc home. Blindly "documenting the release
notes" produces duplicate or wrong content.
Where the docs actually live
source/docs/ is only an index — do not grep it for feature guides. Real
content lives in:
source/core-developers/ — interceptors, configuration, conversion, validation, file upload (~166 pages)
source/tag-developers/ — tags, themes, templates
source/plugins/<name>/ — per-plugin docs (json, rest, spring, convention, …)
source/security/ — security bulletins
Breaking changes — always run this pass
Breaking changes are the highest-value thing to document, and the easiest to
miss: they rarely sit under New Feature, and the JIRA notes have no "breaking"
category. They hide inside Improvement, Bug, Task, and Dependency items.
A breaking change needs a migration / behaviour-change callout
({:.alert .alert-warning}) on the affected page, even when the item itself has
no obvious "feature" page.
Shortlist first, then judge. Don't eyeball ~60 issues — filter titles for the
words that signal breakage, then read the source diff for each hit:
enforce|authoriz|deprecat|remove|delete|rename|narrow|private|require|
default|harden|bump|upgrade|migrat|incompat|minimum|drop|reject
Then scan every shortlisted issue (all types, not just New Feature/Improvement)
against this checklist:
- Changed default — a constant/default flips so existing apps behave differently.
- New enforcement — stricter validation/authorization now rejects input that
previously worked (e.g.
@StrutsParameter enforcement reaching a new channel).
- Removed / deprecated / narrowed API — deleted methods,
protected→private
field changes that break subclasses, renamed/removed config keys.
- Raised minimum requirement — higher Java / Servlet / Jakarta / Spring /
Tomcat baseline. Confirm against the tag's
pom.xml / parent POM and compare to
the previous tag; do not trust the announcement's copied boilerplate paragraph.
- Dependency major bump that changes a user-facing API — e.g. OGNL or
commons-fileupload method renames. These are NOT "purely internal" if user code
or config touches them. Several JIRA "Bump X from A to B" tickets may stack for
one dependency; verify the net version delta in the tag's
pom.xml against
the previous tag, not the single hop shown in any one ticket.
- Output/encoding changes — altered rendered HTML, escaping, redirect bodies.
Check the Version Notes page ({{ site.wiki_url }}/Version+Notes+<X.Y.Z>) for
an upgrade/migration section — but treat it as a bonus, not the source of truth: it
is often empty for a release. The JIRA scan above is the primary discovery method.
Verify each suspected breaking change against the source tag (see Workflow step 4)
before writing the migration note. If a breaking change touches minimum runtime
requirements, also flag it for announcing-struts-release (its spec-versions
paragraph and the getting-started prerequisites may need updating).
Workflow
-
Get the itemized release notes. Fetch the JIRA ReleaseNote.jspa URL and
list every issue (all types) with its WW-XXXX key. Mark each as: a
documentation candidate (New Feature, Improvement, or a Bug implying a
user-visible change — changed default, new option, behavior change) and/or a
breaking change per the checklist above. An item can be both.
-
Check existing coverage FIRST — before planning any edit. For each candidate:
git log --oneline -- <likely page> and search recent commits/PRs for the
version or issue keys: git log --oneline --all | grep -iE "<version>|WW-XXXX".
grep -rn "<feature keyword / constant>" source/.
Many items will already be documented by a prior PR. Drop those.
-
Map each remaining item to its page, then classify it:
- documented — already covered (drop).
- gap — has a doc home, not yet covered (fix it).
- no-doc-home — purely internal (perf, refactors, IDE-plugin, logging,
dependency bumps with no user-facing effect) → list as out-of-scope, do not
invent a page. Note: a dependency bump or removal that breaks user code/config
is a breaking change, not no-doc-home — it still needs a migration note.
-
Verify exact details against the released source tag — NOT JIRA. JIRA
descriptions are proposals; constant names, defaults, and class names often
differ in the merged code. Confirm against the STRUTS_<X>_<Y>_<Z> git tag, e.g.:
core/src/main/resources/org/apache/struts2/default.properties
plugins/<name>/src/main/resources/struts-plugin.xml
Fetch https://raw.githubusercontent.com/apache/struts/STRUTS_X_Y_Z/<path>.
-
Edit the gap pages. Follow each page's existing structure and the repo's
Kramdown conventions (e.g. {:.alert .alert-warning} for callouts). Cross-link
related pages; for parameter-authorization topics, link the
core-developers/struts-parameter-annotation.html hub. Confirm every internal
link target file exists.
-
Commit per page (docs: type, with the Co-Authored-By trailer) on a
branch off (e.g. ). Do touch
announcement files (, , ).
Common mistakes
| Mistake | Fix |
|---|
| Documenting items already covered | Step 2: check git history + grep existing pages first; drop covered items. |
Grepping source/docs/ for feature pages | It is only an index — search core-developers/, tag-developers/, plugins/. |
| Trusting JIRA for constant names/defaults | JIRA is a proposal; verify against the STRUTS_X_Y_Z tag source. |
| Inventing a page for an internal change | If there is no doc home, list it as out-of-scope. |
| Bundling announcement changes | Announcement mechanics belong to announcing-struts-release; keep this branch content-only. |
| Claiming the build passed when it didn't run | Say the local build couldn't run and rely on staging; never assert unverified success. |
| Only scanning New Feature/Improvement for changes | Breaking changes hide in Bug/Task/Dependency items — run the breaking-changes pass over every issue. |
| Dropping dependency bumps as "internal" | A dep bump/removal that changes a user-facing API (OGNL, fileupload renames) is breaking — document it, don't drop it. |
| Re-copying the announcement's minimum-requirements paragraph | Verify Java/Servlet/Jakarta baselines against the tag's POM vs the previous tag; flag raised minimums. |