Skip to content

Commit e7e2714

Browse files
committed
Build/Test Tools: Introduce a workflow for checking built files.
There are several files generated and updated by the build process that are under version control. Including changes to these files is a common missed step for contributors regardless of experience level. This introduces a workflow that checks for changes to versioned files as a result of other changes in pull requests and commits them back to the head branch. Because this workflow requires the `pull_request_target` event instead of `pull_request`, local references to reusable workflows should never be used. In addition to improving the contributor experience, this also opens the door to use Dependabot for monitoring npm dependencies, many of which produce changes to built files when updating. Props desrosj, johnbillion, joemcgill, swissspidy. See #62221. git-svn-id: https://develop.svn.wordpress.org/trunk@59983 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 7aae2ea commit e7e2714

File tree

2 files changed

+214
-0
lines changed

2 files changed

+214
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Checks for uncommitted changes to built files and pushes changes back.
2+
name: Check built files
3+
4+
on:
5+
# Because all commits happen through SVN and should always be manually reviewed by a committer, this workflow only
6+
# runs for pull requests.
7+
#
8+
# Other workflows that run on push will detect changes to versioned files and fail.
9+
pull_request_target:
10+
branches:
11+
- trunk
12+
- '6.[8-9]'
13+
- '[7-9].[0-9]'
14+
paths:
15+
# Any change to a CSS, JavaScript, JSON, or SASS file should run checks.
16+
- '**.css'
17+
- '**.js'
18+
- '**.json'
19+
- '**.sass'
20+
# These files configure npm and the task runner. Changes could affect the outcome.
21+
- 'package*.json'
22+
- 'Gruntfile.js'
23+
- 'webpack.config.js'
24+
- 'tools/webpack/**'
25+
# These files configure Composer. Changes could affect the outcome.
26+
- 'composer.*'
27+
# Confirm any changes to relevant workflow files.
28+
- '.github/workflows/check-built-files.yml'
29+
30+
# Cancels all previous workflow runs for pull requests that have not completed.
31+
concurrency:
32+
# The concurrency group contains the workflow name and the branch name for pull requests
33+
# or the commit hash for any other events.
34+
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request_target' && github.head_ref || github.sha }}
35+
cancel-in-progress: true
36+
37+
# Disable permissions for all available scopes by default.
38+
# Any needed permissions should be configured at the job level.
39+
permissions: {}
40+
41+
jobs:
42+
update-built-files:
43+
name: Update built files
44+
permissions:
45+
contents: write
46+
if: ${{ github.repository == 'WordPress/wordpress-develop' }}
47+
# This should always reference a version of the workflow committed through SVN and never a local reference.
48+
uses: WordPress/wordpress-develop/.github/workflows/reusable-check-built-files.yml@trunk
49+
secrets:
50+
GH_APP_ID: ${{ secrets.GH_APP_ID }}
51+
GH_APP_PRIVATE_KEY: ${{ secrets.GH_APP_PRIVATE_KEY }}
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
name: Lint GitHub Actions workflows
2+
on:
3+
workflow_call:
4+
secrets:
5+
GH_APP_ID:
6+
description: 'A GitHub App ID.'
7+
required: true
8+
GH_APP_PRIVATE_KEY:
9+
description: 'A GitHub App private key.'
10+
required: true
11+
12+
permissions: {}
13+
14+
jobs:
15+
# Checks a PR for uncommitted changes to built files.
16+
#
17+
# This job uses a GitHub App instead of $GITHUB_TOKEN because Dependabot pull requests are only granted
18+
# read-only access.
19+
#
20+
# Performs the following steps:
21+
# - Generates a token for authenticating with the GitHub App.
22+
# - Checks out the repository.
23+
# - Sets up Node.js.
24+
# - Configures caching for Composer.
25+
# - Installs Composer dependencies.
26+
# - Logs general debug information about the runner.
27+
# - Installs npm dependencies.
28+
# - Builds CSS file using SASS.
29+
# - Builds Emoji files.
30+
# - Builds bundled Root Certificate files.
31+
# - Builds WordPress.
32+
# - Checks for changes to versioned files.
33+
# - Displays the result of git diff for debugging purposes.
34+
# - Configures the Git author.
35+
# - Stages changes.
36+
# - Commits changes.
37+
# - Pushes changes.
38+
update-built-files:
39+
name: Check and update built files
40+
runs-on: ubuntu-24.04
41+
# This prevents an unnecessary second run after changes are committed back because Dependabot always rebases
42+
# updates and force pushes.
43+
if: ${{ github.actor != 'dependabot[bot]' || github.event.commits < 2 }}
44+
timeout-minutes: 10
45+
permissions:
46+
contents: write
47+
steps:
48+
- name: Generate Installation Token
49+
id: generate_token
50+
env:
51+
GH_APP_ID: ${{ secrets.GH_APP_ID }}
52+
GH_APP_PRIVATE_KEY: ${{ secrets.GH_APP_PRIVATE_KEY }}
53+
run: |
54+
echo "$GH_APP_PRIVATE_KEY" > private-key.pem
55+
56+
# Generate JWT
57+
JWT=$(python3 - <<EOF
58+
import jwt, time
59+
private_key = open("private-key.pem", "r").read()
60+
payload = {
61+
"iat": int(time.time()),
62+
"exp": int(time.time()) + 600, # 10-minute expiration
63+
"iss": $GH_APP_ID
64+
}
65+
print(jwt.encode(payload, private_key, algorithm="RS256"))
66+
EOF
67+
)
68+
69+
# Get Installation ID
70+
INSTALLATION_ID=$(curl -s -X GET -H "Authorization: Bearer $JWT" \
71+
-H "Accept: application/vnd.github.v3+json" \
72+
https://api.github.com/app/installations | jq -r '.[0].id')
73+
74+
# Request Installation Access Token
75+
ACCESS_TOKEN=$(curl -s -X POST -H "Authorization: Bearer $JWT" \
76+
-H "Accept: application/vnd.github.v3+json" \
77+
"https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens" | jq -r '.token')
78+
79+
echo "ACCESS_TOKEN=$ACCESS_TOKEN" >> "$GITHUB_ENV"
80+
81+
rm -f private-key.pem
82+
83+
- name: Checkout repository
84+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
85+
with:
86+
ref: ${{ github.head_ref }}
87+
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
88+
token: ${{ env.ACCESS_TOKEN }}
89+
90+
- name: Set up Node.js
91+
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
92+
with:
93+
node-version-file: '.nvmrc'
94+
cache: npm
95+
96+
# This date is used to ensure that the PHPCS cache is cleared at least once every week.
97+
# http://man7.org/linux/man-pages/man1/date.1.html
98+
- name: "Get last Monday's date"
99+
id: get-date
100+
run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> "$GITHUB_OUTPUT"
101+
102+
# Since Composer dependencies are installed using `composer update` and no lock file is in version control,
103+
# passing a custom cache suffix ensures that the cache is flushed at least once per week.
104+
- name: Install Composer dependencies
105+
uses: ramsey/composer-install@57532f8be5bda426838819c5ee9afb8af389d51a # v3.0.0
106+
with:
107+
custom-cache-suffix: ${{ steps.get-date.outputs.date }}
108+
109+
- name: Log debug information
110+
run: |
111+
npm --version
112+
node --version
113+
curl --version
114+
git --version
115+
116+
- name: Install npm Dependencies
117+
run: npm ci
118+
119+
- name: Run SASS precommit tasks
120+
run: npm run grunt precommit:css
121+
122+
- name: Run Emoji precommit task
123+
run: npm run grunt precommit:emoji
124+
env:
125+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
126+
127+
- name: Run certificate tasks
128+
run: npm run grunt copy:certificates
129+
130+
- name: Build WordPress
131+
run: npm run build:dev
132+
133+
- name: Check for changes to versioned files
134+
id: built-file-check
135+
run: |
136+
if git diff --quiet; then
137+
echo "uncommitted_changes=false" >> "$GITHUB_OUTPUT"
138+
else
139+
echo "uncommitted_changes=true" >> "$GITHUB_OUTPUT"
140+
fi
141+
142+
- name: Display changes to versioned files
143+
if: ${{ steps.built-file-check.outputs.uncommitted_changes == 'true' }}
144+
run: git diff
145+
146+
- name: Configure git user name and email
147+
if: ${{ steps.built-file-check.outputs.uncommitted_changes == 'true' }}
148+
run: |
149+
git config user.name "dependabot[bot]"
150+
git config user.email 49699333+dependabot[bot]@users.noreply.github.com
151+
152+
- name: Stage changes
153+
if: ${{ steps.built-file-check.outputs.uncommitted_changes == 'true' }}
154+
run: git add .
155+
156+
- name: Commit changes
157+
if: ${{ steps.built-file-check.outputs.uncommitted_changes == 'true' }}
158+
run: |
159+
git commit -m "Automation: Updating built files with changes. [dependabot skip]"
160+
161+
- name: Push changes
162+
if: ${{ steps.built-file-check.outputs.uncommitted_changes == 'true' }}
163+
run: git push

0 commit comments

Comments
 (0)