-
Notifications
You must be signed in to change notification settings - Fork 222
175 lines (154 loc) · 6.81 KB
/
Copy pathunit-tests.yml
File metadata and controls
175 lines (154 loc) · 6.81 KB
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
167
168
169
170
171
172
173
174
175
name: Unit Tests
on:
pull_request:
push:
branches: [ trunk ]
# Daily full run to catch breakage in unpinned external inputs.
schedule:
- cron: '0 3 * * *'
workflow_dispatch:
# Cancel superseded PR runs; trunk pushes get per-commit groups so queued mirrored commits aren't cancelled.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name == 'push' && github.sha || '' }}
cancel-in-progress: true
permissions:
contents: read
pull-requests: read
jobs:
# Run only the suites the changed files can break, per .github/unit-tests-suites.yml.
changes:
name: Detect affected suites
if: github.event_name == 'pull_request' || github.repository == 'WordPress/wordpress.org'
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
standalone: ${{ steps.matrices.outputs.standalone }}
wordpress: ${{ steps.matrices.outputs.wordpress }}
steps:
- uses: actions/checkout@v7
# Emit path filters (suite paths plus type-shared ones) and matrices.
- name: Load suite definitions
id: suites
run: |
suites=$( yq -o=json '.' .github/unit-tests-suites.yml )
# Reject suites the matrix builders below would silently drop.
invalid=$( jq -r '.suites | to_entries | map( select( ( .value.type | IN( "standalone", "wordpress" ) | not ) or ( .value.paths // [] ) == [] ) | .key ) | join( ", " )' <<< "$suites" )
if [ -n "$invalid" ]; then
echo "::error file=.github/unit-tests-suites.yml::Suites with an unknown type or no paths: $invalid"
exit 1
fi
# Add each wordpress suite's environment plugins to its paths so the two can't drift.
for suite in $( jq -r '.suites | to_entries[] | select( .value.type == "wordpress" ) | .key' <<< "$suites" ); do
plugins=$( jq -c '[ .plugins[] | select( startswith( "../" ) ) | sub( "^\\.\\./"; "" ) + "/**" ]' "environments/$suite/.wp-env.test.json" )
suites=$( jq -c --arg suite "$suite" --argjson plugins "$plugins" '.suites[ $suite ].paths += $plugins' <<< "$suites" )
done
filters=$( jq -c '.["shared-paths"] as $shared | .suites | with_entries( .value |= ( $shared[ .type ] + .paths ) )' <<< "$suites" )
standalone=$( jq -c '.suites | to_entries | map( select( .value.type == "standalone" ) | { filter: .key } + ( .value | del( .type, .paths ) ) )' <<< "$suites" )
wordpress=$( jq -c '.suites | to_entries | map( select( .value.type == "wordpress" ) | { filter: .key } + ( .value | del( .type, .paths ) ) )' <<< "$suites" )
{
echo "filters=$filters"
echo "standalone=$standalone"
echo "wordpress=$wordpress"
} >> "$GITHUB_OUTPUT"
- name: Detect changed paths
id: filter
if: github.event_name != 'schedule' && github.event_name != 'workflow_dispatch'
uses: dorny/paths-filter@v4
with:
filters: ${{ steps.suites.outputs.filters }}
- name: Build suite matrices
id: matrices
env:
CHANGES: ${{ steps.filter.outputs.changes }}
STANDALONE: ${{ steps.suites.outputs.standalone }}
WORDPRESS: ${{ steps.suites.outputs.wordpress }}
run: |
if [ -z "$CHANGES" ]; then
# Scheduled and manual runs re-test everything.
standalone="$STANDALONE"
wordpress="$WORDPRESS"
else
standalone=$( jq -c --argjson changed "$CHANGES" 'map( select( .filter as $f | $changed | index( $f ) ) )' <<< "$STANDALONE" )
wordpress=$( jq -c --argjson changed "$CHANGES" 'map( select( .filter as $f | $changed | index( $f ) ) )' <<< "$WORDPRESS" )
fi
{
echo "standalone=$standalone"
echo "wordpress=$wordpress"
} >> "$GITHUB_OUTPUT"
# Standalone PHP tests — no WordPress or database dependency.
# Uses the project's composer-installed PHPUnit 9 + yoast/phpunit-polyfills,
# matching the version that WordPress Core ships its test bootstrap for.
php-standalone:
name: "PHP: ${{ matrix.name }}"
needs: changes
if: needs.changes.outputs.standalone != '[]'
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(needs.changes.outputs.standalone) }}
steps:
- uses: actions/checkout@v7
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.4"
coverage: none
- name: Install composer dependencies
uses: ramsey/composer-install@v4
- name: Create wpdb stub bootstrap
if: matrix.bootstrap == 'wpdb-stub'
run: |
cat > /tmp/phpunit-bootstrap.php << 'PHPEOF'
<?php
class wpdbStub {
public function prepare( $query, ...$args ) { return $query; }
public function get_results( $query, $output = 'OBJECT' ) { return []; }
}
PHPEOF
- name: Run PHPUnit
working-directory: ${{ matrix.working-directory }}
run: ${{ github.workspace }}/vendor/bin/phpunit ${{ matrix.phpunit-args }}
# WordPress-dependent PHP tests — require wp-env (Docker).
php-wordpress:
name: "WP: ${{ matrix.name }}"
needs: changes
if: needs.changes.outputs.wordpress != '[]'
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
# One entry per environment. A script covering several plugins runs
# them all against the environment it starts once.
include: ${{ fromJSON(needs.changes.outputs.wordpress) }}
defaults:
run:
working-directory: environments
steps:
- uses: actions/checkout@v7
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version-file: environments/.nvmrc
cache: npm
cache-dependency-path: environments/package-lock.json
- name: Install dependencies
run: npm ci
# Cache sources for up to a day. No restore-keys: restored caches skip wp-env's source downloads and would pin CI to stale WordPress.
- name: Get cache day
id: cache-day
run: echo "date=$( date -u +%F )" >> "$GITHUB_OUTPUT"
# wp-env homes in ~/wp-env (not ~/.wp-env) on snap hosts like GH runners.
- name: Cache wp-env sources
uses: actions/cache@v6
with:
path: |
~/.wp-env
~/wp-env
key: wp-env-${{ matrix.filter }}-${{ steps.cache-day.outputs.date }}-${{ hashFiles(format('environments/{0}/.wp-env.test.json', matrix.filter), 'environments/package-lock.json') }}
# The scripts start their environment, whose `afterStart` installs PHPUnit
# and the polyfills, and then run each suite it holds.
- name: Run PHPUnit
run: npm run ${{ matrix.script }}