Release v1.61.0-beta.5 candidate

This commit is contained in:
Matysh
2026-08-10 18:01:16 +03:00
parent c8b06996b1
commit f8f1718ad2
50 changed files with 3567 additions and 1889 deletions
+30 -10
View File
@@ -1,5 +1,6 @@
// Exact-SHA Validate gate used by .github/workflows/release.yml.
// The policy is exported so failure/cancel/skip scenarios stay unit-tested.
// Exact-SHA GitHub Actions gate used by release workflows. Prereleases require
// Validate; stable releases additionally require the dedicated full
// performance workflow.
import { resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
@@ -10,12 +11,19 @@ export function classifyValidateRuns(runs) {
return 'success';
}
export const workflowRunsUrl = ({ repo, workflow, sha }) => (
`https://api.github.com/repos/${repo}/actions/workflows/${encodeURIComponent(workflow)}`
+ `/runs?head_sha=${encodeURIComponent(sha)}&per_page=100`
);
const sleep = (ms) => new Promise((done) => setTimeout(done, ms));
export async function waitForGreenValidate({ repo, sha, token, timeoutMs = 60 * 60 * 1000 }) {
if (!repo || !sha || !token) throw new Error('repo, sha and token are required');
export async function waitForGreenWorkflow({
repo, sha, token, workflow = 'validate.yml', label = 'Validate', timeoutMs = 60 * 60 * 1000,
}) {
if (!repo || !sha || !token || !workflow) throw new Error('repo, sha, token and workflow are required');
const deadline = Date.now() + timeoutMs;
const url = `https://api.github.com/repos/${repo}/actions/workflows/validate.yml/runs?head_sha=${encodeURIComponent(sha)}&per_page=100`;
const url = workflowRunsUrl({ repo, workflow, sha });
while (true) {
const response = await fetch(url, {
headers: {
@@ -31,29 +39,41 @@ export async function waitForGreenValidate({ repo, sha, token, timeoutMs = 60 *
const state = classifyValidateRuns(runs);
if (state === 'fail') {
const failed = runs.filter((run) => run?.status === 'completed' && run?.conclusion !== 'success');
throw new Error(`Validate is not green for ${sha}: ${JSON.stringify(failed.map((run) => ({
throw new Error(`${label} is not green for ${sha}: ${JSON.stringify(failed.map((run) => ({
conclusion: run.conclusion, url: run.html_url,
})))}`);
}
if (state === 'success') {
console.log(`Validate is green for ${sha} (${runs.length} run(s))`);
console.log(`${label} is green for ${sha} (${runs.length} run(s))`);
return;
}
if (Date.now() >= deadline) throw new Error(`No completed green Validate for ${sha} within the deadline`);
if (Date.now() >= deadline) throw new Error(`No completed green ${label} for ${sha} within the deadline`);
const running = runs.filter((run) => run?.status !== 'completed').length;
console.log(runs.length ? `waiting: ${running} Validate run(s) still going` : `waiting: no Validate run for ${sha} yet`);
console.log(runs.length
? `waiting: ${running} ${label} run(s) still going`
: `waiting: no ${label} run for ${sha} yet`);
await sleep(30_000);
}
}
export const waitForGreenValidate = (options) => waitForGreenWorkflow({
...options, workflow: 'validate.yml', label: 'Validate',
});
const invokedDirectly = process.argv[1]
&& resolve(process.argv[1]) === resolve(fileURLToPath(import.meta.url));
if (invokedDirectly) {
const sha = process.argv[2];
waitForGreenValidate({
const valueArg = (name) => process.argv
.find((arg) => arg.startsWith(`--${name}=`))?.slice(name.length + 3);
const workflow = valueArg('workflow') || 'validate.yml';
const label = valueArg('label') || (workflow === 'validate.yml' ? 'Validate' : workflow);
waitForGreenWorkflow({
repo: process.env.REPO || process.env.GITHUB_REPOSITORY,
sha,
token: process.env.GH_TOKEN || process.env.GITHUB_TOKEN,
workflow,
label,
}).catch((err) => {
console.error(`::error::${err instanceof Error ? err.message : String(err)}`);
process.exitCode = 1;