Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
7 changes: 7 additions & 0 deletions apps/server/src/orchestration-v2/pullRequestWatch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@ describe("evaluatePullRequestWatch", () => {
assert.deepEqual(evaluatePullRequestWatch(watch(), plain, noRemarks).changes, []);
});

it("reports passed when a check was skipped and the rest succeeded", () => {
const green = detail({ checks: [check("checks", "success"), check("deploy", "skipped")] });
assert.deepEqual(evaluatePullRequestWatch(watch(), green, noRemarks).changes, [
{ kind: "checks-passed", count: 2, required: false },
]);
});

it("reports passed again when a required check shows up already passed", () => {
const required = (name: string, status: PullRequestCheck["status"]) => ({
...check(name, status),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { assert, describe, it } from "@effect/vitest";

import { forgejoChecks } from "./forgejoPullRequestJson.ts";

const status = (context: string, state: string) => ({
context,
status: state,
description: null,
target_url: null,
updated_at: "2026-10-05T12:00:00Z",
});

describe("forgejoChecks", () => {
it("maps every Forgejo status state onto a check status, and unknown ones to pending", () => {
const checks = forgejoChecks(
[
status("CI / checks (pull_request)", "success"),
status("CI / e2e (pull_request)", "failure"),
status("CI / lint (pull_request)", "error"),
status("CI / deploy (pull_request)", "skipped"),
status("CI / audit (pull_request)", "warning"),
status("CI / build (pull_request)", "pending"),
status("CI / docs (pull_request)", "future-state"),
],
"https://forgejo.test/acme/web/pulls/1",
);
assert.deepEqual(
checks.map((check) => [check.name, check.status]),
[
["CI / checks (pull_request)", "success"],
["CI / e2e (pull_request)", "failure"],
["CI / lint (pull_request)", "failure"],
["CI / deploy (pull_request)", "skipped"],
["CI / audit (pull_request)", "neutral"],
["CI / build (pull_request)", "pending"],
["CI / docs (pull_request)", "pending"],
],
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as Option from "effect/Option";
import type {
PullRequestActor,
PullRequestCheck,
PullRequestCheckStatus,
PullRequestComment,
PullRequestCommit,
PullRequestReaction,
Expand Down Expand Up @@ -208,6 +209,24 @@ export function forgejoCommit(commit: typeof ForgejoCommit.Type): PullRequestCom
};
}

// Forgejo's commit status states; Actions reports a job that did not run as `skipped` and a
// cancelled job as `failure`. A skipped job is done, so it must not hold back "checks passed".
function forgejoCheckStatus(state: string): PullRequestCheckStatus {
switch (state) {
case "success":
return "success";
case "failure":
case "error":
return "failure";
case "skipped":
return "skipped";
case "warning":
return "neutral";
default:
return "pending";
}
}

export function forgejoChecks(
statuses: ReadonlyArray<typeof ForgejoStatus.Type>,
pullRequestUrl: string,
Expand All @@ -222,12 +241,7 @@ export function forgejoChecks(
url: status.target_url
? (URL.parse(status.target_url, pullRequestUrl)?.href ?? null)
: null,
status:
status.status === "success"
? "success"
: status.status === "failure" || status.status === "error"
? "failure"
: "pending",
status: forgejoCheckStatus(status.status),
},
})),
);
Expand Down
Loading