Skip to content

Commit

Permalink
distinguish status notifications channels
Browse files Browse the repository at this point in the history
  • Loading branch information
thatportugueseguy committed Dec 20, 2024
1 parent f119bc3 commit 3988656
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 28 deletions.
30 changes: 8 additions & 22 deletions lib/action.ml
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
| Ok res ->
let is_failing_build = Util.Build.is_failing_build n in
let is_failed_build = Util.Build.is_failed_build n in
(* Check if config holds the Github to Slack email mapping for the commit author *)
(* Check if config holds Github to Slack email mapping for the commit author *)
let author = List.assoc_opt email cfg.user_mappings |> Option.default email in
let dm_after_failed_build =
List.assoc_opt author cfg.dev_notifications.dm_after_failed_build
Expand All @@ -176,30 +176,14 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
|> (* dm_for_failing_build is opt out *)
Option.default true
in
print_endline
@@ Printf.sprintf
{|

================================================
user_id_str: %s
finds in config?: %b
is_failing_build: %b
is_failed_build: %b
dm_after_failed_build: %b
dm_for_failing_build: %b
================================================
|}
author
(Option.is_some (List.assoc_opt author cfg.dev_notifications.dm_after_failed_build))
is_failing_build is_failed_build dm_after_failed_build dm_for_failing_build;
(match (dm_for_failing_build && is_failing_build) || (dm_after_failed_build && is_failed_build) with
| true ->
(* if we send a dm for a failing build and we want another dm after the build is finished, we don't
set the pipeline commit immediately. Otherwise, we wouldn't be able to notify later *)
if (is_failing_build && not dm_after_failed_build) || is_failed_build (* TODO: test double opt in *) then
State.set_repo_pipeline_commit ctx.state n;
(* To send a DM, channel parameter is set to the user id of the recipient *)
Lwt.return [ Slack_user_id.to_channel_id res.user.id ]
Lwt.return [ Status_notification.User res.user.id ]
| false -> Lwt.return [])
| Error e ->
log#warn "couldn't match commit email %s to slack profile: %s" n.commit.commit.author.email e;
Expand All @@ -214,13 +198,14 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
(* non-main branch build notifications go to default channel to reduce spam in topic channels *)
match is_main_branch with
| false ->
Lwt.return (Option.map_default (fun c -> [ Slack_channel.to_any c ]) [] cfg.prefix_rules.default_channel)
Lwt.return
(Option.map_default (fun c -> [ Status_notification.inject_channel c ]) [] cfg.prefix_rules.default_channel)
| true ->
(match%lwt Github_api.get_api_commit ~ctx ~repo ~sha:n.commit.sha with
| Error e -> action_error e
| Ok commit ->
let chans = partition_commit cfg commit.files in
Lwt.return (List.map Slack_channel.to_any chans))
Lwt.return (List.map Status_notification.inject_channel chans))
in
(* only notify the failed builds channels for full failed builds with new failed steps on the main branch *)
let notify_failed_builds_channel =
Expand All @@ -243,11 +228,12 @@ module Action (Github_api : Api.Github) (Slack_api : Api.Slack) = struct
List.find_map
(fun ({ name; failed_builds_channel } : Config_t.pipeline) ->
match String.equal name context, failed_builds_channel with
| true, Some failed_builds_channel -> Some (Slack_channel.to_any failed_builds_channel :: chans)
| true, Some failed_builds_channel ->
Some (Status_notification.inject_channel failed_builds_channel :: chans)
| _ -> None)
allowed_pipelines
|> Option.default chans
|> List.sort_uniq Slack_channel.compare
|> List.sort_uniq Status_notification.compare
in
Lwt.return (direct_message @ chans)
in
Expand Down
19 changes: 19 additions & 0 deletions lib/common.ml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,25 @@ module StringSet = struct
let unwrap = to_list
end

module Status_notification = struct
type t =
| Channel of Slack_channel.Any.t
| User of Slack_user_id.t

let inject_channel c = Channel (Slack_channel.to_any c)

let to_slack_channel = function
| Channel c -> c
| User u -> Slack_user_id.to_channel_id u

let is_user = function
| User _ -> true
| Channel _ -> false

let compare a b = Slack_channel.compare (to_slack_channel a) (to_slack_channel b)
let equal a b = compare a b = 0
end

module Map (S : Map.OrderedType) = struct
include Map.Make (S)

Expand Down
12 changes: 6 additions & 6 deletions lib/slack.ml
Original file line number Diff line number Diff line change
Expand Up @@ -335,9 +335,9 @@ let generate_status_notification ~(ctx : Context.t) ?slack_user_id (cfg : Config
let commit_info =
[
(let mention =
match slack_user_id with
| None -> ""
| Some id -> sprintf "<@%s>" (Slack_user_id.project id)
match slack_user_id, channel with
| None, _ | _, Status_notification.User _ -> ""
| Some id, Channel _ -> sprintf "<@%s>" (Slack_user_id.project id)
in
sprintf "*Commit*: `<%s|%s>` %s" html_url (git_short_sha_hash sha) mention);
]
Expand Down Expand Up @@ -395,10 +395,10 @@ let generate_status_notification ~(ctx : Context.t) ?slack_user_id (cfg : Config
List.exists
(fun ({ name; failed_builds_channel } : Config_t.pipeline) ->
String.equal name context
&& Option.map_default Slack_channel.(equal channel $ to_any) false failed_builds_channel)
&& Option.map_default Status_notification.(equal channel $ inject_channel) false failed_builds_channel)
pipelines
in
match Build.is_failed_build notification && is_failed_builds_channel with
match Build.is_failed_build notification && (is_failed_builds_channel || Status_notification.is_user channel) with
| false -> []
| true ->
(* TODO: don't send @mention on DM notification for failed builds *)
Expand All @@ -416,7 +416,7 @@ let generate_status_notification ~(ctx : Context.t) ?slack_user_id (cfg : Config
let attachment =
{ empty_attachments with mrkdwn_in = Some [ "fields"; "text" ]; color = Some color_info; text = Some msg }
in
make_message ~text:summary ~attachments:[ attachment ] ~channel ()
make_message ~text:summary ~attachments:[ attachment ] ~channel:(Status_notification.to_slack_channel channel) ()

let generate_commit_comment_notification ~slack_match_func api_commit notification channel =
let { commit; _ } = api_commit in
Expand Down

0 comments on commit 3988656

Please sign in to comment.