Add Release and Release RC workflows#505
Open
enricobattocchi wants to merge 4 commits into
Open
Conversation
Adds two workflow_dispatch-driven release pipelines ported from
yoast-test-helper:
* `release.yml`: end-to-end stable release. Verifies the changelog.md
section, bumps the version via `grunt set-version` + `grunt
update-version`, commits to trunk, merges into main, tags, deploys
to wp.org SVN via the 10up action, creates a GitHub release with
`duplicate-post-${VERSION}.zip` attached and changelog.md extract as
notes, manages milestones, merges main back into trunk.
* `release-rc.yml`: release-candidate flow. Auto-detects the next RC
number, regenerates changelog.md via the existing
generate-changelog.sh, bumps the version with `grunt
update-version-trunk` (preserves the readme.txt Stable tag), tags
`${VERSION}-RC${N}`, optionally pushes a translation-strings build
to wp.org SVN trunk, and creates a GitHub pre-release with a
separate QA changelog (incremental since previous RC/release,
includes non-user-facing entries and PR links).
Both workflows support a `dry-run` flag that skips every remote
side-effect while still uploading the built artifact as a workflow
artifact. Artifacts are produced as `duplicate-post-${VERSION}.zip`
containing a single top-level `duplicate-post/` folder, with an
`unzip -l` shape check guarding against drift.
Coverage Report for CI Build 26539072857Warning No base build found for commit Coverage: 59.881%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsRequires a base build to compare against. How to fix this → Coverage Stats
💛 - Coveralls |
Resolves shellcheck SC2001 from actionlint's Docker image (bundles a newer shellcheck than the standalone actionlint binary). Verified locally with `docker run rhysd/actionlint:latest`.
Comment on lines
+234
to
+236
| BAD=$(unzip -l "${ZIP_NAME}" \ | ||
| | awk 'NR>3 && $NF != "" && $NF !~ /^duplicate-post\// { print $NF }' \ | ||
| | grep -vE '^[0-9-]+ files?$' || true) |
Comment on lines
+233
to
+235
| BAD=$(unzip -l "${ZIP_NAME}" \ | ||
| | awk 'NR>3 && $NF != "" && $NF !~ /^duplicate-post\// { print $NF }' \ | ||
| | grep -vE '^[0-9-]+ files?$' || true) |
Comment on lines
+111
to
+113
| if ! grep -qE "^## ${VERSION}\b" changelog.md; then | ||
| echo "::error::No '## ${VERSION}' section found in changelog.md. Run the 'Generate Changelog' workflow first." | ||
| exit 1 |
Comment on lines
+150
to
+152
| if ! grep -qE "^## ${VERSION}\b" changelog.md; then | ||
| echo "::error::No '## ${VERSION}' section found in changelog.md. Either label the relevant PRs with a 'changelog:' label so they can be picked up, or run 'Generate Changelog' first." | ||
| exit 1 |
Both flagged by Copilot review on PR #505: * `unzip -l` emits footer lines (`-------` and `N files`) that the awk-based filter doesn't strip, so the shape check would flag valid artifacts. Switched to `unzip -Z1` which lists only entry paths. * `^## ${VERSION}\b` would falsely match `## 4.6.1` when looking for `4.6` because `\b` treats the dot as a word boundary. Switched to `grep -Fxq` for an exact full-line match.
Comment on lines
+225
to
+240
| set -euo pipefail | ||
| if [ ! -f artifact.zip ]; then | ||
| echo "::error::Expected artifact.zip from 'grunt artifact', but it is missing." | ||
| exit 1 | ||
| fi | ||
| ZIP_NAME="duplicate-post-${VERSION}.zip" | ||
| cp artifact.zip "${ZIP_NAME}" | ||
| cp -a artifact duplicate-post | ||
| # Sanity-check the zip shape: every entry must be under `duplicate-post/`. | ||
| BAD=$(unzip -Z1 "${ZIP_NAME}" | grep -v '^duplicate-post/' || true) | ||
| if [ -n "$BAD" ]; then | ||
| echo "::error::Artifact zip contains entries outside duplicate-post/:" | ||
| echo "$BAD" | ||
| exit 1 | ||
| fi | ||
| echo "ZIP_NAME=${ZIP_NAME}" >> "$GITHUB_ENV" |
Comment on lines
+225
to
+240
| set -euo pipefail | ||
| if [ ! -f artifact.zip ]; then | ||
| echo "::error::Expected artifact.zip from 'grunt artifact', but it is missing." | ||
| exit 1 | ||
| fi | ||
| ZIP_NAME="duplicate-post-${RC_VERSION}.zip" | ||
| cp artifact.zip "${ZIP_NAME}" | ||
| cp -a artifact duplicate-post | ||
| BAD=$(unzip -Z1 "${ZIP_NAME}" | grep -v '^duplicate-post/' || true) | ||
| if [ -n "$BAD" ]; then | ||
| echo "::error::Artifact zip contains entries outside duplicate-post/:" | ||
| echo "$BAD" | ||
| exit 1 | ||
| fi | ||
| echo "name=${ZIP_NAME}" >> "$GITHUB_OUTPUT" | ||
|
|
Comment on lines
+198
to
+203
| - name: "Copy composer.json into artifact" | ||
| # Matches deploy.yml behaviour: the dist artifact includes composer.json so | ||
| # downstream tooling that requires it via Packagist installers keeps working. | ||
| run: cp composer.json ./artifact | ||
|
|
||
| - name: Extract release notes from changelog.md |
Ports three post-snapshot fixes from yoast-test-helper that we had inherited the bugs of: * release.yml released trunk's state and ignored release/x.y entirely. Now it selects a source branch (release/x.y when an RC was cut, else trunk), bumps + pushes there, merges the source into main, and tags/builds/deploys/releases from main before back-merging into trunk. * release-rc.yml merged trunk into the release branch on every re-run, pulling next-version work into the frozen RC line and (with the back-merge) collapsing the two branches. Now it re-uses the release branch as-is; fixes reach it via PRs targeting release/x.y directly. * Plugin-folder staging used `cp -a artifact duplicate-post`, which only yields the right shape when the wrapper doesn't already exist. Switched to `mkdir duplicate-post && cp -a artifact/.`. Also added a `git reset --hard HEAD` after the artifact build in release.yml so the merge-back checkout can't be blocked by a dirty tree.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
Ports the
releaseandrelease-rcworkflows fromyoast-test-helperso duplicate-post stops cutting releases by hand.Summary
This PR can be summarized in the following changelog entry:
ReleaseandRelease RCworkflows (dispatch-triggered, dry-run capable) that handle version bump, tag, wp.org SVN deploy, GitHub release, milestone management, and merge-back.Relevant technical choices:
trunkplays y-t-h'sdeveloprole;mainis the stable branch.changelog.md(## X.Yblock), notreadme.txt.grunt update-version-trunkto preservereadme.txtStable tag.10up/action-wordpress-plugin-deploy(notgrunt-wp-deploy).duplicate-post-${VERSION}.zipwith a singleduplicate-post/top-level folder. Shape is sanity-checked withunzip -l.deploy.ymlunchanged: RC tags will keep mirroring toYoast-dist/duplicate-post.WPORG_SVN_USERNAMEandWPORG_SVN_PASSWORDbefore the first non-dry-run release.Test instructions
Test instructions for the acceptance test before the PR gets merged
workflow_dispatchinputs.Relevant test scenarios
Test instructions for QA when the code is in the RC
QA can test this PR by following these steps:
Release RCwithversion=99.0,dry-run=true,deploy-to-svn-trunk=true. Confirm nothing is pushed, the downloadedduplicate-post-99.0-RC1.ziphas a singleduplicate-post/top-level folder, itsreadme.txtStable tag is still4.6, and the "Build QA changelog" step output has PR links plus (if applicable) a### Non user facing:section.99.0-RC1.Releasewithversion=99.0,dry-run=true. Confirm same artifact shape and that the release-notes preview matches the## 4.6-equivalent block fromchangelog.md.Impact check
UI changes
Documentation
Each workflow has a header comment explaining triggers, inputs, dry-run semantics, and pipeline order.
Quality assurance
Innovation
Fixes #