Repository navigation
feat(release): one versioning policy for every repository, and main names the version it released - #12
Conversation
…ames the version it released Every DiluxOne repository now numbers its versions by one written policy (CONTRIBUTING.md, "How a change becomes a version"): a major for a big new capability or for anything that breaks, a minor for additions to what exists, a patch for fixes, security and performance; a breaking change ships only in a major, announced in a minor before it, and every major says in its changelog whether it breaks anything. A big capability is the maintainer's call with the version:major label; the review now says when a feat looks like one, and is told that size is not breakage, so a large compatible feature stays a feat. The version markers on main (the Version header, the PHP constant, Stable tag) now always name a real version. The release job stamped them only in its own checkout and never wrote main, so after 2.0.0 shipped, DiluxOne Offload's main still said 1.0.0, while every document said main keeps the last released version. Now the release pull request, the one that removes the Unreleased. line, sets them to the version it releases (scripts/release-markers.sh prepare), the checks' readme job holds every pull request to it (the last release, or the next one once its release pull request is ready), and the release job refuses to deploy a commit whose markers name another version. No extra pull request after a release, and main is right from the moment the release is decided. This enforces what the documentation already promised (main keeps the last released version), so a repository that followed it needs nothing; the one caller today, DiluxOne Offload, records 2.0.0 in its own pull request right after this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude review · risk high · complexity high · type featThe new commits fixed both earlier findings. No findings. Policy floor: high (touches high-risk paths: .github/workflows/claude-review.yml, .github/workflows/plugin-checks-wp.yml, .github/workflows/plugin-release-wp.yml, .github/workflows/pull-request.yml, CONTRIBUTING.md …). Reviewed e7b1ef3 (since 61b3c3c; review 3 of 5 automatic). Author trusted for auto-merge: true. 🤖 AI review · claude-opus-5-5 (Anthropic) · $0.09, 4 turns |
…ounts its own labels The review found that after a release, a fix merged before anyone opened the next changelog entry made every later pull request fail: the readme is ready (its newest entry is the last release's), something is pending, so the check wanted the next version, and pointed to prepare, which refuses a readme that is not held. The newest entry being the last release's now means nothing is being released yet, and the markers stay at it; a readme that is ready for another version gets a hint that fits (set markers and heading, or settle it with a label, or put the hold back). The check of an open pull request now counts its own labels as if it had merged (next-version.py --with-pull), so a release pull request that carries version:major is checked against the major it will release instead of passing and leaving main refused by the release job. The release workflow's header and its changelog error no longer offer a `= Unreleased =` heading at release time, which the markers check now rejects; the release caller template and the release-automation plan say what the release does now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…a release PR carries no bump The review asked for a self-test of the new --with-pull path and for the checks' comment to say that the review's type:* label, set after the job ran, is not seen either. The fold is now a function with its own test (an open version:major gives the major, a chore adds nothing, a pull request already merged counts once), and the comment says why the release pull request holds nothing but the hold and the markers, and that the release job still refuses anything that slips through. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s say so The review noticed that docs/release.md describes the release job checking the version markers while release.yml still pinned the shared workflow at v2.2.0, which stamped them. The pin moves to DiluxOne/.github#12's merge commit (v2.4.0 once tagged), and the release.yml header and the Makefile's comment on development builds describe the markers the release pull request sets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… roadmap are written down (#19) ## 📝 What changes The version markers on main (Version header, DILUXONE_OFFLOAD_VERSION, Stable tag) go from 1.0.0 to 2.0.0, the version that shipped on 28 September. docs/release.md, AGENTS.md, CONTRIBUTING.md and docs/testing-and-quality.md describe the DiluxOne versioning policy (a major for a big new capability or a break, a minor for additions to what exists, a patch for fixes, security and performance; breaking changes only in a major, announced first; every major states its breaking changes) and the new marker rule: the markers name the last release, or the one being released from its release pull request on, which sets them. They also mention wordpress.org's six-hour hold on plugin updates. docs/roadmap.md: 2.0.0 marked released; 4.0.0 is now Google Cloud Storage native and 5.0.0 DiluxOne Storage; 2.1.0 drops the promise of a Disconnect limited to this site's objects; Cache-Control in 2.3.0 is configurable and the storage class applies to new uploads only, never an archive tier. release.yml pins the shared release workflow at DiluxOne/.github#12's merge commit (v2.4.0), the one that checks the markers, and its header and the Makefile's comment on development builds say so. No change to the plugin's behaviour: the shipped files already said 2.0.0 (the release stamps them) and development builds stamp their own copies. ## 💡 Why The release job stamped the version only in its checkout, so main kept saying 1.0.0 while the docs said it keeps the released version. DiluxOne/.github#12 makes the release pull request set the markers and adds a check that holds every pull request to them; this pull request brings main in line with it. The policy and the roadmap are what the maintainer decided on 28 September after comparing strict SemVer with what other plugins do. ## 🧪 How I tested it scripts/release-markers.sh check (from DiluxOne/.github#12) on this tree with the labels next-version.py gives (last 2.0.0, nothing pending): "Markers OK: 2.0.0". On main before this change it fails on all three markers. DiluxOne/.github#12 is merged; once v2 moves to it, this pull request's checks run the new readme job for real, and the release job reads release-markers.sh from v2. ## 📸 Screenshots Not applicable: no screen changes. ## ✅ Checklist - [x] Tests cover the change. - [x] Docs that describe what changed are updated in this PR. - [x] No credentials, keys or personal data anywhere in the diff. 🤖 AI-generated · Claude Opus 5.5 (Anthropic) --------- Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
📝 What changes
A written versioning policy for every DiluxOne repository, in CONTRIBUTING.md ("How a change becomes a version"): major for a big new capability or anything that breaks, minor for additions to what exists, patch for fixes, security and performance; breaking changes only in a major, announced in a minor first; every major states its breaking changes or "none". The big-capability call stays with the maintainer (version:major); the review profile and prompt now say that size is not breakage and that a feat that looks like a new capability gets a one-line suggestion in the summary, never the label.
New scripts/release-markers.sh:
checkholds the three version markers to the last release, or to the next one once the release pull request is ready;prepareturns a tree into that release pull request (removes the Unreleased. line, stamps the markers). The checks' readme job runscheckon every pull request (it reads the labels of the merged pull requests and, through the newnext-version.py --with-pull, the pull request's own labels as if it had merged, so a release pull request carrying version:major is checked against that major; the job gets pull-requests: read and the central checkout); the release job runs it before deploying and refuses a commit whose markers name another version. The central CI runs its self-tests. README and the workflow headers describe the new flow.💡 Why
The release job stamped the version only in its own checkout, so after 2.0.0 shipped DiluxOne Offload's main still says 1.0.0, while every document says main keeps the last released version. Setting the markers in the release pull request (instead of a bot pull request after every release) keeps main right from the moment the release is decided, with no extra pull request.
The policy is the one the maintainer chose after comparing strict SemVer with what other plugins do (WP Offload Media, Elementor, Angular: a major for a big capability or a break; WordPress and WooCommerce: a counter). The pipeline needed no change for it: version:major already wins.
This enforces what the docs already promised, so a repository that followed them needs nothing. The only caller today, DiluxOne Offload, is off by it (1.0.0 against the 2.0.0 release) and records 2.0.0 in its own pull request right after this merges and v2 moves.
🧪 How I tested it
bash scripts/release-markers.sh --test: 22 cases (held/ready, pending or not, a fix merged after a release with no new entry, markers behind or ahead, the constant alone, no constant, no release yet, prepare on a held readme, a= Unreleased =heading, a CRLF readme, a readme that is not held). Run against a copy of DiluxOne Offload's real tree with the labels from next-version.py: it fails naming the three markers at 1.0.0 against 2.0.0.python3 scripts/next-version.py --testincludes--with-pull(an open version:major gives the major, a chore adds nothing, a merged pull request counts once). actionlint clean, shellcheck clean.📸 Screenshots
Not applicable: no screen.
✅ Checklist
🤖 AI-generated · Claude Opus 5.5 (Anthropic)