Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion .github/workflows/phpunit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ on:
# Confirm any changes to relevant workflow files.
- '.github/workflows/phpunit-tests.yml'
- '.github/workflows/reusable-phpunit-tests-*.yml'
- '.github/workflows/reusable-prepare-gutenberg.yml'
workflow_dispatch:
# Once weekly On Sundays at 00:00 UTC.
schedule:
Expand All @@ -54,6 +55,20 @@ concurrency:
permissions: {}

jobs:
# Downloads and verifies the Gutenberg build once for all PHPUnit jobs.
#
# This condition is the union of the conditions on the jobs that need it, reduced.
# The org matrices require `WordPress/wordpress-develop` or a pull request, and the
# fork matrix requires a pull request, so `wordpress-develop` or a pull request
# covers every case. Keep it in step with those jobs: a narrower condition orphans
# them, because a job that needs a skipped job is skipped too, and a broader one
# downloads a build that nothing consumes.
prepare-gutenberg:
uses: ./.github/workflows/reusable-prepare-gutenberg.yml
permissions:
contents: read
if: ${{ github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' }}

#
# Creates a PHPUnit test job for each PHP/MySQL combination.
#
Expand All @@ -64,6 +79,7 @@ jobs:
test-with-mysql:
name: PHP ${{ matrix.php }}
uses: ./.github/workflows/reusable-phpunit-tests-v3.yml
needs: prepare-gutenberg
permissions:
contents: read
secrets:
Expand Down Expand Up @@ -130,6 +146,8 @@ jobs:
phpunit-config: ${{ matrix.multisite && 'tests/phpunit/multisite.xml' || 'phpunit.xml.dist' }}
tests-domain: ${{ matrix.tests-domain }}
report: ${{ matrix.report || false }}
gutenberg-artifact: gutenberg-build
gutenberg-sha: ${{ needs.prepare-gutenberg.outputs.gutenberg-sha }}

#
# Creates a PHPUnit test job for each PHP/MariaDB combination.
Expand All @@ -143,6 +161,7 @@ jobs:
test-with-mariadb:
name: PHP ${{ matrix.php }}
uses: ./.github/workflows/reusable-phpunit-tests-v3.yml
needs: prepare-gutenberg
permissions:
contents: read
secrets:
Expand Down Expand Up @@ -182,6 +201,8 @@ jobs:
memcached: ${{ matrix.memcached }}
phpunit-config: ${{ matrix.multisite && 'tests/phpunit/multisite.xml' || 'phpunit.xml.dist' }}
report: false
gutenberg-artifact: gutenberg-build
gutenberg-sha: ${{ needs.prepare-gutenberg.outputs.gutenberg-sha }}

#
# Creates PHPUnit test jobs to test MariaDB and MySQL innovation releases.
Expand All @@ -197,6 +218,7 @@ jobs:
test-innovation-releases:
name: PHP ${{ matrix.php }}
uses: ./.github/workflows/reusable-phpunit-tests-v3.yml
needs: prepare-gutenberg
permissions:
contents: read
secrets:
Expand Down Expand Up @@ -228,6 +250,8 @@ jobs:
memcached: ${{ matrix.memcached }}
phpunit-config: ${{ matrix.multisite && 'tests/phpunit/multisite.xml' || 'phpunit.xml.dist' }}
report: false
gutenberg-artifact: gutenberg-build
gutenberg-sha: ${{ needs.prepare-gutenberg.outputs.gutenberg-sha }}

#
# Runs the HTML API test group.
Expand All @@ -240,6 +264,7 @@ jobs:
html-api-test-groups:
name: ${{ matrix.label }}
uses: ./.github/workflows/reusable-phpunit-tests-v3.yml
needs: prepare-gutenberg
permissions:
contents: read
secrets:
Expand All @@ -260,6 +285,8 @@ jobs:
db-type: ${{ matrix.db-type }}
db-version: ${{ matrix.db-version }}
phpunit-test-groups: ${{ matrix.phpunit-test-groups }}
gutenberg-artifact: gutenberg-build
gutenberg-sha: ${{ needs.prepare-gutenberg.outputs.gutenberg-sha }}

#
# Runs unit tests for forks.
Expand All @@ -271,6 +298,7 @@ jobs:
limited-matrix-for-forks:
name: PHP ${{ matrix.php }}
uses: ./.github/workflows/reusable-phpunit-tests-v3.yml
needs: prepare-gutenberg
permissions:
contents: read
secrets:
Expand Down Expand Up @@ -320,14 +348,16 @@ jobs:
db-type: ${{ matrix.db-type }}
memcached: ${{ matrix.memcached || false }}
phpunit-test-groups: ${{ matrix.phpunit-test-groups || '' }}
gutenberg-artifact: gutenberg-build
gutenberg-sha: ${{ needs.prepare-gutenberg.outputs.gutenberg-sha }}

slack-notifications:
name: Slack Notifications
uses: ./.github/workflows/slack-notifications.yml
permissions:
actions: read
contents: read
needs: [ test-with-mysql, test-with-mariadb, test-innovation-releases, html-api-test-groups, limited-matrix-for-forks ]
needs: [ prepare-gutenberg, test-with-mysql, test-with-mariadb, test-innovation-releases, html-api-test-groups, limited-matrix-for-forks ]
if: ${{ github.repository == 'WordPress/wordpress-develop' && github.event_name != 'pull_request' && always() }}
with:
calling_status: ${{ contains( needs.*.result, 'cancelled' ) && 'cancelled' || contains( needs.*.result, 'failure' ) && 'failure' || 'success' }}
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/reusable-phpunit-tests-v3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ on:
required: false
type: boolean
default: false
gutenberg-artifact:
description: 'The name of a same-workflow artifact containing the prepared Gutenberg build.'
required: false
type: string
default: ''
gutenberg-sha:
description: 'The immutable Gutenberg source SHA verified by the calling workflow.'
required: false
type: string
default: ''
secrets:
CODECOV_TOKEN:
description: 'The Codecov token required for uploading reports.'
Expand Down Expand Up @@ -101,6 +111,7 @@ jobs:
# Performs the following steps:
# - Sets environment variables.
# - Checks out the repository.
# - Downloads the prepared Gutenberg build when provided by the calling workflow.
# - Sets up Node.js.
# - Sets up PHP.
# - Installs Composer dependencies.
Expand Down Expand Up @@ -135,6 +146,15 @@ jobs:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

- name: Download prepared Gutenberg build
if: ${{ inputs.gutenberg-artifact != '' }}
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
# Without a run ID, this action reads only from the caller's current workflow run.
name: ${{ inputs.gutenberg-artifact }}
path: gutenberg
digest-mismatch: error

- name: Set up Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
Expand Down Expand Up @@ -166,6 +186,9 @@ jobs:

- name: Build WordPress
run: npm run build:dev
env:
# The producer resolved this once. Matrix jobs must not re-resolve mutable GHCR tags.
GUTENBERG_EXPECTED_SHA: ${{ inputs.gutenberg-sha }}

- name: General debug information
run: |
Expand Down
87 changes: 87 additions & 0 deletions .github/workflows/reusable-prepare-gutenberg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
##
# A reusable workflow that downloads and verifies the Gutenberg build once per
# calling workflow run.
##
name: Prepare Gutenberg build

on:
workflow_call:
outputs:
gutenberg-sha:
description: 'The immutable Gutenberg source SHA verified by this workflow.'
value: ${{ jobs.prepare-gutenberg.outputs.gutenberg-sha }}

# Disable permissions for all available scopes by default.
# Any needed permissions should be configured at the job level.
permissions: {}

jobs:
prepare-gutenberg:
name: Gutenberg
runs-on: ubuntu-24.04
timeout-minutes: 10
outputs:
gutenberg-sha: ${{ steps.download.outputs.gutenberg-sha }}
permissions:
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
# Resolve the Gutenberg ref from the exact commit that started this workflow run.
ref: ${{ github.sha }}
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

- name: Set up Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: '.nvmrc'

- name: Resolve Gutenberg metadata
id: metadata
run: node tools/gutenberg/download.js --metadata

- name: Restore verified Gutenberg archive
id: restore
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: .ci/gutenberg/archive.tar.gz
key: gutenberg-oci-archive-v1-${{ steps.metadata.outputs.source-sha }}-sha256-${{ steps.metadata.outputs.blob-sha256 }}

- name: Download verified Gutenberg archive
if: ${{ steps.restore.outputs.cache-hit != 'true' }}
run: |
rm -f .ci/gutenberg/archive.tar.gz
node tools/gutenberg/download.js \
--archive .ci/gutenberg/archive.tar.gz \
--source-sha "${{ steps.metadata.outputs.source-sha }}" \

Check notice

Code scanning / zizmor

code injection via template expansion Note

code injection via template expansion
--blob-sha256 "${{ steps.metadata.outputs.blob-sha256 }}" \

Check notice

Code scanning / zizmor

code injection via template expansion Note

code injection via template expansion
--blob-size "${{ steps.metadata.outputs.blob-size }}"

Check notice

Code scanning / zizmor

code injection via template expansion Note

code injection via template expansion

Comment on lines +53 to +62
- name: Verify and extract Gutenberg build
id: download
run: |
node tools/gutenberg/download.js \
--archive .ci/gutenberg/archive.tar.gz \
--source-sha "${{ steps.metadata.outputs.source-sha }}" \

Check notice

Code scanning / zizmor

code injection via template expansion Note

code injection via template expansion
--blob-sha256 "${{ steps.metadata.outputs.blob-sha256 }}" \

Check notice

Code scanning / zizmor

code injection via template expansion Note

code injection via template expansion
--blob-size "${{ steps.metadata.outputs.blob-size }}"

Check notice

Code scanning / zizmor

code injection via template expansion Note

code injection via template expansion
echo "gutenberg-sha=${{ steps.metadata.outputs.source-sha }}" >> "$GITHUB_OUTPUT"

Check notice

Code scanning / zizmor

code injection via template expansion Note

code injection via template expansion

- name: Save verified Gutenberg archive
if: ${{ github.repository == 'WordPress/wordpress-develop' && github.event_name == 'push' && startsWith(github.ref, 'refs/heads/') && github.ref_protected == true && steps.restore.outputs.cache-hit != 'true' }}
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: .ci/gutenberg/archive.tar.gz
key: gutenberg-oci-archive-v1-${{ steps.metadata.outputs.source-sha }}-sha256-${{ steps.metadata.outputs.blob-sha256 }}

- name: Upload Gutenberg build
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: gutenberg-build
path: gutenberg/
if-no-files-found: error
include-hidden-files: true
retention-days: 1
20 changes: 19 additions & 1 deletion .github/workflows/test-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ on:
paths:
- '.github/workflows/test-coverage.yml'
- '.github/workflows/reusable-phpunit-tests-v3.yml'
- '.github/workflows/reusable-prepare-gutenberg.yml'
- 'tools/gutenberg/**'
- 'package*.json'
- '.nvmrc'
- 'docker-compose.yml'
- 'phpunit.xml.dist'
- 'tests/phpunit/multisite.xml'
Expand All @@ -17,6 +21,10 @@ on:
paths:
- '.github/workflows/test-coverage.yml'
- '.github/workflows/reusable-phpunit-tests-v3.yml'
- '.github/workflows/reusable-prepare-gutenberg.yml'
- 'tools/gutenberg/**'
- 'package*.json'
- '.nvmrc'
- 'docker-compose.yml'
- 'phpunit.xml.dist'
- 'tests/phpunit/multisite.xml'
Expand All @@ -42,12 +50,20 @@ env:
PUPPETEER_SKIP_DOWNLOAD: true

jobs:
# Downloads and verifies the Gutenberg build once for all coverage jobs.
prepare-gutenberg:
uses: ./.github/workflows/reusable-prepare-gutenberg.yml
permissions:
contents: read
if: ${{ github.repository == 'WordPress/wordpress-develop' }}

#
# Creates a PHPUnit test jobs for generating code coverage reports.
#
test-coverage-report:
name: ${{ matrix.multisite && 'Multisite' || 'Single site' }} report
uses: ./.github/workflows/reusable-phpunit-tests-v3.yml
needs: prepare-gutenberg
permissions:
contents: read
if: ${{ github.repository == 'WordPress/wordpress-develop' }}
Expand All @@ -60,6 +76,8 @@ jobs:
php: '8.3'
multisite: ${{ matrix.multisite }}
coverage-report: ${{ matrix.coverage-report }}
gutenberg-artifact: gutenberg-build
gutenberg-sha: ${{ needs.prepare-gutenberg.outputs.gutenberg-sha }}
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

Expand All @@ -69,7 +87,7 @@ jobs:
permissions:
actions: read
contents: read
needs: [ test-coverage-report ]
needs: [ prepare-gutenberg, test-coverage-report ]
if: ${{ github.repository == 'WordPress/wordpress-develop' && github.event_name != 'pull_request' && always() }}
with:
calling_status: ${{ contains( needs.*.result, 'cancelled' ) && 'cancelled' || contains( needs.*.result, 'failure' ) && 'failure' || 'success' }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ wp-tests-config.php
/packagehash.txt
/.gutenberg-hash
/artifacts
/.ci/gutenberg/archive.tar.gz
/setup.log
/coverage

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@
"test:php": "node ./tools/local-env/scripts/docker.js run --rm php ./vendor/bin/phpunit",
"test:coverage": "npm run test:php -- --coverage-html ./coverage/html/ --coverage-php ./coverage/php/report.php --coverage-text=./coverage/text/report.txt",
"test:e2e": "wp-scripts test-playwright --config tests/e2e/playwright.config.js",
"test:tools": "node --test tools/gutenberg/tests/",
"test:visual": "wp-scripts test-playwright --config tests/visual-regression/playwright.config.js",
"typecheck:php": "node ./tools/local-env/scripts/docker.js run --rm php composer phpstan",
"gutenberg:copy": "node tools/gutenberg/copy.js",
Expand Down
Loading
Loading