Simple Ruby/Sinatra Github
webhook script
KYOSS July 2015
Jeff Squyres
Github: A popular Git-hosting service
www.github.com
Github hosts
your Git repos
Git
repo
Git
repo
Git
repo
Github hosts
your Organization’s Git repos
Git
repo
Git
repo
Git
repo
Yoyodyne
Organization
Github hosts
your Organization’s Git repos
Git
repo
Git
repo
Git
repo
Yoyodyne
Organization
Git
repo
Git
repo
Git
repo
Git
repo
Github has other services
Wiki
Github has other services
WikiAPI hooks
The Github Webhook
Hey!
Something just
happened!
The Github Webhook
Hey!
Something just
happened!
Github servers
The Github Webhook
Your serverGithub servers
HTTP post
{
"action": "opened",
"number": 1138,
"pull_request": {
"url": "https://api.github.com/repos/ofiwg/libfabric/pulls/1138",
"id": 39149978,
"html_url": "https://github.com/ofiwg/libfabric/pull/1138",
"diff_url": "https://github.com/ofiwg/libfabric/pull/1138.diff",
"patch_url": "https://github.com/ofiwg/libfabric/pull/1138.patch",
"issue_url": "https://api.github.com/repos/ofiwg/libfabric/issues/1138",
"number": 1138,
"state": "open",
"locked": false,
"title": "replace usd_open with usd_open_for_attrs ",
…
}
Hey!
Something just
happened!
This is what
happened
What can you do with Github
webhooks?
A common Github webhook use
Your serverGithub servers
A pull request
was just opened
Kick off a build
of the pull request
and test the result
Send results
back to Github
Example: Github kicked off tests
Example: all tests passed
Let’s look at another case
The Libfabric project
• Next generation high
performance
networking user stack
• Multi-vendor /
organization
• Open source
• Hosted on Github
Libfabric commits
Require a “Signed-off-by” line in Git commit messages
commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417
Author: Jeff Squyres <jsquyres@cisco.com>
Date: Thu Jul 2 15:03:42 2015 -0700
libfabric.so: bump the Libtool .so version to 2:0:1
Per https://www.gnu.org/software/libtool/manual/libtool.html. Fixes #1118.
Signed-off-by: Jeff Squyres <jsquyres@cisco.com>
Libfabric commits
Require a “Signed-off-by” line in Git commit messages
commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417
Author: Jeff Squyres <jsquyres@cisco.com>
Date: Thu Jul 2 15:03:42 2015 -0700
libfabric.so: bump the Libtool .so version to 2:0:1
Per https://www.gnu.org/software/libtool/manual/libtool.html. Fixes #1118.
Signed-off-by: Jeff Squyres <jsquyres@cisco.com>
commit efd7a5c878f53ba12ed771fa006d57b7f9d264fd
Author: Jithin Jose <jithin.jose@intel.com>
Date: Thu Jul 2 09:05:16 2015 -0700
sockets: fix resource leak in comm buffer
Signed-off-by: Jithin Jose <jithin.jose@intel.com>
Libfabric commits
Require a “Signed-off-by” line in Git commit messages
commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417
Author: Jeff Squyres <jsquyres@cisco.com>
Date: Thu Jul 2 15:03:42 2015 -0700
libfabric.so: bump the Libtool .so version to 2:0:1
Per https://www.gnu.org/software/libtool/manual/libtool.html. Fixes #1118.
Signed-off-by: Jeff Squyres <jsquyres@cisco.com>
commit efd7a5c878f53ba12ed771fa006d57b7f9d264fd
Author: Jithin Jose <jithin.jose@intel.com>
Date: Thu Jul 2 09:05:16 2015 -0700
sockets: fix resource leak in comm buffer
Signed-off-by: Jithin Jose <jithin.jose@intel.com>
commit 621dd04cbe2c9e066602393d508c85d175bebbb9
Author: James Swaro <jswaro@cray.com>
Date: Mon Jun 29 12:28:32 2015 -0500
Initialize param_list to avoid crashing in library destructor
Libfabric commits
Require a “Signed-off-by” line in Git commit messages
commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417
Author: Jeff Squyres <jsquyres@cisco.com>
Date: Thu Jul 2 15:03:42 2015 -0700
libfabric.so: bump the Libtool .so version to 2:0:1
Per https://www.gnu.org/software/libtool/manual/libtool.html. Fixes #1118.
Signed-off-by: Jeff Squyres <jsquyres@cisco.com>
commit efd7a5c878f53ba12ed771fa006d57b7f9d264fd
Author: Jithin Jose <jithin.jose@intel.com>
Date: Thu Jul 2 09:05:16 2015 -0700
sockets: fix resource leak in comm buffer
Signed-off-by: Jithin Jose <jithin.jose@intel.com>
commit 621dd04cbe2c9e066602393d508c85d175bebbb9
Author: James Swaro <jswaro@cray.com>
Date: Mon Jun 29 12:28:32 2015 -0500
Initialize param_list to avoid crashing in library destructor
commit 621dd04cbe2c9e066602393d508c85d175bebbb9
Author: James Swaro <jswaro@cray.com>
Date: Mon Jun 29 12:28:32 2015 -0500
Initialize param_list to avoid crashing in library destructor
Missing Signed-off-by line!
Libfabric only accepts commits
via pull requests
Libfabric Github
Git repo
Libfabric only accepts commits
via pull requests
Libfabric Github
Git repo
jsquyres Github
forked libfabric repo
Step 1: Jeff makes a Gihub “fork”
of the upstream Libfabric repo
Libfabric only accepts commits
via pull requests
Libfabric Github
Git repo
jsquyres Github
forked libfabric repo commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417
Author: Jeff Squyres <jsquyres@cisco.com>
Date: Thu Jul 2 15:03:42 2015 -0700
libfabric.so: bump the Libtool .so version to 2:0:1
Per https://www.gnu.org/software/libtool/manual/...
Signed-off-by: Jeff Squyres <jsquyres@cisco.com>
Step 2: Jeff makes a commit on his
libfabric fork
Libfabric only accepts commits
via pull requests
Libfabric Github
Git repo
jsquyres Github
forked libfabric repo commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417
Author: Jeff Squyres <jsquyres@cisco.com>
Date: Thu Jul 2 15:03:42 2015 -0700
libfabric.so: bump the Libtool .so version to 2:0:1
Per https://www.gnu.org/software/libtool/manual/...
Signed-off-by: Jeff Squyres <jsquyres@cisco.com>
Step 3: Jeff files a pull request to ask
if his commit can be accepted into
the main Libfabric repo
Libfabric only accepts commits
via pull requests
Libfabric Github
Git repo
jsquyres Github
forked libfabric repo commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417
Author: Jeff Squyres <jsquyres@cisco.com>
Date: Thu Jul 2 15:03:42 2015 -0700
libfabric.so: bump the Libtool .so version to 2:0:1
Per https://www.gnu.org/software/libtool/manual/...
Signed-off-by: Jeff Squyres <jsquyres@cisco.com>
Step 4: A libfabric maintainer accepts
Jeff’s pull request
commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417
Author: Jeff Squyres <jsquyres@cisco.com>
Date: Thu Jul 2 15:03:42 2015 -0700
libfabric.so: bump the Libtool .so version to 2:0:1
Per https://www.gnu.org/software/libtool/manual/...
Signed-off-by: Jeff Squyres <jsquyres@cisco.com>
commit d70ebb7b6f7afb51e3026c92c40b
Author: Jeff Squyres <jsquyres@cisc
Date: Thu Jul 2 15:03:42 2015 -07
libfabric.so: bump the Libtool
Per https://www.gnu.org/softwar
Signed-off-by: Jeff Squyres <js
Wait – you missed a step
The missing step
1. Jeff makes a Gihub “fork” of the upstream
Libfabric repo
2. Jeff makes a commit on his libfabric fork
3. Jeff files a pull request to ask if his commit
can be accepted into the main Libfabric repo
4. Libfabric maintainers review the pull request
commit(s)
5. A libfabric maintainer accepts Jeff’s pull
request
The missing step
1. Jeff makes a Gihub “fork” of the upstream
Libfabric repo
2. Jeff makes a commit on his libfabric fork
3. Jeff files a pull request to ask if his commit
can be accepted into the main Libfabric repo
4. Libfabric maintainers review the pull request
commit(s)
5. A libfabric maintainer accepts Jeff’s pull
request
The missing step
1. Jeff makes a Gihub “fork” of the upstream
Libfabric repo
2. Jeff makes a commit on his libfabric fork
3. Jeff files a pull request to ask if his commit
can be accepted into the main Libfabric repo
4. Libfabric maintainers review the pull request
commit(s)
5. A libfabric maintainer accepts Jeff’s pull
request
Is there a Signed-off-by line?
The Signed-off-by line
It’s kind of a silly thing
It has nothing to do with the code itself
The Signed-off-by line
But the lawyers tell us we must have it
The Signed-off-by line
We developers don’t want to have to deal with it
We just want to make sure it happens, but at zero cost to us
The Signed-off-by line
Sounds like a perfect job
for automation
Example: PR with three commits
Example: PR with three commits
Example PR with Badness
Example PR with Badness
Example PR with Badness
Why is this one marked bad?
Example PR with Badness
Why is this one marked bad?
Github uses the status of the last commit as the status
of the overall pull request
That’s what it does
Now let’s look what it is
Sinatra
sinatrarb.com
Sinatra
sinatrarb.com
Sinatra: logistics
Sinatra processLocal browser
http://localhost:4567
Sinatra: logistics
Sinatra process
http://localhost:4567
nginx processRemote browser
http://example.com
Sinatra “Signed-off-by” Github webhook
Your serverGithub servers
A pull request
was just opened
(or modified)
Check to make sure
each commit has a
Signed-off-by line
Send results
back to Github
Github to Sinatra logistics
Github servers
Some web server
verify-
signed-off.rb
Send results
back to Github
“Signed-off-by” checker
Source code:
https://github.com/ofiwg/libfabric/blob/master/config/github-webhook/verify-signed-off.rb
github.com/ofiwg/libfabric
config subdir
github-webhook subdir
verify-signed-off.rb
Heavily inspired by
http://git-scm.com/book/en/v2/GitHub-Scripting-GitHub
Setup
require 'rubygems’ # Required by RHEL 6
require 'httparty’ # Used in the body below for HTTP requests
require 'sinatra’ # All the Sinatra glue
require 'json’ # Used in the body below for JSON stuff
# Put Sinatra on port 5000 (a fairly arbitrary choice)
set :port, 5000
# Globals
user_agent = 'ofiwg/signed-off-by-checker'
# Read the Github auth token in from the environment (it wouldn't do
# the hard-code it where it would show up in a public Github repo!)
auth_token = ENV['GITHUB_AUTH_TOKEN
if auth_token == nil then
puts "Someone forgot to set $GITHUB_AUTH_TOKEN before launching me. Aborting!n"
exit 1
end
Handle HTTP Get
# Github webhooks are not delivered as HTTP GETs. If we don't have
# this Sinatra method here, Sinatra displays a goofy error message if
# someone just visits "http[s]://url_to_this_script".
# Responds to an HTTP Get for “/”
get '/' do
# Output this plain string and exit
'Nothing to see here but us chickens'
end
Handle HTTP Post
# Respond to an HTTP Post to “/”
post '/' do
# Parse the JSON into the “push” variable
push = JSON.parse(request.body.read)
repo_name = push['repository']['full_name']
# If this is not a push on a pull request (i.e., if there's no
# commits to examine, such as if this is a test webhook ping from
# github), then just return HTTP status 200 (i.e., success) with a
# handy message that you can see in the Github webhook debug logs.
if push['action'] == nil || (push['action'] != 'synchronize' &&
push['action'] != 'opened') then
# Returns an HTTP 200 status and a plain string
return [200, ‘Nothing for this bot to do!']
end
…continues…
Get all commits on this pull request
# Get _all_ commits associated with this pull request
commits_url = push['pull_request']['commits_url']
commits = HTTParty.get(commits_url,
:headers => {
'Content-Type' => 'application/json',
'User-Agent' => user_agent,
'Authorization' => "token #{auth_token}" }
)
# Setup some variables
happy = true
targetURL = 'https://github.com/ofiwg/libfabric/wiki#how-to-contribute'
debug_message = "checking debug URL: #{commits_url}nn"
final_message = ''
…continues…
Start analyzing the commit messages
# Loop over all the commit meta data we just downloaded
commits.each_with_index do |commit, index|
sha = commit['sha']
status_url = “https://api.github.com/repos/#{repo_name}/statuses/#{sha}”
status = { 'context' => 'Signed-off-by checker’ }
# Look for a Signed-off-by string in this commit
if /Signed-off-by/.match commit['commit']['message']
status['state'] = 'success'
status['description'] = 'This commit is signed off'
else
status['state'] = 'failure'
status['description'] = 'This commit is not signed off'
status['target_url'] = targetURL
happy = false
end
final_message = status['description']
…continues…
Is this the last commit?
if index == (commits.length - 1) && index > 0 then
if happy then
status['state'] = 'success'
status['description'] = 'All commits were signed off. Yay!'
else
status['state'] = 'failure'
status['description'] = 'At least one commit was not signed off'
status['target_url’] = targetURL
end
final_message = status['description']
end
…continues…
Send back the results for this commit
HTTParty.post(status_url,
:body => status.to_json,
:headers => {
'Content-Type' => 'application/json',
'User-Agent' => user_agent,
'Authorization' => "token #{auth_token}" }
)
end
…continues…
All done!
# Return HTTP status 200 and a message that shows up in the
# Github webhook debug logs
return [200, ”Thanks for playing -- #{final_message}"]
end
Example / reminder of output
Yay!

Fun with Github webhooks: verifying Signed-off-by

  • 1.
    Simple Ruby/Sinatra Github webhookscript KYOSS July 2015 Jeff Squyres
  • 2.
    Github: A popularGit-hosting service www.github.com
  • 3.
    Github hosts your Gitrepos Git repo Git repo Git repo
  • 4.
    Github hosts your Organization’sGit repos Git repo Git repo Git repo Yoyodyne Organization
  • 5.
    Github hosts your Organization’sGit repos Git repo Git repo Git repo Yoyodyne Organization Git repo Git repo Git repo Git repo
  • 6.
    Github has otherservices Wiki
  • 7.
    Github has otherservices WikiAPI hooks
  • 8.
  • 9.
    The Github Webhook Hey! Somethingjust happened! Github servers
  • 10.
    The Github Webhook YourserverGithub servers HTTP post { "action": "opened", "number": 1138, "pull_request": { "url": "https://api.github.com/repos/ofiwg/libfabric/pulls/1138", "id": 39149978, "html_url": "https://github.com/ofiwg/libfabric/pull/1138", "diff_url": "https://github.com/ofiwg/libfabric/pull/1138.diff", "patch_url": "https://github.com/ofiwg/libfabric/pull/1138.patch", "issue_url": "https://api.github.com/repos/ofiwg/libfabric/issues/1138", "number": 1138, "state": "open", "locked": false, "title": "replace usd_open with usd_open_for_attrs ", … } Hey! Something just happened! This is what happened
  • 11.
    What can youdo with Github webhooks?
  • 12.
    A common Githubwebhook use Your serverGithub servers A pull request was just opened Kick off a build of the pull request and test the result Send results back to Github
  • 13.
  • 14.
  • 15.
    Let’s look atanother case
  • 16.
    The Libfabric project •Next generation high performance networking user stack • Multi-vendor / organization • Open source • Hosted on Github
  • 17.
    Libfabric commits Require a“Signed-off-by” line in Git commit messages commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417 Author: Jeff Squyres <jsquyres@cisco.com> Date: Thu Jul 2 15:03:42 2015 -0700 libfabric.so: bump the Libtool .so version to 2:0:1 Per https://www.gnu.org/software/libtool/manual/libtool.html. Fixes #1118. Signed-off-by: Jeff Squyres <jsquyres@cisco.com>
  • 18.
    Libfabric commits Require a“Signed-off-by” line in Git commit messages commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417 Author: Jeff Squyres <jsquyres@cisco.com> Date: Thu Jul 2 15:03:42 2015 -0700 libfabric.so: bump the Libtool .so version to 2:0:1 Per https://www.gnu.org/software/libtool/manual/libtool.html. Fixes #1118. Signed-off-by: Jeff Squyres <jsquyres@cisco.com> commit efd7a5c878f53ba12ed771fa006d57b7f9d264fd Author: Jithin Jose <jithin.jose@intel.com> Date: Thu Jul 2 09:05:16 2015 -0700 sockets: fix resource leak in comm buffer Signed-off-by: Jithin Jose <jithin.jose@intel.com>
  • 19.
    Libfabric commits Require a“Signed-off-by” line in Git commit messages commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417 Author: Jeff Squyres <jsquyres@cisco.com> Date: Thu Jul 2 15:03:42 2015 -0700 libfabric.so: bump the Libtool .so version to 2:0:1 Per https://www.gnu.org/software/libtool/manual/libtool.html. Fixes #1118. Signed-off-by: Jeff Squyres <jsquyres@cisco.com> commit efd7a5c878f53ba12ed771fa006d57b7f9d264fd Author: Jithin Jose <jithin.jose@intel.com> Date: Thu Jul 2 09:05:16 2015 -0700 sockets: fix resource leak in comm buffer Signed-off-by: Jithin Jose <jithin.jose@intel.com> commit 621dd04cbe2c9e066602393d508c85d175bebbb9 Author: James Swaro <jswaro@cray.com> Date: Mon Jun 29 12:28:32 2015 -0500 Initialize param_list to avoid crashing in library destructor
  • 20.
    Libfabric commits Require a“Signed-off-by” line in Git commit messages commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417 Author: Jeff Squyres <jsquyres@cisco.com> Date: Thu Jul 2 15:03:42 2015 -0700 libfabric.so: bump the Libtool .so version to 2:0:1 Per https://www.gnu.org/software/libtool/manual/libtool.html. Fixes #1118. Signed-off-by: Jeff Squyres <jsquyres@cisco.com> commit efd7a5c878f53ba12ed771fa006d57b7f9d264fd Author: Jithin Jose <jithin.jose@intel.com> Date: Thu Jul 2 09:05:16 2015 -0700 sockets: fix resource leak in comm buffer Signed-off-by: Jithin Jose <jithin.jose@intel.com> commit 621dd04cbe2c9e066602393d508c85d175bebbb9 Author: James Swaro <jswaro@cray.com> Date: Mon Jun 29 12:28:32 2015 -0500 Initialize param_list to avoid crashing in library destructor commit 621dd04cbe2c9e066602393d508c85d175bebbb9 Author: James Swaro <jswaro@cray.com> Date: Mon Jun 29 12:28:32 2015 -0500 Initialize param_list to avoid crashing in library destructor Missing Signed-off-by line!
  • 21.
    Libfabric only acceptscommits via pull requests Libfabric Github Git repo
  • 22.
    Libfabric only acceptscommits via pull requests Libfabric Github Git repo jsquyres Github forked libfabric repo Step 1: Jeff makes a Gihub “fork” of the upstream Libfabric repo
  • 23.
    Libfabric only acceptscommits via pull requests Libfabric Github Git repo jsquyres Github forked libfabric repo commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417 Author: Jeff Squyres <jsquyres@cisco.com> Date: Thu Jul 2 15:03:42 2015 -0700 libfabric.so: bump the Libtool .so version to 2:0:1 Per https://www.gnu.org/software/libtool/manual/... Signed-off-by: Jeff Squyres <jsquyres@cisco.com> Step 2: Jeff makes a commit on his libfabric fork
  • 24.
    Libfabric only acceptscommits via pull requests Libfabric Github Git repo jsquyres Github forked libfabric repo commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417 Author: Jeff Squyres <jsquyres@cisco.com> Date: Thu Jul 2 15:03:42 2015 -0700 libfabric.so: bump the Libtool .so version to 2:0:1 Per https://www.gnu.org/software/libtool/manual/... Signed-off-by: Jeff Squyres <jsquyres@cisco.com> Step 3: Jeff files a pull request to ask if his commit can be accepted into the main Libfabric repo
  • 25.
    Libfabric only acceptscommits via pull requests Libfabric Github Git repo jsquyres Github forked libfabric repo commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417 Author: Jeff Squyres <jsquyres@cisco.com> Date: Thu Jul 2 15:03:42 2015 -0700 libfabric.so: bump the Libtool .so version to 2:0:1 Per https://www.gnu.org/software/libtool/manual/... Signed-off-by: Jeff Squyres <jsquyres@cisco.com> Step 4: A libfabric maintainer accepts Jeff’s pull request commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417 Author: Jeff Squyres <jsquyres@cisco.com> Date: Thu Jul 2 15:03:42 2015 -0700 libfabric.so: bump the Libtool .so version to 2:0:1 Per https://www.gnu.org/software/libtool/manual/... Signed-off-by: Jeff Squyres <jsquyres@cisco.com> commit d70ebb7b6f7afb51e3026c92c40b Author: Jeff Squyres <jsquyres@cisc Date: Thu Jul 2 15:03:42 2015 -07 libfabric.so: bump the Libtool Per https://www.gnu.org/softwar Signed-off-by: Jeff Squyres <js
  • 26.
    Wait – youmissed a step
  • 27.
    The missing step 1.Jeff makes a Gihub “fork” of the upstream Libfabric repo 2. Jeff makes a commit on his libfabric fork 3. Jeff files a pull request to ask if his commit can be accepted into the main Libfabric repo 4. Libfabric maintainers review the pull request commit(s) 5. A libfabric maintainer accepts Jeff’s pull request
  • 28.
    The missing step 1.Jeff makes a Gihub “fork” of the upstream Libfabric repo 2. Jeff makes a commit on his libfabric fork 3. Jeff files a pull request to ask if his commit can be accepted into the main Libfabric repo 4. Libfabric maintainers review the pull request commit(s) 5. A libfabric maintainer accepts Jeff’s pull request
  • 29.
    The missing step 1.Jeff makes a Gihub “fork” of the upstream Libfabric repo 2. Jeff makes a commit on his libfabric fork 3. Jeff files a pull request to ask if his commit can be accepted into the main Libfabric repo 4. Libfabric maintainers review the pull request commit(s) 5. A libfabric maintainer accepts Jeff’s pull request Is there a Signed-off-by line?
  • 30.
    The Signed-off-by line It’skind of a silly thing It has nothing to do with the code itself
  • 31.
    The Signed-off-by line Butthe lawyers tell us we must have it
  • 32.
    The Signed-off-by line Wedevelopers don’t want to have to deal with it We just want to make sure it happens, but at zero cost to us
  • 33.
    The Signed-off-by line Soundslike a perfect job for automation
  • 34.
    Example: PR withthree commits
  • 35.
    Example: PR withthree commits
  • 36.
  • 37.
  • 38.
    Example PR withBadness Why is this one marked bad?
  • 39.
    Example PR withBadness Why is this one marked bad? Github uses the status of the last commit as the status of the overall pull request
  • 40.
    That’s what itdoes Now let’s look what it is
  • 41.
  • 42.
  • 43.
    Sinatra: logistics Sinatra processLocalbrowser http://localhost:4567
  • 44.
  • 45.
    Sinatra “Signed-off-by” Githubwebhook Your serverGithub servers A pull request was just opened (or modified) Check to make sure each commit has a Signed-off-by line Send results back to Github
  • 46.
    Github to Sinatralogistics Github servers Some web server verify- signed-off.rb Send results back to Github
  • 47.
    “Signed-off-by” checker Source code: https://github.com/ofiwg/libfabric/blob/master/config/github-webhook/verify-signed-off.rb github.com/ofiwg/libfabric configsubdir github-webhook subdir verify-signed-off.rb Heavily inspired by http://git-scm.com/book/en/v2/GitHub-Scripting-GitHub
  • 48.
    Setup require 'rubygems’ #Required by RHEL 6 require 'httparty’ # Used in the body below for HTTP requests require 'sinatra’ # All the Sinatra glue require 'json’ # Used in the body below for JSON stuff # Put Sinatra on port 5000 (a fairly arbitrary choice) set :port, 5000 # Globals user_agent = 'ofiwg/signed-off-by-checker' # Read the Github auth token in from the environment (it wouldn't do # the hard-code it where it would show up in a public Github repo!) auth_token = ENV['GITHUB_AUTH_TOKEN if auth_token == nil then puts "Someone forgot to set $GITHUB_AUTH_TOKEN before launching me. Aborting!n" exit 1 end
  • 49.
    Handle HTTP Get #Github webhooks are not delivered as HTTP GETs. If we don't have # this Sinatra method here, Sinatra displays a goofy error message if # someone just visits "http[s]://url_to_this_script". # Responds to an HTTP Get for “/” get '/' do # Output this plain string and exit 'Nothing to see here but us chickens' end
  • 50.
    Handle HTTP Post #Respond to an HTTP Post to “/” post '/' do # Parse the JSON into the “push” variable push = JSON.parse(request.body.read) repo_name = push['repository']['full_name'] # If this is not a push on a pull request (i.e., if there's no # commits to examine, such as if this is a test webhook ping from # github), then just return HTTP status 200 (i.e., success) with a # handy message that you can see in the Github webhook debug logs. if push['action'] == nil || (push['action'] != 'synchronize' && push['action'] != 'opened') then # Returns an HTTP 200 status and a plain string return [200, ‘Nothing for this bot to do!'] end …continues…
  • 51.
    Get all commitson this pull request # Get _all_ commits associated with this pull request commits_url = push['pull_request']['commits_url'] commits = HTTParty.get(commits_url, :headers => { 'Content-Type' => 'application/json', 'User-Agent' => user_agent, 'Authorization' => "token #{auth_token}" } ) # Setup some variables happy = true targetURL = 'https://github.com/ofiwg/libfabric/wiki#how-to-contribute' debug_message = "checking debug URL: #{commits_url}nn" final_message = '' …continues…
  • 52.
    Start analyzing thecommit messages # Loop over all the commit meta data we just downloaded commits.each_with_index do |commit, index| sha = commit['sha'] status_url = “https://api.github.com/repos/#{repo_name}/statuses/#{sha}” status = { 'context' => 'Signed-off-by checker’ } # Look for a Signed-off-by string in this commit if /Signed-off-by/.match commit['commit']['message'] status['state'] = 'success' status['description'] = 'This commit is signed off' else status['state'] = 'failure' status['description'] = 'This commit is not signed off' status['target_url'] = targetURL happy = false end final_message = status['description'] …continues…
  • 53.
    Is this thelast commit? if index == (commits.length - 1) && index > 0 then if happy then status['state'] = 'success' status['description'] = 'All commits were signed off. Yay!' else status['state'] = 'failure' status['description'] = 'At least one commit was not signed off' status['target_url’] = targetURL end final_message = status['description'] end …continues…
  • 54.
    Send back theresults for this commit HTTParty.post(status_url, :body => status.to_json, :headers => { 'Content-Type' => 'application/json', 'User-Agent' => user_agent, 'Authorization' => "token #{auth_token}" } ) end …continues…
  • 55.
    All done! # ReturnHTTP status 200 and a message that shows up in the # Github webhook debug logs return [200, ”Thanks for playing -- #{final_message}"] end
  • 56.
  • 57.