-
Notifications
You must be signed in to change notification settings - Fork 8
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
[WIP] Feat/send notification to slack #6
[WIP] Feat/send notification to slack #6
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've opted not to use the curl.lwt module as it didn't seem necessary as i'm not doing any processing while the request is running.
this is not true, server is asynchronous and can handle other requests while current one is doing curl query
and c = Curl.init () in | ||
Curl.set_timeout c 1200; | ||
Curl.set_sslverifypeer c false; | ||
Curl.set_sslverifyhost c Curl.SSLVERIFYHOST_EXISTENCE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
meh, use proper ssl verification (and anyway this option maps to strict name check in modern libcurl)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not exactly sure how to do it. Looking at the curl
lib examples and having a look around libcurls' docs, it seems that https://github.com/ygrek/ocurl/blob/master/examples/ossl.ml#L14 could be an option:
Curl.set_sslverifypeer c true;
Curl.set_sslverifyhost c Curl.SSLVERIFYHOST_HOSTNAME;
Would this be enough? Seems that the next step in verification would imply having code to validate the actual certificate (iiuc).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the way, yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no next step is needed, libcurl verifies the certificate against the system ca bundle alright
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
configuration.ml
Outdated
Curl.set_writefunction c (writer_callback r); | ||
Curl.set_tcpnodelay c true; | ||
Curl.set_verbose c false; | ||
Curl.set_post c false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would assume slack webhook should actually be post?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing this line, as it's set up on the send_notification
function.
notabot.ml
Outdated
let fields = | ||
match List.length labels with | ||
| n when n > 0 -> ( | ||
let labels_string = List.fold ~init:"" ~f:(fun acc label -> Printf.sprintf "%s %s," acc label.name) labels in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let labels_string = List.fold ~init:"" ~f:(fun acc label -> Printf.sprintf "%s %s," acc label.name) labels in | |
let value = String.concat ", " @@ List.map (fun x -> x.name) labels |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! (ended up having to make the more changes than the suggestion, so didn't accept the suggested change, but implemented it.)
} | ||
|
||
let git_short_sha_hash hash = | ||
String.sub ~pos:0 ~len:8 (Github_events_notifications_j.string_of_commit_hash hash) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
8 is not enough for our repos now, there should be short_hash field in github message which select minimum unambiguous length, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, not. I did look for it, though. Looking at the compare link for the push notification, they use 12 length. I used 8 by copying from the github extension which shows only 8.
Actually this is something that will only be visible on slack, it's not going to be part of any link or something like that. When we click on it, it will open the link that will show the proper commits.
I will change to 12, in case we ever want to copy and use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, right, then no change needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
8 it is, then :)
notabot.ml
Outdated
let commit_branch = | ||
(* take out refs/heads and get the full name of the branch *) | ||
String.concat ~sep:"/" @@ Array.to_list @@ Array.subo ~pos:2 ref_tokens in | ||
let number_of_commits = List.length commits in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
identifier longer than the expression it replaces 😬
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point. 👌
notabot.ml
Outdated
} | ||
] in | ||
let attachments = [ | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could have { empty_attachment with color = ... }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
notabot.ml
Outdated
let fields = [ | ||
{ | ||
title = None; | ||
value = String.concat ~sep:"\n" @@ title :: status :: description :: commit_info :: author_info :: []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better use [title;status;...]
here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
notabot.ml
Outdated
let open Github_notifications_handler in | ||
match request_notification with | ||
| Push notification -> Ok (generate_push_notification notification) | ||
| Pull_request n when is_review_requested n.action -> Ok (generate_pull_request_notification n) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we probably want all PRs, not only those with review requested
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are all the options 👇 Maybe we just want a subset of them? For example: a PR opened with labels and a review requested will trigger 3 webhooks notifications, if i understand correctly. This would mean having multiple notifications per most PRs..
type pr_action =
Assigned | Unassigned | Review_requested | Review_request_removed
| Labeled | Unlabeled | Opened | Edited | Closed | Ready_for_review
| Locked | Unlocked | Reopened
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets have all and then limit later when we see it in action
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
notabot.ml
Outdated
Curl.set_postfieldsize c (String.length data); | ||
Curl.perform c; | ||
let rc = Curl.get_responsecode c in | ||
Curl.cleanup c; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cleanup is not called in case of exn in perform
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added cleanup in %lwt.finally
. I'm not sure if that's exactly how it should be as (iiuc) it will always run regardless of the outcome of the try with
block.
I'm still wrapping my head around some bit of the lwt docs, but got the impression this isn't what we want, but it's used like so on the ocurl lwt tests
, so i'm not sure i understood it correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as (iiuc) it will always run regardless of the outcome of the try with block
and that's exactly what we want, we need to dispose the resource regardless of the outcome of operation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I had misinterpreted your first commentary as it meaning that cleanup should not be called in case of exn, hence the question.
notabot.ml
Outdated
Curl.set_httpheader c [ "Content-Type: " ^ content_type ]; | ||
Curl.set_postfields c data; | ||
Curl.set_postfieldsize c (String.length data); | ||
Curl.perform c; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exn handling is needed ofc - just catch all exns from curl.perform and log in case of error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handled a few error cases. Please comment if adequate.
let title = | ||
Printf.sprintf "*<%s|%i new commit%s> pushed to `<%s|%s>`*" compare (List.length commits) (match commits with [_] -> "s" | _ -> "") repository.url commit_branch in | ||
let commits_text_list = List.map commits ~f:(fun { url; id; message; _ } -> | ||
Printf.sprintf "`<%s|%s>` - `%s`" url (git_short_sha_hash id) message) in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but probably should do something with single quotes in the message itself (aka escape)
| code -> | ||
Stdio.print_endline @@ Printf.sprintf "Slack notification request errored: %s" (Curl.strerror code); | ||
Lwt.return None | ||
with exn -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try is not needed, easier to match against exception exn
then
Branches off and is blocked by #5.
Added the ability to send notifications to slack.
There is still no error handling on the curl request, as i'm not sure what would be considered enough. I've seen different examples for error handling and would like to know if it's enough just to have a catch all catch or if i should handle any specific cases, like curl exceptions. Some pointers here would be welcome :)
I've opted not to use the
curl.lwt
module as it didn't seem necessary as i'm not doing any processing while the request is running. Please let me know if i'm not looking at this the right way.(meant to create a WIP PR, but pressed the create button by mistake and now can't change the type of PR