Enabling webhooks to close review-requests after commits
Review Request #9585 — Created Feb. 4, 2018 and updated
Review request for feature of rb-gateway to support webhooks on git events. The workflow is
1) Once rb-gateway runs, it installs hookscripts in the repos' it manages. It will install the hookscript under:path/to/repo/.git/hooks/<event-type>.d/99-rb-gateway.sh
in addition to a<event-type>
script underpath/to/repo/.git/hooks/
that runs any pre-existing<event-type>
scripts in the repo. We only support thepost-commit
event for now.
2) Make a commit in the repo hosted on rb-gateway. This will run the hookscript installed in Step 1
3) Hookscript will run which will pipe the commit data from Step 2 to rb-gateway and rb-gateway will make an HTTP request to the reviewboard instance (assuming this is properly configured inconfig.json
)
4) Reviewboard will receive this HTTP request, and close the corresponding reviewBetween the first diff and the latest one, there's been a lot of file movement since I was working off a patch link r/9402 but there was a non-trivial rewrite of rb-gateway in between on master.
Changes include:
1) Updating README on how to run rbgateway
2) Adding API calls for changing the config through http requests rather than having to change the file itself(i.e.DeleteWebhook
DisableWebhook
RegisterWebhook
)
3) Default hookscripts included in rb-gateway, rb-gateway will automatically install them based on ./config/post-commit.sh (or whatever future event-type we will support)
4) Rb-gateway sending an HTTPPOST
to the webhook urlsCorresponding review for reviewboard side of the code:
https://reviews.reviewboard.org/r/9700/
Ran tests
Manual test:
1) Make review request on locally running reviewboard instance of repo rb-gateway will be managing
2) Run rb-gateway with config pointing to a local repo and a webhook
3) Make commit in local repoReview request in Step 1 is closed after Step 3 has completed.
Description | From | Last Updated |
---|---|---|
Remove this. |
|
|
So the method you're doing here will work, but it does modify existing files (which we probably do not want … |
|
|
Git hooks should be named post-commit, etc. without the .sh. |
|
|
Should the last character (',') be truncated from the error message? |
![]() |
|
Are their constants/enums for HTTP methods somewhere? |
|
|
Is there a way to not hardcode this here? Perhaps move it somewhere else in (or out of) the code? |
|
|
Can you rewrite the summary in the imperative mood, e.g.: // Register a wehook. |
|
|
This should return 201 Created. |
|
|
Likewise here. |
|
|
Unnecessary, as thats the default behaviour of the HTTP standard. |
|
|
Care to put the body param before the t? |
|
|
} on next line. |
|
|
Is that a single space or is it a tab character? IMO we should use two (my preference) or four … |
|
|
Missing a period. |
|
|
I think we should either manage webhooks exclusively via the API or exclusively via config.json. If the former, we should … |
|
|
We really just need the ID. Everything else we can get if we need it. |
|
|
Comments should be in proper sentences beginning with capitals and ending with periods. Same goes for all comments throughout. |
|
|
Can you write your doc-comments in the imperative mood, e.g. "Return whether or not the webhook has valid fields." |
|
|
remove this line. |
|
|
Can be one statement |
|
|
Ideally we can have this as a template string inside go and then replace (1) the path to rbgateway and … |
|
|
So this isn't strictly correct if you're not pushing to master. You will want to read from standard input the … |
|
|
This should live in the hooks package |
|
|
Can we move the code thats executed when triggeredByHookscript is true into another function? That way we can do: if … |
|
|
Testing code? |
|
|
You should use "${HOOK}" here in case it contains a space. |
|
|
No blank line here. |
|
|
I've never read or worked with Go before, but I think it's pretty cool how readable some of it is. … |
JT jtrang | |
Another question, what does the syntax for the parameter t *testing.T mean? |
JT jtrang | |
I'm not familiar with go lang at all really so I'm just wondering, how come sometimes you use "if err … |
JC jcorrive |
Change Summary:
Added routing for Deleting and Registering webhooks via an http request.
Added some commented out functions on the install hookscripts.TODO: Need to test with the BasicAuth function for deleting and registering.
Testing done: Using httpie, make a post request, and successfully modifies the config.json after delete and register.
Commit: |
|
||
---|---|---|---|
Diff: |
Revision 2 (+538 -51) |
Checks run (2 succeeded)
Change Summary:
Function for installing hookscripts instead of manually copying and pasting the script to a path.
Commit: |
|
||||
---|---|---|---|---|---|
Diff: |
Revision 3 (+556 -52) |
Checks run (2 succeeded)
Commit: |
|
||||
---|---|---|---|---|---|
Diff: |
Revision 4 (+706 -49) |
Checks run (2 succeeded)
-
-
-
git_repository.go (Diff revision 4) So the method you're doing here will work, but it does modify existing files (which we probably do not want to do).
Instead how about the following approach:
- Make a new directory
.git/hooks/{SCRIPT_TYPE}.d
, whereSCRIPT_TYPE
is e.g.,post-commit
- If
.git/hooks/{SCRIPT_TYPE}
exists, move it to.git/hooks/{SCRIPT_TYPE}.d/00-original
- Install our hook script as
.git/hooks/{SCRIPT_TYPE}.d/99-rbgateway
: - Create a new
.git/hooks/{SCRIPT_TYPE}
with the following template (see here):
#!/bin/sh for HOOK in { .ScriptType }.d/*; do if [ -x "${HOOK}" ]; then /bin/sh -c $HOOK fi done
This allows us to install our own hooks without modifying the hooks already installed, as well as allows the maintainers to add multiple hooks.
Also, since git by default has a hooks directory full of examples that are not marked +x, we can safely copy them into the
hooks/{SCRIPT_TYPE}.d/
directory. In your original implementation, if the original git hook is made by git and non-executable, the code won't run.Additionally we can
chmod +x .git/hooks/{SCRIPT_TYPE}/99-rbgateway
withos.Chmod
. - Make a new directory
-
Commit: |
|
||||
---|---|---|---|---|---|
Diff: |
Revision 5 (+778 -73) |
Checks run (2 succeeded)
Commit: |
|
||||
---|---|---|---|---|---|
Diff: |
Revision 6 (+902 -75) |
Checks run (2 succeeded)
Commit: |
|
||||
---|---|---|---|---|---|
Diff: |
Revision 7 (+895 -76) |
Checks run (2 succeeded)
Commit: |
|
||||
---|---|---|---|---|---|
Diff: |
Revision 8 (+1991 -826) |
Checks run (2 succeeded)
Summary: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Description: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Testing Done: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Commit: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Diff: |
Revision 9 (+2003 -825) |
Checks run (2 succeeded)
Testing Done: |
|
---|
-
-
-
main.go (Diff revision 9) Do assignments in Go not return tha value? i.e. could this be
(err = watcher.Add(config.DefaultConfigPath)) != nil
? -
-
repositories/git_test.go (Diff revision 9) Is there a way to not hardcode this here? Perhaps move it somewhere else in (or out of) the code?
Commit: |
|
||||
---|---|---|---|---|---|
Diff: |
Revision 10 (+827 -66) |
Checks run (2 succeeded)
-
-
api/routes.go (Diff revision 10) Can you rewrite the summary in the imperative mood, e.g.:
// Register a wehook.
-
-
-
-
-
-
config/config.go (Diff revision 10) Is that a single space or is it a tab character? IMO we should use two (my preference) or four space indent or tab.
-
-
sample_config.json (Diff revision 10) I think we should either manage webhooks exclusively via the API or exclusively via config.json. If the former, we should store them in a separate file so that adding a webhook does not cause cause the server to restart (as fs notifier currently will notice we wrote the file and).
Or we manage them excusively via config.json, in which case a restart is to be expected.
Commit: |
|
||||
---|---|---|---|---|---|
Diff: |
Revision 11 (+911 -53) |
Checks run (2 succeeded)
-
-
hooks/webhook.go (Diff revision 11) We really just need the ID. Everything else we can get if we need it.
-
hooks/webhook.go (Diff revision 11) Comments should be in proper sentences beginning with capitals and ending with periods.
Same goes for all comments throughout.
-
hooks/webhook.go (Diff revision 11) Can you write your doc-comments in the imperative mood, e.g.
"Return whether or not the webhook has valid fields."
-
-
-
hookscripts/post-commit.sh (Diff revision 11) Ideally we can have this as a template string inside go and then replace (1) the path to rbgateway and (2) the reponame ourselves when we install it. It also would mean we don't need to include this text file when distributing rb-gateway
-
hookscripts/post-commit.sh (Diff revision 11) So this isn't strictly correct if you're not pushing to master.
You will want to read from standard input the data about the changes received. (This links to the pre-receive hook but they get the same input).
e.g.
read OLD NEW REF_NAME echo "$OLD $NEW $REF_NAME" | $rbgatewaypath -send-webhook=post-commit -repository=$reponame
where REF_NAME is the name of the ref being updated (e.g.,
master
) and OLD and NEW are the new revisions. -
-
main.go (Diff revision 11) Can we move the code thats executed when
triggeredByHookscript
is true into another function?That way we can do:
if triggeredByHookscript { return executeHook(...) } // server stuff here
-
-
-
repositories/git_test.go (Diff revision 11) As an FYI, you can use
touch filename
to modify the mtime (last modified time) offilename
or createfilename
if it doesnt exist. -
Commit: |
|
||||
---|---|---|---|---|---|
Diff: |
Revision 12 (+951 -80) |
Checks run (2 timed out)
-
No comments, just questions. This is my first encounter with Go, but your code is very readable!
-
api/api.go (Diff revision 12) I've never read or worked with Go before, but I think it's pretty cool how readable some of it is. Would this syntax allow you to chain multiple methods?
-
api/routes_test.go (Diff revision 12) Another question, what does the syntax for the parameter
t *testing.T
mean?
-
-
repositories/git_test.go (Diff revision 12) I'm not familiar with go lang at all really so I'm just wondering, how come sometimes you use "if err == " and other times it's "if err = "?
Commit: |
|
||||
---|---|---|---|---|---|
Diff: |
Revision 13 (+995 -93) |