Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle multi-step states #156

Merged
merged 3 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
# apt update is implicit
# pinning package implicit
# depext install implicit
- run: opam install . ocamlformat.0.20.1
- run: opam install . ocamlformat.0.26.2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this kind of change should go to master directly


- name: compile
run: opam exec -- make
Expand Down
4 changes: 2 additions & 2 deletions lib/action.ml
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
| Some branch_statuses ->
let has_same_status_as_prev (branch : branch) =
match StringMap.find_opt branch.name branch_statuses with
| Some state when state = current_status -> true
| Some { status; _ } when status = current_status -> true
| _ -> false
in
let branches = List.filter (Fun.negate has_same_status_as_prev) n.branches in
Expand All @@ -196,7 +196,7 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
end
else Lwt.return []
in
State.set_repo_pipeline_status ctx.state repo.url ~pipeline ~branches:n.branches ~status:current_status;
State.set_repo_pipeline_status ctx.state repo.url ~pipeline n;
Lwt.return recipients

let partition_commit_comment (ctx : Context.t) n =
Expand Down
16 changes: 15 additions & 1 deletion lib/state.atd
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,22 @@ type 'v map_as_object <ocaml from="Common"> = abstract
type 'v table_as_object <ocaml from="Common"> = abstract
type string_set <ocaml from="Common"> = abstract

type ci_commit = {
sha: string;
author: string;
commit_message: string;
build_link: string option;
last_updated: string;
}

type build_status = {
status: status_state;
?original_failed_commit:ci_commit nullable;
?current_failed_commit:ci_commit nullable;
}

(* A map from branch names to build statuses *)
type branch_statuses = status_state map_as_object
type branch_statuses = build_status map_as_object

(* A map from pipeline names to [branch_statuses] maps. This tracks the
last build state matched by the status_rules for each pipeline and
Expand Down
58 changes: 54 additions & 4 deletions lib/state.ml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,60 @@ let find_or_add_repo' state repo_url =
let set_repo_state { state } repo_url repo_state = Stringtbl.replace state.repos repo_url repo_state
let find_or_add_repo { state } repo_url = find_or_add_repo' state repo_url

let set_repo_pipeline_status { state } repo_url ~pipeline ~(branches : Github_t.branch list) ~status =
let set_branch_status branch_statuses =
let new_statuses = List.map (fun (b : Github_t.branch) -> b.name, status) branches in
let init = Option.default StringMap.empty branch_statuses in
let set_repo_pipeline_status { state } repo_url ~pipeline (notification : Github_t.status_notification) =
let branches = notification.branches in
let set_branch_status per_branch_statuses =
let current_fail_state =
match notification.state with
| Failure | Error ->
Some
{
State_t.sha = notification.sha;
author = notification.commit.commit.author.email;
commit_message = notification.commit.commit.message;
last_updated = notification.updated_at;
build_link = notification.target_url;
}
| _ -> None
in
let initial_build_status_state =
{ State_t.status = notification.state; original_failed_commit = None; current_failed_commit = None }
in
let new_statuses =
List.map
(fun (branch : Github_t.branch) ->
let step_status =
Option.map_default
(fun all_branches_statuses ->
match StringMap.find_opt branch.name all_branches_statuses with
| Some (current_build_status : State_t.build_status) ->
let new_state = notification.state in
let original_failed_commit, current_failed_commit =
match new_state with
| Success -> None, None
| Pending ->
(* when new jobs are pending, we keep the existing state *)
current_build_status.original_failed_commit, current_build_status.current_failed_commit
| Failure | Error ->
(* if we don't have a failed step yet, set it *)
(* if we have a failed build and are retrying failed jobs: *)
(* - if we retried the original commit job, update the timestamp *)
(* - if we have a different commit that is failing that step, update the new failing commit *)
match current_build_status.original_failed_commit with
| None -> current_fail_state, None
| Some original_failed_commit ->
match original_failed_commit.sha = notification.sha with
| true -> current_fail_state, current_build_status.current_failed_commit
| false -> current_build_status.original_failed_commit, current_fail_state
in
{ State_t.status = new_state; original_failed_commit; current_failed_commit }
| None -> initial_build_status_state)
initial_build_status_state per_branch_statuses
in
branch.name, step_status)
branches
in
let init = Option.default StringMap.empty per_branch_statuses in
Some (List.fold_left (fun m (key, data) -> StringMap.add key data m) init new_statuses)
in
let repo_state = find_or_add_repo' state repo_url in
Expand Down
2 changes: 1 addition & 1 deletion mock_payloads/status.state_hide_success_test.json
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,4 @@
"type": "User",
"site_admin": true
}
}
}
18 changes: 14 additions & 4 deletions mock_states/status.commit1-02-failed.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
{
"pipeline_statuses": {
"buildkite/pipeline2": {
"master": "failure"
"master": {
"status": "failure",
"original_failed_commit": {
"sha": "7e0a933e9c71b4ca107680ca958ca1888d5e479b",
"author": "[email protected]",
"commit_message": "c1 message",
"build_link": [
"Some",
"https://buildkite.com/ahrefs/monorepo/builds/181732"
],
"last_updated": "2024-06-02T04:57:47+00:00"
}
}
}
},
"pipeline_commits": {
"buildkite/pipeline2": {
"s1": [
"7e0a933e9c71b4ca107680ca958ca1888d5e479b"
],
"s1": ["7e0a933e9c71b4ca107680ca958ca1888d5e479b"],
"s2": []
}
}
Expand Down
18 changes: 16 additions & 2 deletions mock_states/status.state_hide_success_test.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
{
"pipeline_statuses": {
"default": {
"master": "failure"
"master": {
"status": "failure",
"original_failed_commit": {
"sha": "0d95302addd66c1816bce1b1d495ed1c93ccd478",
"author": "[email protected]",
"commit_message": "Update README.md",
"build_link": [
"Some",
"https://buildkite.com/org/pipeline2/builds/2"
],
"last_updated": "2020-06-02T03:21:39+00:00"
}
}
},
"buildkite/pipeline2": {
"master": "success"
"master": {
"status": "success"
}
}
},
"pipeline_commits": {}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
{
"pipeline_statuses": {
"buildkite/pipeline2": {
"master": "failure"
"master": {
"status": "failure",
"original_failed_commit": {
"sha": "0d95302addd66c1816bce1b1d495ed1c93ccd478",
"author": "[email protected]",
"commit_message": "Update README.md",
"build_link": [
"Some",
"https://buildkite.com/org/pipeline2/builds/2"
],
"last_updated": "2020-06-02T03:21:39+00:00"
}
}
}
},
"pipeline_commits": {}
Expand Down
Loading