Skip to content
This repository was archived by the owner on Mar 20, 2024. It is now read-only.

Removing broken Travis webhook integration #117

Merged
merged 1 commit into from
Jun 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 58 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
[![Hommando]][Akemi Homura]

Homu is a bot that integrates with GitHub and your favorite continuous
integration service, such as [Buildbot] or [Travis CI].
integration service such as [Travis CI], [Appveyor] or [Buildbot].

[Hommando]: https://i.imgur.com/j0jNvHF.png
[Akemi Homura]: https://wiki.puella-magi.net/Homura_Akemi
[Buildbot]: http://buildbot.net/
[Travis CI]: https://travis-ci.org/
[Appveyor]: https://www.appveyor.com/

## Why is it needed?

Expand All @@ -31,8 +32,9 @@ approval comment from one of the configured reviewers. When the pull request is
approved, Homu tests it using your favorite continuous integration service, and
only when it passes all the tests, it is merged into `master`.

Note that Homu is **not** a replacement of Travis CI or Buildbot. It works on
top of them. Homu itself doesn't have the ability to test pull requests.
Note that Homu is **not** a replacement of Travis CI, Buildbot or Appveyor. It
works on top of them. Homu itself doesn't have the ability to test pull
requests.

## Influences of bors

Expand All @@ -50,8 +52,8 @@ before the merge" came from bors. However, there are also some differences:
feature. This approach improves the overall performance and the response
time, because the bot is informed about the status changes immediately.

And also, Homu has more features, such as `rollup`, `try`, and the Travis CI
support.
And also, Homu has more features, such as `rollup`, `try`, and the Travis CI &
Appveyor support.

[bors]: https://github.com/graydon/bors
[Webhooks]: https://developer.github.com/webhooks/
Expand All @@ -62,74 +64,71 @@ support.
### How to install

```sh
sudo apt-get install python3-venv

pyvenv .venv
. .venv/bin/activate

# Stable version

pip install homu

# Development version

git clone https://github.com/barosl/homu.git
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while you're at it make this servo instead of barosl

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

pip install -e homu
$ sudo apt-get install python3-venv
$ pyvenv .venv
$ . .venv/bin/activate
$ git clone https://github.com/servo/homu.git
$ pip install -e homu
```

### How to configure

1. Copy `cfg.sample.toml` to `cfg.toml`, and edit it accordingly.

2. Create a GitHub account that will be used by Homu. You can also use an
existing account. In the [account settings][settings], register a new
application and generate a new access token (with the `repo` permission).
The OAuth Callback URL should be `http://HOST:PORT/callback`, the homepage URL
isn't needed and can be anything, for example `http://HOST:PORT/`.

3. Add a Webhook to your repository:

- Payload URL: `http://HOST:PORT/github`
- Content type: `application/json`
- Secret: The same as `repo.NAME.github.secret` in cfg.toml
- Events: `Issue Comment`, `Pull Request`, `Push`, `Status`
In the following instructions, `HOST` refers to the hostname (or IP address)
where you are running your custom homu instance. `PORT` is the port the service
is listening to and is configured in `web.port` in `cfg.toml`. `NAME` refers to
the name of the repository you are configuring homu for.

4. Add a Webhook to your continuous integration service:
1. Copy `cfg.sample.toml` to `cfg.toml`. You'll need to edit this file to set up
your configuration. The following steps explain where you can find important
config values.

- Buildbot

Insert the following code to the `master.cfg` file:

```python
from buildbot.status.status_push import HttpStatusPush

c['status'].append(HttpStatusPush(
2. Create a GitHub account that will be used by Homu. You can also use an
existing account. In the [account settings][settings], go to "OAuth
applications" and create a new application:
- Make note of the "Client ID" and "Client Secret"; you will need to put them in
your `cgf.toml`.
- The OAuth Callback URL should be `http://HOST:PORT/callback`.
- The homepage URL isn't necessary; you could set `http://HOST:PORT/`.

3. Go to the user settings of the GitHub account you created/used in the
previous step. Go to "Personal access tokens". Click "Generate new token" and
choose the "repo" and "user" scopes. Put the token value in your `cfg.toml`.

4. Add your new GitHub account as a Collaborator to the GitHub repo you are
setting up homu for. This can be done in repo (NOT user) "Settings", then
"Collaborators".

5. Add a Webhook to your repository. This is done under repo (NOT user)
"Settings", then "Webhooks". Click "Add webhook", the set:
- Payload URL: `http://HOST:PORT/github`
- Content type: `application/json`
- Secret: The same as `repo.NAME.github.secret` in `cfg.toml`
- Events: `Issue Comment`, `Pull Request`, `Push`, `Status`

6. Add a Webhook to your continuous integration service, if necessary. You don't
need this if using Travis/Appveyor.
- Buildbot

Insert the following code to the `master.cfg` file:

```python
from buildbot.status.status_push import HttpStatusPush

c['status'].append(HttpStatusPush(
serverUrl='http://HOST:PORT/buildbot',
extra_post_params={'secret': 'repo.NAME.buildbot.secret in cfg.toml'},
))
```
))
```

- Travis CI

Add [your Travis token][travis] as `repo.NAME.travis.token` in cfg.toml.
Insert the following code to the `.travis.yml` file:

```yaml
notifications:
webhooks: http://HOST:PORT/travis

branches:
only:
- auto
```
7. Go through the rest of your `cfg.toml` and uncomment (and change, if needed)
parts of the config you'll need.

[settings]: https://github.com/settings/applications
[travis]: https://travis-ci.org/profile/info

### How to run

```sh
. .venv/bin/activate

homu
$ . .venv/bin/activate
$ homu
```
100 changes: 56 additions & 44 deletions cfg.sample.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Information for securely interacting with GitHub. These are found/generated
# under <https://github.com/settings/applications>.

# A GitHub personal access token
# A GitHub personal access token.
access_token = ""

# A GitHub oauth application for this instance of homu:
Expand All @@ -16,28 +16,29 @@ max_priority = 9001
[git]

# Use the local Git command. Required to use some advanced features. It also
# speeds up Travis by reducing temporary commits
# speeds up Travis by reducing temporary commits.
#local_git = false

# SSH private key. Needed only when the local Git command is used
# SSH private key. Needed only when the local Git command is used.
#ssh_key = """
#"""

# By default, Homu extracts the name+email from the Github account. However,
# you may want to use a private email for the account, and associate the commits
# with a public email address.
# By default, Homu extracts the name+email from the Github account it will be
# using. However, you may want to use a private email for the account, and
# associate the commits with a public email address.
#user = "Some Cool Project Bot"
#email = "coolprojectbot-devel@example.com"

[web]

# The port homu listens on
# The port homu listens on.
port = 54856

# Synchronize all open PRs on startup
#sync_on_start = false
# Synchronize all open PRs on startup. "Synchronize" means fetch the state of
# all open PRs.
sync_on_start = true

# Custom hooks can be added as well
# Custom hooks can be added as well.
# Homu will ping the given endpoint with POSTdata of the form:
# {'body': 'comment body', 'extra_data': 'extra data', 'pull': pull req number}
# The extra data is the text specified in `@homu hookname=text`
Expand All @@ -49,46 +50,74 @@ port = 54856
# has_response = true # Should the response be posted back to github? Only allowed if realtime=true
# realtime = true # Should it only run in realtime mode? If false, this will be replayed each time homu is started (probably not what you want)

# An example configuration for repository (there can be many of these)
# An example configuration for repository (there can be many of these). NAME
# refers to your repo name.
[repo.NAME]

# github.com/<owner>/<name>
# Which repo are we talking about? You can get these fields from your repo URL:
# github.com/<owner>/<name>
owner = ""
name = ""

# who has r+ rights?
reviewers = ["barosl", "graydon"]
# Alternatively, set this to allow any github collaborator;
# Who can approve PRs (r+ rights)? You can put GitHub usernames here.
reviewers = []
# Alternatively, set this allow any github collaborator;
# note that you can *also* specify reviewers above.
# auth_collaborators = true

# who has 'try' rights? (try, retry, force, clean, prioritization)
# Who has 'try' rights? (try, retry, force, clean, prioritization). It's fine to
# keep this empty.
try_users = []

# Keep the commit history linear. Requires the local Git command
# Keep the commit history linear. Requires the local Git command.
#linear = false

# Auto-squash commits. Requires the local Git command
# Auto-squash commits. Requires the local Git command.
#autosquash = true

# If the PR already has the same success statuses that we expect on the auto
# If the PR already has the same success statuses that we expect on the `auto`
# branch, then push directly to branch if safe to do so. Requires the local Git
# command.
#status_based_exemption = false

## branch names (these settings here are the defaults)
# Branch names. These settings are the defaults; it makes sense to leave these
# as-is.
#[repo.NAME.branch]
#
#auto = "auto"
#try = "try"
#rollup = "rollup"

[repo.NAME.github]

# arbitrary secret (e.g. openssl rand -hex 20)
# Arbitrary secret. You can generate one with: openssl rand -hex 20
secret = ""

## Use buildbot for running tests
# Travis integration. Don't forget to allow Travis to test the `auto` branch!
[repo.NAME.status.travis]
# String label set by status updates. Don't touch this unless you really know
# what you're doing.
context = 'continuous-integration/travis-ci/push'

# Appveyor integration. Don't forget to allow Appveyor to test the `auto` branch!
#[repo.NAME.status.appveyor]
#
# String label set by status updates. Don't touch this unless you really know
# what you're doing.
#context = 'continuous-integration/appveyor/branch'

# Generic GitHub Status API support. You don't need this if you're using the
# above examples for Travis/Appveyor.
#[repo.NAME.status.LABEL]
#
# String label set by status updates.
#context = ""
#
# Equivalent context to look for on the PR itself if checking whether the
# build should be exempted. If omitted, looks for the same context. This is
# only used if status_based_exemption is true.
#pr_context = ""

# Use buildbot for running tests
#[repo.NAME.buildbot]
#
#url = ""
Expand All @@ -100,28 +129,11 @@ secret = ""
#username = ""
#password = ""

## Use travis for running tests
#[repo.NAME.travis]
#
## found under <https://travis-ci.org/profile/info>.
#token = ""

## Use the Status API
#[repo.NAME.status.LABEL]
#
## String label set by status updates
#context = ""
#
## Boolean which indicates whether the builder is included in try builds (defaults to true)
#try = false
#
## Equivalent context to look for on the PR itself if checking whether the
## build should be exempted. If omitted, looks for the same context. This is
## only used if status_based_exemption is true.
#pr_context = ""

## The database homu uses
#[db]
#
## SQLite file
#file = "main.db"
# The database homu uses
[db]
# SQLite file
file = "main.db"
46 changes: 0 additions & 46 deletions homu/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
abort,
response,
)
import hashlib
from threading import Thread
import sys
import os
Expand Down Expand Up @@ -677,51 +676,6 @@ def buildbot():
return 'OK'


@post('/travis')
def travis():
logger = g.logger.getChild('travis')

info = json.loads(request.forms.payload)

lazy_debug(logger, lambda: 'info: {}'.format(utils.remove_url_keys_from_json(info))) # noqa

try:
state, repo_label = find_state(info['commit'])
except ValueError:
lazy_debug(logger, lambda: 'Invalid commit ID from Travis: {}'.format(info['commit'])) # noqa
return 'OK'

lazy_debug(logger, lambda: 'state: {}, {}'.format(state, state.build_res_summary())) # noqa

if 'travis' not in state.build_res:
lazy_debug(logger, lambda: 'travis is not a monitored target for {}'.format(state)) # noqa
return 'OK'

repo_cfg = g.repo_cfgs[repo_label]
token = repo_cfg['travis']['token']
auth_header = request.headers['Authorization']

slug = '{}/{}{}'.format(state.owner, state.name, token)
code = hashlib.sha256((slug).encode('utf-8')).hexdigest()

if auth_header != code:
# this isn't necessarily an error, e.g. maybe someone is
# fabricating travis notifications to try to trick Homu, but,
# I imagine that this will most often occur because a repo is
# misconfigured.
logger.warn('authorization failed for {}, maybe the repo has the '
'wrong travis token? header = {}, computed = {}'
.format(state, auth_header, code))
abort(400, 'Authorization failed')

succ = info['result'] == 0

report_build_res(succ, info['build_url'], 'travis', state, logger,
repo_cfg)

return 'OK'


def synch(user_gh, state, repo_label, repo_cfg, repo):
if not repo.is_collaborator(user_gh.user().login):
abort(400, 'You are not a collaborator')
Expand Down