From 0bb443865e03f3265e63b3ba6eb5db3feee9d567 Mon Sep 17 00:00:00 2001 From: Adrian Moldovan <3854374+adimoldovan@users.noreply.github.com> Date: Tue, 11 Aug 2026 20:43:51 +0300 Subject: [PATCH] Build/Test Tools: Stop testing downgrades in the upgrade testing workflow. When the workflow is dispatched with a specific version, the matrices still spawn jobs that start from a newer version. Those are downgrades, and `wp core update` declines to move backwards without `--force`, so the jobs pass without testing anything. Build the list of starting versions for each matrix from the version being tested, dropping every version that is not older than it, and skip a job whose list ends up empty. --- .github/workflows/upgrade-testing.yml | 117 +++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 11 deletions(-) diff --git a/.github/workflows/upgrade-testing.yml b/.github/workflows/upgrade-testing.yml index 4a077ed452a1a..52cde95e0e5e5 100644 --- a/.github/workflows/upgrade-testing.yml +++ b/.github/workflows/upgrade-testing.yml @@ -57,11 +57,102 @@ permissions: {} # - 5.6.x Docker containers are available and work, but 5.6 only accounts for ~2.3% of installs as of 12/6/2024.defaults: # - 5.7.x accounts for ~20% of installs, so this is used below instead. jobs: + # Builds the list of starting versions for each matrix below. Drops every version that is not older than the target + # version, because upgrading from one of those is a downgrade. A job whose list ends up empty is skipped. + # + # A major target (6.4 or 6.4.0) drops its own branch, because no upgrade would occur. + # + # A minor target (6.4.4) keeps its own branch, because 6.4 to 6.4.4 is a real upgrade. The called workflow runs + # `wp core update --minor` before the final upgrade step, so the minor update performs that upgrade and the final + # upgrade step is a no-op. When the target is not the newest release on its branch, the minor update overshoots + # the target and the target is never installed. + # + # "latest" and "nightly" drop nothing. Any other unrecognized target is treated the same way, with a warning. + build-test-matrix: + name: Build Test Matrix + runs-on: ubuntu-24.04 + permissions: {} + if: ${{ github.repository == 'WordPress/wordpress-develop' }} + timeout-minutes: 5 + outputs: + recent-releases: ${{ steps.versions.outputs.recent-releases }} + wp-6x: ${{ steps.versions.outputs.wp-6x }} + wp-5x-php-7x: ${{ steps.versions.outputs.wp-5x-php-7x }} + wp-5x-php-8x: ${{ steps.versions.outputs.wp-5x-php-8x }} + oldest-wp: ${{ steps.versions.outputs.oldest-wp }} + + steps: + - name: Drop the versions that are not older than the version being tested + id: versions + env: + NEW_VERSION: ${{ inputs.new-version && inputs.new-version || 'latest' }} + # The versions each job below starts from. See the comment on the job for why those versions are tested. + RECENT_RELEASES: '7.0 7.1' # upgrade-tests-recent-releases + WP_6X: '6.0 6.3 6.4 6.5' # upgrade-tests-wp-6x-mysql + WP_5X_PHP_7X: '5.0 5.1 5.3 5.4 5.5 5.6 5.9' # upgrade-tests-wp-5x-php-7x-mysql + WP_5X_PHP_8X: '5.3 5.4 5.5 5.6 5.9' # upgrade-tests-wp-5x-php-8x-mysql + OLDEST_WP: '4.7' # upgrade-tests-oldest-wp-mysql + run: | + # Branches are compared as a single number so that 7.0 sorts above 6.9. The spacing leaves room for a + # pre-release to sort between its own branch and the one before it. The base is forced to 10 so that a + # version number with a leading zero is not read as an invalid octal value. + if [[ "$NEW_VERSION" =~ ^v?([0-9]+)\.([0-9]+)(\.([0-9]+))?$ ]]; then + target=$(( 10#${BASH_REMATCH[1]} * 10000 + 10#${BASH_REMATCH[2]} * 100 )) + + # A version with no patch number, or a patch number of 0, is a major release: drop its own branch too. + if [[ -z "${BASH_REMATCH[4]}" || "${BASH_REMATCH[4]}" == "0" ]]; then + target=$(( target - 1 )) + fi + else + # Sorts above every version in the lists above, so nothing is dropped. + target=999999 + + if [[ "$NEW_VERSION" != 'latest' && "$NEW_VERSION" != 'nightly' ]]; then + echo "::warning::\"${NEW_VERSION}\" was not read as a version number, so every version will be tested." + fi + fi + + # Writes the versions of $2 that are older than the target to the $1 output, as a JSON array. + filter() { + local kept='' wp branch + local -a versions + + # Guards against a list being renamed in the environment above without updating the call below, which + # would otherwise skip the whole job in silence. + [[ -n "$2" ]] || { echo "::error::No versions are listed for the ${1} matrix."; exit 1; } + + read -ra versions <<< "$2" + + for wp in "${versions[@]}"; do + [[ "$wp" =~ ^([0-9]+)\.([0-9]+) ]] || continue + branch=$(( 10#${BASH_REMATCH[1]} * 10000 + 10#${BASH_REMATCH[2]} * 100 )) + + # A pre-release sorts just below its own branch, so 7.1-RC2 is tested against a target of 7.1 but + # not against 7.0.1. + if [[ "$wp" == *-* ]]; then + branch=$(( branch - 1 )) + fi + + if (( branch <= target )); then + kept+="\"${wp}\"," + fi + done + + echo "$1=[${kept%,}]" >> "$GITHUB_OUTPUT" + } + + filter recent-releases "$RECENT_RELEASES" + filter wp-6x "$WP_6X" + filter wp-5x-php-7x "$WP_5X_PHP_7X" + filter wp-5x-php-8x "$WP_5X_PHP_8X" + filter oldest-wp "$OLDEST_WP" + # Tests the full list of PHP/MySQL combinations for the two most recent versions of WordPress. upgrade-tests-recent-releases: name: ${{ matrix.wp }} to ${{ inputs.new-version && inputs.new-version || 'latest' }} uses: ./.github/workflows/reusable-upgrade-testing.yml - if: ${{ github.repository == 'WordPress/wordpress-develop' }} + if: ${{ github.repository == 'WordPress/wordpress-develop' && needs.build-test-matrix.outputs.recent-releases != '[]' }} + needs: [ build-test-matrix ] permissions: contents: read strategy: @@ -71,7 +162,7 @@ jobs: php: [ '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ] db-type: [ 'mysql' ] db-version: [ '5.7', '8.0', '8.4', '9.7' ] - wp: [ '7.0', '7.1' ] + wp: ${{ fromJSON( needs.build-test-matrix.outputs.recent-releases ) }} multisite: [ false, true ] with: os: ${{ matrix.os }} @@ -86,7 +177,8 @@ jobs: upgrade-tests-wp-6x-mysql: name: ${{ matrix.wp }} to ${{ inputs.new-version && inputs.new-version || 'latest' }} uses: ./.github/workflows/reusable-upgrade-testing.yml - if: ${{ github.repository == 'WordPress/wordpress-develop' }} + if: ${{ github.repository == 'WordPress/wordpress-develop' && needs.build-test-matrix.outputs.wp-6x != '[]' }} + needs: [ build-test-matrix ] permissions: contents: read strategy: @@ -96,7 +188,7 @@ jobs: php: [ '7.4', '8.0', '8.4' ] db-type: [ 'mysql' ] db-version: [ '5.7', '8.4' ] - wp: [ '6.0', '6.3', '6.4', '6.5' ] + wp: ${{ fromJSON( needs.build-test-matrix.outputs.wp-6x ) }} multisite: [ false, true ] with: os: ${{ matrix.os }} @@ -111,7 +203,8 @@ jobs: upgrade-tests-wp-5x-php-7x-mysql: name: ${{ matrix.wp }} to ${{ inputs.new-version && inputs.new-version || 'latest' }} uses: ./.github/workflows/reusable-upgrade-testing.yml - if: ${{ github.repository == 'WordPress/wordpress-develop' }} + if: ${{ github.repository == 'WordPress/wordpress-develop' && needs.build-test-matrix.outputs.wp-5x-php-7x != '[]' }} + needs: [ build-test-matrix ] permissions: contents: read strategy: @@ -121,7 +214,7 @@ jobs: php: [ '7.4' ] db-type: [ 'mysql' ] db-version: [ '5.7', '8.4' ] - wp: [ '5.0', '5.1', '5.3', '5.4', '5.5', '5.6', '5.9' ] + wp: ${{ fromJSON( needs.build-test-matrix.outputs.wp-5x-php-7x ) }} multisite: [ false, true ] with: os: ${{ matrix.os }} @@ -140,7 +233,8 @@ jobs: upgrade-tests-wp-5x-php-8x-mysql: name: ${{ matrix.wp }} to ${{ inputs.new-version && inputs.new-version || 'latest' }} uses: ./.github/workflows/reusable-upgrade-testing.yml - if: ${{ github.repository == 'WordPress/wordpress-develop' }} + if: ${{ github.repository == 'WordPress/wordpress-develop' && needs.build-test-matrix.outputs.wp-5x-php-8x != '[]' }} + needs: [ build-test-matrix ] permissions: contents: read strategy: @@ -150,7 +244,7 @@ jobs: php: [ '8.0', '8.4' ] db-type: [ 'mysql' ] db-version: [ '5.7', '8.4' ] - wp: [ '5.3', '5.4', '5.5', '5.6', '5.9' ] + wp: ${{ fromJSON( needs.build-test-matrix.outputs.wp-5x-php-8x ) }} multisite: [ false, true ] with: os: ${{ matrix.os }} @@ -170,7 +264,8 @@ jobs: upgrade-tests-oldest-wp-mysql: name: ${{ matrix.wp }} to ${{ inputs.new-version && inputs.new-version || 'latest' }} uses: ./.github/workflows/reusable-upgrade-testing.yml - if: ${{ github.repository == 'WordPress/wordpress-develop' }} + if: ${{ github.repository == 'WordPress/wordpress-develop' && needs.build-test-matrix.outputs.oldest-wp != '[]' }} + needs: [ build-test-matrix ] permissions: contents: read strategy: @@ -180,7 +275,7 @@ jobs: php: [ '7.4' ] db-type: [ 'mysql' ] db-version: [ '5.7', '8.0', '8.4', '9.7' ] - wp: [ '4.7' ] + wp: ${{ fromJSON( needs.build-test-matrix.outputs.oldest-wp ) }} multisite: [ false, true ] with: os: ${{ matrix.os }} @@ -197,7 +292,7 @@ jobs: permissions: actions: read contents: read - needs: [ upgrade-tests-recent-releases, upgrade-tests-wp-6x-mysql, upgrade-tests-wp-5x-php-7x-mysql, upgrade-tests-wp-5x-php-8x-mysql, upgrade-tests-oldest-wp-mysql ] + needs: [ build-test-matrix, upgrade-tests-recent-releases, upgrade-tests-wp-6x-mysql, upgrade-tests-wp-5x-php-7x-mysql, upgrade-tests-wp-5x-php-8x-mysql, upgrade-tests-oldest-wp-mysql ] 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' }}