name: 'CI' on: pull_request: push: branches: - 'trunk' - 'release/*' concurrency: group: '${{ github.workflow }}-${{ github.ref }}' cancel-in-progress: true jobs: project-matrix: # 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 script to detect # which projects have changed and what kind of change occurred. This lets us build a # matrix that we can use to run CI tasks only on the projects that need them. name: 'Build Project Matrix' runs-on: 'ubuntu-20.04' outputs: matrix: ${{ steps.project-matrix.outputs.matrix }} steps: - uses: 'actions/checkout@v3' name: 'Checkout' with: fetch-depth: 0 - uses: './.github/actions/setup-woocommerce-monorepo' with: php-version: false # We don't want to waste time installing PHP since we aren't using it in this job. name: 'Setup Monorepo' - uses: actions/github-script@v6 id: 'project-matrix' name: 'Build Matrix' with: script: | let baseRef = ${{ toJson( github.base_ref ) }}; if ( baseRef ) { baseRef = 'origin/' + baseRef; } const buildCIMatrix = require( './.github/workflows/scripts/build-ci-matrix' ); core.setOutput( 'matrix', JSON.stringify( await buildCIMatrix( baseRef ) ) ); project-task-matrix: # This is the actual CI job that will be ran against every project with applicable changes. # Note that we only run the tasks that have commands set. Our script will set them if # they are needed and so all the workflow needs to do is run them. name: '${{ matrix.projectName }} - ${{ matrix.taskName }}' # Note: GitHub doesn't process expressions for skipped jobs so when there's no matrix the name will literally be this. runs-on: 'ubuntu-20.04' needs: 'project-matrix' if: ${{ needs.project-matrix.outputs.matrix != '[]' }} strategy: fail-fast: false matrix: include: ${{ fromJSON( needs.project-matrix.outputs.matrix ) }} steps: - uses: 'actions/checkout@v3' name: 'Checkout' with: fetch-depth: 0 - uses: './.github/actions/setup-woocommerce-monorepo' id: 'setup-monorepo' name: 'Setup Monorepo' with: install: '${{ matrix.projectName }}...' build: '${{ matrix.projectName }}' - name: 'Lint' if: ${{ ! cancelled() && matrix.lintCommand && steps.setup-monorepo.conclusion == 'success' }} run: 'pnpm --filter="${{ matrix.projectName }}" ${{ matrix.lintCommand }}' - name: 'Prepare Test Environment' id: 'prepare-test-environment' if: ${{ ! cancelled() && matrix.testEnvCommand && steps.setup-monorepo.conclusion == 'success' }} env: ${{ matrix.testEnvVars }} run: 'pnpm --filter="${{ matrix.projectName }}" ${{ matrix.testEnvCommand }}' - name: 'Test - JS' if: ${{ ! cancelled() && matrix.jsTestCommand && steps.setup-monorepo.conclusion == 'success' && ( ! matrix.testEnvCommand || steps.prepare-test-environment.conclusion == 'success' ) }} run: 'pnpm --filter="${{ matrix.projectName }}" ${{ matrix.jsTestCommand }}' - name: 'Test - PHP' if: ${{ ! cancelled() && matrix.phpTestCommand && steps.setup-monorepo.conclusion == 'success' && ( ! matrix.testEnvCommand || steps.prepare-test-environment.conclusion == 'success' ) }} run: 'pnpm --filter="${{ matrix.projectName }}" ${{ matrix.phpTestCommand }}' project-task-matrix-evaluation: # In order to add a required status check we need a consistent job that we can grab onto. # Since we are dynamically generating a project matrix, however, we can't rely on # on any specific job being present. We can get around this limitation by using # a job that runs after all the others and either passes or fails based on the # results of the other jobs in the workflow. name: 'Evaluate Project Matrix' runs-on: 'ubuntu-20.04' needs: [ 'project-matrix', 'project-task-matrix' ] if: ${{ always() }} steps: - name: 'Check Matrix Success' run: | result="${{ needs.project-matrix.result }}" if [[ $result != "success" && $result != "skipped" ]]; then echo "An error occurred generating the CI matrix." exit 1 fi result="${{ needs.project-task-matrix.result }}" if [[ $result != "success" && $result != "skipped" ]]; then echo "One or more jobs in the matrix has failed." exit 1 fi echo "The matrix has completed successfully."