Commit 9c54df43a31 for woocommerce
commit 9c54df43a31d6b76be2b6fc7b3bf3ff58493c691
Author: Jorge A. Torres <jorge.torres@automattic.com>
Date: Wed Mar 18 14:10:36 2026 +0000
[Release] Various documentation and process fixes based on 10.6's experience (#63668)
diff --git a/.github/workflows/cherry-pick-milestoned-prs.yml b/.github/workflows/cherry-pick-milestoned-prs.yml
index d2b1dcb8e26..ed06aad2ffb 100644
--- a/.github/workflows/cherry-pick-milestoned-prs.yml
+++ b/.github/workflows/cherry-pick-milestoned-prs.yml
@@ -55,6 +55,13 @@ jobs:
return;
}
+ // If this PR is itself a cherry-pick, extract the source branch so we can
+ // avoid cherry-picking back to the branch it originally came from.
+ const sourceMatch = body.match(/^<!--\s*cherry-pick-source-branch:\s*(.+?)\s*-->$/m);
+ if ( sourceMatch ) {
+ core.setOutput( 'source_branch', sourceMatch[1] );
+ }
+
core.setOutput( 'should_cherry_pick', ${{ ! contains(github.event.pull_request.labels.*.name, 'Release') }} ? 'true' : 'false' );
# Extract base version from milestone (e.g., 9.9 from 9.9.0)
@@ -75,10 +82,12 @@ jobs:
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1
env:
BASE_VERSION: ${{ steps.extract-version.outputs.base_version }}
+ SOURCE_BRANCH: ${{ steps.check-cherry-pick.outputs.source_branch }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const baseVersion = process.env.BASE_VERSION;
+ const sourceBranch = process.env.SOURCE_BRANCH || '';
const [majorStr, minorStr] = baseVersion.split('.');
let major = parseInt(majorStr, 10);
let minor = parseInt(minorStr, 10);
@@ -111,8 +120,10 @@ jobs:
const nextBranch = `release/${nextMajor}.${nextMinor}`;
const nextExists = await branchExists(nextBranch);
- core.setOutput('milestoned_branch', milestonedExists ? milestonedBranch : '');
- core.setOutput('next_branch', nextExists ? nextBranch : '');
+ // Skip branches that match the source branch to avoid cherry-pick loops
+ // (e.g., a PR cherry-picked from release/9.8 to trunk should not be cherry-picked back to release/9.8)
+ core.setOutput('milestoned_branch', (milestonedExists && milestonedBranch !== sourceBranch) ? milestonedBranch : '');
+ core.setOutput('next_branch', (nextExists && nextBranch !== sourceBranch) ? nextBranch : '');
# Cherry-pick to milestoned branch
cherry-pick-milestoned:
diff --git a/.github/workflows/release-create-tracking-issue.yml b/.github/workflows/release-create-tracking-issue.yml
index 9d8761a5744..ddbf94be940 100644
--- a/.github/workflows/release-create-tracking-issue.yml
+++ b/.github/workflows/release-create-tracking-issue.yml
@@ -193,6 +193,7 @@ jobs:
console.log( `Looking for parent issue: "${ parentTitle }"` );
const parentIssues = await linearClient.issues( {
+ includeArchived: true,
filter: {
team: { id: { eq: '${{ secrets.LINEAR_TEAM_ID }}' } },
title: { eq: parentTitle }
diff --git a/.github/workflows/scripts/assign-milestone-on-merge.js b/.github/workflows/scripts/assign-milestone-on-merge.js
index 354cfb66f60..f3a2c429ecd 100644
--- a/.github/workflows/scripts/assign-milestone-on-merge.js
+++ b/.github/workflows/scripts/assign-milestone-on-merge.js
@@ -51,13 +51,22 @@ module.exports = async ({ github, context, core }) => {
}
let version = versionMatch[1].trim().replace(/-dev$/, '');
- const versionParts = version.split('.').map(Number);
- const major = versionParts[0];
- const minor = versionParts[1];
+ const [major, minor] = version.split('.').map(Number);
core.info(`Parsed version: ${versionMatch[1].trim()} -> ${major}.${minor}`);
- const targetMilestone = `${major}.${minor}.0`;
+ // If the release branch for this version already exists, the version in trunk
+ // hasn't been bumped yet — target the next milestone instead.
+ version = `${major}.${minor}`;
+ try {
+ await github.rest.repos.getBranch({ owner: owner, repo: repo, branch: `release/${version}` });
+ core.info(`Branch release/${version} exists, advancing to next version`);
+ version = (Number(version) + 0.1).toFixed(1);
+ } catch (error) {
+ if (error.status !== 404) throw error;
+ }
+
+ const targetMilestone = `${version}.0`;
core.info(`PR #${prNumber} targets next main release`);
core.info(`Looking for milestone: ${targetMilestone}`);
diff --git a/.github/workflows/shared-cherry-pick.yml b/.github/workflows/shared-cherry-pick.yml
index 1afc214c978..5469b1d4b46 100644
--- a/.github/workflows/shared-cherry-pick.yml
+++ b/.github/workflows/shared-cherry-pick.yml
@@ -342,7 +342,9 @@ jobs:
});
// Create PR body
- let prBody = `This PR is a cherry-pick of #${prNumber} to \`${targetBranch}\`.\n\n`;
+ const sourceBranch = originalPr.base.ref;
+ let prBody = `<!-- cherry-pick-source-branch: ${sourceBranch} -->\n`;
+ prBody += `This PR is a cherry-pick of #${prNumber} to \`${targetBranch}\`.\n\n`;
if (hasConflicts) {
prBody += `> [!WARNING]\n`;
@@ -514,4 +516,4 @@ jobs:
echo "status=success" >> $GITHUB_OUTPUT
echo "error_message=" >> $GITHUB_OUTPUT
echo "cherry_pick_pr_number=${{ needs.cherry-pick.outputs.cherry_pick_pr_number }}" >> $GITHUB_OUTPUT
- fi
\ No newline at end of file
+ fi
diff --git a/.linear/release-kickoff-beta.md b/.linear/release-kickoff-beta.md
index f5b9f1d4d6f..0747746e4d3 100644
--- a/.linear/release-kickoff-beta.md
+++ b/.linear/release-kickoff-beta.md
@@ -23,7 +23,7 @@ Keep the _[Release Troubleshooting & Recovery](https://developer.woocommerce.com
- [ ] Run workflow **[Release: Bump version number]({repository_url}/actions/workflows/release-bump-version.yml)**: enter `{release_main_version}` as _Release branch_ and `{release_type}` as _Type of version bump to perform_.
- [ ] Review and merge the PR that was generated against the release branch. Check the [{release_milestone} milestone]({repository_url}/issues?q=is:open+milestone:{release_milestone}).
- [ ] Run workflow **[Release: Compile changelog]({repository_url}/actions/workflows/release-compile-changelog.yml)**: enter `{release_main_version}` as _Version_ and leave _Release date_ empty, except when building the package ahead of schedule.
-- [ ] Review and merge the PRs that were generated: one against `trunk` and another one against the release branch. Both should be under the [{release_milestone} milestone]({repository_url}/issues?q=is:open+milestone:{release_milestone}).
+- [ ] Review and merge the PRs that were generated: one against `trunk` and another one against the release branch. Both are linked in the workflow run.
- [ ] Run workflow **[Release: Build ZIP file]({repository_url}/actions/workflows/release-build-zip-file.yml)** to build the asset and create the GitHub release: enter `{release_main_version}` as _Release branch_ and check _Create GitHub release_.
- [ ] Confirm that a draft `{release_version}` release [was created in the repository]({repository_url}/releases) with an attached `woocommerce.zip` asset.
diff --git a/.linear/release-kickoff-patch.md b/.linear/release-kickoff-patch.md
index 710ea061647..ee6db0ce738 100644
--- a/.linear/release-kickoff-patch.md
+++ b/.linear/release-kickoff-patch.md
@@ -20,10 +20,10 @@ Keep the _[Release Troubleshooting & Recovery](https://developer.woocommerce.com
### 2. Build the release package
-- [ ] Run workflow **[Release: Bump version number]({repository_url}/actions/workflows/release-bump-version.yml)**: enter `{release_main_version}` as _Release branch_ and `{release_type}` as _Type of version bump to perform_.
+- [ ] Run workflow **[Release: Bump version number]({repository_url}/actions/workflows/release-bump-version.yml)**: enter `{release_main_version}` as _Release branch_ and `stable` as _Type of version bump to perform_.
- [ ] Review and merge the PR that was generated against the release branch. Check the [{release_milestone} milestone]({repository_url}/issues?q=is:open+milestone:{release_milestone}).
- [ ] Run workflow **[Release: Compile changelog]({repository_url}/actions/workflows/release-compile-changelog.yml)**: enter `{release_main_version}` as _Version_ and leave _Release date_ empty, except when building the package ahead of schedule.
-- [ ] Review and merge the PRs that were generated: one against `trunk` and another one against the release branch. Both should be under the [{release_milestone} milestone]({repository_url}/issues?q=is:open+milestone:{release_milestone}).
+- [ ] Review and merge the PRs that were generated: one against `trunk` and another one against the release branch. Both are linked in the workflow run.
- [ ] Run workflow **[Release: Build ZIP file]({repository_url}/actions/workflows/release-build-zip-file.yml)** to build the asset and create the GitHub release: enter `{release_main_version}` as _Release branch_ and check _Create GitHub release_.
- [ ] Confirm that a draft `{release_version}` release [was created in the repository]({repository_url}/releases) with an attached `woocommerce.zip` asset.
diff --git a/.linear/release-kickoff-rc.md b/.linear/release-kickoff-rc.md
index 43936517d67..0b78030cbc1 100644
--- a/.linear/release-kickoff-rc.md
+++ b/.linear/release-kickoff-rc.md
@@ -23,7 +23,7 @@ Keep the _[Release Troubleshooting & Recovery](https://developer.woocommerce.com
- [ ] Run workflow **[Release: Bump version number]({repository_url}/actions/workflows/release-bump-version.yml)**: enter `{release_main_version}` as _Release branch_ and `{release_type}` as _Type of version bump to perform_.
- [ ] Review and merge the PR that was generated against the release branch. Check the [{release_milestone} milestone]({repository_url}/issues?q=is:open+milestone:{release_milestone}).
- [ ] Run workflow **[Release: Compile changelog]({repository_url}/actions/workflows/release-compile-changelog.yml)**: enter `{release_main_version}` as _Version_ and leave _Release date_ empty, except when building the package ahead of schedule.
-- [ ] Review and merge the PRs that were generated: one against `trunk` and another one against the release branch. Both should be under the [{release_milestone} milestone]({repository_url}/issues?q=is:open+milestone:{release_milestone}).
+- [ ] Review and merge the PRs that were generated: one against `trunk` and another one against the release branch. Both are linked in the workflow run.
- [ ] Run workflow **[Release: Build ZIP file]({repository_url}/actions/workflows/release-build-zip-file.yml)** to build the asset and create the GitHub release: enter `{release_main_version}` as _Release branch_ and check _Create GitHub release_.
- [ ] Confirm that a draft `{release_version}` release [was created in the repository]({repository_url}/releases) with an attached `woocommerce.zip` asset.
diff --git a/docs/contribution/releases/point-release-fixes.md b/docs/contribution/releases/point-release-fixes.md
index 9fb7de1340b..b6912d2c18d 100644
--- a/docs/contribution/releases/point-release-fixes.md
+++ b/docs/contribution/releases/point-release-fixes.md
@@ -6,6 +6,10 @@ sidebar_position: 4
# Point Release Requests in WooCommerce
+:::important
+The formal Point Release Request (PRR) issue template is not strictly required for all point release fixes. In practice, coordinating directly with the release lead is often sufficient to get fixes included in a point release. The rest of this document remains useful for understanding what types of fixes qualify for point releases and how to prepare them in the repository.
+:::
+
Point releases address critical issues discovered in already-shipped WooCommerce versions. These are patch releases (e.g., 9.9.0 → 9.9.1) that contain only essential fixes for production environments.
Note that this process applies only to ALREADY-RELEASED VERSIONS that are in customer production environments.
diff --git a/docs/contribution/releases/point-releases.md b/docs/contribution/releases/point-releases.md
index cd52bca5aad..b47f5fcf904 100644
--- a/docs/contribution/releases/point-releases.md
+++ b/docs/contribution/releases/point-releases.md
@@ -6,6 +6,10 @@ sidebar_position: 2
# Point Releases
+:::important
+The formal Point Release Request (PRR) issue template is not strictly required for all point release fixes. In practice, coordinating directly with the release lead is often sufficient to get fixes included in a point release. The rest of this document remains useful for understanding what types of fixes qualify for point releases and how to prepare them in the repository.
+:::
+
## What Are Point Releases?
Point releases are patch releases that address specific issues without adding substantial new functionality. Point releases typically contain:
@@ -68,16 +72,16 @@ After a PRR is opened, the **release lead** evaluates it.
When deciding whether to approve a PRR, the release lead should consider the following:
| Evaluation Criterion | Guidance |
-| -------------------- | -------- |
-| **Scope of Impact** | How many stores are already affected? Larger reach increases urgency. |
+| ---------------------- | ---------- |
+| **Scope of Impact** | How many stores are already affected? Larger reach increases urgency. |
| **Error Commonality** | Does the problem stem from a widely-used core flow, plugin, or theme? Issues in common components usually merit faster action. |
-| **Workarounds** | Is there an easy, documented workaround (e.g., a filter, setting toggle, or temporary feature disable) that store owners can apply? Readily available workarounds lower the need for a point release. |
-| **Impact Severity** | Does the bug block critical commerce functionality (checkout, payments, product visibility)? The more business-critical the failure, the higher the priority. |
+| **Workarounds** | Is there an easy, documented workaround (e.g., a filter, setting toggle, or temporary feature disable) that store owners can apply? Readily available workarounds lower the need for a point release. |
+| **Impact Severity** | Does the bug block critical commerce functionality (checkout, payments, product visibility)? The more business-critical the failure, the higher the priority. |
#### 4. Approval or Rejection
| Outcome | Release-Lead Action | Workflow Triggered |
-|---------|--------------------|--------------------|
+| --------- | -------------------- | ------------------- |
| **Approve** | Apply the **`Approved`** label to the PRR issue and optionally leave a short rationale referencing the criteria above. | Labels are automatically added to the PR (“cherry pick to trunk”, “cherry pick to frozen release”); the issue milestone is set to the current release; the PRR is commented with an approval note. |
| **Reject** | Apply the **`Rejected`** label and briefly state the reason (e.g., limited impact, simple workaround available). | A workflow adds a comment, closes the PRR, and the author must retarget the PR to `trunk`, resolve conflicts, and merge through the normal path. |
@@ -101,7 +105,7 @@ When deciding whether to approve a PRR, the release lead should consider the fol
After the primary fix is merged into `release/x.y`, the labels that remain on the PR determine what happens next:
| Label present | Automation result | What the release lead must do |
-|---------------|------------------|------------------------------|
+| --------------- | ------------------- | ------------------------------ |
| `cherry pick to trunk` | Action opens a new PR targeting `trunk` and adds the current milestone. | Review tests / CI and merge this PR. |
| `cherry pick to frozen release` | Action opens a new PR targeting the **next frozen branch** (e.g., `release/9.6`) and adds the milestone. | Review and merge this PR as well. |