Skip to content

Commit 5b98f22

Browse files
committed
Convert to a reusable workflow pattern.
1 parent c2b1910 commit 5b98f22

5 files changed

Lines changed: 322 additions & 122 deletions

.github/workflows/detect-gutenberg-sha-change.yml

Lines changed: 7 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -23,92 +23,20 @@ permissions: {}
2323

2424
jobs:
2525
# Detects whether the gutenberg.sha value in the package.json file has changed.
26-
#
27-
# Performs the following steps:
28-
# - Checks out the repository.
29-
# - Check if the pinned hash has changed.
3026
detect-hash-change:
3127
name: Detect Gutenberg SHA change
32-
runs-on: ubuntu-24.04
33-
if: ${{ github.repository == 'wordpress/wordpress-develop' }}
28+
uses: ./.github/workflows/reusable-detect-gutenberg-hash-change-v1.yml
3429
permissions:
3530
contents: read
36-
outputs:
37-
sha_changed: ${{ steps.check-sha.outputs.sha_changed }}
38-
base_sha: ${{ steps.check-sha.outputs.base_sha }}
39-
head_sha: ${{ steps.check-sha.outputs.head_sha }}
40-
41-
steps:
42-
- name: Checkout repository
43-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
44-
with:
45-
fetch-depth: 0
46-
persist-credentials: false
47-
48-
- name: Check if the pinned Gutenberg hash has changed
49-
id: check-sha
50-
run: |
51-
BASE_GUTENBERG_SHA=$(git show ${{ github.event.pull_request.base.sha }}:package.json | jq -r '.gutenberg.sha // empty')
52-
HEAD_GUTENBERG_SHA=$(git show ${{ github.event.pull_request.head.sha }}:package.json | jq -r '.gutenberg.sha // empty')
53-
54-
echo "base_sha=$BASE_GUTENBERG_SHA" >> "$GITHUB_OUTPUT"
55-
echo "head_sha=$HEAD_GUTENBERG_SHA" >> "$GITHUB_OUTPUT"
56-
57-
if [ "$BASE_GUTENBERG_SHA" != "$HEAD_GUTENBERG_SHA" ]; then
58-
echo "sha_changed=true" >> "$GITHUB_OUTPUT"
59-
echo "The pinned Gutenberg Repository hash has changed."
60-
echo " Previous SHA (base branch): $BASE_GUTENBERG_SHA"
61-
echo " New SHA (head branch): $HEAD_GUTENBERG_SHA"
62-
else
63-
echo "sha_changed=false" >> "$GITHUB_OUTPUT"
64-
echo "The pinned Gutenberg repository hash has not changed: $HEAD_GUTENBERG_SHA"
65-
fi
6631

6732
# Generates a list of changes between two specified hashes.
68-
#
69-
# Performs the following steps:
70-
# - Checks out the repository.
71-
# - Generates a list of changes.
72-
# - Uploads the changelog as an artifact.
7333
generate-changelog:
7434
name: Generate a list of changes between the hashes
75-
runs-on: ubuntu-24.04
35+
uses: ./.github/workflows/reusable-generate-gutenberg-changelog-v1.yml
7636
needs: [ 'detect-hash-change' ]
7737
if: ${{ needs.detect-hash-change.outputs.sha_changed == 'true' }}
7838
permissions:
7939
contents: read
80-
outputs:
81-
has_changes: ${{ steps.change-list.outputs.has_changes }}
82-
83-
steps:
84-
- name: Checkout Gutenberg repository
85-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
86-
with:
87-
repository: WordPress/gutenberg
88-
filter: blob:none
89-
fetch-depth: 0
90-
91-
- name: Generate a list of changes
92-
id: change-list
93-
env:
94-
BASE_SHA: ${{ needs.detect-hash-change.outputs.base_sha }}
95-
HEAD_SHA: ${{ needs.detect-hash-change.outputs.head_sha }}
96-
run: |
97-
git log --reverse --format="- %s" "$BASE_SHA".."$HEAD_SHA" | \
98-
sed 's|#\([0-9][0-9]*\)|https://github.com/WordPress/gutenberg/pull/\1|g; /github\.com\/WordPress\/gutenberg\/pull/!d' \
99-
> changelog.txt
100-
101-
if [ -s changelog.txt ]; then
102-
echo "has_changes=true" >> "$GITHUB_OUTPUT"
103-
else
104-
echo "has_changes=false" >> "$GITHUB_OUTPUT"
105-
fi
106-
107-
- name: Upload changelog as an artifact
108-
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
109-
with:
110-
path: changelog.txt
111-
archive: false
11240

11341
# Drafts a commit message containing a detailed list of changes being merged.
11442
#
@@ -118,53 +46,11 @@ jobs:
11846
# - Uploads the commit message as an artifact.
11947
generate-commit-message:
12048
name: Generate commit message
121-
runs-on: ubuntu-24.04
49+
uses: ./.github/workflows/reusable-generate-commit-message-v1.yml
12250
needs: [ 'detect-hash-change', 'generate-changelog' ]
123-
if: ${{ needs.detect-hash-change.outputs.sha_changed == 'true' }}
51+
if: ${{ needs.generate-changelog.outputs.has_changes == 'true' }}
12452
permissions:
12553
contents: read
126-
127-
steps:
128-
- name: Download changelog artifact
129-
if: ${{ needs.generate-changelog.outputs.has_changes == 'true' }}
130-
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
131-
with:
132-
name: changelog.txt
133-
skip-decompress: true
134-
135-
- name: Build commit message
136-
env:
137-
BASE_SHA: ${{ needs.detect-hash-change.outputs.base_sha }}
138-
HEAD_SHA: ${{ needs.detect-hash-change.outputs.head_sha }}
139-
HAS_CHANGES: ${{ needs.generate-changelog.outputs.has_changes }}
140-
run: |
141-
{
142-
printf 'Editor: Bump pinned hash for the Gutenberg repository.\n\n'
143-
printf "This updates the pinned hash from the gutenberg from \`%s\` to \`%s\`.\n\n" "$BASE_SHA" "$HEAD_SHA"
144-
145-
if [ "$HAS_CHANGES" = "false" ]; then
146-
printf '> [!WARNING]\n'
147-
printf '> No pull request references were found in the commits between the two hashes. Please verify the hash range is correct.\n\n'
148-
else
149-
printf 'The following changes are included:\n\n'
150-
cat changelog.txt
151-
printf '\n'
152-
fi
153-
154-
printf 'A full list of changes can be found on GitHub: https://github.com/WordPress/gutenberg/compare/%s...%s.\n\n' "$BASE_SHA" "$HEAD_SHA"
155-
printf 'See #64595, #64393.\n'
156-
} > commit-message.md
157-
158-
- name: Upload commit message as an artifact
159-
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
160-
with:
161-
path: commit-message.md
162-
archive: false
163-
164-
- name: Post PR comment
165-
env:
166-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
167-
PR_NUMBER: ${{ github.event.pull_request.number }}
168-
REPO: ${{ github.repository }}
169-
run: |
170-
gh pr comment "$PR_NUMBER" --body-file commit-message.md --repo "$REPO"
54+
with:
55+
previous-hash: ${{ needs.detect-hash-change.outputs.base_sha }}
56+
new-hash: ${{ needs.detect-hash-change.outputs.head_sha }}

.github/workflows/pull-request-comments.yml

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
pull_request_target:
66
types: [ 'opened', 'synchronize', 'reopened', 'edited' ]
77
workflow_run:
8-
workflows: [ 'Test Build Processes' ]
8+
workflows: [ 'Test Build Processes', 'Draft commit message' ]
99
types:
1010
- completed
1111

@@ -228,3 +228,120 @@ jobs:
228228
`,
229229
} );
230230
}
231+
232+
# Adds a comment with a drafted commit message.
233+
drafted-commit-message:
234+
name: Manage commit message draft
235+
runs-on: ubuntu-24.04
236+
permissions:
237+
issues: write
238+
pull-requests: write
239+
if: ${{ github.repository == 'WordPress/wordpress-develop' && github.event_name == 'pull_request_target' && ! github.event.pull_request.draft && github.event.pull_request.state == 'open' }}
240+
241+
steps:
242+
- name: Download artifact
243+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
244+
with:
245+
script: |
246+
const fs = require( 'fs' );
247+
248+
const artifacts = await github.rest.actions.listWorkflowRunArtifacts( {
249+
owner: context.repo.owner,
250+
repo: context.repo.repo,
251+
run_id: process.env.RUN_ID,
252+
} );
253+
254+
const matchPrNumberArtifact = artifacts.data.artifacts.filter( ( artifact ) => {
255+
return artifact.name === 'pr-number'
256+
} )[0];
257+
258+
if ( ! matchPrNumberArtifact ) {
259+
core.setFailed( 'No PR number artifact found!' );
260+
return;
261+
}
262+
263+
const downloadPrNumber = await github.rest.actions.downloadArtifact( {
264+
owner: context.repo.owner,
265+
repo: context.repo.repo,
266+
artifact_id: matchPrNumberArtifact.id,
267+
archive_format: 'zip',
268+
} );
269+
270+
fs.writeFileSync( '${{github.workspace}}/pr-number.zip', Buffer.from( downloadPrNumber.data ) )
271+
272+
const matchMessageArtifact = artifacts.data.artifacts.filter( ( artifact ) => {
273+
return artifact.name === 'commit-message.md'
274+
} )[0];
275+
276+
if ( ! matchMessageArtifact ) {
277+
core.setFailed( 'No commit message artifact found!' );
278+
return;
279+
}
280+
281+
const downloadCommitMessage = await github.rest.actions.downloadArtifact( {
282+
owner: context.repo.owner,
283+
repo: context.repo.repo,
284+
artifact_id: matchMessageArtifact.id,
285+
archive_format: 'zip',
286+
} );
287+
288+
fs.writeFileSync( '${{github.workspace}}/commit-message.zip', Buffer.from( downloadCommitMessage.data ) )
289+
env:
290+
RUN_ID: ${{ github.event.workflow_run.id }}
291+
292+
- name: Unzip the artifact containing the PR number
293+
run: unzip pr-number.zip
294+
295+
- name: Unzip the artifact containing the commit mesage
296+
run: unzip commit-message.zip
297+
298+
- name: Leave or update a comment with the commit message draft
299+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
300+
with:
301+
script: |
302+
const fs = require( 'fs' );
303+
const issue_number = Number( fs.readFileSync( './NR' ) );
304+
305+
core.info( `Checking pull request #${issue_number}.` );
306+
307+
// Confirm that the pull request is still open before leaving a comment.
308+
const pr = await github.rest.pulls.get({
309+
owner: context.repo.owner,
310+
repo: context.repo.repo,
311+
pull_number: issue_number,
312+
});
313+
314+
if ( pr.data.state !== 'open' ) {
315+
core.info( 'The pull request has been closed. No comment will be left.' );
316+
return;
317+
}
318+
319+
// Comments are only added once and then updated on future commits.
320+
const commentInfo = {
321+
owner: context.repo.owner,
322+
repo: context.repo.repo,
323+
issue_number,
324+
};
325+
326+
const comments = ( await github.rest.issues.listComments( commentInfo ) ).data;
327+
const hasCommitMessageDraft = comments.find( comment => comment.user.type === 'Bot' && comment.body.includes( 'Editor: Bump pinned hash' ) );
328+
329+
// Construct comment
330+
commentInfo.body = '## Commit Message Draft\n' +
331+
'This pull request changes the pinned hash for the Gutenberg repository. Here is a commit message draft containing a compiled list of changes included with additional required information:\n\n' +
332+
```\n' +
333+
commitMessageContents +
334+
'\n```\n' +
335+
'**Always verify these commit message drafts before using. And don't forget to include props!**';
336+
337+
// Only update the comment when there are changes.
338+
if ( hasCommitMessageDraft ) {
339+
if ( hasCommitMessageDraft.body != commentInfo.body ) {
340+
commentInfo.comment_id = hasCommitMessageDraft.id;
341+
342+
github.rest.issues.updateComment( commentInfo );
343+
}
344+
return;
345+
}
346+
347+
github.rest.issues.createComment( commentInfo );
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
##
2+
# A reusable workflow that detects when the `gutenberg.sha` value changes in the `package.json` file.
3+
##
4+
name: Detect hash change (reusable)
5+
6+
on:
7+
workflow_call:
8+
9+
# Disable permissions for all available scopes by default.
10+
# Any needed permissions should be configured at the job level.
11+
permissions: {}
12+
13+
jobs:
14+
# Detects whether the gutenberg.sha value in the package.json file has changed.
15+
#
16+
# Performs the following steps:
17+
# - Checks out the repository.
18+
# - Check if the pinned hash has changed.
19+
detect-hash-change:
20+
name: Detect Gutenberg SHA change
21+
runs-on: ubuntu-24.04
22+
if: ${{ github.repository == 'wordpress/wordpress-develop' }}
23+
permissions:
24+
contents: read
25+
timeout-minutes: 5
26+
outputs:
27+
sha_changed: ${{ steps.check-sha.outputs.sha_changed }}
28+
base_sha: ${{ steps.check-sha.outputs.base_sha }}
29+
head_sha: ${{ steps.check-sha.outputs.head_sha }}
30+
31+
steps:
32+
- name: Checkout repository
33+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
34+
with:
35+
fetch-depth: 0
36+
persist-credentials: false
37+
38+
- name: Check if the pinned Gutenberg hash has changed
39+
id: check-sha
40+
run: |
41+
BASE_GUTENBERG_SHA=$(git show ${{ github.event.pull_request.base.sha }}:package.json | jq -r '.gutenberg.sha // empty')
42+
HEAD_GUTENBERG_SHA=$(git show ${{ github.event.pull_request.head.sha }}:package.json | jq -r '.gutenberg.sha // empty')
43+
44+
echo "base_sha=$BASE_GUTENBERG_SHA" >> "$GITHUB_OUTPUT"
45+
echo "head_sha=$HEAD_GUTENBERG_SHA" >> "$GITHUB_OUTPUT"
46+
47+
if [ "$BASE_GUTENBERG_SHA" != "$HEAD_GUTENBERG_SHA" ]; then
48+
echo "sha_changed=true" >> "$GITHUB_OUTPUT"
49+
echo "The pinned Gutenberg Repository hash has changed."
50+
echo " Previous SHA (base branch): $BASE_GUTENBERG_SHA"
51+
echo " New SHA (head branch): $HEAD_GUTENBERG_SHA"
52+
else
53+
echo "sha_changed=false" >> "$GITHUB_OUTPUT"
54+
echo "The pinned Gutenberg repository hash has not changed: $HEAD_GUTENBERG_SHA"
55+
fi

0 commit comments

Comments
 (0)