Skip to content

Commit 3d97884

Browse files
handle multi-step states (#156)
* handle multi-step states * update ci step ocamlformat dep * inline comment
1 parent 3c18db3 commit 3d97884

7 files changed

+115
-15
lines changed

lib/action.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
182182
| Some branch_statuses ->
183183
let has_same_status_as_prev (branch : branch) =
184184
match StringMap.find_opt branch.name branch_statuses with
185-
| Some state when state = current_status -> true
185+
| Some { status; _ } when status = current_status -> true
186186
| _ -> false
187187
in
188188
let branches = List.filter (Fun.negate has_same_status_as_prev) n.branches in
@@ -196,7 +196,7 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
196196
end
197197
else Lwt.return []
198198
in
199-
State.set_repo_pipeline_status ctx.state repo.url ~pipeline ~branches:n.branches ~status:current_status;
199+
State.set_repo_pipeline_status ctx.state repo.url ~pipeline n;
200200
Lwt.return recipients
201201

202202
let partition_commit_comment (ctx : Context.t) n =

lib/state.atd

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,22 @@ type 'v map_as_object <ocaml from="Common"> = abstract
33
type 'v table_as_object <ocaml from="Common"> = abstract
44
type string_set <ocaml from="Common"> = abstract
55

6+
type ci_commit = {
7+
sha: string;
8+
author: string;
9+
commit_message: string;
10+
build_link: string option;
11+
last_updated: string;
12+
}
13+
14+
type build_status = {
15+
status: status_state;
16+
?original_failed_commit:ci_commit nullable;
17+
?current_failed_commit:ci_commit nullable;
18+
}
19+
620
(* A map from branch names to build statuses *)
7-
type branch_statuses = status_state map_as_object
21+
type branch_statuses = build_status map_as_object
822

923
(* A map from pipeline names to [branch_statuses] maps. This tracks the
1024
last build state matched by the status_rules for each pipeline and

lib/state.ml

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,60 @@ let find_or_add_repo' state repo_url =
2323
let set_repo_state { state } repo_url repo_state = Stringtbl.replace state.repos repo_url repo_state
2424
let find_or_add_repo { state } repo_url = find_or_add_repo' state repo_url
2525

26-
let set_repo_pipeline_status { state } repo_url ~pipeline ~(branches : Github_t.branch list) ~status =
27-
let set_branch_status branch_statuses =
28-
let new_statuses = List.map (fun (b : Github_t.branch) -> b.name, status) branches in
29-
let init = Option.default StringMap.empty branch_statuses in
26+
let set_repo_pipeline_status { state } repo_url ~pipeline (notification : Github_t.status_notification) =
27+
let branches = notification.branches in
28+
let set_branch_status per_branch_statuses =
29+
let current_fail_state =
30+
match notification.state with
31+
| Failure | Error ->
32+
Some
33+
{
34+
State_t.sha = notification.sha;
35+
author = notification.commit.commit.author.email;
36+
commit_message = notification.commit.commit.message;
37+
last_updated = notification.updated_at;
38+
build_link = notification.target_url;
39+
}
40+
| _ -> None
41+
in
42+
let initial_build_status_state =
43+
{ State_t.status = notification.state; original_failed_commit = None; current_failed_commit = None }
44+
in
45+
let new_statuses =
46+
List.map
47+
(fun (branch : Github_t.branch) ->
48+
let step_status =
49+
Option.map_default
50+
(fun all_branches_statuses ->
51+
match StringMap.find_opt branch.name all_branches_statuses with
52+
| Some (current_build_status : State_t.build_status) ->
53+
let new_state = notification.state in
54+
let original_failed_commit, current_failed_commit =
55+
match new_state with
56+
| Success -> None, None
57+
| Pending ->
58+
(* when new jobs are pending, we keep the existing state *)
59+
current_build_status.original_failed_commit, current_build_status.current_failed_commit
60+
| Failure | Error ->
61+
(* if we don't have a failed step yet, set it *)
62+
(* if we have a failed build and are retrying failed jobs: *)
63+
(* - if we retried the original commit job, update the timestamp *)
64+
(* - if we have a different commit that is failing that step, update the new failing commit *)
65+
match current_build_status.original_failed_commit with
66+
| None -> current_fail_state, None
67+
| Some original_failed_commit ->
68+
match original_failed_commit.sha = notification.sha with
69+
| true -> current_fail_state, current_build_status.current_failed_commit
70+
| false -> current_build_status.original_failed_commit, current_fail_state
71+
in
72+
{ State_t.status = new_state; original_failed_commit; current_failed_commit }
73+
| None -> initial_build_status_state)
74+
initial_build_status_state per_branch_statuses
75+
in
76+
branch.name, step_status)
77+
branches
78+
in
79+
let init = Option.default StringMap.empty per_branch_statuses in
3080
Some (List.fold_left (fun m (key, data) -> StringMap.add key data m) init new_statuses)
3181
in
3282
let repo_state = find_or_add_repo' state repo_url in

mock_payloads/status.state_hide_success_test.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,4 @@
219219
"type": "User",
220220
"site_admin": true
221221
}
222-
}
222+
}

mock_states/status.commit1-02-failed.json

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
{
22
"pipeline_statuses": {
33
"buildkite/pipeline2": {
4-
"master": "failure"
4+
"master": {
5+
"status": "failure",
6+
"original_failed_commit": {
7+
"sha": "7e0a933e9c71b4ca107680ca958ca1888d5e479b",
8+
"author": "author@ahrefs.com",
9+
"commit_message": "c1 message",
10+
"build_link": [
11+
"Some",
12+
"https://buildkite.com/ahrefs/monorepo/builds/181732"
13+
],
14+
"last_updated": "2024-06-02T04:57:47+00:00"
15+
}
16+
}
517
}
618
},
719
"pipeline_commits": {
820
"buildkite/pipeline2": {
9-
"s1": [
10-
"7e0a933e9c71b4ca107680ca958ca1888d5e479b"
11-
],
21+
"s1": ["7e0a933e9c71b4ca107680ca958ca1888d5e479b"],
1222
"s2": []
1323
}
1424
}

mock_states/status.state_hide_success_test.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
11
{
22
"pipeline_statuses": {
33
"default": {
4-
"master": "failure"
4+
"master": {
5+
"status": "failure",
6+
"original_failed_commit": {
7+
"sha": "0d95302addd66c1816bce1b1d495ed1c93ccd478",
8+
"author": "mail@example.org",
9+
"commit_message": "Update README.md",
10+
"build_link": [
11+
"Some",
12+
"https://buildkite.com/org/pipeline2/builds/2"
13+
],
14+
"last_updated": "2020-06-02T03:21:39+00:00"
15+
}
16+
}
517
},
618
"buildkite/pipeline2": {
7-
"master": "success"
19+
"master": {
20+
"status": "success"
21+
}
822
}
923
},
1024
"pipeline_commits": {}

mock_states/status.state_hide_success_test_disallowed_pipeline.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
{
22
"pipeline_statuses": {
33
"buildkite/pipeline2": {
4-
"master": "failure"
4+
"master": {
5+
"status": "failure",
6+
"original_failed_commit": {
7+
"sha": "0d95302addd66c1816bce1b1d495ed1c93ccd478",
8+
"author": "mail@example.org",
9+
"commit_message": "Update README.md",
10+
"build_link": [
11+
"Some",
12+
"https://buildkite.com/org/pipeline2/builds/2"
13+
],
14+
"last_updated": "2020-06-02T03:21:39+00:00"
15+
}
16+
}
517
}
618
},
719
"pipeline_commits": {}

0 commit comments

Comments
 (0)