From b8c2cf8cdec7ca2a6507866cac847cef5694bcf4 Mon Sep 17 00:00:00 2001 From: jonathansadowski Date: Tue, 9 Jul 2024 08:50:57 -0500 Subject: [PATCH] Update ci.yml to be dispatchable and skippable (#45331) Co-authored-by: Adrian Moldovan <3854374+adimoldovan@users.noreply.github.com> --- .github/workflows/ci.yml | 86 +++++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a18e5d23d7c..5c4ba6383d3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,12 @@ on: required: true default: 'default' type: string + workflow_dispatch: + inputs: + pr_simulate: + description: 'Would you like to run CI on a pull request? If so, enter the PR number here. If blank, the entire suite will be run.' + type: string + default: '' concurrency: group: '${{ github.workflow }}-${{ github.ref }}' @@ -23,6 +29,33 @@ env: FORCE_COLOR: 1 jobs: + dispatch-handler: + name: 'Handle dispatched workflow' + runs-on: 'ubuntu-20.04' + if: ${{ github.event_name == 'workflow_dispatch' && inputs.pr_simulate }} + outputs: + head: ${{ steps.pr-info.outputs.head }} + base: ${{ steps.pr-info.outputs.base }} + + steps: + - uses: actions/github-script@v7 + name: 'Grab PR info.' + id: 'pr-info' + env: + PR: ${{ inputs.pr_simulate }} + with: + retries: 3 + script: | + if ( ! process.env.PR ) { + return; + } + const PR = await github.rest.pulls.get( { + pull_number: process.env.PR, + repo: context.repo.repo, + owner: context.repo.owner, + } ); + core.setOutput( 'head', PR.data.head.ref ); + core.setOutput( 'base', PR.data.base.ref ); project-jobs: # Since this is a monorepo, not every pull request or change is going to impact every project. # Instead of running CI tasks on all projects indiscriminately, we use a command to detect @@ -30,6 +63,12 @@ jobs: # matrices that we can use to run CI tasks only on the projects that need them. name: 'Build Project Jobs' runs-on: 'ubuntu-20.04' + needs: 'dispatch-handler' + # Because forks of this repository may want to skip running this CI automatically, but still + # be able to run it via workflow_dispatch, if the SKIP_CI variable is truthy, and we're not + # running from a workflow_dispatch, we'll skip generating the project matrix and any jobs. + # Because dispatch-handler may be skipped, we need the always() here. + if: ${{ always() && ( github.event_name == 'workflow_dispatch' || ! vars.SKIP_CI ) }} outputs: lint-jobs: ${{ steps.project-jobs.outputs.lint-jobs }} test-jobs: ${{ steps.project-jobs.outputs.test-jobs }} @@ -39,16 +78,24 @@ jobs: name: 'Checkout' with: fetch-depth: 0 + # If the workflow wasn't triggered by dispatch, this will be empty and use defaults. + ref: ${{ needs.dispatch-handler.outputs.head }} + - uses: './.github/actions/setup-woocommerce-monorepo' name: 'Setup Monorepo' with: php-version: false # We don't want to waste time installing PHP since we aren't using it in this job. + - uses: actions/github-script@v7 name: 'Build Matrix' id: 'project-jobs' + env: + PR_SIM: ${{ needs.dispatch-handler.outputs.base }} with: script: | - let baseRef = ${{ toJson( github.base_ref ) }}; + const prSim = process.env.PR_SIM; + + let baseRef = prSim || ${{ toJson( github.base_ref ) }}; if ( baseRef ) { baseRef = `--base-ref origin/${ baseRef }`; } @@ -71,23 +118,35 @@ jobs: githubEvent = trigger; } + // Override the event 'workflow_dispatch' event type if we're simulating a PR. + if ( prSim ) { + githubEvent = 'pull_request'; + } + const child_process = require( 'node:child_process' ); child_process.execSync( `pnpm utils ci-jobs ${ baseRef } --event ${ githubEvent }` ); - + project-lint-jobs: name: "Lint - ${{ matrix.projectName }} ${{ matrix.optional && ' (optional)' || ''}}" runs-on: 'ubuntu-20.04' - needs: 'project-jobs' - if: ${{ needs.project-jobs.outputs.lint-jobs != '[]' && github.event_name == 'pull_request' }} + needs: [ + 'project-jobs', + 'dispatch-handler' + ] + # Because dispatch-handler may be skipped, we need the always() here. + if: ${{ always() && needs.project-jobs.outputs.lint-jobs != '[]' && ( github.event_name == 'pull_request' || inputs.pr_simulate != '' ) }} strategy: fail-fast: false matrix: include: ${{ fromJSON( needs.project-jobs.outputs.lint-jobs ) }} + steps: - uses: 'actions/checkout@v4' name: 'Checkout' with: fetch-depth: 0 + # If the workflow wasn't triggered by dispatch, this will be empty and use defaults. + ref: ${{ needs.dispatch-handler.outputs.head }} - uses: './.github/actions/setup-woocommerce-monorepo' name: 'Setup Monorepo' @@ -97,20 +156,27 @@ jobs: - name: 'Lint' run: 'pnpm --filter="${{ matrix.projectName }}" ${{ matrix.command }}' - + project-test-jobs: name: "${{ matrix.name }}" runs-on: 'ubuntu-20.04' - needs: 'project-jobs' - if: ${{ needs.project-jobs.outputs.test-jobs != '[]' }} + needs: [ + 'project-jobs', + 'dispatch-handler' + ] + if: ${{ always() && needs.project-jobs.outputs.test-jobs != '[]' }} env: ${{ matrix.testEnv.envVars }} strategy: fail-fast: false matrix: include: ${{ fromJSON( needs.project-jobs.outputs.test-jobs ) }} + steps: - uses: 'actions/checkout@v4' name: 'Checkout' + with: + # If the workflow wasn't triggered by dispatch, this will be empty and use defaults. + ref: ${{ needs.dispatch-handler.outputs.head }} - uses: './.github/actions/setup-woocommerce-monorepo' name: 'Install Monorepo' @@ -233,7 +299,7 @@ jobs: 'project-lint-jobs', 'project-test-jobs', ] - if: ${{ always() && github.event_name != 'pull_request' }} + if: ${{ always() && github.event_name != 'pull_request' && ! github.event.pull_request.head.repo.fork }} steps: - uses: 'actions/checkout@v4' name: 'Checkout' @@ -270,7 +336,7 @@ jobs: 'project-jobs', 'project-test-jobs', ] - if: ${{ always() && needs.project-jobs.outputs.report-jobs != '[]' }} + if: ${{ always() && needs.project-jobs.outputs.report-jobs != '[]' && ! github.event.pull_request.head.repo.fork }} strategy: fail-fast: false matrix: @@ -324,7 +390,7 @@ jobs: -f suite="$REPORT_NAME" \ -f report_title="$REPORT_TITLE" \ --repo woocommerce/woocommerce-test-reports - + report-flaky-tests: name: 'Create issues for flaky tests' if: ${{ !cancelled() && ! github.event.pull_request.head.repo.fork }}