mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-14 20:37:14 +01:00
test(pregate): clear --run-url accepts a failed or running run of the lane's own workflow (red, GSTA-203 PR 8)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
2b3a7981cd
commit
dae4edb7ec
1 file changed
+19
-3
@@ -73,12 +73,12 @@ function check(repo: FixtureRepo, runs: FakeRun[], over: Partial<RunCheck> = {})
|
||||
return { repo: 'fx/fx', deps, profiles: PROFILES, gateRuns: GATE_RUNS, now: NOW, inventory: () => ['test/a.test.ts', 'test/b.test.ts'], ...over };
|
||||
}
|
||||
|
||||
/** A check whose only readable run is 300, a successful run of `workflow` on `head`. */
|
||||
function runOfWorkflow(repo: FixtureRepo, head: string, workflow: string): RunCheck {
|
||||
/** A check whose only readable run is 300, a run of `workflow` on `head` (completed with success unless `state` says otherwise). */
|
||||
function runOfWorkflow(repo: FixtureRepo, head: string, workflow: string, state: Pick<ApiRun, 'status' | 'conclusion'> = { status: 'completed', conclusion: 'success' }): RunCheck {
|
||||
const c = check(repo, []);
|
||||
const run = (id: number): ApiRun => {
|
||||
if (id !== 300) throw new Error('HTTP 404');
|
||||
return { id, run_attempt: 1, status: 'completed', conclusion: 'success', event: 'pull_request', head_sha: head, path: `.github/workflows/${workflow}`, repository: { full_name: 'fx/fx' }, head_repository: { full_name: 'fx/fx' } };
|
||||
return { id, run_attempt: 1, ...state, event: 'pull_request', head_sha: head, path: `.github/workflows/${workflow}`, repository: { full_name: 'fx/fx' }, head_repository: { full_name: 'fx/fx' } };
|
||||
};
|
||||
return { ...c, deps: { ...c.deps, run } };
|
||||
}
|
||||
@@ -206,6 +206,22 @@ describe.skipIf(process.platform === 'win32')('clear --run: Actions runs as remo
|
||||
expect(clearDecision(file, PLATFORM, { runUrl: url }, repo.work)).toEqual({ receipt: url, attested: false });
|
||||
}, 120_000);
|
||||
|
||||
test('a lane with no profile refuses a --run-url run of its own workflow that failed, was cancelled or is still running, and still clears from a green one (GSTA-203 PR 8)', async () => {
|
||||
const repo = fixture();
|
||||
const head = repo.git('rev-parse', 'HEAD');
|
||||
const base = await pregateAt(repo);
|
||||
const PLATFORM = 'a.yml/job';
|
||||
const file: PregateFile = { ...base, requires_remote: [...base.requires_remote!, { lane: PLATFORM, platform: 'windows', workflow: 'a.yml', job: 'job', tests: ['test/a.test.ts'], receipt: null }] };
|
||||
const url = 'https://github.com/fx/fx/actions/runs/300';
|
||||
const msg = (d: ReturnType<typeof clearDecision>) => ('refused' in d ? `${d.refused}: ${d.message}; fix: ${d.fix}` : `cleared ${d.receipt}`);
|
||||
const rerun = `fix: rerun a.yml (gh run rerun 300, or gh workflow run a.yml --ref <branch>), then gstack-pregate clear --remote ${PLATFORM} --run-url <the green run's URL>`;
|
||||
for (const conclusion of ['failure', 'cancelled', 'timed_out']) {
|
||||
expect(msg(clearDecision(file, PLATFORM, { runUrl: url, evidence: runOfWorkflow(repo, head, 'a.yml', { status: 'completed', conclusion }) }, repo.work))).toBe(`PREGATE_RECEIPT_INVALID: REUSE: refused reason=run_not_success — run 300 attempt 1 concluded ${conclusion}; ${PLATFORM} stays uncleared; ${rerun}`);
|
||||
}
|
||||
expect(msg(clearDecision(file, PLATFORM, { runUrl: `${url}/job/9?pr=1`, evidence: runOfWorkflow(repo, head, 'a.yml', { status: 'in_progress', conclusion: null }) }, repo.work))).toBe(`PREGATE_RECEIPT_INVALID: REUSE: refused reason=run_in_progress — run 300 attempt 1 is in_progress; ${PLATFORM} stays uncleared; fix: wait for run 300 to finish green (or rerun a.yml if it fails), then gstack-pregate clear --remote ${PLATFORM} --run-url <the green run's URL>`);
|
||||
expect(clearDecision(file, PLATFORM, { runUrl: url, evidence: runOfWorkflow(repo, head, 'a.yml') }, repo.work)).toEqual({ receipt: url, attested: false });
|
||||
}, 120_000);
|
||||
|
||||
test('on this repository\'s own workflows the Windows obligation is windows-smoke.yml/windows-smoke: a windows-smoke.yml run clears it, a run of any other workflow is refused (GSTA-203)', async () => {
|
||||
const lanes = discoverLanes(path.resolve(import.meta.dir, '..'), 'linux');
|
||||
const owed = lanes.filter(l => l.tier === 'platform' && l.platform === 'windows' && l.runsTests && !l.manual);
|
||||
|
||||
Reference in new issue
Block a user