Skip to content

Commit 52d02cb

Browse files
committed
metrics: ci configs, git & github utils (wip)
1 parent 495a31f commit 52d02cb

File tree

7 files changed

+200
-5
lines changed

7 files changed

+200
-5
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Replay metrics configuration & entrypoints (scripts)
22

3-
* [dev] contains scripts launched during local development
4-
* [ci] contains scripts launched in CI
3+
* [dev](dev) contains scripts launched during local development
4+
* [ci](ci) contains scripts launched in CI
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Metrics, MetricsCollector } from '../../src/collector.js';
2+
import { JankTestScenario } from '../../src/scenarios.js';
3+
import { latestResultFile } from './env.js';
4+
5+
const collector = new MetricsCollector();
6+
const result = await collector.execute({
7+
name: 'dummy',
8+
a: new JankTestScenario(false),
9+
b: new JankTestScenario(true),
10+
runs: 1,
11+
tries: 1,
12+
async test(_aResults: Metrics[], _bResults: Metrics[]) {
13+
return true;
14+
},
15+
});
16+
17+
result.writeToFile(latestResultFile);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export const previousResultsDir = 'out/previous-results';
2+
export const baselineResultsDir = 'out/baseline-results';
3+
export const latestResultFile = 'out/latest-result.json';
4+
export const artifactName = "sdk-metrics-replay"
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import path from 'path';
2+
// import { AnalyzerItemMetric, ResultsAnalyzer } from '../../src/results/analyzer.js';
3+
import { Result } from '../../src/results/result.js';
4+
// import { ResultsSet } from '../../src/results/results-set.js';
5+
import { Git } from '../../src/util/git.js';
6+
import { GitHub } from '../../src/util/github.js';
7+
import { latestResultFile, previousResultsDir, baselineResultsDir, artifactName } from './env.js';
8+
9+
const latestResult = Result.readFromFile(latestResultFile);
10+
console.debug(latestResult);
11+
12+
GitHub.downloadPreviousArtifact(await Git.baseBranch, baselineResultsDir, artifactName);
13+
GitHub.downloadPreviousArtifact(await Git.branch, previousResultsDir, artifactName);
14+
15+
GitHub.writeOutput("artifactName", artifactName)
16+
GitHub.writeOutput("artifactPath", path.resolve(previousResultsDir));
17+
18+
// const resultsSet = new ResultsSet(outDir);
19+
// const analysis = ResultsAnalyzer.analyze(latestResult, resultsSet);
20+
21+
// val prComment = PrCommentBuilder()
22+
// prComment.addCurrentResult(latestResults)
23+
// if (Git.baseBranch != Git.branch) {
24+
// prComment.addAdditionalResultsSet(
25+
// "Baseline results on branch: ${Git.baseBranch}",
26+
// ResultsSet(baselineResultsDir)
27+
// )
28+
// }
29+
// prComment.addAdditionalResultsSet(
30+
// "Previous results on branch: ${Git.branch}",
31+
// ResultsSet(previousResultsDir)
32+
// )
33+
34+
// GitHub.addOrUpdateComment(prComment);
35+
36+
// Copy the latest test run results to the archived result dir.
37+
// await resultsSet.add(latestResultFile, true);

packages/replay/metrics/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
"build": "tsc",
1010
"deps": "yarn --cwd ../ build:bundle && yarn --cwd ../../tracing/ build:bundle",
1111
"dev:collect": "ts-node-esm ./configs/dev/collect.ts",
12-
"dev:process": "ts-node-esm ./configs/dev/process.ts"
12+
"dev:process": "ts-node-esm ./configs/dev/process.ts",
13+
"ci:collect": "ts-node-esm ./configs/ci/collect.ts",
14+
"ci:process": "ts-node-esm ./configs/ci/process.ts"
1315
},
1416
"dependencies": {
1517
"@types/node": "^18.11.17",

packages/replay/metrics/src/util/git.ts

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,60 @@
11
import { simpleGit } from 'simple-git';
22

33
export type GitHash = string;
4+
const git = simpleGit();
5+
6+
async function defaultBranch(): Promise<string> {
7+
const remoteInfo = await git.remote(['show', 'origin']) as string;
8+
for (let line of remoteInfo.split('\n')) {
9+
line = line.trim();
10+
if (line.startsWith('HEAD branch:')) {
11+
return line.substring('HEAD branch:'.length).trim();
12+
}
13+
}
14+
throw "Couldn't find base branch name";
15+
}
416

5-
// A testing scenario we want to collect metrics for.
617
export const Git = {
18+
get repository(): Promise<string> {
19+
return (async () => {
20+
if (typeof process.env.GITHUB_REPOSITORY == 'string' && process.env.GITHUB_REPOSITORY.length > 0) {
21+
return `github.com/${process.env.GITHUB_REPOSITORY}`;
22+
} else {
23+
let url = await git.remote(['get-url', 'origin']) as string;
24+
url = url.trim();
25+
url = url.replace(/^git@/, '');
26+
url = url.replace(/\.git$/, '');
27+
return url.replace(':', '/');
28+
}
29+
})();
30+
},
31+
32+
get branch(): Promise<string> {
33+
return (async () => {
34+
if (typeof process.env.GITHUB_HEAD_REF == 'string' && process.env.GITHUB_HEAD_REF.length > 0) {
35+
return process.env.GITHUB_HEAD_REF;
36+
} else if (typeof process.env.GITHUB_REF == 'string' && process.env.GITHUB_REF.startsWith('refs/heads/')) {
37+
return process.env.GITHUB_REF.substring('refs/heads/'.length);
38+
} else {
39+
const branches = (await git.branchLocal()).branches;
40+
for (const name in branches) {
41+
if (branches[name].current) return name;
42+
}
43+
throw "Couldn't find current branch name";
44+
}
45+
})();
46+
},
47+
48+
get baseBranch(): Promise<string> {
49+
if (typeof process.env.GITHUB_BASE_REF == 'string' && process.env.GITHUB_BASE_REF.length > 0) {
50+
return Promise.resolve(process.env.GITHUB_BASE_REF);
51+
} else {
52+
return defaultBranch();
53+
}
54+
},
55+
756
get hash(): Promise<GitHash> {
857
return (async () => {
9-
const git = simpleGit();
1058
let gitHash = await git.revparse('HEAD');
1159
let diff = await git.diff();
1260
if (diff.trim().length > 0) {
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import * as fs from 'fs';
2+
3+
export const GitHub = {
4+
writeOutput(name: string, value: any): void {
5+
if (typeof process.env.GITHUB_OUTPUT == 'string' && process.env.GITHUB_OUTPUT.length > 0) {
6+
fs.appendFileSync(process.env.GITHUB_OUTPUT, `${name}=${value}\n`);
7+
}
8+
console.log(`Output ${name}`, value);
9+
},
10+
11+
downloadPreviousArtifact(branch: string, targetDir: string, artifactName: string): void {
12+
fs.mkdirSync(targetDir, { recursive: true });
13+
14+
// if (workflow == null) {
15+
// println("Skipping previous artifact '$artifactName' download for branch '$branch' - not running in CI")
16+
// return
17+
// }
18+
console.log(`Trying to download previous artifact '${artifactName}' for branch '${branch}'`)
19+
20+
// val run = workflow!!.listRuns()
21+
// .firstOrNull { it.headBranch == branch && it.conclusion == GHWorkflowRun.Conclusion.SUCCESS }
22+
// if (run == null) {
23+
// println("Couldn't find any successful run workflow ${workflow!!.name}")
24+
// return
25+
// }
26+
27+
// val artifact = run.listArtifacts().firstOrNull { it.name == artifactName }
28+
// if (artifact == null) {
29+
// println("Couldn't find any artifact matching $artifactName")
30+
// return
31+
// }
32+
33+
// println("Downloading artifact ${artifact.archiveDownloadUrl} and extracting to $targetDir")
34+
// artifact.download {
35+
// val zipStream = ZipInputStream(it)
36+
// var entry: ZipEntry?
37+
// // while there are entries I process them
38+
// while (true) {
39+
// entry = zipStream.nextEntry
40+
// if (entry == null) {
41+
// break
42+
// }
43+
// if (entry.isDirectory) {
44+
// Path.of(entry.name).createDirectories()
45+
// } else {
46+
// println("Extracting ${entry.name}")
47+
// val outFile = FileOutputStream(targetDir.resolve(entry.name).toFile())
48+
// while (zipStream.available() > 0) {
49+
// val c = zipStream.read()
50+
// if (c > 0) {
51+
// outFile.write(c)
52+
// } else {
53+
// break
54+
// }
55+
// }
56+
// outFile.close()
57+
// }
58+
// }
59+
// }
60+
},
61+
62+
// fun addOrUpdateComment(commentBuilder: PrCommentBuilder) {
63+
// if (pullRequest == null) {
64+
// val file = File("out/comment.html")
65+
// println("No PR available (not running in CI?): writing built comment to ${file.absolutePath}")
66+
// file.writeText(commentBuilder.body)
67+
// } else {
68+
// val comments = pullRequest!!.comments
69+
// // Trying to fetch `github!!.myself` throws (in CI only): Exception in thread "main" org.kohsuke.github.HttpException:
70+
// // {"message":"Resource not accessible by integration","documentation_url":"https://docs.github.com/rest/reference/users#get-the-authenticated-user"}
71+
// // Let's make this conditional on some env variable that's unlikely to be set.
72+
// // Do not use "CI" because that's commonly set during local development and testing.
73+
// val author = if (env.containsKey("GITHUB_ACTION")) "github-actions[bot]" else github!!.myself.login
74+
// val comment = comments.firstOrNull {
75+
// it.user.login.equals(author) &&
76+
// it.body.startsWith(commentBuilder.title, ignoreCase = true)
77+
// }
78+
// if (comment != null) {
79+
// println("Updating PR comment ${comment.htmlUrl} body")
80+
// comment.update(commentBuilder.body)
81+
// } else {
82+
// println("Adding new PR comment to ${pullRequest!!.htmlUrl}")
83+
// pullRequest!!.comment(commentBuilder.body)
84+
// }
85+
// }
86+
// }
87+
}

0 commit comments

Comments
 (0)