Add an integration for Travis CI.
Review Request #8921 — Created May 5, 2017 and submitted
This change adds a new integration which allows people to build prospective
changes via Travis CI.The Travis CI API allows triggering a build in a way that overrides the config
from the repository's.travis.yml
file. We use this to send a new
configuration which knows how to apply the patch and report the results back to
Review Board.The configuration for the integration allows users to set the conditions
normally, with the exception that the choices for the "Repository" condition
are limited to only show GitHub repositories (since Travis CI doesn't work with
anything else). It also requires selecting which Travis endpoint to use (either
travis-ci.org for open-source projects, travis-ci.com for private projects, or
an enterprise server with a custom domain), along with providing an API token.Currently, builds show up under the main "Branches" section of the repository
in the Travis CI user interface. Because this can pollute things (for example,
showing that themaster
branch is broken because a build of a review request
failed), for now I'm recommending that people create a fakereview-requests
branch on their GitHub remote and then set that branch name in the integration
config. This isn't perfect, but it at least keeps review requests builds
separate. I'm starting to talk to the Travis CI folks to see if we can get some
more control through the API, perhaps even letting us list these builds in the
"Pull Requests" section instead of the "Branches" section.The modifications made to the user-entered configuration involve changing the
script
section to insert a few commands to check out the correct parent
revision and apply the patch, and modifications to thenotifications
section
to disable e-mail notification and set up a webhook to receive results. For
example, if the build config was set to the following:language: python python: - 2.7 env: - DJANGO_VERSION=1.6.11 - DJANGO_VERSION=1.8.2 install: - python setup.py develop - pip install -r dev-requirements.txt script: - python ./tests/runtests.py
Then the resulting configuration that would be sent to Travis would look
something like this:language: python python: - 2.7 env: global: - REVIEWBOARD_STATUS_UPDATE_ID=71 - REVIEWBOARD_TRAVIS_INTEGRATION_CONFIG_ID=4 matrix: - DJANGO_VERSION=1.6.11 - DJANGO_VERSION=1.8.2 install: - python setup.py develop - pip install -r dev-requirements.txt merge_mode: replace notifications: email: false webhooks: on_start: always urls: - http://reviewboard.example.com/rbintegrations/travis-ci/webhook/ script: - git fetch --unshallow origin - git checkout 5ec2912cd1cad96a3a20ea5857e9ed2d1de0d465 - echo <big base64 blob> | base64 --decode | patch -p1 - python ./tests/runtests.py
Integration configuration:
- Tested that only GitHub repositories showed up under the "Repository"
condition. - Tested interaction where the server name field was hidden by default and only
shown when the "Travis CI" field was set to "Enterprise (custom domain)". - Verified that a correct error message was shown if the API token was
incorrect. - Verified that an incorrect configuration would show the proper errors as
reported by the Travis CI lint API.
Usage:
- Posted a variety of changes which should either fail or pass the build, and
saw the results reported correctly. - Verified that webhook signature validation was correct, passing in regular
use and failing if I made any changes to the payload contents.
Description | From | Last Updated |
---|---|---|
Small typo in the example generated configuration. The comma shouldn't be there after the DJANGO_VERSION=1.6.11. |
chipx86 | |
This help text should probs be aligned with the description above. |
brennie | |
Alignment here is off. |
brennie | |
We definitely should have a warning that they should omit secret environment variables, because people will be able to print … |
brennie | |
Col: 15 'selectedEndpoint' is defined but never used. |
reviewbot | |
'django.utils.six.moves.urllib.error.URLError' imported but unused |
reviewbot | |
local variable 'url' is assigned to but never used |
reviewbot | |
'django.core.exceptions.ValidationError' imported but unused |
reviewbot | |
local variable 'section_name' is assigned to but never used |
reviewbot | |
'json' imported but unused |
reviewbot | |
local variable 'review_request_id' is assigned to but never used |
reviewbot | |
local variable 'data' is assigned to but never used |
reviewbot | |
Any reason you don't use an arrow func here? |
brennie | |
Module docstring |
brennie | |
Can we not just use the one from hostingsvcs to avoid duplicate code? |
brennie | |
"HTTP GET" |
brennie | |
Should be indented. |
brennie | |
Needs to be qualified. |
brennie | |
Should be indented. |
brennie | |
Needs to be qualified. |
brennie | |
Needs to be qualified. |
brennie | |
Needs to be qualified. |
brennie | |
Should be indented. |
brennie | |
Needs to be qualified. |
brennie | |
Should be indented. |
brennie | |
Module level docstring. |
brennie | |
Don't we usually have these at top of funcs? |
brennie | |
Django behaviour is to remove error'ed fields from cleaned_data. Shouldn't this be a ValidationError(_(...)) since self.error_class is ErrorList ? Same … |
brennie | |
Module level docstring. |
brennie | |
Can we distribute these? |
brennie | |
Rather, review requests that are attachment-only. |
brennie | |
This isn't Review Bot. |
brennie | |
Module level docstring. |
brennie | |
No blank line here. |
brennie | |
Blank line between these. |
brennie | |
W503 line break before binary operator |
reviewbot | |
You still need to pop travis_custom_endpoint out of self._errors. Same below. |
brennie | |
E127 continuation line over-indented for visual indent |
reviewbot | |
E501 line too long (83 > 79 characters) |
reviewbot | |
W503 line break before binary operator |
reviewbot | |
E127 continuation line over-indented for visual indent |
reviewbot | |
E501 line too long (83 > 79 characters) |
reviewbot | |
Can we use travis-ci instead of travisci? |
chipx86 | |
You can do: $server.setVisible($endpoint.val() === 'E'); |
chipx86 | |
Maybe condense these to be two lines? u = urlopen(URLRequest(...)) return json.loads(u.read()) |
chipx86 | |
dict? |
chipx86 | |
reviewboard.reviews.models.review_request.ReviewRequest |
chipx86 | |
Maybe we can use the existing list and perform a - [ReviewRequestRepositoryTypeChoice] (or whatever)? |
chipx86 | |
and on the previous line. |
chipx86 | |
W503 line break before binary operator |
reviewbot | |
We should probably use six.text_type(e) instead of e directly. Same below. |
chipx86 | |
Can simplify this a bit: if warning['key']: ... message = ... else: message = warning['message'] self._errors['travis_yml'] = self.error_class([message]) |
chipx86 | |
Can we log with request=self.request on all these logging statements, so we'll have user/Local Site context? |
chipx86 | |
repository's Let's also just use double quotes for this string instead of escaping the apostrophes. |
chipx86 | |
Let's pull out the repository into a variable. It'll prevent the Review Bot complaint, since it should be able to … |
chipx86 | |
E127 continuation line over-indented for visual indent |
reviewbot | |
We can include this in the function. |
chipx86 | |
Can these be: notifications = travis_config.get('notifications') or {} ? |
chipx86 | |
Can use += [ ... ] |
chipx86 | |
We're going to need to check for IntegrityErrors, in case another process beat this one to the punch on creating … |
chipx86 | |
*args |
chipx86 | |
**kwargs |
chipx86 | |
E501 line too long (83 > 79 characters) |
reviewbot | |
You can wrap after the . anywhere now. |
chipx86 | |
This will crash if HTTP_SIGNATURE isn't present. |
chipx86 | |
Should be bullet-proof this? Log an error if we get a KeyError? |
chipx86 | |
Does this raise an exception if any part of this fails? |
chipx86 | |
We should bullet-proof this as well. |
chipx86 | |
W503 line break before binary operator |
reviewbot | |
E501 line too long (81 > 79 characters) |
reviewbot | |
E501 line too long (83 > 79 characters) |
reviewbot | |
E122 continuation line missing indentation or outdented |
reviewbot | |
You can pass the method in directory. There's no this being used. |
chipx86 | |
We should guard against the request failing or the data not being parsable. (Proxy servers may get in the way … |
chipx86 | |
"GitHub" |
chipx86 | |
GitHub |
brennie | |
Can you wrap these in parens so it's a little more visually clear what's happening? Since this is Python 2.7, … |
chipx86 | |
W503 line break before binary operator |
reviewbot | |
Should this be marked for translation? |
brennie | |
Do we want to limit the scope of this token? |
brennie | |
E501 line too long (83 > 79 characters) |
reviewbot | |
Sine this line's too long, and we dig into cryptography.hazmat.primitives a bunch, let's just pull primitives out. |
chipx86 | |
W503 line break before binary operator |
reviewbot |
- Commit:
-
c98d7f3ee064cc1ddf4fc489854f401f2d482289c0112d02f0b7c92c854ffc9a1076ba2d0b916bc5
- Diff:
-
Revision 2 (+949 -1)
Checks run (2 succeeded, 1 failed with error)
- Commit:
-
c0112d02f0b7c92c854ffc9a1076ba2d0b916bc58fd69d70f07b57c21ad8733c1c04ae604d21493f
- Diff:
-
Revision 3 (+961 -1)
- Change Summary:
-
Some random fixes and improvements that came up as I was writing tests.
- Commit:
-
8fd69d70f07b57c21ad8733c1c04ae604d21493f07a5b58bfa7efe5c5880dec5995ac12f557383bc
- Diff:
-
Revision 4 (+962 -1)
- Commit:
-
07a5b58bfa7efe5c5880dec5995ac12f557383bc0f1422b22a439a8e6a89032ab25d4e78500c09bf
- Diff:
-
Revision 5 (+968 -1)
-
-
Small typo in the example generated configuration. The comma shouldn't be there after the
DJANGO_VERSION=1.6.11
. -
-
-
-
-
-
Maybe we can use the existing list and perform a
- [ReviewRequestRepositoryTypeChoice]
(or whatever)? -
-
-
Can simplify this a bit:
if warning['key']: ... message = ... else: message = warning['message'] self._errors['travis_yml'] = self.error_class([message])
-
Can we log with
request=self.request
on all these logging statements, so we'll have user/Local Site context? -
-
Let's pull out the repository into a variable. It'll prevent the Review Bot complaint, since it should be able to wrap, and we access the repository further below anyway.
-
-
-
-
We're going to need to check for
IntegrityErrors
, in case another process beat this one to the punch on creating the user. -
-
-
-
-
-
-
- Description:
-
This change adds a new integration which allows people to build prospective
changes via Travis CI. The Travis CI API allows triggering a build in a way that overrides the config
from the repository's .travis.yml
file. We use this to send a newconfiguration which knows how to apply the patch and report the results back to Review Board. The configuration for the integration allows users to set the conditions
normally, with the exception that the choices for the "Repository" condition are limited to only show GitHub repositories (since Travis CI doesn't work with anything else). It also requires selecting which Travis endpoint to use (either travis-ci.org for open-source projects, travis-ci.com for private projects, or an enterprise server with a custom domain), along with providing an API token. Currently, builds show up under the main "Branches" section of the repository
in the Travis CI user interface. Because this can pollute things (for example, showing that the master
branch is broken because a build of a review requestfailed), for now I'm recommending that people create a fake review-requests
branch on their GitHub remote and then set that branch name in the integration config. This isn't perfect, but it at least keeps review requests builds separate. I'm starting to talk to the Travis CI folks to see if we can get some more control through the API, perhaps even letting us list these builds in the "Pull Requests" section instead of the "Branches" section. The modifications made to the user-entered configuration involve changing the
script
section to insert a few commands to check out the correct parentrevision and apply the patch, and modifications to the notifications
sectionto disable e-mail notification and set up a webhook to receive results. For example, if the build config was set to the following: language: python
python:
- 2.7
env:
- DJANGO_VERSION=1.6.11
- DJANGO_VERSION=1.8.2
install:
- python setup.py develop
- pip install -r dev-requirements.txt
script:
- python ./tests/runtests.py
Then the resulting configuration that would be sent to Travis would look
something like this: language: python
python:
- 2.7
env:
global:
- REVIEWBOARD_STATUS_UPDATE_ID=71
- REVIEWBOARD_TRAVIS_INTEGRATION_CONFIG_ID=4
matrix:
~ - DJANGO_VERSION=1.6.11,
~ - DJANGO_VERSION=1.6.11
- DJANGO_VERSION=1.8.2
install:
- python setup.py develop
- pip install -r dev-requirements.txt
merge_mode: replace
notifications:
email: false
webhooks:
on_start: always
urls:
- http://reviewboard.example.com/rbintegrations/travis-ci/webhook/
script:
- git fetch --unshallow origin
- git checkout 5ec2912cd1cad96a3a20ea5857e9ed2d1de0d465
- echo <big base64 blob> | base64 --decode | patch -p1
- python ./tests/runtests.py
- - - - Documentation and unit tests will be forthcoming in future changes.
- Commit:
-
0f1422b22a439a8e6a89032ab25d4e78500c09bfd2840643f6e929a6da5872400244fe9ebeb3e5e7
- Diff:
-
Revision 6 (+970 -1)
- Commit:
-
d2840643f6e929a6da5872400244fe9ebeb3e5e731e510562cf021a7d67cb92dadfc23adad7ccde2
- Diff:
-
Revision 7 (+971 -1)
-
-
-
We should guard against the request failing or the data not being parsable. (Proxy servers may get in the way and spit out garbage, for instance.)
What we do in GitHub and other places is we have a function that does the request and returns JSON data, and it checks everything. We should maybe have
_make_request
do that (optionally, if it's being used for non-JSON requests as well). -
-
Can you wrap these in parens so it's a little more visually clear what's happening?
Since this is Python 2.7, we can also use
{...}
instead ofset([...]}
. -
Sine this line's too long, and we dig into
cryptography.hazmat.primitives
a bunch, let's just pullprimitives
out.
- Commit:
-
31e510562cf021a7d67cb92dadfc23adad7ccde2958654befc4863eb1613d1959f8120f08f3ea036
- Diff:
-
Revision 8 (+973 -1)
- Commit:
-
958654befc4863eb1613d1959f8120f08f3ea036c032765c380055b556c547efe348ec0b2020432b
- Diff:
-
Revision 9 (+973 -1)