Skip to content

Options, Meta APIs: Prime transient options prior to use. #12780

Options, Meta APIs: Prime transient options prior to use.

Options, Meta APIs: Prime transient options prior to use. #12780

Workflow file for this run

name: Performance Tests
on:
push:
branches:
- trunk
- '6.[2-9]'
- '[7-9].[0-9]'
tags:
- '[0-9]+.[0-9]'
- '[0-9]+.[0-9].[0-9]+'
- '![45].[0-9].[0-9]+'
- '!6.[01].[0-9]+'
pull_request:
branches:
- trunk
- '6.[2-9]'
- '[7-9].[0-9]'
workflow_dispatch:
# 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 == 'pull_request' && github.head_ref || github.sha }}
cancel-in-progress: true
# Disable permissions for all available scopes by default.
# Any needed permissions should be configured at the job level.
permissions: {}
env:
PUPPETEER_SKIP_DOWNLOAD: ${{ true }}
# Performance testing should be performed in an environment reflecting a standard production environment.
LOCAL_WP_DEBUG: false
LOCAL_SCRIPT_DEBUG: false
LOCAL_SAVEQUERIES: false
LOCAL_WP_DEVELOPMENT_MODE: "''"
# This workflow takes two sets of measurements — one for the current commit,
# and another against a consistent version that is used as a baseline measurement.
# This is done to isolate variance in measurements caused by the GitHub runners
# from differences caused by code changes between commits. The BASE_TAG value here
# represents the version being used for baseline measurements. It should only be
# changed if we want to normalize results against a different baseline.
BASE_TAG: '6.1.1'
LOCAL_DIR: build
TARGET_REF: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref || '' }}
TARGET_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }}
jobs:
# Runs the performance test suite.
#
# Performs the following steps:
# - Configure environment variables.
# - Checkout repository.
# - Set up Node.js.
# - Log debug information.
# - Install npm dependencies.
# - Install Playwright browsers.
# - Build WordPress.
# - Start Docker environment.
# - Log running Docker containers.
# - Docker debug information.
# - Install WordPress.
# - Install WordPress Importer plugin.
# - Import mock data.
# - Deactivate WordPress Importer plugin.
# - Update permalink structure.
# - Install additional languages.
# - Disable external HTTP requests.
# - Disable cron.
# - List defined constants.
# - Install MU plugin.
# - Run performance tests (current commit).
# - Download previous build artifact (target branch or previous commit).
# - Download artifact.
# - Unzip the build.
# - Run any database upgrades.
# - Flush cache.
# - Delete expired transients.
# - Run performance tests (previous/target commit).
# - Set the environment to the baseline version.
# - Run any database upgrades.
# - Flush cache.
# - Delete expired transients.
# - Run baseline performance tests.
# - Archive artifacts.
# - Compare results.
# - Add workflow summary.
# - Set the base sha.
# - Set commit details.
# - Publish performance results.
# - Ensure version-controlled files are not modified or deleted.
performance:
name: Run performance tests ${{ matrix.memcached && '(with memcached)' || '' }}
runs-on: ubuntu-latest
permissions:
contents: read
if: ${{ ( github.repository == 'WordPress/wordpress-develop' || github.event_name == 'pull_request' ) && ! contains( github.event.before, '00000000' ) }}
strategy:
fail-fast: false
matrix:
memcached: [ true, false ]
env:
LOCAL_PHP_MEMCACHED: ${{ matrix.memcached }}
steps:
- name: Configure environment variables
run: |
echo "PHP_FPM_UID=$(id -u)" >> $GITHUB_ENV
echo "PHP_FPM_GID=$(id -g)" >> $GITHUB_ENV
- name: Checkout repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
- name: Set up Node.js
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version-file: '.nvmrc'
cache: npm
- name: Log debug information
run: |
npm --version
node --version
curl --version
git --version
locale -a
- name: Install npm dependencies
run: npm ci
- name: Install Playwright browsers
run: npx playwright install --with-deps chromium
- name: Build WordPress
run: npm run build
- name: Start Docker environment
run: npm run env:start
- name: Install object cache drop-in
if: ${{ matrix.memcached }}
run: cp src/wp-content/object-cache.php build/wp-content/object-cache.php
- name: Log running Docker containers
run: docker ps -a
- name: Docker debug information
run: |
docker -v
docker compose run --rm mysql mysql --version
docker compose run --rm php php --version
docker compose run --rm php php -m
docker compose run --rm php php -i
docker compose run --rm php locale -a
- name: Install WordPress
run: npm run env:install
- name: Install WordPress Importer plugin
run: npm run env:cli -- plugin install wordpress-importer --activate --path=/var/www/${{ env.LOCAL_DIR }}
- name: Import mock data
run: |
curl -O https://raw.githubusercontent.com/WordPress/theme-test-data/b9752e0533a5acbb876951a8cbb5bcc69a56474c/themeunittestdata.wordpress.xml
npm run env:cli -- import themeunittestdata.wordpress.xml --authors=create --path=/var/www/${{ env.LOCAL_DIR }}
rm themeunittestdata.wordpress.xml
- name: Deactivate WordPress Importer plugin
run: npm run env:cli -- plugin deactivate wordpress-importer --path=/var/www/${{ env.LOCAL_DIR }}
- name: Update permalink structure
run: npm run env:cli -- rewrite structure '/%year%/%monthnum%/%postname%/' --path=/var/www/${{ env.LOCAL_DIR }}
- name: Install additional languages
run: |
npm run env:cli -- language core install de_DE --path=/var/www/${{ env.LOCAL_DIR }}
npm run env:cli -- language plugin install de_DE --all --path=/var/www/${{ env.LOCAL_DIR }}
npm run env:cli -- language theme install de_DE --all --path=/var/www/${{ env.LOCAL_DIR }}
# Prevent background update checks from impacting test stability.
- name: Disable external HTTP requests
run: npm run env:cli -- config set WP_HTTP_BLOCK_EXTERNAL true --raw --type=constant --path=/var/www/${{ env.LOCAL_DIR }}
# Prevent background tasks from impacting test stability.
- name: Disable cron
run: npm run env:cli -- config set DISABLE_WP_CRON true --raw --type=constant --path=/var/www/${{ env.LOCAL_DIR }}
- name: List defined constants
run: npm run env:cli -- config list --path=/var/www/${{ env.LOCAL_DIR }}
- name: Install MU plugin
run: |
mkdir ./${{ env.LOCAL_DIR }}/wp-content/mu-plugins
cp ./tests/performance/wp-content/mu-plugins/server-timing.php ./${{ env.LOCAL_DIR }}/wp-content/mu-plugins/server-timing.php
- name: Run performance tests (current commit)
run: npm run test:performance
- name: Download previous build artifact (target branch or previous commit)
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
id: get-previous-build
with:
script: |
const artifacts = await github.rest.actions.listArtifactsForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
name: 'wordpress-build-' + process.env.TARGET_SHA,
});
const matchArtifact = artifacts.data.artifacts[0];
if ( ! matchArtifact ) {
core.setFailed( 'No artifact found!' );
return false;
}
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 }}/before.zip', Buffer.from( download.data ) )
return true;
- name: Unzip the build
if: ${{ steps.get-previous-build.outputs.result }}
run: |
unzip ${{ github.workspace }}/before.zip
unzip -o ${{ github.workspace }}/wordpress.zip
- name: Run any database upgrades
if: ${{ steps.get-previous-build.outputs.result }}
run: npm run env:cli -- core update-db --path=/var/www/${{ env.LOCAL_DIR }}
- name: Flush cache
if: ${{ steps.get-previous-build.outputs.result }}
run: npm run env:cli -- cache flush --path=/var/www/${{ env.LOCAL_DIR }}
- name: Delete expired transients
if: ${{ steps.get-previous-build.outputs.result }}
run: npm run env:cli -- transient delete --expired --path=/var/www/${{ env.LOCAL_DIR }}
- name: Run target performance tests (previous/target commit)
if: ${{ steps.get-previous-build.outputs.result }}
env:
TEST_RESULTS_PREFIX: before
run: npm run test:performance
- name: Set the environment to the baseline version
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' }}
run: |
npm run env:cli -- core update --version=${{ env.BASE_TAG }} --force --path=/var/www/${{ env.LOCAL_DIR }}
npm run env:cli -- core version --path=/var/www/${{ env.LOCAL_DIR }}
- name: Run any database upgrades
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' }}
run: npm run env:cli -- core update-db --path=/var/www/${{ env.LOCAL_DIR }}
- name: Flush cache
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' }}
run: npm run env:cli -- cache flush --path=/var/www/${{ env.LOCAL_DIR }}
- name: Delete expired transients
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' }}
run: npm run env:cli -- transient delete --expired --path=/var/www/${{ env.LOCAL_DIR }}
- name: Run baseline performance tests
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' }}
env:
TEST_RESULTS_PREFIX: base
run: npm run test:performance
- name: Archive artifacts
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
if: always()
with:
name: performance-artifacts${{ matrix.memcached && '-memcached' || '' }}-${{ github.run_id }}
path: artifacts
if-no-files-found: ignore
- name: Compare results
run: node ./tests/performance/compare-results.js ${{ runner.temp }}/summary.md
- name: Add workflow summary
run: cat ${{ runner.temp }}/summary.md >> $GITHUB_STEP_SUMMARY
- name: Set the base sha
# Only needed when publishing results.
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' && ! matrix.memcached }}
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
id: base-sha
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const baseRef = await github.rest.git.getRef({ owner: context.repo.owner, repo: context.repo.repo, ref: 'tags/${{ env.BASE_TAG }}' });
return baseRef.data.object.sha;
- name: Set commit details
# Only needed when publishing results.
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' && ! matrix.memcached }}
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
id: commit-timestamp
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const commit_details = await github.rest.git.getCommit({ owner: context.repo.owner, repo: context.repo.repo, commit_sha: context.sha });
return parseInt((new Date( commit_details.data.author.date ).getTime() / 1000).toFixed(0))
- name: Publish performance results
# Only publish results on pushes to trunk.
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/trunk' && ! matrix.memcached }}
env:
BASE_SHA: ${{ steps.base-sha.outputs.result }}
COMMITTED_AT: ${{ steps.commit-timestamp.outputs.result }}
CODEVITALS_PROJECT_TOKEN: ${{ secrets.CODEVITALS_PROJECT_TOKEN }}
HOST_NAME: "www.codevitals.run"
run: node ./tests/performance/log-results.js $CODEVITALS_PROJECT_TOKEN trunk $GITHUB_SHA $BASE_SHA $COMMITTED_AT $HOST_NAME
- name: Ensure version-controlled files are not modified or deleted
run: git diff --exit-code
slack-notifications:
name: Slack Notifications
uses: WordPress/wordpress-develop/.github/workflows/slack-notifications.yml@trunk
permissions:
actions: read
contents: read
needs: [ performance ]
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' }}
secrets:
SLACK_GHA_SUCCESS_WEBHOOK: ${{ secrets.SLACK_GHA_SUCCESS_WEBHOOK }}
SLACK_GHA_CANCELLED_WEBHOOK: ${{ secrets.SLACK_GHA_CANCELLED_WEBHOOK }}
SLACK_GHA_FIXED_WEBHOOK: ${{ secrets.SLACK_GHA_FIXED_WEBHOOK }}
SLACK_GHA_FAILURE_WEBHOOK: ${{ secrets.SLACK_GHA_FAILURE_WEBHOOK }}
failed-workflow:
name: Failed workflow tasks
runs-on: ubuntu-latest
permissions:
actions: write
needs: [ slack-notifications ]
if: |
always() &&
github.repository == 'WordPress/wordpress-develop' &&
github.event_name != 'pull_request' &&
github.run_attempt < 2 &&
(
contains( needs.*.result, 'cancelled' ) ||
contains( needs.*.result, 'failure' )
)
steps:
- name: Dispatch workflow run
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
retries: 2
retry-exempt-status-codes: 418
script: |
github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'failed-workflow.yml',
ref: 'trunk',
inputs: {
run_id: '${{ github.run_id }}'
}
});