Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 25 additions & 18 deletions .github/scripts/__tests__/agents-verifier-context.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ const buildGithubStub = ({
},
});

const withEmptyJobs = (result) => ({
...result,
jobs_summary: { total: 0, conclusions: {}, samples: [], truncated: false },
jobs_error_category: '',
jobs_error_message: '',
});

test('buildVerifierContext skips when pull request is not merged', async () => {
const core = buildCore();
const context = {
Expand Down Expand Up @@ -768,27 +775,27 @@ test('buildVerifierContext selects CI results for the merge commit SHA', async (
assert.ok(headShas.length > 0);
assert.ok(headShas.every((sha) => sha === 'merge-sha-333'));
assert.deepEqual(result.ciResults, [
{
withEmptyJobs({
workflow_name: 'Gate',
conclusion: 'success',
run_url: 'https://ci/gate-merge',
error_category: '',
error_message: '',
},
{
}),
withEmptyJobs({
workflow_name: 'Selftest CI',
conclusion: 'success',
run_url: 'https://ci/selftest-merge',
error_category: '',
error_message: '',
},
{
}),
withEmptyJobs({
workflow_name: 'PR 11 - Minimal invariant CI',
conclusion: 'success',
run_url: 'https://ci/pr11-merge',
error_category: '',
error_message: '',
},
}),
]);

const contextPath = result.contextPath || path.join(process.cwd(), 'verifier-context.md');
Expand Down Expand Up @@ -896,27 +903,27 @@ test('buildVerifierContext falls back to head SHA when merge runs are missing',

assert.equal(result.shouldRun, true);
assert.deepEqual(result.ciResults, [
{
withEmptyJobs({
workflow_name: 'Gate',
conclusion: 'success',
run_url: 'https://ci/pr-00-gate.yml',
error_category: '',
error_message: '',
},
{
}),
withEmptyJobs({
workflow_name: 'Selftest CI',
conclusion: 'success',
run_url: 'https://ci/selftest-ci.yml',
error_category: '',
error_message: '',
},
{
}),
withEmptyJobs({
workflow_name: 'PR 11 - Minimal invariant CI',
conclusion: 'success',
run_url: 'https://ci/pr-11-ci-smoke.yml',
error_category: '',
error_message: '',
},
}),
]);
for (const workflowId of workflowIds) {
assert.ok(calls.includes(`${workflowId}:merge-sha-555`));
Expand Down Expand Up @@ -983,27 +990,27 @@ test('buildVerifierContext uses merge commit SHA for push events', async () => {
assert.ok(headShas.length > 0);
assert.ok(headShas.every((sha) => sha === 'merge-sha-444'));
assert.deepEqual(result.ciResults, [
{
withEmptyJobs({
workflow_name: 'Gate',
conclusion: 'success',
run_url: 'https://ci/gate-push',
error_category: '',
error_message: '',
},
{
}),
withEmptyJobs({
workflow_name: 'Selftest CI',
conclusion: 'success',
run_url: 'https://ci/selftest-push',
error_category: '',
error_message: '',
},
{
}),
withEmptyJobs({
workflow_name: 'PR 11 - Minimal invariant CI',
conclusion: 'success',
run_url: 'https://ci/pr11-push',
error_category: '',
error_message: '',
},
}),
]);

const contextPath = result.contextPath || path.join(process.cwd(), 'verifier-context.md');
Expand Down
63 changes: 35 additions & 28 deletions .github/scripts/__tests__/verifier-ci-query.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ const assert = require('node:assert/strict');

const { queryVerifierCiResults } = require('../verifier_ci_query.js');

const withEmptyJobs = (result) => ({
...result,
jobs_summary: { total: 0, conclusions: {}, samples: [], truncated: false },
jobs_error_category: '',
jobs_error_message: '',
});

const buildGithubStub = ({
runsByWorkflow = {},
errorWorkflow = null,
Expand Down Expand Up @@ -57,27 +64,27 @@ test('queryVerifierCiResults selects runs and reports conclusions', async () =>
});

assert.equal(results.length, 3);
assert.deepEqual(results[0], {
assert.deepEqual(results[0], withEmptyJobs({
workflow_name: 'Gate',
conclusion: 'success',
run_url: 'gate-url',
error_category: '',
error_message: '',
});
assert.deepEqual(results[1], {
}));
assert.deepEqual(results[1], withEmptyJobs({
workflow_name: 'Selftest CI',
conclusion: 'in_progress',
run_url: 'selftest-url',
error_category: '',
error_message: '',
});
assert.deepEqual(results[2], {
}));
assert.deepEqual(results[2], withEmptyJobs({
workflow_name: 'PR 11',
conclusion: 'not_found',
run_url: '',
error_category: '',
error_message: '',
});
}));
});

test('queryVerifierCiResults supports workflowId/workflowName aliases', async () => {
Expand All @@ -101,13 +108,13 @@ test('queryVerifierCiResults supports workflowId/workflowName aliases', async ()
});

assert.deepEqual(results, [
{
withEmptyJobs({
workflow_name: 'Selftest CI',
conclusion: 'success',
run_url: 'selftest-alias-url',
error_category: '',
error_message: '',
},
}),
]);
});

Expand All @@ -124,13 +131,13 @@ test('queryVerifierCiResults treats query errors as api_error', async () => {
});

assert.deepEqual(results, [
{
withEmptyJobs({
workflow_name: 'Gate',
conclusion: 'api_error',
run_url: '',
error_category: 'resource',
error_message: 'listWorkflowRuns:pr-00-gate.yml failed after 1 attempt(s): boom',
},
}),
]);
});

Expand All @@ -153,13 +160,13 @@ test('queryVerifierCiResults uses latest run when no target SHA is provided', as
});

assert.deepEqual(results, [
{
withEmptyJobs({
workflow_name: 'Gate',
conclusion: 'success',
run_url: 'gate-latest-url',
error_category: '',
error_message: '',
},
}),
]);
});

Expand Down Expand Up @@ -194,13 +201,13 @@ test('queryVerifierCiResults falls back to secondary SHA when primary has no run
});

assert.deepEqual(results, [
{
withEmptyJobs({
workflow_name: 'Gate',
conclusion: 'success',
run_url: 'head-url',
error_category: '',
error_message: '',
},
}),
]);
assert.deepEqual(headShas, ['merge-sha', 'head-sha']);
});
Expand Down Expand Up @@ -228,27 +235,27 @@ test('queryVerifierCiResults falls back to default workflows', async () => {
});

assert.deepEqual(results, [
{
withEmptyJobs({
workflow_name: 'Gate',
conclusion: 'success',
run_url: 'gate-default-url',
error_category: '',
error_message: '',
},
{
}),
withEmptyJobs({
workflow_name: 'Selftest CI',
conclusion: 'failure',
run_url: 'selftest-default-url',
error_category: '',
error_message: '',
},
{
}),
withEmptyJobs({
workflow_name: 'PR 11 - Minimal invariant CI',
conclusion: 'success',
run_url: 'pr11-default-url',
error_category: '',
error_message: '',
},
}),
]);
});

Expand All @@ -269,13 +276,13 @@ test('queryVerifierCiResults uses API url when html_url is missing', async () =>
});

assert.deepEqual(results, [
{
withEmptyJobs({
workflow_name: 'Gate',
conclusion: 'success',
run_url: 'api-url',
error_category: '',
error_message: '',
},
}),
]);
});

Expand All @@ -296,13 +303,13 @@ test('queryVerifierCiResults treats completed runs without conclusion as unknown
});

assert.deepEqual(results, [
{
withEmptyJobs({
workflow_name: 'Gate',
conclusion: 'unknown',
run_url: 'gate-url',
error_category: '',
error_message: '',
},
}),
]);
});

Expand Down Expand Up @@ -341,13 +348,13 @@ test('queryVerifierCiResults retries transient errors and returns success', asyn
assert.equal(attempts, 3);
assert.equal(warnings.length, 2);
assert.deepEqual(results, [
{
withEmptyJobs({
workflow_name: 'Gate',
conclusion: 'success',
run_url: 'retry-url',
error_category: '',
error_message: '',
},
}),
]);
});

Expand Down Expand Up @@ -381,13 +388,13 @@ test('queryVerifierCiResults returns api_error after max retries', async (t) =>
assert.equal(attempts, 4);
assert.equal(warnings.length, 4);
assert.deepEqual(results, [
{
withEmptyJobs({
workflow_name: 'Gate',
conclusion: 'api_error',
run_url: '',
error_category: 'transient',
error_message: `listWorkflowRuns:pr-00-gate.yml failed after 4 attempt(s): status-${status}`,
},
}),
]);
});
}
Expand Down
21 changes: 19 additions & 2 deletions .github/workflows/agents-auto-pilot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ jobs:
if: steps.check_enabled.outputs.enabled == 'true'
uses: actions/checkout@v6

- name: Set up Node
if: steps.check_enabled.outputs.enabled == 'true'
uses: actions/setup-node@v6
with:
node-version: '20'

- name: Install GitHub API dependencies
if: steps.check_enabled.outputs.enabled == 'true'
run: npm install --no-save --no-package-lock @octokit/rest @octokit/auth-app

- name: Export load balancer tokens
if: steps.check_enabled.outputs.enabled == 'true'
uses: ./.github/actions/export-load-balancer-tokens
Expand All @@ -128,10 +138,17 @@ jobs:
uses: actions/github-script@v8
with:
script: |
const { data } = await github.rest.repos.get({
const { createTokenAwareRetry } = require('./.github/scripts/github-api-with-retry.js');
const { withRetry } = await createTokenAwareRetry({
github,
core,
task: 'auto-pilot-resolve-workflows-ref',
});

const { data } = await withRetry((client) => client.rest.repos.get({
owner: 'stranske',
repo: 'Workflows'
});
}));
if (!data?.default_branch) {
core.setFailed('Could not determine Workflows default branch');
return;
Expand Down
Loading
Loading