Skip to content

Commit 4346747

Browse files
authored
Improve validation in Release: Build ZIP file workflow (#60262)
1 parent 1131d03 commit 4346747

File tree

3 files changed

+67
-97
lines changed

3 files changed

+67
-97
lines changed

.github/workflows/release-build-zip-file.yml

Lines changed: 64 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,30 @@ on:
33
workflow_dispatch:
44
inputs:
55
branch:
6-
description: 'Release branch to use. Defaults to the branch the workflow is run from.'
7-
required: false
8-
default: ''
6+
description: 'Release branch (e.g.: release/x.y).'
7+
required: true
98
skip_verify:
109
description: 'Skip verification steps.'
1110
type: boolean
1211
required: true
1312
create_github_release:
14-
description: 'Create a draft GitHub release.'
13+
description: 'Create GitHub release.'
1514
type: boolean
16-
required: true
15+
default: false
1716
workflow_call:
1817
inputs:
1918
branch:
20-
description: 'Release branch to use. Defaults to the branch the workflow is run from.'
19+
description: 'Release branch.'
2120
type: string
22-
required: false
23-
default: ''
21+
required: true
2422
skip_verify:
2523
description: 'Skip verification steps.'
2624
type: boolean
27-
required: true
25+
default: false
2826
create_github_release:
29-
description: 'Create a draft GitHub release.'
27+
description: 'Create GitHub release.'
3028
type: boolean
31-
required: true
29+
default: false
3230
outputs:
3331
artifact_url:
3432
description: 'URL of the built release artifact'
@@ -40,87 +38,30 @@ concurrency:
4038
group: release-build-zip-file-${{ inputs.branch }}-${{ ( inputs.create_github_release == true && 'with-release' ) || github.run_id }}
4139

4240
jobs:
43-
verify-prs:
44-
name: 'Verify if any PR is left open by author:app/github-actions'
45-
outputs:
46-
runBuildZipJob: ${{ steps.verify-prs.outputs.runBuildZipJob }}
41+
verify:
42+
name: 'Pre-build verification'
4743
runs-on: ${{ ( github.repository == 'woocommerce/woocommerce' && 'blacksmith-2vcpu-ubuntu-2404' ) || 'ubuntu-latest' }}
44+
permissions:
45+
contents: write # Required to fetch draft releases for some reason. See https://github.com/cli/cli/issues/9076#issuecomment-2146148572.
4846
steps:
49-
- name: Verify if any PR is left open by author:app/github-actions
50-
id: verify-prs
51-
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1
52-
with:
53-
github-token: ${{ secrets.GITHUB_TOKEN }}
54-
script: |
55-
let runBuildZipJob = true;
56-
const event = context.payload;
57-
58-
if ('${{ inputs.skip_verify }}' === 'true') {
59-
core.setOutput('runBuildZipJob', runBuildZipJob);
60-
console.log('Skipping verification step');
61-
return;
62-
}
63-
64-
const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');
65-
66-
// Helper function to add delay between API calls
67-
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
68-
69-
// Function to handle API call with retry logic
70-
const searchPRs = async (query) => {
71-
let attempts = 0;
72-
while (attempts < 5) {
73-
try {
74-
return await github.rest.search.issuesAndPullRequests({ q: query });
75-
} catch (error) {
76-
if (error.status === 403 && error.message.includes('secondary rate limit')) {
77-
console.log('Rate limit hit, retrying...');
78-
await delay(31000); // 31 second delay before retry
79-
attempts++;
80-
} else {
81-
throw error;
82-
}
83-
}
84-
}
85-
throw new Error('Failed to fetch PRs after multiple attempts');
86-
};
87-
88-
// Search for PRs from github-actions bot
89-
const githubActionsPRsQuery = await searchPRs(`repo:${owner}/${repo} is:pr is:open author:app/github-actions`);
90-
const prsOpenByGithubActions = githubActionsPRsQuery.data.items;
91-
92-
let failureMessage = ``;
93-
94-
if (prsOpenByGithubActions.length > 0) {
95-
runBuildZipJob = false;
96-
97-
failureMessage += `Identified \`${prsOpenByGithubActions.length}\` open PR(s) from \`github-actions\` bot which should be merged or closed before proceeding. <https://github.com/${owner}/${repo}/issues?q=is%3Apr+is%3Aopen+author%3Aapp%2Fgithub-actions|Link to PRs>`;
98-
99-
failureMessage += '\n\nThis step maintains the code integrity and is critical to avoid regression in future releases. Please merge them or close them before proceeding or set \`skip_verify\` to \`true\` before running the workflow to skip this step if you are confident that the PRs are irrelevant.';
100-
101-
console.error(failureMessage);
102-
core.setOutput('failureMessage', failureMessage);
103-
}
104-
core.setOutput('runBuildZipJob', runBuildZipJob);
47+
- name: Workflow checks
48+
run: |
49+
# No special checks when running as a reusable workflow.
50+
if [ "${{ ! contains( github.workflow_ref, 'release-build-zip-file.yml' ) }}" = "true" ]; then
51+
exit 0
52+
fi
10553
106-
- name: Notify Slack on failure
107-
if: ${{ steps.verify-prs.outputs.failureMessage != '' && inputs.create_github_release }}
108-
uses: archive/github-actions-slack@f530f3aa696b2eef0e5aba82450e387bd7723903 #v2.0.0
109-
with:
110-
slack-bot-user-oauth-access-token: ${{ secrets.CODE_FREEZE_BOT_TOKEN }}
111-
slack-channel: ${{ secrets.WOO_RELEASE_SLACK_CHANNEL }}
112-
slack-text: |
113-
:x: Oops we may have missed PRs left open by `github-actions` bot. WooCommerce release zip build failed.
114-
:warning-8c: ${{ steps.verify-prs.outputs.failureMessage }}
115-
<https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}|Workflow Run>
116-
slack-optional-unfurl_links: false
117-
slack-optional-unfurl_media: false
118-
continue-on-error: true
54+
# Must run from trunk.
55+
if [ "${{ github.ref }}" != "refs/heads/trunk" ]; then
56+
echo "::error::This workflow must be run from the `trunk` branch. Enter the release branch as input."
57+
exit 1
58+
fi
11959
120-
verify-release-versions:
121-
name: 'Verify release and stable tag versions'
122-
runs-on: ${{ ( github.repository == 'woocommerce/woocommerce' && 'blacksmith-2vcpu-ubuntu-2404' ) || 'ubuntu-latest' }}
123-
steps:
60+
# Can not skip verification for actual releases.
61+
if [ "${{ inputs.create_github_release }}" = "true" ] && [ "${{ inputs.skip_verify }}" = "true" ]; then
62+
echo "::error::Verification can not be skipped when building for a release."
63+
exit 1
64+
fi
12465
- uses: actions/checkout@v4
12566
with:
12667
ref: ${{ inputs.branch || github.ref }}
@@ -129,13 +70,22 @@ jobs:
12970
/plugins/woocommerce/woocommerce.php
13071
/plugins/woocommerce/readme.txt
13172
sparse-checkout-cone-mode: false
132-
if: ${{ inputs.create_github_release && ! inputs.skip_verify }}
73+
if: ${{ ! inputs.skip_verify }}
13374

13475
- name: 'Pre-build verification'
135-
if: ${{ inputs.create_github_release && ! inputs.skip_verify }}
76+
if: ${{ ! inputs.skip_verify }}
13677
env:
13778
BRANCH: ${{ inputs.branch || github.ref }}
79+
GH_TOKEN: ${{ github.token }}
80+
GH_REPO: ${{ github.repository }}
13881
run: |
82+
# No PRs by automated tools should remain open.
83+
count=$( gh pr list --search "is:open author:app/github-actions" --limit 1 --json number | jq length )
84+
if (( count > 0 )); then
85+
echo "::error::Pre-build verification: there are automated PRs by 'github-actions' still open."
86+
exit 1
87+
fi
88+
13989
# Branch name must be 'release/*'.
14090
branch_name="${BRANCH#refs/heads/}"
14191
if [[ $branch_name != release/* ]] ; then
@@ -151,6 +101,12 @@ jobs:
151101
exit 1
152102
fi
153103
104+
# GH release should not already exist.
105+
if gh release view "$branch_plugin_version" &>/dev/null; then
106+
echo "::error::Pre-build verification: GitHub release '$branch_plugin_version' already exists."
107+
exit 1
108+
fi
109+
154110
# Release should not already exist on wporg.
155111
tag_exists=$(curl -s 'https://api.wordpress.org/plugins/info/1.2/?action=plugin_information&request\[slug\]=woocommerce' | jq "(.versions | has(\"$branch_plugin_version\"))")
156112
if [ "$tag_exists" == "true" ]; then
@@ -166,10 +122,25 @@ jobs:
166122
exit 1
167123
fi
168124
125+
# No PRs against release branch should remain open.
126+
count=$( gh pr list --search "is:open base:$BRANCH" --limit 1 --json number | jq length )
127+
if (( count > 0 )); then
128+
echo "::error::Pre-build verification: there are PRs against the release branch ($BRANCH) still open."
129+
exit 1
130+
fi
131+
132+
# No PRs with same milestone as main version should remain open.
133+
milestone="$version_prefix.0"
134+
count=$( gh pr list --search "is:open milestone:$milestone" --limit 1 --json number | jq length )
135+
if (( count > 0 )); then
136+
echo "::error::Pre-build verification: there are PRs with milestone '$milestone' still open."
137+
exit 1
138+
fi
139+
169140
build:
170141
name: Build release zip file
171142
runs-on: ${{ ( github.repository == 'woocommerce/woocommerce' && 'blacksmith-4vcpu-ubuntu-2404' ) || 'ubuntu-latest' }}
172-
needs: [ verify-prs, verify-release-versions ]
143+
needs: [ verify ]
173144
outputs:
174145
artifact-url: ${{ steps.fetch-build-details.outputs.artifact-url }}
175146
commit-hash: ${{ steps.fetch-build-details.outputs.commit-hash }}
@@ -224,7 +195,7 @@ jobs:
224195
create-release:
225196
name: Create GitHub release
226197
runs-on: ${{ ( github.repository == 'woocommerce/woocommerce' && 'blacksmith-2vcpu-ubuntu-2404' ) || 'ubuntu-latest' }}
227-
needs: build
198+
needs: [ build ]
228199
if: ${{ inputs.create_github_release }}
229200
permissions:
230201
contents: write
@@ -259,7 +230,7 @@ jobs:
259230
gh release create ${{ steps.get_version.outputs.version }} \
260231
'./woocommerce.zip' \
261232
--title '${{ steps.get_version.outputs.version }}' \
262-
--notes '' \
233+
--notes '${{ steps.get_version.outputs.version }}' \
263234
--target '${{ needs.build.outputs.commit-hash }}' \
264235
--latest=false \
265236
--draft \

.github/workflows/release-code-freeze.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,6 @@ jobs:
177177
gh release edit '${{ needs.prepare-for-code-freeze.outputs.nextReleaseVersion }}-dev' \
178178
--prerelease \
179179
--latest=false \
180-
--notes='' \
181180
--draft=false
182181
183182
echo "release-zip=https://github.com/${{ github.repository }}/releases/download/${{ needs.prepare-for-code-freeze.outputs.nextReleaseVersion }}-dev/woocommerce.zip" >> $GITHUB_OUTPUT

docs/contribution/releases/building-and-publishing.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ sidebar_label: Building and Publishing
3030
- Run from `trunk` and enter the major version number and the intended release date.
3131
- Review and merge the two PRs created (one for trunk, one for the release branch).
3232
- Ensure the changelog date is correct.
33-
3. **Build the release ZIP file.**
34-
- Run the [“Release: Build ZIP file” workflow](https://github.com/woocommerce/woocommerce/actions/workflows/release-build-zip-file.yml) from the release branch.
35-
- Set "Create a draft GitHub release" to `true`.
33+
3. **Build the release ZIP file using the [“Release: Build ZIP file” workflow](https://github.com/woocommerce/woocommerce/actions/workflows/release-build-zip-file.yml).**
34+
- Run from `trunk` and enter the release branch as argument.
35+
- Set "Create GitHub release" to `true`.
3636
- The workflow will create a [draft release tag](https://github.com/woocommerce/woocommerce/releases) with an attached `woocommerce.zip` file.
3737

3838
## Publishing the Release

0 commit comments

Comments
 (0)