Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions .github/workflows/perf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ on:
branches:
- main

permissions: {}
permissions:
contents: 'read'
id-token: 'write'

defaults:
run:
shell: bash

jobs:
list:
timeout-minutes: 30
timeout-minutes: 5
runs-on: ubuntu-latest
outputs:
workflows: ${{ steps.workflows.outputs.workflows }}
Expand Down Expand Up @@ -43,4 +45,13 @@ jobs:
- 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 }}
# We utilize the google-github-actions/auth action to allow us to get an active credential using workflow
# identity federation. This allows us to request short lived credentials on demand, rather than storing
# credentials in secrets long term. More information can be found at:
# https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-google-cloud-platform
- uses: 'google-github-actions/auth@v2'
with:
project_id: 'internal-200822'
workload_identity_provider: 'projects/823469418460/locations/global/workloadIdentityPools/measurables-tracking/providers/angular'
service_account: 'measures-uploader@internal-200822.iam.gserviceaccount.com'
- run: yarn ng-dev perf workflows --name ${{ matrix.workflow }} --commit-sha ${{github.sha}}
3 changes: 2 additions & 1 deletion ng-dev/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ NG_DEV_EXTERNALS = [
# `typescript` is external because we want the project to provide a TypeScript version.
# TODO: Figure out how we want to manage dependencies for the dev-infra tool.
"typescript",
# Package uses `__filename` and `__dirname` and cannot be bundled in ESM. We do not
# Packages using `__filename` and `__dirname` and cannot be bundled in ESM. We do not
# intend to provide interop globals for this as it could hide other significant issues.
"@yarnpkg/lockfile",
"@google-cloud/spanner",
]

ts_library(
Expand Down
1 change: 1 addition & 0 deletions ng-dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
}
},
"dependencies": {
"@google-cloud/spanner": "7.16.0",
"@octokit/rest": "21.0.2",
"@types/semver": "^7.3.6",
"@types/supports-color": "^8.1.1",
Expand Down
1 change: 1 addition & 0 deletions ng-dev/perf/workflow/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ ts_library(
visibility = ["//ng-dev:__subpackages__"],
deps = [
"//ng-dev/utils",
"@npm//@google-cloud/spanner",
"@npm//@types/node",
"@npm//@types/yargs",
"@npm//yaml",
Expand Down
39 changes: 30 additions & 9 deletions ng-dev/perf/workflow/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ import {measureWorkflow} from './workflow.js';
import {loadWorkflows} from './loader.js';
import {join} from 'path';
import {determineRepoBaseDirFromCwd} from '../../utils/repo-directory.js';
import {addWorkflowPerformanceResult} from './database.js';
import {Spinner} from '../../utils/spinner.js';

interface WorkflowsParams {
configFile: string;
list: boolean;
name?: string;
commitSha?: string;
}

/** Builds the checkout pull request command. */
Expand All @@ -34,30 +37,48 @@ function builder(yargs: Argv) {
.option('name', {
type: 'string',
description: 'A specific workflow to run by name',
})
.option('commit-sha' as 'commitSha', {
type: 'string',
description: 'The commit sha to associate the measurement with, uploading it to our database',
});
}

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

if (list) {
process.stdout.write(JSON.stringify(Object.keys(workflows)));
return;
}

const results: {name: string; value: number}[] = [];

if (name) {
const {duration} = await measureWorkflow(workflows[name]);
process.stdout.write(JSON.stringify({[name]: duration}));
return;
const {value} = await measureWorkflow(workflows[name]);
results.push({value, name});
} else {
for (const workflow of Object.values(workflows)) {
const {name, value} = await measureWorkflow(workflow);
results.push({value, name});
}
}

const results: {[key: string]: number} = {};
for (const workflow of Object.values(workflows)) {
const {name, duration} = await measureWorkflow(workflow);
results[name] = duration;
if (commitSha) {
const spinner = new Spinner('Uploading performance results to database');
try {
for (let {value, name} of results) {
await addWorkflowPerformanceResult({
name,
value,
commit_sha: commitSha,
});
}
} finally {
spinner.success('Upload complete');
}
}
process.stdout.write(JSON.stringify(results));
}

/** yargs command module for checking out a PR. */
Expand Down
54 changes: 54 additions & 0 deletions ng-dev/perf/workflow/database.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* @license
* Copyright Google LLC
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {Spanner} from '@google-cloud/spanner';

/**
* The workflow performance results are stored in a spanner database within our
* project to be able to retrieve later, The commit sha will be used as a foreign
* key to point to specific commits found in the table of commit shas expressing
* the full graph of commits within the git graph for the repository.
*
* The workflow performance table is defined with the following characteristics.
*
* |--------------------------------------------------------------------|
* | Column | Type | Notes |
* |--------------------------------------------------------------------|
* | workflow_performance_id | STRING(36) | Autogenerated |
* | commit_sha | STRING(40) | |
* | value | FLOAT64 | |
* | name | STRING(256) | |
* |--------------------------------------------------------------------|
*/

/** The reuslt of workflow performance eresult to be stored in the database. */
export interface WorkflowPerformanceRowResult {
commit_sha: string;
value: number;
name: string;
}

/** Add a single workflow performance result to the spanner database. */
export async function addWorkflowPerformanceResult(result: WorkflowPerformanceRowResult) {
/** The spanner client instance. */
const spanner = new Spanner({
projectId: 'internal-200822',
});
/** The spanner instance within our project. */
const instance = spanner.instance('ng-measurables');
/** The commit performance database within our spanner instance. */
const database = instance.database('commit_performance');
/** The table holding workflow performance information. */
const workflowPerformanceTable = database.table('WorkflowPerformance');

try {
await workflowPerformanceTable.insert(result);
} finally {
await database.close();
}
}
5 changes: 4 additions & 1 deletion ng-dev/perf/workflow/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ export async function measureWorkflow({name, workflow, prepare, cleanup}: Workfl

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

return results.toJSON();
return {
name,
value: results.duration,
};
} finally {
spinner.complete();
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"@bazel/ibazel": "^0.23.0",
"@bazel/jasmine": "patch:@bazel/jasmine@npm:5.8.1#.yarn/patches/@bazel-jasmine-npm.patch",
"@google-cloud/firestore": "^7.0.0",
"@google-cloud/spanner": "7.16.0",
"@google-cloud/storage": "^7.0.0",
"@inquirer/prompts": "^7.0.0",
"@inquirer/type": "^3.0.0",
Expand Down
Loading