mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-18 07:47:23 +01:00
allow terrapin checks to by manually triggered and report results back to GitHub (#302451)
* initial terrapin check poc * bump terrapin timeout, remove trigger * allow terrapin checks to by manually triggered and report results back to GitHub Co-authored-by: Copilot <copilot@github.com> --------- Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
133
build/azure-pipelines/github-check-run.js
Normal file
133
build/azure-pipelines/github-check-run.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// @ts-check
|
||||
|
||||
const crypto = require('crypto');
|
||||
const https = require('https');
|
||||
|
||||
/**
|
||||
* @param {string} appId
|
||||
* @param {string} privateKey
|
||||
* @returns {string}
|
||||
*/
|
||||
function createJwt(appId, privateKey) {
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
const header = Buffer.from(JSON.stringify({ alg: 'RS256', typ: 'JWT' })).toString('base64url');
|
||||
const payload = Buffer.from(JSON.stringify({ iat: now - 60, exp: now + 600, iss: appId })).toString('base64url');
|
||||
const signature = crypto.sign('sha256', Buffer.from(`${header}.${payload}`), privateKey).toString('base64url');
|
||||
return `${header}.${payload}.${signature}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('https').RequestOptions} options
|
||||
* @param {object} [body]
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
function request(options, body) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = https.request(options, res => {
|
||||
let data = '';
|
||||
res.on('data', chunk => data += chunk);
|
||||
res.on('end', () => {
|
||||
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
||||
resolve(JSON.parse(data));
|
||||
} else {
|
||||
reject(new Error(`HTTP ${res.statusCode}: ${data}`));
|
||||
}
|
||||
});
|
||||
});
|
||||
req.on('error', reject);
|
||||
if (body) {
|
||||
req.write(JSON.stringify(body));
|
||||
}
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} jwt
|
||||
* @param {string} installationId
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async function getInstallationToken(jwt, installationId) {
|
||||
/** @type {{ token: string }} */
|
||||
const result = await request({
|
||||
hostname: 'api.github.com',
|
||||
path: `/app/installations/${encodeURIComponent(installationId)}/access_tokens`,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${jwt}`,
|
||||
'Accept': 'application/vnd.github+json',
|
||||
'User-Agent': 'VSCode-ADO-Pipeline',
|
||||
'X-GitHub-Api-Version': '2022-11-28'
|
||||
}
|
||||
});
|
||||
return result.token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} token
|
||||
* @param {string} checkRunId
|
||||
* @param {string} conclusion
|
||||
* @param {string} detailsUrl
|
||||
*/
|
||||
function updateCheckRun(token, checkRunId, conclusion, detailsUrl) {
|
||||
return request({
|
||||
hostname: 'api.github.com',
|
||||
path: `/repos/microsoft/vscode/check-runs/${encodeURIComponent(checkRunId)}`,
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Authorization': `token ${token}`,
|
||||
'Accept': 'application/vnd.github+json',
|
||||
'User-Agent': 'VSCode-ADO-Pipeline',
|
||||
'X-GitHub-Api-Version': '2022-11-28'
|
||||
}
|
||||
}, {
|
||||
status: 'completed',
|
||||
conclusion,
|
||||
completed_at: new Date().toISOString(),
|
||||
details_url: detailsUrl
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const appId = process.env.GITHUB_APP_ID;
|
||||
const privateKey = process.env.GITHUB_APP_PRIVATE_KEY;
|
||||
const installationId = process.env.GITHUB_APP_INSTALLATION_ID;
|
||||
const checkRunId = process.env.CHECK_RUN_ID;
|
||||
const jobStatus = process.env.AGENT_JOBSTATUS;
|
||||
const detailsUrl = `${process.env.SYSTEM_COLLECTIONURI}${process.env.SYSTEM_TEAMPROJECT}/_build/results?buildId=${process.env.BUILD_BUILDID}`;
|
||||
|
||||
if (!appId || !privateKey || !installationId || !checkRunId) {
|
||||
throw new Error('Missing required environment variables');
|
||||
}
|
||||
|
||||
const jwt = createJwt(appId, privateKey);
|
||||
const token = await getInstallationToken(jwt, installationId);
|
||||
|
||||
/** @type {string} */
|
||||
let conclusion;
|
||||
switch (jobStatus) {
|
||||
case 'Succeeded':
|
||||
case 'SucceededWithIssues':
|
||||
conclusion = 'success';
|
||||
break;
|
||||
case 'Canceled':
|
||||
conclusion = 'cancelled';
|
||||
break;
|
||||
default:
|
||||
conclusion = 'failure';
|
||||
break;
|
||||
}
|
||||
|
||||
await updateCheckRun(token, checkRunId, conclusion, detailsUrl);
|
||||
console.log(`Updated check run ${checkRunId} with conclusion: ${conclusion}`);
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -2,6 +2,16 @@ trigger: none
|
||||
|
||||
pr: none
|
||||
|
||||
parameters:
|
||||
- name: GITHUB_APP_ID
|
||||
type: string
|
||||
- name: GITHUB_APP_INSTALLATION_ID
|
||||
type: string
|
||||
- name: GITHUB_APP_PRIVATE_KEY
|
||||
type: string
|
||||
- name: GITHUB_CHECK_RUN_ID
|
||||
type: string
|
||||
|
||||
variables:
|
||||
- name: NPM_REGISTRY
|
||||
value: "https://pkgs.dev.azure.com/monacotools/Monaco/_packaging/vscode/npm/registry/"
|
||||
@@ -112,3 +122,13 @@ jobs:
|
||||
- script: .github/workflows/check-clean-git-state.sh
|
||||
displayName: Check clean git state
|
||||
condition: and(succeeded(), eq(variables['SHOULD_VALIDATE'], 'true'))
|
||||
|
||||
- script: node build/azure-pipelines/github-check-run.js
|
||||
displayName: Update GitHub check run
|
||||
condition: always()
|
||||
env:
|
||||
GITHUB_APP_ID: ${{ parameters.GITHUB_APP_ID }}
|
||||
GITHUB_APP_INSTALLATION_ID: ${{ parameters.GITHUB_APP_INSTALLATION_ID }}
|
||||
GITHUB_APP_PRIVATE_KEY: ${{ parameters.GITHUB_APP_PRIVATE_KEY }}
|
||||
CHECK_RUN_ID: ${{ parameters.GITHUB_CHECK_RUN_ID }}
|
||||
AGENT_JOBSTATUS: $(Agent.JobStatus)
|
||||
|
||||
Reference in New Issue
Block a user