Top Banner
Simple Ruby/Sinatra Github webhook script KYOSS July 2015 Jeff Squyres
57

Fun with Github webhooks: verifying Signed-off-by

Aug 08, 2015

Download

Software

Jeff Squyres
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Fun with Github webhooks: verifying Signed-off-by

Simple Ruby/Sinatra Github webhook script

KYOSS July 2015Jeff Squyres

Page 2: Fun with Github webhooks: verifying Signed-off-by

Github: A popular Git-hosting service

www.github.com

Page 3: Fun with Github webhooks: verifying Signed-off-by

Github hostsyour Git repos

Git repo

Git repo

Git repo

Page 4: Fun with Github webhooks: verifying Signed-off-by

Github hostsyour Organization’s Git repos

Git repo

Git repo

Git repo

YoyodyneOrganization

Page 5: Fun with Github webhooks: verifying Signed-off-by

Github hostsyour Organization’s Git repos

Git repo

Git repo

Git repo

YoyodyneOrganization

Git repo

Git repo

Git repo

Git repo

Page 6: Fun with Github webhooks: verifying Signed-off-by

Github has other services

Wiki

Code reviews

Git web UIWeb UI for editing / committing

Git branch control

Git repo forkingPull requestsIssue tracking

Milestone tracking

Github PagesMarkdown rendering

Read-only Git accessOrganization teams

Gravatar integration

Federated login services

Page 7: Fun with Github webhooks: verifying Signed-off-by

Github has other services

Wiki

Code reviews

Git web UIWeb UI for editing / committing

Git branch control

Git repo forkingPull requestsIssue tracking

Milestone tracking

Github PagesMarkdown rendering

Read-only Git accessOrganization teams

Gravatar integration

Federated login services

API hooks

Page 8: Fun with Github webhooks: verifying Signed-off-by

The Github Webhook

Hey!Something

just happened!

Page 9: Fun with Github webhooks: verifying Signed-off-by

The Github Webhook

Hey!Something

just happened!

Github servers

Page 10: Fun with Github webhooks: verifying Signed-off-by

The Github Webhook

Your serverGithub serversHTTP 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

Page 11: Fun with Github webhooks: verifying Signed-off-by

What can you do with Github webhooks?

Page 12: Fun with Github webhooks: verifying Signed-off-by

A common Github webhook use

Your serverGithub servers

A pull request was just opened

Kick off a buildof the pull requestand test the result

Send resultsback to Github

Page 13: Fun with Github webhooks: verifying Signed-off-by

Example: Github kicked off tests

Page 14: Fun with Github webhooks: verifying Signed-off-by

Example: all tests passed

Page 15: Fun with Github webhooks: verifying Signed-off-by

Let’s look at another case

Page 16: Fun with Github webhooks: verifying Signed-off-by

The Libfabric project

• Next generation high performance networking user stack

• Multi-vendor / organization

• Open source• Hosted on Github

Page 17: Fun with Github webhooks: verifying Signed-off-by

Libfabric commits

Require a “Signed-off-by” line in Git commit messages

commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417Author: Jeff Squyres <[email protected]>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 <[email protected]>

Page 18: Fun with Github webhooks: verifying Signed-off-by

Libfabric commits

Require a “Signed-off-by” line in Git commit messages

commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417Author: Jeff Squyres <[email protected]>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 <[email protected]>

commit efd7a5c878f53ba12ed771fa006d57b7f9d264fdAuthor: Jithin Jose <[email protected]>Date: Thu Jul 2 09:05:16 2015 -0700

sockets: fix resource leak in comm buffer Signed-off-by: Jithin Jose <[email protected]>

Page 19: Fun with Github webhooks: verifying Signed-off-by

Libfabric commits

Require a “Signed-off-by” line in Git commit messages

commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417Author: Jeff Squyres <[email protected]>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 <[email protected]>

commit efd7a5c878f53ba12ed771fa006d57b7f9d264fdAuthor: Jithin Jose <[email protected]>Date: Thu Jul 2 09:05:16 2015 -0700

sockets: fix resource leak in comm buffer Signed-off-by: Jithin Jose <[email protected]>

commit 621dd04cbe2c9e066602393d508c85d175bebbb9Author: James Swaro <[email protected]>Date: Mon Jun 29 12:28:32 2015 -0500

Initialize param_list to avoid crashing in library destructor

Page 20: Fun with Github webhooks: verifying Signed-off-by

Libfabric commits

Require a “Signed-off-by” line in Git commit messages

commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417Author: Jeff Squyres <[email protected]>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 <[email protected]>

commit efd7a5c878f53ba12ed771fa006d57b7f9d264fdAuthor: Jithin Jose <[email protected]>Date: Thu Jul 2 09:05:16 2015 -0700

sockets: fix resource leak in comm buffer Signed-off-by: Jithin Jose <[email protected]>

commit 621dd04cbe2c9e066602393d508c85d175bebbb9Author: James Swaro <[email protected]>Date: Mon Jun 29 12:28:32 2015 -0500

Initialize param_list to avoid crashing in library destructor

commit 621dd04cbe2c9e066602393d508c85d175bebbb9Author: James Swaro <[email protected]>Date: Mon Jun 29 12:28:32 2015 -0500

Initialize param_list to avoid crashing in library destructor

Missing Signed-off-by line!

Page 21: Fun with Github webhooks: verifying Signed-off-by

Libfabric only accepts commitsvia pull requests

Libfabric Github Git repo

Page 22: Fun with Github webhooks: verifying Signed-off-by

Libfabric only accepts commitsvia pull requests

Libfabric Github Git repo

jsquyres Github forked libfabric repo

Step 1: Jeff makes a Gihub “fork”of the upstream Libfabric repo

Page 23: Fun with Github webhooks: verifying Signed-off-by

Libfabric only accepts commitsvia pull requests

Libfabric Github Git repo

jsquyres Github forked libfabric repo commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417

Author: Jeff Squyres <[email protected]>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 <[email protected]>

Step 2: Jeff makes a commit on hislibfabric fork

Page 24: Fun with Github webhooks: verifying Signed-off-by

Libfabric only accepts commitsvia pull requests

Libfabric Github Git repo

jsquyres Github forked libfabric repo commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417

Author: Jeff Squyres <[email protected]>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 <[email protected]>

Step 3: Jeff files a pull request to askif his commit can be accepted intothe main Libfabric repo

Page 25: Fun with Github webhooks: verifying Signed-off-by

Libfabric only accepts commitsvia pull requests

Libfabric Github Git repo

jsquyres Github forked libfabric repo commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417

Author: Jeff Squyres <[email protected]>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 <[email protected]>

Step 4: A libfabric maintainer acceptsJeff’s pull request

commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417Author: Jeff Squyres <[email protected]>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 <[email protected]>

commit d70ebb7b6f7afb51e3026c92c40b6aedae8b1417Author: Jeff Squyres <[email protected]>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 <[email protected]>

Page 26: Fun with Github webhooks: verifying Signed-off-by

Wait – you missed a step

Page 27: Fun with Github webhooks: verifying Signed-off-by

The missing step

1. Jeff makes a Gihub “fork” of the upstream Libfabric repo

2. Jeff makes a commit on his libfabric fork3. Jeff files a pull request to ask if his commit can

be accepted into the main Libfabric repo4. Libfabric maintainers review the pull request

commit(s)5. A libfabric maintainer accepts Jeff’s pull

request

Page 28: Fun with Github webhooks: verifying Signed-off-by

The missing step

1. Jeff makes a Gihub “fork” of the upstream Libfabric repo

2. Jeff makes a commit on his libfabric fork3. Jeff files a pull request to ask if his commit can

be accepted into the main Libfabric repo4. Libfabric maintainers review the pull request

commit(s)5. A libfabric maintainer accepts Jeff’s pull

request

Is the commit good?

Does the code fit the style guide?

Is the code correct?

Does the code fit with the rest?

Does the code pass CI?

Does the code break anything?

Page 29: Fun with Github webhooks: verifying Signed-off-by

The missing step

1. Jeff makes a Gihub “fork” of the upstream Libfabric repo

2. Jeff makes a commit on his libfabric fork3. Jeff files a pull request to ask if his commit can

be accepted into the main Libfabric repo4. Libfabric maintainers review the pull request

commit(s)5. A libfabric maintainer accepts Jeff’s pull

request

Is the commit good?

Does the code fit the style guide?

Is the code correct?

Does the code fit with the rest?

Does the code pass CI?

Does the code break anything?

Is there a Signed-off-by line?

Page 30: Fun with Github webhooks: verifying Signed-off-by

The Signed-off-by lineIt’s kind of a silly thing

It has nothing to do with the code itself

Page 31: Fun with Github webhooks: verifying Signed-off-by

The Signed-off-by line

But the lawyers tell us we must have it

Page 32: Fun with Github webhooks: verifying Signed-off-by

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

Page 33: Fun with Github webhooks: verifying Signed-off-by

The Signed-off-by line

Sounds like a perfect jobfor automation

Page 34: Fun with Github webhooks: verifying Signed-off-by

Example: PR with three commits

Page 35: Fun with Github webhooks: verifying Signed-off-by

Example: PR with three commits

Page 36: Fun with Github webhooks: verifying Signed-off-by

Example PR with Badness

Page 37: Fun with Github webhooks: verifying Signed-off-by

Example PR with Badness

Page 38: Fun with Github webhooks: verifying Signed-off-by

Example PR with Badness

Why is this one marked bad?

Page 39: Fun with Github webhooks: verifying Signed-off-by

Example PR with Badness

Why is this one marked bad?

Github uses the status of the last commit as the statusof the overall pull request

Page 40: Fun with Github webhooks: verifying Signed-off-by

That’s what it doesNow let’s look what it is

Page 41: Fun with Github webhooks: verifying Signed-off-by

Sinatra

sinatrarb.com

Page 42: Fun with Github webhooks: verifying Signed-off-by

Sinatra

sinatrarb.com

Page 43: Fun with Github webhooks: verifying Signed-off-by

Sinatra: logistics

Sinatra processLocal browser

http://localhost:4567

Page 44: Fun with Github webhooks: verifying Signed-off-by

Sinatra: logistics

Sinatra process

http:

//lo

calh

ost:4

567

nginx processRemote browser

http:

//ex

ampl

e.co

m

Page 45: Fun with Github webhooks: verifying Signed-off-by

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 resultsback to Github

Page 46: Fun with Github webhooks: verifying Signed-off-by

Github to Sinatra logistics

Github servers Some web serververify-

signed-off.rb

Send resultsback to Github

Page 47: Fun with Github webhooks: verifying Signed-off-by

“Signed-off-by” checkerSource 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 byhttp://git-scm.com/book/en/v2/GitHub-Scripting-GitHub

Page 48: Fun with Github webhooks: verifying Signed-off-by

Setuprequire 'rubygems’ # Required by RHEL 6require 'httparty’ # Used in the body below for HTTP requestsrequire 'sinatra’ # All the Sinatra gluerequire 'json’ # Used in the body below for JSON stuff

# Put Sinatra on port 5000 (a fairly arbitrary choice)set :port, 5000

# Globalsuser_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_TOKENif auth_token == nil then puts "Someone forgot to set \$GITHUB_AUTH_TOKEN before launching me. Aborting!\n" exit 1end

Page 49: Fun with Github webhooks: verifying Signed-off-by

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

Page 50: Fun with Github webhooks: verifying Signed-off-by

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…

Page 51: Fun with Github webhooks: verifying Signed-off-by

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}\n\n" final_message = ''

…continues…

Page 52: Fun with Github webhooks: verifying Signed-off-by

Start analyzing the commit messages

# Loop over all the commit meta data we just downloadedcommits.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…

Page 53: Fun with Github webhooks: verifying Signed-off-by

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…

Page 54: Fun with Github webhooks: verifying Signed-off-by

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…

Page 55: Fun with Github webhooks: verifying Signed-off-by

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

Page 56: Fun with Github webhooks: verifying Signed-off-by

Example / reminder of output

Page 57: Fun with Github webhooks: verifying Signed-off-by

Yay!