1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
# Commits all missed changes to built files back to pull request branches.
name: Commit Built File Changes (PRs)
on:
workflow_run:
workflows: [ 'Check Built Files (PRs)' ]
types:
- completed
# Cancels all previous workflow runs for pull requests that have not completed.
concurrency:
# The concurrency group contains the workflow name and the branch name for pull requests
# or the commit hash for any other events.
group: ${{ github.workflow }}-${{ github.event_name == 'workflow_run' && format( '{0}-{1}', github.event.workflow_run.head_branch, github.event.workflow_run.head_repository.name ) || github.sha }}
# Disable permissions for all available scopes by default.
# Any needed permissions should be configured at the job level.
permissions: {}
jobs:
# Checks a PR for uncommitted changes to built files.
#
# Performs the following steps:
# - Attempts to download the artifact containing the PR diff.
# - Checks for the existence of an artifact.
# - Unzips the artifact.
# - Generates a token for authenticating with the GitHub App.
# - Checks out the repository.
# - Applies the patch file.
# - Displays the result of git diff.
# - Configures the Git author.
# - Stages changes.
# - Commits changes.
# - Pushes changes.
update-built-files:
name: Check and update built files
runs-on: ubuntu-24.04
if: ${{ github.repository == 'wordpress/wordpress-develop' }}
timeout-minutes: 10
permissions:
contents: write
steps:
- name: Download artifact
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const artifacts = await github.rest.actions.listWorkflowRunArtifacts( {
owner: context.repo.owner,
repo: context.repo.repo,
run_id: process.env.RUN_ID,
} );
const matchArtifact = artifacts.data.artifacts.filter( ( artifact ) => {
return artifact.name === 'pr-built-file-changes'
} )[0];
if ( ! matchArtifact ) {
core.info( 'No artifact found!' );
return;
}
const download = await github.rest.actions.downloadArtifact( {
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
} );
const fs = require( 'fs' );
fs.writeFileSync( '${{ github.workspace }}/pr-built-file-changes.zip', Buffer.from( download.data ) )
env:
RUN_ID: ${{ github.event.workflow_run.id }}
- name: Check for artifact
id: artifact-check
run: |
if [ -f "pr-built-file-changes.zip" ]; then
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Unzip the artifact containing the PR data
if: ${{ steps.artifact-check.outputs.exists == 'true' }}
run: unzip pr-built-file-changes.zip
- name: Generate Installation Token
id: generate_token
if: ${{ steps.artifact-check.outputs.exists == 'true' }}
env:
GH_APP_ID: ${{ secrets.GH_PR_BUILT_FILES_APP_ID }}
GH_APP_PRIVATE_KEY: ${{ secrets.GH_PR_BUILT_FILES_PRIVATE_KEY }}
run: |
echo "$GH_APP_PRIVATE_KEY" > private-key.pem
# Generate JWT
JWT=$(python3 - <<EOF
import jwt, time
private_key = open("private-key.pem", "r").read()
payload = {
"iat": int(time.time()),
"exp": int(time.time()) + 600, # 10-minute expiration
"iss": $GH_APP_ID
}
print(jwt.encode(payload, private_key, algorithm="RS256"))
EOF
)
# Get Installation ID
INSTALLATION_ID=$(curl -s -X GET -H "Authorization: Bearer $JWT" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/app/installations | jq -r '.[0].id')
# Request Installation Access Token
ACCESS_TOKEN=$(curl -s -X POST -H "Authorization: Bearer $JWT" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens" | jq -r '.token')
echo "ACCESS_TOKEN=$ACCESS_TOKEN" >> "$GITHUB_ENV"
rm -f private-key.pem
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
if: ${{ steps.artifact-check.outputs.exists == 'true' }}
with:
repository: ${{ github.event.workflow_run.head_repository.full_name }}
ref: ${{ github.event.workflow_run.head_branch }}
path: 'pr-repo'
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
token: ${{ env.ACCESS_TOKEN }}
- name: Apply patch
if: ${{ steps.artifact-check.outputs.exists == 'true' }}
working-directory: 'pr-repo'
run: git apply ${{ github.workspace }}/changes.diff
- name: Display changes to versioned files
if: ${{ steps.artifact-check.outputs.exists == 'true' }}
working-directory: 'pr-repo'
run: git diff
- name: Configure git user name and email
if: ${{ steps.artifact-check.outputs.exists == 'true' }}
working-directory: 'pr-repo'
env:
GH_APP_ID: ${{ secrets.GH_PR_BUILT_FILES_APP_ID }}
run: |
git config user.name "wordpress-develop-pr-bot[bot]"
git config user.email ${{ env.GH_APP_ID }}+wordpress-develop-pr-bot[bot]@users.noreply.github.com
- name: Stage changes
if: ${{ steps.artifact-check.outputs.exists == 'true' }}
working-directory: 'pr-repo'
run: git add .
- name: Commit changes
if: ${{ steps.artifact-check.outputs.exists == 'true' }}
working-directory: 'pr-repo'
run: |
git commit -m "Automation: Updating built files with changes. [dependabot skip]"
- name: Push changes
if: ${{ steps.artifact-check.outputs.exists == 'true' }}
working-directory: 'pr-repo'
run: git push
|