Skip to content

Commit 1ab6cf9

Browse files
committed
feat(ng-dev): add support for uploading results of workflow testing to database
Uploads the workflow test results our database when a specific github sha is provided as a reference key for the data.
1 parent 01c8c16 commit 1ab6cf9

File tree

9 files changed

+361
-51
lines changed

9 files changed

+361
-51
lines changed

.github/workflows/perf.yml

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
name: Performance Tracking
22

33
on:
4+
pull_request:
45
push:
56
branches:
6-
- main
7+
- add-uploading
78

8-
permissions: {}
9+
permissions: {
10+
id-token: write
11+
}
912

1013
defaults:
1114
run:
@@ -18,15 +21,16 @@ jobs:
1821
outputs:
1922
workflows: ${{ steps.workflows.outputs.workflows }}
2023
steps:
21-
# Because the checkout and setup node action is contained in the dev-infra repo, we must
22-
# checkout the repo to be able to run the action we have created. Other repos will skip
23-
# this step.
24-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
25-
- uses: ./github-actions/npm/checkout-and-setup-node
26-
- uses: ./github-actions/bazel/setup
27-
- run: yarn install --immutable
28-
- id: workflows
29-
run: echo "workflows=$(yarn ng-dev perf workflows --list)" >> "$GITHUB_OUTPUT"
24+
25+
- uses: 'google-github-actions/auth@v2'
26+
with:
27+
project_id: 'internal-200822'
28+
workload_identity_provider: 'projects/823469418460/locations/global/workloadIdentityPools/measurables-tracking/providers/angular'
29+
service_account: '[email protected]'
30+
- run: gcloud auth list
31+
- name: Setup tmate session
32+
uses: mxschmitt/action-tmate@v3
33+
3034

3135
workflow:
3236
timeout-minutes: 30
@@ -42,5 +46,10 @@ jobs:
4246
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
4347
- uses: ./github-actions/npm/checkout-and-setup-node
4448
- uses: ./github-actions/bazel/setup
49+
- uses: 'google-github-actions/auth@v2'
50+
with:
51+
project_id: 'internal-200822'
52+
workload_identity_provider: 'projects/823469418460/locations/global/workloadIdentityPools/measurables-tracking/providers/angular'
53+
service_account: '[email protected]'
4554
- run: yarn install --immutable
46-
- run: yarn ng-dev perf workflows --name ${{ matrix.workflow }}
55+
- run: yarn ng-dev perf workflows --name ${{ matrix.workflow }} --commit-sha ${{github.sha}}

ng-dev/BUILD.bazel

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ NG_DEV_EXTERNALS = [
66
# `typescript` is external because we want the project to provide a TypeScript version.
77
# TODO: Figure out how we want to manage dependencies for the dev-infra tool.
88
"typescript",
9-
# Package uses `__filename` and `__dirname` and cannot be bundled in ESM. We do not
9+
# Packages using `__filename` and `__dirname` and cannot be bundled in ESM. We do not
1010
# intend to provide interop globals for this as it could hide other significant issues.
1111
"@yarnpkg/lockfile",
12+
"@google-cloud/spanner",
1213
]
1314

1415
ts_library(

ng-dev/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
}
1616
},
1717
"dependencies": {
18+
"@google-cloud/spanner": "7.16.0",
1819
"@octokit/rest": "21.0.2",
1920
"@types/semver": "^7.3.6",
2021
"@types/supports-color": "^8.1.1",

ng-dev/perf/workflow/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ ts_library(
66
visibility = ["//ng-dev:__subpackages__"],
77
deps = [
88
"//ng-dev/utils",
9+
"@npm//@google-cloud/spanner",
910
"@npm//@types/node",
1011
"@npm//@types/yargs",
1112
"@npm//yaml",

ng-dev/perf/workflow/cli.ts

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@ import {measureWorkflow} from './workflow.js';
1111
import {loadWorkflows} from './loader.js';
1212
import {join} from 'path';
1313
import {determineRepoBaseDirFromCwd} from '../../utils/repo-directory.js';
14+
import {addWorkflowPerformanceResult} from './database.js';
15+
import {Spinner} from '../../utils/spinner.js';
1416

1517
interface WorkflowsParams {
1618
configFile: string;
1719
list: boolean;
1820
name?: string;
21+
commitSha?: string;
1922
}
2023

2124
/** Builds the checkout pull request command. */
@@ -34,30 +37,48 @@ function builder(yargs: Argv) {
3437
.option('name', {
3538
type: 'string',
3639
description: 'A specific workflow to run by name',
40+
})
41+
.option('commit-sha' as 'commitSha', {
42+
type: 'string',
43+
description: 'The commit sha to associate the measurement with, uploading it to our database',
3744
});
3845
}
3946

4047
/** Handles the checkout pull request command. */
41-
async function handler({configFile, list, name}: WorkflowsParams) {
48+
async function handler({configFile, list, name, commitSha}: WorkflowsParams) {
4249
const workflows = await loadWorkflows(join(determineRepoBaseDirFromCwd(), configFile));
4350

4451
if (list) {
4552
process.stdout.write(JSON.stringify(Object.keys(workflows)));
4653
return;
4754
}
4855

56+
const results: {name: string; value: number}[] = [];
57+
4958
if (name) {
50-
const {duration} = await measureWorkflow(workflows[name]);
51-
process.stdout.write(JSON.stringify({[name]: duration}));
52-
return;
59+
const {value} = await measureWorkflow(workflows[name]);
60+
results.push({value, name});
61+
} else {
62+
for (const workflow of Object.values(workflows)) {
63+
const {name, value} = await measureWorkflow(workflow);
64+
results.push({value, name});
65+
}
5366
}
5467

55-
const results: {[key: string]: number} = {};
56-
for (const workflow of Object.values(workflows)) {
57-
const {name, duration} = await measureWorkflow(workflow);
58-
results[name] = duration;
68+
if (commitSha) {
69+
const spinner = new Spinner('Uploading performance results to database');
70+
try {
71+
for (let {value, name} of results) {
72+
await addWorkflowPerformanceResult({
73+
name,
74+
value,
75+
commit_sha: commitSha,
76+
});
77+
}
78+
} finally {
79+
spinner.success('Upload complete');
80+
}
5981
}
60-
process.stdout.write(JSON.stringify(results));
6182
}
6283

6384
/** yargs command module for checking out a PR. */

ng-dev/perf/workflow/database.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {Spanner} from '@google-cloud/spanner';
10+
11+
export interface WorkflowPerformanceRowResult {
12+
commit_sha: string;
13+
value: number;
14+
name: string;
15+
}
16+
17+
export async function addWorkflowPerformanceResult(result: WorkflowPerformanceRowResult) {
18+
const spanner = new Spanner({
19+
projectId: 'internal-200822',
20+
});
21+
22+
const instance = spanner.instance('ng-measurables');
23+
const database = instance.database('commit_performance');
24+
const workflowPerformanceTable = database.table('WorkflowPerformance');
25+
26+
try {
27+
await workflowPerformanceTable.insert([result]);
28+
} finally {
29+
await database.close();
30+
}
31+
}

ng-dev/perf/workflow/workflow.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ export async function measureWorkflow({name, workflow, prepare, cleanup}: Workfl
3333

3434
spinner.success(`${name}: ${results.duration.toFixed(2)}ms`);
3535

36-
return results.toJSON();
36+
return {
37+
name,
38+
value: results.duration,
39+
};
3740
} finally {
3841
spinner.complete();
3942
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"@bazel/ibazel": "^0.23.0",
7272
"@bazel/jasmine": "patch:@bazel/jasmine@npm:5.8.1#.yarn/patches/@bazel-jasmine-npm.patch",
7373
"@google-cloud/firestore": "^7.0.0",
74+
"@google-cloud/spanner": "7.16.0",
7475
"@google-cloud/storage": "^7.0.0",
7576
"@inquirer/prompts": "^7.0.0",
7677
"@inquirer/type": "^3.0.0",

0 commit comments

Comments
 (0)