swadhinbiswas Complete PR checks provider parity and setup UX · 2/19/2026
e17418c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { describe, expect, it } from "vitest";
import { normalizeExternalCiCheckPayload } from "@/lib/external-ci-check-payload";
describe("normalizeExternalCiCheckPayload", () => {
it("accepts normalized payloads", () => {
const result = normalizeExternalCiCheckPayload({
pullRequestNumber: 42,
name: "ci/build",
headSha: "abc123",
status: "completed",
conclusion: "success",
});
expect(result.ok).toBe(true);
if (!result.ok) return;
expect(result.data.provider).toBe("normalized");
expect(result.data.status).toBe("completed");
expect(result.data.conclusion).toBe("success");
});
it("normalizes GitHub check_run payloads", () => {
const result = normalizeExternalCiCheckPayload({
check_run: {
id: 999,
name: "build",
head_sha: "abc123",
status: "completed",
conclusion: "success",
details_url: "https://github.com/acme/app/actions/runs/999",
pull_requests: [{ number: 77 }],
},
});
expect(result.ok).toBe(true);
if (!result.ok) return;
expect(result.data.provider).toBe("github_actions");
expect(result.data.pullRequestNumber).toBe(77);
expect(result.data.name).toBe("build");
});
it("normalizes GitLab pipeline payloads", () => {
const result = normalizeExternalCiCheckPayload({
object_kind: "pipeline",
object_attributes: {
id: 1234,
status: "failed",
sha: "abc123",
},
merge_request: { iid: 55 },
});
expect(result.ok).toBe(true);
if (!result.ok) return;
expect(result.data.provider).toBe("gitlab");
expect(result.data.pullRequestNumber).toBe(55);
expect(result.data.status).toBe("completed");
expect(result.data.conclusion).toBe("failure");
});
it("normalizes CircleCI workflow payloads", () => {
const result = normalizeExternalCiCheckPayload({
workflow: {
id: "wf-1",
name: "test",
status: "running",
},
vcs: {
revision: "abc123",
pull_requests: ["https://github.com/acme/app/pull/31"],
},
});
expect(result.ok).toBe(true);
if (!result.ok) return;
expect(result.data.provider).toBe("circleci");
expect(result.data.status).toBe("in_progress");
expect(result.data.pullRequestNumber).toBe(31);
});
it("normalizes Buildkite payloads", () => {
const result = normalizeExternalCiCheckPayload({
build: {
id: "bk-1",
state: "passed",
commit: "abc123",
pipeline: { slug: "app" },
pull_request: { id: 11 },
},
});
expect(result.ok).toBe(true);
if (!result.ok) return;
expect(result.data.provider).toBe("buildkite");
expect(result.data.status).toBe("completed");
expect(result.data.conclusion).toBe("success");
});
it("normalizes Jenkins payloads", () => {
const result = normalizeExternalCiCheckPayload({
status: "SUCCESS",
head_sha: "abc123",
pull_request: { number: 9 },
name: "jenkins/build",
});
expect(result.ok).toBe(true);
if (!result.ok) return;
expect(result.data.provider).toBe("jenkins");
expect(result.data.pullRequestNumber).toBe(9);
expect(result.data.conclusion).toBe("success");
});
it("rejects unsupported payloads", () => {
const result = normalizeExternalCiCheckPayload({ foo: "bar" });
expect(result.ok).toBe(false);
});
});