Skip to content

Commit

Permalink
Use ci-jobs Utility For ci.yml Matrix (woocommerce#43532)
Browse files Browse the repository at this point in the history
This adds support for using the `pnpm utils ci-jobs` command in our `ci.yml` file. One of the bigger benefits to this change too is that we're now distributing a bundled version of the utils tool. This lets us run it without actually having to install the repo and will let us speed up any workflows that currently do.
  • Loading branch information
ObliviousHarmony authored Jan 13, 2024
1 parent 4f8922a commit 758df48
Show file tree
Hide file tree
Showing 89 changed files with 3,805 additions and 1,214 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
*.tsx text eol=lf
*.css text eol=lf
*.scss text eol=lf
*.flf text eol=lf
104 changes: 61 additions & 43 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ concurrency:
group: '${{ github.workflow }}-${{ github.ref }}'
cancel-in-progress: true
jobs:
project-matrix:
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 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'
# Instead of running CI tasks on all projects indiscriminately, we use a command to detect
# which projects have changed and what kind of change occurred. This lets us build the
# 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'
outputs:
matrix: ${{ steps.project-matrix.outputs.matrix }}
lint-jobs: ${{ steps.project-jobs.outputs.lint-jobs }}
test-jobs: ${{ steps.project-jobs.outputs.test-jobs }}
steps:
- uses: 'actions/checkout@v3'
name: 'Checkout'
Expand All @@ -29,27 +30,24 @@ jobs:
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@v6
name: 'Build Matrix'
id: 'project-matrix'
id: 'project-jobs'
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.
const child_process = require( 'node:child_process' );
child_process.execSync( 'pnpm utils ci-jobs ' + baseRef );
project-lint-jobs:
name: 'Lint - ${{ matrix.projectName }}'
runs-on: 'ubuntu-20.04'
needs: 'project-matrix'
if: ${{ needs.project-matrix.outputs.matrix != '[]' }}
needs: 'project-jobs'
if: ${{ needs.project-jobs.outputs.lint-jobs != '[]' }}
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON( needs.project-matrix.outputs.matrix ) }}
include: ${{ fromJSON( needs.project-jobs.outputs.lint-jobs ) }}
steps:
- uses: 'actions/checkout@v3'
name: 'Checkout'
Expand All @@ -60,45 +58,65 @@ jobs:
id: '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 }}'
run: 'pnpm --filter="${{ matrix.projectName }}" ${{ matrix.command }}'
project-test-jobs:
name: 'Test - ${{ matrix.projectName }} - ${{ matrix.name }}'
runs-on: 'ubuntu-20.04'
needs: 'project-jobs'
if: ${{ needs.project-jobs.outputs.test-jobs != '[]' }}
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON( needs.project-jobs.outputs.test-jobs ) }}
steps:
- uses: 'actions/checkout@v3'
name: 'Checkout'
with:
fetch-depth: 0
- uses: './.github/actions/setup-woocommerce-monorepo'
name: 'Setup Monorepo'
id: 'setup-monorepo'
with:
install: '${{ matrix.projectName }}...'
build: '${{ matrix.projectName }}'
- 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:
if: ${{ matrix.testEnv.shouldCreate }}
env: ${{ matrix.testEnv.envVars }}
run: 'pnpm --filter="${{ matrix.projectName }}" ${{ matrix.testEnv.start }}'
- name: 'Test'
run: 'pnpm --filter="${{ matrix.projectName }}" ${{ matrix.command }}'
evaluate-project-jobs:
# 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'
# Since we are dynamically generating a matrix for the project jobs, 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 Job Statuses'
runs-on: 'ubuntu-20.04'
needs: [
'project-matrix',
'project-task-matrix'
'project-jobs',
'project-lint-jobs',
'project-test-jobs'
]
if: ${{ always() }}
steps:
- name: 'Check Matrix Success'
- name: 'Evaluation'
run: |
result="${{ needs.project-matrix.result }}"
result="${{ needs.project-jobs.result }}"
if [[ $result != "success" && $result != "skipped" ]]; then
echo "An error occurred generating the CI jobs."
exit 1
fi
result="${{ needs.project-lint-jobs.result }}"
if [[ $result != "success" && $result != "skipped" ]]; then
echo "An error occurred generating the CI matrix."
echo "One or more lint jobs have failed."
exit 1
fi
result="${{ needs.project-task-matrix.result }}"
result="${{ needs.project-test-jobs.result }}"
if [[ $result != "success" && $result != "skipped" ]]; then
echo "One or more jobs in the matrix has failed."
echo "One or more test jobs have failed."
exit 1
fi
echo "The matrix has completed successfully."
echo "All jobs have completed successfully."
Loading

0 comments on commit 758df48

Please sign in to comment.