Skip to content

Commit

Permalink
Add Travis CI configuration to validate DCO and gofmt
Browse files Browse the repository at this point in the history
After each push, Travis CI will trigger, and check two things:

- make sure that each commit in the push has the Docker certificate of origin
- make sure that all .go files changed by this sequence of commits are correctly formatted in the most recent commit

Note: there is one edge case; if you do a git force push, we cannot figure out the actual commits in the force push, and we will just run the checks as if upstream master were the base. Pull requests will always be tested correctly, though.

Docker-DCO-1.0-Signed-off-by: Andrew Page <admwiggin@gmail.com> (github: tianon)
  • Loading branch information
tianon committed Jan 7, 2014
1 parent a0298c0 commit 561d1db
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 0 deletions.
22 changes: 22 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Note: right now we don't use go-specific features of travis.
# Later we might automate "go test" etc. (or do it inside a docker container...?)

language: go

go: 1.2

# Disable the normal go build.
install: true

before_script:
- env | sort
- sudo apt-get update -qq
- sudo apt-get install -qq python-yaml
- git remote add upstream git://github.com/dotcloud/docker.git
- git fetch upstream +refs/heads/master:refs/remotes/upstream/master

script:
- hack/travis/dco.py
- hack/travis/gofmt.py

# vim:set sw=2 ts=2:
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Solomon Hykes <solomon@dotcloud.com> (@shykes)
Guillaume Charmes <guillaume@dotcloud.com> (@creack)
Victor Vieux <victor@dotcloud.com> (@vieux)
Michael Crosby <michael@crosbymichael.com> (@crosbymichael)
.travis.yml: Tianon Gravi <admwiggin@gmail.com> (@tianon)
api.go: Victor Vieux <victor@dotcloud.com> (@vieux)
Dockerfile: Tianon Gravi <admwiggin@gmail.com> (@tianon)
Makefile: Tianon Gravi <admwiggin@gmail.com> (@tianon)
Expand Down
41 changes: 41 additions & 0 deletions hack/travis/dco.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env python
import re
import subprocess
import yaml

from env import commit_range

commit_format = '-%n hash: %h%n author: %aN <%aE>%n message: |%n%w(0,2,2)%B'

gitlog = subprocess.check_output([
'git', 'log', '--reverse',
'--format=format:'+commit_format,
'..'.join(commit_range), '--',
])

commits = yaml.load(gitlog)
if not commits:
exit(0) # what? how can we have no commits?

DCO = 'Docker-DCO-1.0-Signed-off-by:'

p = re.compile(r'^{0} ([^<]+) <([^<>@]+@[^<>]+)> \(github: (\S+)\)$'.format(re.escape(DCO)), re.MULTILINE|re.UNICODE)

failed_commits = 0

for commit in commits:
m = p.search(commit['message'])
if not m:
print 'Commit {1} does not have a properly formatted "{0}" marker.'.format(DCO, commit['hash'])
failed_commits += 1
continue # print ALL the commits that don't have a proper DCO

(name, email, github) = m.groups()

# TODO verify that "github" is the person who actually made this commit via the GitHub API

if failed_commits > 0:
exit(failed_commits)

print 'All commits have a valid "{0}" marker.'.format(DCO)
exit(0)
21 changes: 21 additions & 0 deletions hack/travis/env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import os
import subprocess

if 'TRAVIS' not in os.environ:
print 'TRAVIS is not defined; this should run in TRAVIS. Sorry.'
exit(127)

if os.environ['TRAVIS_PULL_REQUEST'] != 'false':
commit_range = [os.environ['TRAVIS_BRANCH'], 'FETCH_HEAD']
else:
try:
subprocess.check_call([
'git', 'log', '-1', '--format=format:',
os.environ['TRAVIS_COMMIT_RANGE'], '--',
])
commit_range = os.environ['TRAVIS_COMMIT_RANGE'].split('...')
if len(commit_range) == 1: # if it didn't split, it must have been separated by '..' instead
commit_range = commit_range[0].split('..')
except subprocess.CalledProcessError:
print 'TRAVIS_COMMIT_RANGE is invalid. This seems to be a force push. We will just assume it must be against upstream master and compare all commits in between.'
commit_range = ['upstream/master', 'HEAD']
28 changes: 28 additions & 0 deletions hack/travis/gofmt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env python
import subprocess

from env import commit_range

files = subprocess.check_output([
'git', 'diff', '--diff-filter=ACMR',
'--name-only', '...'.join(commit_range), '--',
])

exit_status = 0

for filename in files.split('\n'):
if filename.endswith('.go'):
try:
out = subprocess.check_output(['gofmt', '-s', '-l', filename])
if out != '':
print out,
exit_status = 1
except subprocess.CalledProcessError:
exit_status = 1

if exit_status != 0:
print 'Reformat the files listed above with "gofmt -s -w" and try again.'
exit(exit_status)

print 'All files pass gofmt.'
exit(0)

0 comments on commit 561d1db

Please sign in to comment.