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

[WIP] Feat/send notification to slack #6

Merged

Conversation

thatportugueseguy
Copy link
Collaborator

@thatportugueseguy thatportugueseguy commented Jul 28, 2019

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

@thatportugueseguy thatportugueseguy changed the title Feat/send notification to slack [WIP] Feat/send notification to slack Jul 28, 2019
Copy link
Contributor

@ygrek ygrek left a 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;
Copy link
Contributor

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)

Copy link
Collaborator Author

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).

Copy link
Contributor

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.

Copy link
Contributor

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

Copy link
Collaborator Author

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;
Copy link
Contributor

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?

Copy link
Collaborator Author

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
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
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

Copy link
Collaborator Author

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)
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

Copy link
Contributor

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

Copy link
Collaborator Author

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
Copy link
Contributor

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 😬

Copy link
Collaborator Author

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 = [
{
Copy link
Contributor

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 = ... }

Copy link
Collaborator Author

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 :: [];
Copy link
Contributor

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

Copy link
Collaborator Author

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)
Copy link
Contributor

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

Copy link
Collaborator Author

@thatportugueseguy thatportugueseguy Jul 29, 2019

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

Copy link
Contributor

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

Copy link
Collaborator Author

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;
Copy link
Contributor

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

Copy link
Collaborator Author

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.

Copy link
Contributor

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

Copy link
Collaborator Author

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;
Copy link
Contributor

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

Copy link
Collaborator Author

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
Copy link
Contributor

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 ->
Copy link
Contributor

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

@ygrek ygrek merged commit d06113d into fix/fix-request-signature-validation Jul 31, 2019
@ygrek ygrek deleted the feat/send-notification-to-slack branch July 31, 2019 05:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants