Make WordPress Core

Changeset 63438


Ignore:
Timestamp:
09/02/2026 06:21:17 PM (2 weeks ago)
Author:
lancewillett
Message:

Build/Test Tools: Allow PHPUnit workflows to test other repositories.

Add optional repository and ref inputs to the reusable PHPUnit and Gutenberg preparation workflows. Add a same-run overlay artifact for caller-provided tests.

Name prepared Gutenberg artifacts by ref, reject refs that cannot form artifact names, and retry Gutenberg downloads for older branches. Existing callers retain their current behavior.

Developed in: https://github.com/WordPress/wordpress-develop/pull/12862

Props lucatume.
Fixes #65964.

Location:
trunk/.github/workflows
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/.github/workflows/reusable-phpunit-tests-v3.yml

    r63412 r63438  
    1414        type: 'string'
    1515        default: 'ubuntu-24.04'
     16      repository:
     17        description: 'The repository to check out and test. Defaults to the repository calling this workflow.'
     18        required: false
     19        type: 'string'
     20        default: ''
     21      # Also composes the Gutenberg build name, under the producer's constraint: a valid
     22      # artifact name, so no slashes and none of : < > | * ? "
     23      ref:
     24        description: 'The branch, tag, or SHA to check out. Defaults to the ref that triggered the calling workflow.'
     25        required: false
     26        type: 'string'
     27        default: ''
    1628      php:
    1729        description: 'The version of PHP to use, in the format of X.Y'
     
    8092      gutenberg-sha:
    8193        description: 'The immutable Gutenberg source SHA verified by the calling workflow.'
     94        required: false
     95        type: string
     96        default: ''
     97      overlay-artifact:
     98        description: 'The name of a same-workflow artifact whose contents are unpacked over the checkout. Optional: for callers whose test files are not part of the repository being tested.'
    8299        required: false
    83100        type: string
     
    113130  #
    114131  # Performs the following steps:
     132  # - Requires a ref when the caller points at another repository.
    115133  # - Sets environment variables.
    116134  # - Checks out the repository.
     135  # - Unpacks the caller-provided overlay artifact over the checkout, if any.
    117136  # - Downloads the prepared Gutenberg build provided by the calling workflow.
    118137  # - Sets up Node.js.
     
    141160
    142161    steps:
     162      # `ref` otherwise falls back to checkout's own default, which for another repository is
     163      # its default branch: a "WordPress 6.2" job would test trunk and report green.
     164      - name: Require a ref when testing another repository
     165        if: ${{ inputs.repository != '' && inputs.ref == '' }}
     166        run: |
     167          echo 'Testing another repository needs an explicit ref.' >&2
     168          exit 1
     169
     170      # `ref` also composes the Gutenberg artifact name, so reject what that name cannot carry
     171      # here rather than at a download step the job only reaches minutes later.
     172      - name: Require a ref the artifact name accepts
     173        if: ${{ inputs.ref != '' }}
     174        env:
     175          REF: ${{ inputs.ref }}
     176        run: |
     177          invalid='[/:<>|*?"\]'
     178          if [[ "$REF" =~ $invalid ]]; then
     179            echo "A ref that names an artifact cannot contain / : < > | * ? \" \\ - received: $REF" >&2
     180            exit 1
     181          fi
     182
    143183      - name: Configure environment variables
    144184        run: |
     
    149189        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
    150190        with:
     191          repository: ${{ inputs.repository || github.repository }}
     192          ref: ${{ inputs.ref }}
    151193          show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
    152194          persist-credentials: false
     195
     196      # If the caller specifies an overlay artifact then unpack it over the checkout.
     197      - name: Download overlay artifact
     198        if: inputs.overlay-artifact != ''
     199        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
     200        with:
     201          # Without a run ID, this action reads only from the caller's current workflow run.
     202          name: ${{ inputs.overlay-artifact }}
     203          path: .
     204          digest-mismatch: error
    153205
    154206      # Only WordPress 7.0+ include Gutenberg-maintained assets from a built zip file.
     
    157209        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
    158210        with:
    159           name: gutenberg-build
     211          # Every branch in a run shares one artifact namespace, so the producer names each
     212          # build after the ref it came from. Compose the same name here rather than taking
     213          # it as an input: the two sides already agree on `ref`.
     214          name: gutenberg-build${{ inputs.ref && format( '-{0}', inputs.ref ) || '' }}
    160215          path: gutenberg
    161216          digest-mismatch: error
  • trunk/.github/workflows/reusable-prepare-gutenberg.yml

    r62862 r63438  
    77on:
    88  workflow_call:
     9    inputs:
     10      repository:
     11        description: 'The repository to check out. Defaults to the repository calling this workflow.'
     12        required: false
     13        type: 'string'
     14        default: ''
     15      # Names the uploaded build too, so it must also be a valid artifact name: no slashes,
     16      # and none of : < > | * ? " — a `refs/heads/trunk` or `feature/x` value fails the upload.
     17      ref:
     18        description: 'The branch, tag, or SHA to check out. Defaults to the commit that started the calling workflow run.'
     19        required: false
     20        type: 'string'
     21        default: ''
    922    outputs:
    1023      gutenberg-sha:
     
    2033    name: Gutenberg
    2134    runs-on: ubuntu-24.04
    22     timeout-minutes: 10
     35    # Two download attempts of up to six minutes each, where download.js retries internally.
     36    timeout-minutes: 15
    2337    outputs:
    2438      gutenberg-sha: ${{ steps.download.outputs.gutenberg-sha }}
     
    2741
    2842    steps:
     43      # `ref` otherwise falls back to this run's commit, which another repository does not have.
     44      - name: Require a ref when preparing another repository
     45        if: ${{ inputs.repository != '' && inputs.ref == '' }}
     46        run: |
     47          echo 'Preparing another repository needs an explicit ref.' >&2
     48          exit 1
     49
     50      # The upload names the artifact after `ref` and is this job's last step, so an unusable
     51      # value would otherwise fail only once the whole download and verify has already run.
     52      - name: Require a ref the artifact name accepts
     53        if: ${{ inputs.ref != '' }}
     54        env:
     55          REF: ${{ inputs.ref }}
     56        run: |
     57          invalid='[/:<>|*?"\]'
     58          if [[ "$REF" =~ $invalid ]]; then
     59            echo "A ref that names an artifact cannot contain / : < > | * ? \" \\ - received: $REF" >&2
     60            exit 1
     61          fi
     62
    2963      - name: Checkout repository
    3064        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
    3165        with:
    32           # Resolve the Gutenberg ref from the exact commit that started this workflow run.
    33           ref: ${{ github.sha }}
     66          repository: ${{ inputs.repository || github.repository }}
     67          # Resolve the Gutenberg ref from the exact commit that started this workflow run,
     68          # unless the caller is preparing a build for a repository or branch of its own.
     69          ref: ${{ inputs.ref || github.sha }}
    3470          show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
    3571          persist-credentials: false
     
    4379        id: download
    4480        run: |
    45           node tools/gutenberg/download.js
     81          # Branches whose download.js predates the in-script retry stream the blob straight
     82          # into tar in a single attempt, so an interrupted stream fails the run outright.
     83          # One retry, not two: where download.js does retry, it already allows three tries of
     84          # two minutes each, and a third attempt here would outrun `timeout-minutes` and have
     85          # the job killed rather than reported.
     86          if ! node tools/gutenberg/download.js; then
     87            echo 'Gutenberg download failed; retrying in 5 seconds...'
     88            sleep 5
     89            node tools/gutenberg/download.js
     90          fi
     91
    4692          gutenberg_sha="$(tr -d '\n' < gutenberg/.gutenberg-hash)"
    4793          if [[ ! "$gutenberg_sha" =~ ^[a-fA-F0-9]{40}$ ]]; then
     
    54100        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
    55101        with:
    56           name: gutenberg-build
     102          # Every branch in a run shares one artifact namespace, so name the build after the
     103          # ref it came from. The PHPUnit consumer composes the same name from its own `ref`,
     104          # so the name is never passed between them.
     105          name: gutenberg-build${{ inputs.ref && format( '-{0}', inputs.ref ) || '' }}
    57106          path: gutenberg/
    58107          if-no-files-found: error
Note: See TracChangeset for help on using the changeset viewer.