1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
13 | if (k2 === undefined) k2 = k;
|
14 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
15 | }) : (function(o, m, k, k2) {
|
16 | if (k2 === undefined) k2 = k;
|
17 | o[k2] = m[k];
|
18 | }));
|
19 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
20 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
21 | }) : function(o, v) {
|
22 | o["default"] = v;
|
23 | });
|
24 | var __importStar = (this && this.__importStar) || function (mod) {
|
25 | if (mod && mod.__esModule) return mod;
|
26 | var result = {};
|
27 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
28 | __setModuleDefault(result, mod);
|
29 | return result;
|
30 | };
|
31 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
32 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
33 | };
|
34 | Object.defineProperty(exports, "__esModule", { value: true });
|
35 | exports.createCheck = exports.parseGithubCheckFlag = void 0;
|
36 | const got_1 = __importDefault(require("got"));
|
37 | const jsonwebtoken = __importStar(require("jsonwebtoken"));
|
38 |
|
39 |
|
40 |
|
41 | function parseGithubCheckFlag(flag) {
|
42 | const parsed = JSON.parse(flag);
|
43 | if (!parsed.appId || !parsed.installationId || !parsed.repo ||
|
44 | !parsed.commit) {
|
45 | throw new Error(`Invalid --github-check flag. Must be a JSON object ` +
|
46 | `with properties: appId, installationId, repo, and commit.`);
|
47 | }
|
48 | return {
|
49 | label: String(parsed.label || 'Tachometer Benchmarks'),
|
50 | appId: Number(parsed.appId),
|
51 | installationId: Number(parsed.installationId),
|
52 | repo: String(parsed.repo),
|
53 | commit: String(parsed.commit),
|
54 | };
|
55 | }
|
56 | exports.parseGithubCheckFlag = parseGithubCheckFlag;
|
57 |
|
58 |
|
59 |
|
60 |
|
61 | async function createCheck(config) {
|
62 | const { label, appId, installationId, repo, commit } = config;
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 | const appPrivateKey = (process.env.GITHUB_APP_PRIVATE_KEY || '').trim().replace(/\\n/g, '\n');
|
76 | if (appPrivateKey === '') {
|
77 | throw new Error('Missing or empty GITHUB_APP_PRIVATE_KEY environment variable, ' +
|
78 | 'which is required when using --github-check.');
|
79 | }
|
80 | const appToken = getAppToken(appId, appPrivateKey);
|
81 | const installationToken = await getInstallationToken({ installationId, appToken });
|
82 |
|
83 |
|
84 | const checkId = await createCheckRun({ label, repo, commit, installationToken });
|
85 | return (markdown) => completeCheckRun({ label, repo, installationToken, checkId, markdown });
|
86 | }
|
87 | exports.createCheck = createCheck;
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 | function getAppToken(appId, privateKey) {
|
98 | const expireMinutes = 10;
|
99 | const issuedTimestamp = Math.floor(Date.now() / 1000);
|
100 | const expireTimestamp = issuedTimestamp + expireMinutes * 60;
|
101 | const payload = {
|
102 | iss: appId,
|
103 | iat: issuedTimestamp,
|
104 | exp: expireTimestamp,
|
105 | };
|
106 | return jsonwebtoken.sign(payload, privateKey, { algorithm: 'RS256' });
|
107 | }
|
108 |
|
109 |
|
110 |
|
111 |
|
112 | async function getInstallationToken({ installationId, appToken }) {
|
113 | const resp = await got_1.default.post(`https://api.github.com/installations/${installationId}/access_tokens`, {
|
114 | headers: {
|
115 | Accept: 'application/vnd.github.machine-man-preview+json',
|
116 | Authorization: `Bearer ${appToken}`,
|
117 | },
|
118 | });
|
119 | const data = JSON.parse(resp.body);
|
120 | return data.token;
|
121 | }
|
122 |
|
123 |
|
124 |
|
125 |
|
126 | async function createCheckRun({ label, repo, commit, installationToken }) {
|
127 | const resp = await got_1.default.post(`https://api.github.com/repos/${repo}/check-runs`, {
|
128 | headers: {
|
129 | Accept: 'application/vnd.github.antiope-preview+json',
|
130 | Authorization: `Bearer ${installationToken}`,
|
131 | },
|
132 |
|
133 | body: JSON.stringify({
|
134 | head_sha: commit,
|
135 | name: label,
|
136 | }),
|
137 | });
|
138 | const data = JSON.parse(resp.body);
|
139 | return data.id;
|
140 | }
|
141 |
|
142 |
|
143 |
|
144 |
|
145 | async function completeCheckRun({ label, repo, installationToken, checkId, markdown }) {
|
146 | await got_1.default.patch(`https://api.github.com/repos/${repo}/check-runs/${checkId}`, {
|
147 | headers: {
|
148 | Accept: 'application/vnd.github.antiope-preview+json',
|
149 | Authorization: `Bearer ${installationToken}`,
|
150 | },
|
151 |
|
152 | body: JSON.stringify({
|
153 | name: label,
|
154 | completed_at: new Date().toISOString(),
|
155 |
|
156 |
|
157 |
|
158 | conclusion: 'neutral',
|
159 | output: {
|
160 | title: label,
|
161 | summary: 'Benchmark results',
|
162 | text: markdown,
|
163 | }
|
164 | }),
|
165 | });
|
166 | }
|
167 |
|
\ | No newline at end of file |