Skip to content

Commit 42b7247

Browse files
committed
ci: ignore superseded Periphery runs
1 parent 2d26a36 commit 42b7247

2 files changed

Lines changed: 162 additions & 0 deletions

File tree

.github/workflows/ios-periphery-comment.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,29 @@ jobs:
365365
return;
366366
}
367367
368+
const workflowRuns = await github.paginate(github.rest.actions.listWorkflowRuns, {
369+
owner,
370+
repo,
371+
workflow_id: run.workflow_id,
372+
event: "pull_request",
373+
head_sha: run.head_sha,
374+
per_page: 100,
375+
});
376+
const supersedingRun = workflowRuns.find(
377+
(candidate) =>
378+
(candidate.id === run.id ||
379+
candidate.pull_requests?.some(
380+
(candidatePull) => candidatePull.number === pr.number,
381+
)) &&
382+
(candidate.run_number > run.run_number ||
383+
(candidate.run_number === run.run_number &&
384+
candidate.run_attempt > run.run_attempt)),
385+
);
386+
if (supersedingRun) {
387+
core.info(`Skipping superseded run ${run.id} attempt ${run.run_attempt}; run ${supersedingRun.id} attempt ${supersedingRun.run_attempt} is newer.`);
388+
return;
389+
}
390+
368391
if (existing) {
369392
await github.rest.issues.updateComment({
370393
owner,

test/scripts/ios-periphery-comment-workflow.test.ts

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@ type ExistingComment = {
5050
};
5151
};
5252

53+
type WorkflowRun = {
54+
head_sha: string;
55+
id: number;
56+
pull_requests?: Array<{ number: number }>;
57+
run_attempt: number;
58+
run_number: number;
59+
workflow_id: number;
60+
};
61+
5362
function commenterScript(): string {
5463
const workflow = parse(readFileSync(WORKFLOW_PATH, "utf8")) as Workflow;
5564
const step = workflow.jobs?.comment?.steps?.find(
@@ -71,6 +80,7 @@ async function runCommenter(
7180
liveHeadShaAfter?: string;
7281
runHeadSha?: string;
7382
runAttempt?: number;
83+
workflowRuns?: WorkflowRun[];
7484
} = {},
7585
) {
7686
const script = commenterScript();
@@ -93,6 +103,7 @@ async function runCommenter(
93103
rest: {
94104
actions: {
95105
listWorkflowRunArtifacts() {},
106+
listWorkflowRuns() {},
96107
async downloadArtifact() {
97108
downloadCount += 1;
98109
return { data: archiveData };
@@ -131,6 +142,19 @@ async function runCommenter(
131142
artifactListCount += 1;
132143
return [{ ...artifact, name: artifact.name || ARTIFACT_NAME }];
133144
}
145+
if (params.workflow_id === 999) {
146+
return (
147+
options.workflowRuns ?? [
148+
{
149+
head_sha: options.runHeadSha ?? "head-sha",
150+
id: 12345,
151+
run_attempt: options.runAttempt ?? 2,
152+
run_number: 8,
153+
workflow_id: 999,
154+
},
155+
]
156+
);
157+
}
134158
if (params.issue_number === 123) {
135159
return options.existingComments ?? [];
136160
}
@@ -147,6 +171,8 @@ async function runCommenter(
147171
pull_requests: [{ number: 123 }],
148172
repository: { full_name: "openclaw/openclaw" },
149173
run_attempt: options.runAttempt ?? 2,
174+
run_number: 8,
175+
workflow_id: 999,
150176
},
151177
},
152178
repo: {
@@ -444,6 +470,119 @@ describe("iOS Periphery comment workflow", () => {
444470
expect(result.updatedBodies).toEqual([]);
445471
});
446472

473+
it("does not publish findings from a superseded workflow attempt", async () => {
474+
const archive = makeZip({
475+
"periphery.json": JSON.stringify([
476+
{
477+
kind: "function",
478+
location: "Sources/Test.swift:12",
479+
name: "unused",
480+
},
481+
]),
482+
"periphery.status": "1\n",
483+
});
484+
const result = await runCommenter(
485+
{
486+
expired: false,
487+
id: 77,
488+
name: "ios-periphery-dead-code-12345-1",
489+
size_in_bytes: archive.length,
490+
},
491+
archive,
492+
{
493+
runAttempt: 1,
494+
workflowRuns: [
495+
{
496+
head_sha: "head-sha",
497+
id: 12345,
498+
run_attempt: 2,
499+
run_number: 8,
500+
workflow_id: 999,
501+
},
502+
],
503+
},
504+
);
505+
506+
expect(result.downloadCount).toBe(1);
507+
expect(result.pullGetCount).toBe(2);
508+
expect(result.createdBodies).toEqual([]);
509+
expect(result.updatedBodies).toEqual([]);
510+
});
511+
512+
it("does not publish findings from a newer run for the same pull request", async () => {
513+
const archive = makeZip({
514+
"periphery.json": JSON.stringify([
515+
{
516+
kind: "function",
517+
location: "Sources/Test.swift:12",
518+
name: "unused",
519+
},
520+
]),
521+
"periphery.status": "1\n",
522+
});
523+
const result = await runCommenter(
524+
{
525+
expired: false,
526+
id: 77,
527+
name: ARTIFACT_NAME,
528+
size_in_bytes: archive.length,
529+
},
530+
archive,
531+
{
532+
workflowRuns: [
533+
{
534+
head_sha: "head-sha",
535+
id: 54321,
536+
pull_requests: [{ number: 123 }],
537+
run_attempt: 1,
538+
run_number: 9,
539+
workflow_id: 999,
540+
},
541+
],
542+
},
543+
);
544+
545+
expect(result.createdBodies).toEqual([]);
546+
expect(result.updatedBodies).toEqual([]);
547+
});
548+
549+
it("does not treat a run for another pull request as superseding", async () => {
550+
const archive = makeZip({
551+
"periphery.json": JSON.stringify([
552+
{
553+
kind: "function",
554+
location: "Sources/Test.swift:12",
555+
name: "unused",
556+
},
557+
]),
558+
"periphery.status": "1\n",
559+
});
560+
const result = await runCommenter(
561+
{
562+
expired: false,
563+
id: 77,
564+
name: ARTIFACT_NAME,
565+
size_in_bytes: archive.length,
566+
},
567+
archive,
568+
{
569+
workflowRuns: [
570+
{
571+
head_sha: "head-sha",
572+
id: 54321,
573+
pull_requests: [{ number: 456 }],
574+
run_attempt: 1,
575+
run_number: 9,
576+
workflow_id: 999,
577+
},
578+
],
579+
},
580+
);
581+
582+
expect(result.createdBodies).toHaveLength(1);
583+
expect(result.updatedBodies).toEqual([]);
584+
});
585+
447586
it("escapes finding text before creating a PR comment", async () => {
448587
const longName = `![click](https://example.invalid)\r\n@octocat|next${"a".repeat(260)}`;
449588
const archive = makeZip({

0 commit comments

Comments
 (0)