From 9ac0c8367aee5fd83630c27ebe52adade6c6436a Mon Sep 17 00:00:00 2001 From: Joey Perrott Date: Mon, 18 Nov 2024 17:27:33 +0000 Subject: [PATCH] refactor(ng-dev): allow for perf workflows to be run for individual workflows Allow individual workflows to be run, and fan out CI job to multiple jobs via matrix. --- .github/workflows/perf.yml | 24 ++++++++++++++++++++++-- .ng-dev/dx-perf-workflows.yml | 6 ++++-- ng-dev/perf/workflow/cli.ts | 32 +++++++++++++++++++++++--------- ng-dev/perf/workflow/loader.ts | 2 +- 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 7f4f0e857..fae343ec6 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -12,9 +12,11 @@ defaults: shell: bash jobs: - workflow-perf: + list: timeout-minutes: 30 runs-on: ubuntu-latest + outputs: + workflows: ${{ steps.workflows.outputs.workflows }} steps: # Because the checkout and setup node action is contained in the dev-infra repo, we must # checkout the repo to be able to run the action we have created. Other repos will skip @@ -23,4 +25,22 @@ jobs: - uses: ./github-actions/npm/checkout-and-setup-node - uses: ./github-actions/bazel/setup - run: yarn install --immutable - - run: yarn ng-dev perf workflows --json + - id: workflows + run: echo "workflows=$(yarn ng-dev perf workflows --list)" >> "$GITHUB_OUTPUT" + + workflow: + timeout-minutes: 30 + runs-on: ubuntu-latest + needs: list + strategy: + matrix: + workflow: ${{ fromJSON(needs.list.outputs.workflows) }} + steps: + # Because the checkout and setup node action is contained in the dev-infra repo, we must + # checkout the repo to be able to run the action we have created. Other repos will skip + # this step. + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: ./github-actions/npm/checkout-and-setup-node + - uses: ./github-actions/bazel/setup + - run: yarn install --immutable + - run: yarn ng-dev perf workflows --name ${{ matrix.workflow }} diff --git a/.ng-dev/dx-perf-workflows.yml b/.ng-dev/dx-perf-workflows.yml index a1ebf0af7..34a6f5c96 100644 --- a/.ng-dev/dx-perf-workflows.yml +++ b/.ng-dev/dx-perf-workflows.yml @@ -1,5 +1,6 @@ workflows: - - name: Rerun a test + rerun: + name: Rerun a test prepare: - bazel clean; - bazel build //ng-dev/utils/test; @@ -10,7 +11,8 @@ workflows: cleanup: - git apply -R .ng-dev/perf-tests/test-rerun.diff; - - name: Build Everything + build-everything: + name: Build Everything prepare: - bazel clean; workflow: diff --git a/ng-dev/perf/workflow/cli.ts b/ng-dev/perf/workflow/cli.ts index cbeeeab2c..cd4ea3018 100644 --- a/ng-dev/perf/workflow/cli.ts +++ b/ng-dev/perf/workflow/cli.ts @@ -14,7 +14,8 @@ import {determineRepoBaseDirFromCwd} from '../../utils/repo-directory.js'; interface WorkflowsParams { configFile: string; - json: boolean; + list: boolean; + name?: string; } /** Builds the checkout pull request command. */ @@ -25,25 +26,38 @@ function builder(yargs: Argv) { type: 'string', description: 'The path to the workflow definitions in a yml file', }) - .option('json', { + .option('list', { default: false, type: 'boolean', - description: 'Whether to output the results as a json object', + description: 'Whether to get back a list of workflows that can be executed', + }) + .option('name', { + type: 'string', + description: 'A specific workflow to run by name', }); } /** Handles the checkout pull request command. */ -async function handler({configFile, json}: WorkflowsParams) { +async function handler({configFile, list, name}: WorkflowsParams) { const workflows = await loadWorkflows(join(determineRepoBaseDirFromCwd(), configFile)); + + if (list) { + process.stdout.write(JSON.stringify(Object.keys(workflows))); + return; + } + + if (name) { + const {duration} = await measureWorkflow(workflows[name]); + process.stdout.write(JSON.stringify({[name]: duration})); + return; + } + const results: {[key: string]: number} = {}; - for (const workflow of workflows) { + for (const workflow of Object.values(workflows)) { const {name, duration} = await measureWorkflow(workflow); results[name] = duration; } - - if (json) { - process.stdout.write(JSON.stringify(results)); - } + process.stdout.write(JSON.stringify(results)); } /** yargs command module for checking out a PR. */ diff --git a/ng-dev/perf/workflow/loader.ts b/ng-dev/perf/workflow/loader.ts index 7829441ec..25b6685f3 100644 --- a/ng-dev/perf/workflow/loader.ts +++ b/ng-dev/perf/workflow/loader.ts @@ -10,5 +10,5 @@ export interface Workflow { export async function loadWorkflows(src: string) { const rawWorkflows = await readFile(src, {encoding: 'utf-8'}); - return parse(rawWorkflows).workflows as Workflow[]; + return parse(rawWorkflows).workflows as {[key: string]: Workflow}; }