Skip to content

Commit

Permalink
Add per pipeline failed builds channel config (#164)
Browse files Browse the repository at this point in the history
* add per pipeline failed builds channel cfg

* add atd adapter for old allowed_pipelines config
  • Loading branch information
thatportugueseguy authored Oct 18, 2024
1 parent caf3992 commit 94fcbbb
Show file tree
Hide file tree
Showing 15 changed files with 1,178 additions and 12 deletions.
19 changes: 14 additions & 5 deletions lib/action.ml
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,23 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
in
let notify_failed_builds_channel =
(* we only notify the failed builds channels for failed builds on the main branch *)
Util.Build.is_failed_build n && Option.is_some cfg.status_rules.failed_builds_channel && is_main_branch
Util.Build.is_failed_build n && Option.is_some cfg.status_rules.allowed_pipelines && is_main_branch
in
match notify_failed_builds_channel with
| false -> Lwt.return (direct_message @ chans)
| true ->
match notify_failed_builds_channel, cfg.status_rules.allowed_pipelines with
| false, _ | true, None -> Lwt.return (direct_message @ chans)
| true, Some allowed_pipelines ->
(* if we have a failed build and a failed builds channel, we send one notification there too,
but we don't notify the same channel twice *)
let chans = Option.get cfg.status_rules.failed_builds_channel :: chans |> List.sort_uniq String.compare in
let chans =
List.find_map
(fun ({ name; failed_builds_channel } : Config_t.pipeline) ->
match String.equal name n.context, failed_builds_channel with
| true, Some failed_builds_channel -> Some (failed_builds_channel :: chans)
| _ -> None)
allowed_pipelines
|> Option.default chans
|> List.sort_uniq String.compare
in
Lwt.return (direct_message @ chans)
in
let%lwt recipients =
Expand Down
14 changes: 14 additions & 0 deletions lib/atd_adapters.ml
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,17 @@ module Slack_response_adapter : Atdgen_runtime.Json_adapter.S = struct
| `List [ `String "Error"; `String msg ] -> `Assoc (mk_fields false [ "error", `String msg ])
| _ -> x
end

(* This adapter is meant to avoid breaking changes in the config because the type for
[allowed_pipelines] was changed from a string list to a pipeline record list. *)
module Strings_to_pipelines_adapter : Atdgen_runtime.Json_adapter.S = struct
let normalize (x : Yojson.Safe.t) =
match x with
| `String s -> `Assoc [ "name", `String s; "failed_builds_channel", `Null ]
| _ -> x

let restore (x : Yojson.Safe.t) =
match x with
| `Assoc [ ("name", `String s); ("failed_builds_channel", _) ] -> `String s
| _ -> x
end
10 changes: 7 additions & 3 deletions lib/config.atd
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ type prefix_rule <ocaml from="Rule"> = abstract
type label_rule <ocaml from="Rule"> = abstract
type project_owners_rule <ocaml from="Rule"> = abstract

type pipeline = {
name: string;
?failed_builds_channel: string nullable;
} <json adapter.ocaml="Atd_adapters.Strings_to_pipelines_adapter">

(* This type of rule is used for CI build notifications. *)
type status_rules = {
?allowed_pipelines : string list nullable; (* keep only status events with a title matching this list *)
?failed_builds_channel: string nullable; (* channel to post failed builds notifications to *)
?allowed_pipelines : pipeline list nullable; (* keep only status events with a title matching this list *)
rules: status_rule list;
}

Expand Down Expand Up @@ -34,7 +38,7 @@ type project_owners = {
type config = {
prefix_rules : prefix_rules;
label_rules : label_rules;
~status_rules <ocaml default="{allowed_pipelines = Some []; rules = []; failed_builds_channel = None}"> : status_rules;
~status_rules <ocaml default="{allowed_pipelines = None; rules = []}"> : status_rules;
~project_owners <ocaml default="{rules = []}"> : project_owners;
~ignored_users <ocaml default="[]">: string list; (* list of ignored users *)
?main_branch_name : string nullable; (* the name of the main branch; used to filter out notifications about merges of main branch into other branches *)
Expand Down
4 changes: 3 additions & 1 deletion lib/context.ml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ let is_pipeline_allowed ctx repo_url ~pipeline =
| None -> true
| Some config ->
match config.status_rules.allowed_pipelines with
| Some allowed_pipelines when not @@ List.exists (String.equal pipeline) allowed_pipelines -> false
| Some allowed_pipelines
when not @@ List.exists (fun (p : Config_t.pipeline) -> String.equal p.name pipeline) allowed_pipelines ->
false
| _ -> true

let refresh_secrets ctx =
Expand Down
8 changes: 7 additions & 1 deletion lib/slack.ml
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,13 @@ let generate_status_notification ~(ctx : Context.t) ?slack_user_id (cfg : Config
in
let failed_builds_info =
let is_failed_builds_channel =
Option.map_default (String.equal channel) false cfg.status_rules.failed_builds_channel
match cfg.status_rules.allowed_pipelines with
| None -> false
| Some pipelines ->
List.exists
(fun ({ name; failed_builds_channel } : Config_t.pipeline) ->
String.equal name context && Option.map_default (String.equal channel) false failed_builds_channel)
pipelines
in
match Util.Build.is_failed_build notification && is_failed_builds_channel with
| false -> []
Expand Down
252 changes: 252 additions & 0 deletions mock_payloads/status.commit1-02-failed_diff_pipeline.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
{
"id": 17813296,
"sha": "7e0a933e9c71b4ca107680ca958ca1888d5e479b",
"name": "ahrefs/monorepo",
"target_url": "https://buildkite.com/ahrefs/monorepo/builds/181732",
"avatar_url": "https://github.com/avatars/oa/6?",
"context": "buildkite/qa",
"description": "Build #181732 failed (7 minutes, 29 seconds)",
"state": "failure",
"commit": {
"sha": "7e0a933e9c71b4ca107680ca958ca1888d5e479b",
"node_id": "MDY6Q29tbWl0ODU6N2UwYTkzM2U5YzcxYjRjYTEwNzY4MGNhOTU4Y2ExODg4ZDVlNDc5Yg==",
"commit": {
"author": {
"name": "author",
"email": "[email protected]",
"date": "2024-05-31T03:54:00Z"
},
"committer": {
"name": "author",
"email": "[email protected]",
"date": "2024-05-31T03:54:00Z"
},
"message": "c1 message",
"tree": {
"sha": "51d7c2d0fc8f182f8ffad40ef79471789e6f5578",
"url": "https://github.com/api/v3/repos/ahrefs/monorepo/git/trees/51d7c2d0fc8f182f8ffad40ef79471789e6f5578"
},
"url": "https://github.com/api/v3/repos/ahrefs/monorepo/git/commits/7e0a933e9c71b4ca107680ca958ca1888d5e479b",
"comment_count": 0,
"verification": {
"verified": false,
"reason": "unsigned",
"signature": null,
"payload": null
}
},
"url": "https://github.com/api/v3/repos/ahrefs/monorepo/commits/7e0a933e9c71b4ca107680ca958ca1888d5e479b",
"html_url": "https://github.com/ahrefs/monorepo/commit/7e0a933e9c71b4ca107680ca958ca1888d5e479b",
"comments_url": "https://github.com/api/v3/repos/ahrefs/monorepo/commits/7e0a933e9c71b4ca107680ca958ca1888d5e479b/comments",
"author": {
"login": "author",
"id": 92,
"node_id": "MDQ6VXNlcjky",
"avatar_url": "https://github.com/avatars/u/92?",
"gravatar_id": "",
"url": "https://github.com/api/v3/users/author",
"html_url": "https://github.com/author",
"followers_url": "https://github.com/api/v3/users/author/followers",
"following_url": "https://github.com/api/v3/users/author/following{/other_user}",
"gists_url": "https://github.com/api/v3/users/author/gists{/gist_id}",
"starred_url": "https://github.com/api/v3/users/author/starred{/owner}{/repo}",
"subscriptions_url": "https://github.com/api/v3/users/author/subscriptions",
"organizations_url": "https://github.com/api/v3/users/author/orgs",
"repos_url": "https://github.com/api/v3/users/author/repos",
"events_url": "https://github.com/api/v3/users/author/events{/privacy}",
"received_events_url": "https://github.com/api/v3/users/author/received_events",
"type": "User",
"site_admin": false
},
"committer": {
"login": "author",
"id": 92,
"node_id": "MDQ6VXNlcjky",
"avatar_url": "https://github.com/avatars/u/92?",
"gravatar_id": "",
"url": "https://github.com/api/v3/users/author",
"html_url": "https://github.com/author",
"followers_url": "https://github.com/api/v3/users/author/followers",
"following_url": "https://github.com/api/v3/users/author/following{/other_user}",
"gists_url": "https://github.com/api/v3/users/author/gists{/gist_id}",
"starred_url": "https://github.com/api/v3/users/author/starred{/owner}{/repo}",
"subscriptions_url": "https://github.com/api/v3/users/author/subscriptions",
"organizations_url": "https://github.com/api/v3/users/author/orgs",
"repos_url": "https://github.com/api/v3/users/author/repos",
"events_url": "https://github.com/api/v3/users/author/events{/privacy}",
"received_events_url": "https://github.com/api/v3/users/author/received_events",
"type": "User",
"site_admin": false
},
"parents": [
{
"sha": "b2f115b1be68ab14975f0e581283a954bf67734a",
"url": "https://github.com/api/v3/repos/ahrefs/monorepo/commits/b2f115b1be68ab14975f0e581283a954bf67734a",
"html_url": "https://github.com/ahrefs/monorepo/commit/b2f115b1be68ab14975f0e581283a954bf67734a"
},
{
"sha": "53f8468ca5eafb0e0885b9d62806c52c872ea2af",
"url": "https://github.com/api/v3/repos/ahrefs/monorepo/commits/53f8468ca5eafb0e0885b9d62806c52c872ea2af",
"html_url": "https://github.com/ahrefs/monorepo/commit/53f8468ca5eafb0e0885b9d62806c52c872ea2af"
}
]
},
"branches": [
{
"name": "author/patches/js-storage",
"commit": {
"sha": "7e0a933e9c71b4ca107680ca958ca1888d5e479b",
"url": "https://github.com/api/v3/repos/ahrefs/monorepo/commits/7e0a933e9c71b4ca107680ca958ca1888d5e479b"
},
"protected": false
}
],
"created_at": "2024-06-02T04:57:47+00:00",
"updated_at": "2024-06-02T04:57:47+00:00",
"repository": {
"id": 85,
"node_id": "MDEwOlJlcG9zaXRvcnk4NQ==",
"name": "monorepo",
"full_name": "ahrefs/monorepo",
"private": true,
"owner": {
"login": "ahrefs",
"id": 7,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc=",
"avatar_url": "https://github.com/avatars/u/7?",
"gravatar_id": "",
"url": "https://github.com/api/v3/users/ahrefs",
"html_url": "https://github.com/ahrefs",
"followers_url": "https://github.com/api/v3/users/ahrefs/followers",
"following_url": "https://github.com/api/v3/users/ahrefs/following{/other_user}",
"gists_url": "https://github.com/api/v3/users/ahrefs/gists{/gist_id}",
"starred_url": "https://github.com/api/v3/users/ahrefs/starred{/owner}{/repo}",
"subscriptions_url": "https://github.com/api/v3/users/ahrefs/subscriptions",
"organizations_url": "https://github.com/api/v3/users/ahrefs/orgs",
"repos_url": "https://github.com/api/v3/users/ahrefs/repos",
"events_url": "https://github.com/api/v3/users/ahrefs/events{/privacy}",
"received_events_url": "https://github.com/api/v3/users/ahrefs/received_events",
"type": "Organization",
"site_admin": false
},
"html_url": "https://github.com/ahrefs/monorepo",
"description": "main repository",
"fork": false,
"url": "https://github.com/api/v3/repos/ahrefs/monorepo",
"forks_url": "https://github.com/api/v3/repos/ahrefs/monorepo/forks",
"keys_url": "https://github.com/api/v3/repos/ahrefs/monorepo/keys{/key_id}",
"collaborators_url": "https://github.com/api/v3/repos/ahrefs/monorepo/collaborators{/collaborator}",
"teams_url": "https://github.com/api/v3/repos/ahrefs/monorepo/teams",
"hooks_url": "https://github.com/api/v3/repos/ahrefs/monorepo/hooks",
"issue_events_url": "https://github.com/api/v3/repos/ahrefs/monorepo/issues/events{/number}",
"events_url": "https://github.com/api/v3/repos/ahrefs/monorepo/events",
"assignees_url": "https://github.com/api/v3/repos/ahrefs/monorepo/assignees{/user}",
"branches_url": "https://github.com/api/v3/repos/ahrefs/monorepo/branches{/branch}",
"tags_url": "https://github.com/api/v3/repos/ahrefs/monorepo/tags",
"blobs_url": "https://github.com/api/v3/repos/ahrefs/monorepo/git/blobs{/sha}",
"git_tags_url": "https://github.com/api/v3/repos/ahrefs/monorepo/git/tags{/sha}",
"git_refs_url": "https://github.com/api/v3/repos/ahrefs/monorepo/git/refs{/sha}",
"trees_url": "https://github.com/api/v3/repos/ahrefs/monorepo/git/trees{/sha}",
"statuses_url": "https://github.com/api/v3/repos/ahrefs/monorepo/statuses/{sha}",
"languages_url": "https://github.com/api/v3/repos/ahrefs/monorepo/languages",
"stargazers_url": "https://github.com/api/v3/repos/ahrefs/monorepo/stargazers",
"contributors_url": "https://github.com/api/v3/repos/ahrefs/monorepo/contributors",
"subscribers_url": "https://github.com/api/v3/repos/ahrefs/monorepo/subscribers",
"subscription_url": "https://github.com/api/v3/repos/ahrefs/monorepo/subscription",
"commits_url": "https://github.com/api/v3/repos/ahrefs/monorepo/commits{/sha}",
"git_commits_url": "https://github.com/api/v3/repos/ahrefs/monorepo/git/commits{/sha}",
"comments_url": "https://github.com/api/v3/repos/ahrefs/monorepo/comments{/number}",
"issue_comment_url": "https://github.com/api/v3/repos/ahrefs/monorepo/issues/comments{/number}",
"contents_url": "https://github.com/api/v3/repos/ahrefs/monorepo/contents/{+path}",
"compare_url": "https://github.com/api/v3/repos/ahrefs/monorepo/compare/{base}...{head}",
"merges_url": "https://github.com/api/v3/repos/ahrefs/monorepo/merges",
"archive_url": "https://github.com/api/v3/repos/ahrefs/monorepo/{archive_format}{/ref}",
"downloads_url": "https://github.com/api/v3/repos/ahrefs/monorepo/downloads",
"issues_url": "https://github.com/api/v3/repos/ahrefs/monorepo/issues{/number}",
"pulls_url": "https://github.com/api/v3/repos/ahrefs/monorepo/pulls{/number}",
"milestones_url": "https://github.com/api/v3/repos/ahrefs/monorepo/milestones{/number}",
"notifications_url": "https://github.com/api/v3/repos/ahrefs/monorepo/notifications{?since,all,participating}",
"labels_url": "https://github.com/api/v3/repos/ahrefs/monorepo/labels{/name}",
"releases_url": "https://github.com/api/v3/repos/ahrefs/monorepo/releases{/id}",
"deployments_url": "https://github.com/api/v3/repos/ahrefs/monorepo/deployments",
"created_at": "2017-03-06T23:40:04Z",
"updated_at": "2024-05-14T07:59:19Z",
"pushed_at": "2024-06-02T04:49:58Z",
"git_url": "git://github.com/ahrefs/monorepo.git",
"ssh_url": "[email protected]:ahrefs/monorepo.git",
"clone_url": "https://github.com/ahrefs/monorepo.git",
"svn_url": "https://github.com/ahrefs/monorepo",
"homepage": "https://ahrefs.com",
"size": 2927252,
"stargazers_count": 6,
"watchers_count": 6,
"language": "HTML",
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": false,
"has_discussions": false,
"forks_count": 0,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 422,
"license": null,
"allow_forking": false,
"is_template": false,
"web_commit_signoff_required": false,
"topics": [],
"visibility": "private",
"forks": 0,
"open_issues": 422,
"watchers": 6,
"default_branch": "develop"
},
"organization": {
"login": "ahrefs",
"id": 7,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc=",
"url": "https://github.com/api/v3/orgs/ahrefs",
"repos_url": "https://github.com/api/v3/orgs/ahrefs/repos",
"events_url": "https://github.com/api/v3/orgs/ahrefs/events",
"hooks_url": "https://github.com/api/v3/orgs/ahrefs/hooks",
"issues_url": "https://github.com/api/v3/orgs/ahrefs/issues",
"members_url": "https://github.com/api/v3/orgs/ahrefs/members{/member}",
"public_members_url": "https://github.com/api/v3/orgs/ahrefs/public_members{/member}",
"avatar_url": "https://github.com/avatars/u/7?",
"description": null
},
"enterprise": {
"id": 1,
"slug": "ahrefs-pte-ltd",
"name": "Ahrefs Pte Ltd",
"node_id": "MDEwOkVudGVycHJpc2Ux",
"avatar_url": "https://github.com/avatars/b/1?",
"description": null,
"website_url": null,
"html_url": "https://github.com/enterprises/ahrefs-pte-ltd",
"created_at": "2019-01-09T18:50:55Z",
"updated_at": "2024-03-18T14:38:02Z"
},
"sender": {
"login": "ip",
"id": 3,
"node_id": "MDQ6VXNlcjM=",
"avatar_url": "https://github.com/avatars/u/3?",
"gravatar_id": "",
"url": "https://github.com/api/v3/users/ip",
"html_url": "https://github.com/ip",
"followers_url": "https://github.com/api/v3/users/ip/followers",
"following_url": "https://github.com/api/v3/users/ip/following{/other_user}",
"gists_url": "https://github.com/api/v3/users/ip/gists{/gist_id}",
"starred_url": "https://github.com/api/v3/users/ip/starred{/owner}{/repo}",
"subscriptions_url": "https://github.com/api/v3/users/ip/subscriptions",
"organizations_url": "https://github.com/api/v3/users/ip/orgs",
"repos_url": "https://github.com/api/v3/users/ip/repos",
"events_url": "https://github.com/api/v3/users/ip/events{/privacy}",
"received_events_url": "https://github.com/api/v3/users/ip/received_events",
"type": "User",
"site_admin": true
}
}
Loading

0 comments on commit 94fcbbb

Please sign in to comment.