Files
wehub-resource-sync 85742ab165
Deploy Documentation / deploy (push) Has been cancelled
CPU Test / Test (Utilities, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (LLM proxy, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Others, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Store, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Utilities, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Weave, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (AgentOps, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (LLM proxy, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Others, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Weave, latest, Python 3.13) (push) Has been cancelled
Dashboard / Chromatic (push) Has been cancelled
CPU Test / Lint - fast (push) Has been cancelled
CPU Test / Lint - next (push) Has been cancelled
CPU Test / Lint - slow (push) Has been cancelled
CPU Test / Lint - JavaScript (push) Has been cancelled
CPU Test / Build documentation (push) Has been cancelled
CPU Test / Test (AgentOps, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (LLM proxy, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (Others, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (Store, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (Weave, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (AgentOps, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Store, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Utilities, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Weave, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (AgentOps, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (LLM proxy, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (Others, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (Store, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (Utilities, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (JavaScript) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:44:17 +08:00

118 lines
4.5 KiB
JavaScript

// Copyright (c) Microsoft. All rights reserved.
/**
* Aggregates the “latest completed” results of several dependent workflows and fails
* this step if any required job/variant is missing or not successful.
*
* Usage (from actions/github-script@v8):
*
* const badgeAggregation = require('./scripts/badge_aggregation.js');
* const dependencies = [
* { workflow: 'examples-calc-x.yml', label: 'calc-x.latest', variants: ['latest'] },
* { workflow: 'examples-spider.yml', label: 'spider.latest', variants: ['latest'] },
* { workflow: 'examples-apo.yml', label: 'apo.latest', variants: ['latest'] },
* { workflow: 'examples-unsloth.yml', label: 'unsloth.latest', variants: ['latest'] },
* { workflow: 'tests-full.yml', label: 'tests-full.latest', variants: ['latest'] },
* ];
* await badgeAggregation({ github, context, core, dependencies });
*
* Notes:
* - Requires the workflow files above to exist in .github/workflows/.
* - Looks at the default branch "main" unless you override per dependency with dep.branch.
* - Assumes matrix job names contain the variant in parentheses, e.g. "tests (latest)".
*/
module.exports = async function badgeAggregation({ github, context, core, dependencies }) {
const failures = [];
// Defensive: validate inputs early for nicer error messages.
if (!github?.rest?.actions || !context?.repo || !core) {
throw new Error('badgeAggregation: expected { github, context, core } from actions/github-script.');
}
if (!Array.isArray(dependencies) || dependencies.length === 0) {
core.info('No dependencies provided; nothing to check.');
return;
}
// Helper: paginate jobs for a run attempt (handles >100 jobs edge case).
async function listAllJobsForAttempt(run_id, attempt_number) {
const all = [];
let page = 1;
while (true) {
const { data } = await github.rest.actions.listJobsForWorkflowRunAttempt({
owner: context.repo.owner,
repo: context.repo.repo,
run_id,
attempt_number,
per_page: 100,
page,
});
const jobs = data.jobs ?? [];
all.push(...jobs);
if (!data.total_count || all.length >= data.total_count || jobs.length === 0) break;
page += 1;
}
return all;
}
// For each dependency: find the latest completed run on the target branch; then inspect its jobs.
for (const dep of dependencies) {
const branch = dep.branch || 'main';
// You can pass the workflow file name as workflow_id (e.g. "examples-apo.yml").
const { data: runsData } = await github.rest.actions.listWorkflowRuns({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: dep.workflow,
branch: 'main', // Always check the main branch status no matter what
status: 'completed', // only completed runs
per_page: 50, // retrieve latest 50 so we can filter
sort: 'created',
direction: 'desc',
});
const filteredRuns = runsData?.workflow_runs?.filter(run => ['schedule', 'workflow_dispatch'].includes(run.event));
const run = filteredRuns?.[0];
if (!run) {
failures.push(`No completed run found for ${dep.label} on branch "${branch}"`);
continue;
}
core.info(`[${dep.label}] Found run ${run.id} with attempt ${run.run_attempt}`);
// Get the specific attempt we want to inspect (latest attempt for that run).
const attempt = run.run_attempt ?? 1;
// Robust: paginate jobs in case the workflow has many.
const jobs = await listAllJobsForAttempt(run.id, attempt);
core.info(`[${dep.label}] Found ${jobs.length} jobs: ${jobs.map(j => j.name).join(', ')}`);
// Match each required variant to a job. We look for the variant in parentheses, e.g. "(latest)".
for (const variant of dep.variants || []) {
const matchingJobs = jobs.filter(
j => typeof j.name === 'string' && j.name.includes(variant)
);
if (matchingJobs.length === 0) {
failures.push(`Missing job for ${dep.label} (variant: ${variant})`);
continue;
}
for (const job of matchingJobs) {
core.info(`[${dep.label}] ${job.name} => ${job.conclusion}`);
// Accept only a strict "success".
if (job.conclusion !== 'success') {
failures.push(`${dep.label} (${job.name}) concluded ${job.conclusion}`);
}
}
}
}
// Surface aggregated result to the workflow.
if (failures.length) {
core.setFailed(failures.join(' | '));
} else {
core.info('All latest variants succeeded.');
}
};