|
3 | 3 | // Must reference esnext.asynciterable lib, since octokit uses AsyncIterable internally |
4 | 4 | const { Octokit } = require("@octokit/rest"); |
5 | 5 | const fs = require("fs"); |
| 6 | +const ado = require("azure-devops-node-api"); |
| 7 | +const { default: fetch } = require("node-fetch"); |
6 | 8 |
|
7 | | -const requester = process.env.requesting_user; |
8 | | -const source = process.env.source_issue; |
9 | | -const postedComment = process.env.status_comment; |
10 | | -console.log(`Loading fragment from ${process.argv[3]}...`); |
11 | | -const outputTableText = fs.readFileSync(process.argv[3], { encoding: "utf8" }); |
12 | | -console.log(`Fragment contents: |
13 | | -${outputTableText}`); |
14 | 9 |
|
15 | | -const gh = new Octokit({ |
16 | | - auth: process.argv[2] |
17 | | -}); |
18 | | -gh.issues.createComment({ |
19 | | - issue_number: +source, |
20 | | - owner: "Microsoft", |
21 | | - repo: "TypeScript", |
22 | | - body: `@${requester} |
23 | | -The results of the perf run you requested are in! |
24 | | -<details><summary> Here they are:</summary><p> |
25 | | -${outputTableText} |
26 | | -</p></details>` |
27 | | -}).then(async data => { |
28 | | - console.log(`Results posted!`); |
29 | | - const newCommentUrl = data.data.html_url; |
30 | | - const comment = await gh.issues.getComment({ |
31 | | - owner: "Microsoft", |
32 | | - repo: "TypeScript", |
33 | | - comment_id: +postedComment |
34 | | - }); |
35 | | - const newBody = `${comment.data.body} |
36 | | -
|
37 | | -Update: [The results are in!](${newCommentUrl})`; |
38 | | - return await gh.issues.updateComment({ |
39 | | - owner: "Microsoft", |
40 | | - repo: "TypeScript", |
41 | | - comment_id: +postedComment, |
42 | | - body: newBody |
43 | | - }); |
44 | | -}).catch(e => { |
| 10 | +async function main() { |
| 11 | + const source = process.env.SOURCE_ISSUE; |
| 12 | + if (!source) throw new Error("SOURCE_ISSUE environment variable not set."); |
| 13 | + |
| 14 | + const requester = process.env.REQUESTING_USER; |
| 15 | + if (!requester) throw new Error("REQUESTING_USER environment variable not set."); |
| 16 | + |
| 17 | + const buildId = process.env.BUILD_BUILDID; |
| 18 | + if (!requester) throw new Error("BUILD_BUILDID environment variable not set."); |
| 19 | + |
| 20 | + const postedComment = process.env.STATUS_COMMENT; |
| 21 | + if (!postedComment) throw new Error("STATUS_COMMENT environment variable not set."); |
| 22 | + |
| 23 | + const [auth, fragment, includeArtifact] = process.argv.slice(2); |
| 24 | + if (!auth) throw new Error("First argument must be a GitHub auth token."); |
| 25 | + if (!fragment) throw new Error("Second argument must be a path to an HTML fragment."); |
| 26 | + |
| 27 | + const gh = new Octokit({ auth }); |
| 28 | + try { |
| 29 | + console.log(`Loading fragment from ${fragment}...`); |
| 30 | + const outputTableText = fs.readFileSync(fragment, { encoding: "utf8" }); |
| 31 | + console.log(`Fragment contents:\n${outputTableText}`); |
| 32 | + |
| 33 | + let benchmarkText = ""; |
| 34 | + if (includeArtifact === "--include-artifact") { |
| 35 | + // post a link to the benchmark file |
| 36 | + const cli = new ado.WebApi("https://typescript.visualstudio.com/defaultcollection", ado.getHandlerFromToken("")); // Empty token, anon auth |
| 37 | + const build = await cli.getBuildApi(); |
| 38 | + const artifact = await build.getArtifact("typescript", +buildId, "benchmark"); |
| 39 | + const updatedUrl = new URL(artifact.resource.url); |
| 40 | + updatedUrl.search = `artifactName=benchmark&fileId=${artifact.resource.data}&fileName=manifest`; |
| 41 | + const resp = await (await fetch(`${updatedUrl}`)).json(); |
| 42 | + for (const file of resp.items) { |
| 43 | + if (/[\\/]linux\.benchmark$/.test(file.path)) { |
| 44 | + const benchmarkUrl = new URL(artifact.resource.url); |
| 45 | + benchmarkUrl.search = `artifactName=benchmark&fileId=${file.blob.id}&fileName=${file.path}`; |
| 46 | + benchmarkText = `\n<details><summary>Developer Information:</summary><p><a href="${benchmarkUrl.href}">Download Benchmark</a></p></details>\n`; |
| 47 | + break; |
| 48 | + } |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + const data = await gh.issues.createComment({ |
| 53 | + issue_number: +source, |
| 54 | + owner: "Microsoft", |
| 55 | + repo: "TypeScript", |
| 56 | + body: `@${requester}\nThe results of the perf run you requested are in!\n<details><summary> Here they are:</summary><p>\n${outputTableText}\n</p>${benchmarkText}</details>` |
| 57 | + }); |
| 58 | + |
| 59 | + console.log(`Results posted!`); |
| 60 | + const newCommentUrl = data.data.html_url; |
| 61 | + const comment = await gh.issues.getComment({ |
| 62 | + owner: "Microsoft", |
| 63 | + repo: "TypeScript", |
| 64 | + comment_id: +postedComment |
| 65 | + }); |
| 66 | + const newBody = `${comment.data.body}\n\nUpdate: [The results are in!](${newCommentUrl})`; |
| 67 | + await gh.issues.updateComment({ |
| 68 | + owner: "Microsoft", |
| 69 | + repo: "TypeScript", |
| 70 | + comment_id: +postedComment, |
| 71 | + body: newBody |
| 72 | + }); |
| 73 | + } |
| 74 | + catch (e) { |
| 75 | + const gh = new Octokit({ auth }); |
| 76 | + await gh.issues.createComment({ |
| 77 | + issue_number: +source, |
| 78 | + owner: "Microsoft", |
| 79 | + repo: "TypeScript", |
| 80 | + body: `Hey @${requester}, something went wrong when publishing results. ([You can check the log here](https://typescript.visualstudio.com/TypeScript/_build/index?buildId=${buildId}&_a=summary)).` |
| 81 | + }); |
| 82 | + } |
| 83 | +} |
| 84 | + |
| 85 | +main().catch(e => { |
45 | 86 | console.error(e); |
46 | 87 | process.exit(1); |
47 | 88 | }); |
0 commit comments