Compare commits
2 Commits
821dcdf277
...
8e72bedcf1
Author | SHA1 | Date | |
---|---|---|---|
8e72bedcf1 | |||
59d4123321 |
75
README.md
Normal file
75
README.md
Normal file
@ -0,0 +1,75 @@
|
||||
# `bebot`
|
||||
|
||||
Bebot is a Gitlab webhook handler that publishes messages to Matrix when
|
||||
interesting things happen in your configured repos.
|
||||
|
||||
Currently-supported Gitlab event types:
|
||||
|
||||
* Push events
|
||||
* Tag push events
|
||||
* Issue events
|
||||
* Merge request events
|
||||
* Pipeline events (only publishes on failure for now)
|
||||
|
||||
## Building
|
||||
|
||||
Bebot is written in Rust, and requires a Rust toolchain in order to
|
||||
build. The usual `cargo build` or `cargo build --release` will do the
|
||||
trick.
|
||||
|
||||
You can also build and install the latest released version of Bebot by
|
||||
running `cargo install bebot`.
|
||||
|
||||
## Setup
|
||||
|
||||
Bebot requires a configuration file in YAML format. See
|
||||
`sample-config.yaml` for all existing configuration options. They
|
||||
should hopefully be fairly self-explanatory, but a few clarifications:
|
||||
|
||||
1. `bind_address` and `bind_port` determine what IP/interface and port
|
||||
the webhook handler will listen on.
|
||||
2. Bebot's webhook will be served from `/hooks/gitlab`. You can use
|
||||
`url_prefix` to prepend further path segments in front of that.
|
||||
3. `user_id` and `password` are for the Matrix user that the bot will
|
||||
sign into Matrix as. Ensure that `user_id` is the full username,
|
||||
including the homeserver.
|
||||
4. `default_room` is the room that Bebot will publish to if not
|
||||
specified in the per-repo configuration.
|
||||
5. `repo_configs` is a map where the key is of the form
|
||||
`$GITLAB_INSTANCE/$NAMESPACE/$REPO`. It is recommended that you use
|
||||
a unique, randomly-generated `token` for each repository. You can
|
||||
specify `room` here as well if you don't want messages to go to
|
||||
`default_room`.
|
||||
|
||||
When setting up the webhook in Gitlab, use the same `token` from the
|
||||
configuration file in the webhook's "Secret token" field. You should
|
||||
only select "Push events", "Tag push events", "Issues events", "Merge
|
||||
request events", and "Pipeline events". You can leave some of these out
|
||||
if you don't want Bebot to publish messages for everything.
|
||||
|
||||
Bebot does not support serving the webhook over TLS, so you will
|
||||
probably want to put it behind a reverse-proxy such as nginx.
|
||||
|
||||
In the `scripts` directory is a `set-webhook.py` script that can set up
|
||||
(or update) webhooks for your repository, automatically generating a
|
||||
token for you. If setting up the webhook for the first time, it will
|
||||
output to stdout a YAML snippet that goes under the `repo_configs`
|
||||
section of the configuration file. If you run the script with no
|
||||
arguments, it will print out usage details.
|
||||
|
||||
## Running
|
||||
|
||||
After you've done all that, simply run Bebot:
|
||||
|
||||
```
|
||||
bebot /path/to/config-file.yaml
|
||||
```
|
||||
|
||||
You can set the `BEBOT_LOG` environment variable to increase or decrease
|
||||
logging verbosity. (Try `debug`, `info`, `warn` `error`, or `off`.)
|
||||
|
||||
### Docker
|
||||
|
||||
A `Dockerfile` is also provided. When running the container it builds,
|
||||
mount the configuration file so it appears inside the container as
|
||||
`/bebot/config/bebot.yaml`.
|
12
sample-config.yaml
Normal file
12
sample-config.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
bind_address: 127.0.0.1
|
||||
bind_port: 3000
|
||||
url_prefix: "/bebot"
|
||||
user_id: "@mybebot:example.com"
|
||||
password: "secret-matrix-account-password"
|
||||
default_room: "#my-project-commits:example.com"
|
||||
repo_configs:
|
||||
"gitlab.example.com/myorg/my-cool-app":
|
||||
token: "abcdefg12345"
|
||||
"gitlab.example.com/myuser/some-other-less-cool-app":
|
||||
room: "#my-other-room:example.com"
|
||||
token: "kljaslkdjaklsdjalksd"
|
@ -202,6 +202,8 @@ pub enum GitlabEvent {
|
||||
user: User,
|
||||
project: Project,
|
||||
},
|
||||
#[serde(other)]
|
||||
Other,
|
||||
}
|
||||
|
||||
impl GitlabEventExt for GitlabEvent {
|
||||
@ -212,6 +214,7 @@ impl GitlabEventExt for GitlabEvent {
|
||||
GitlabEvent::Issue { project, .. } => project,
|
||||
GitlabEvent::MergeRequest { project, .. } => &project,
|
||||
GitlabEvent::Pipeline { project, .. } => &project,
|
||||
GitlabEvent::Other => unreachable!("Unsupported event type"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,6 +225,7 @@ impl GitlabEventExt for GitlabEvent {
|
||||
GitlabEvent::Issue { .. } => None,
|
||||
GitlabEvent::MergeRequest { object_attributes, .. } => Some(&object_attributes.target_branch),
|
||||
GitlabEvent::Pipeline { object_attributes, .. } => Some(&object_attributes.r#ref),
|
||||
GitlabEvent::Other => unreachable!("Unsupported event type"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,6 +236,7 @@ impl GitlabEventExt for GitlabEvent {
|
||||
GitlabEvent::Issue { user, .. } => &user.name,
|
||||
GitlabEvent::MergeRequest { user, .. } => &user.name,
|
||||
GitlabEvent::Pipeline { user, .. } => &user.name,
|
||||
GitlabEvent::Other => unreachable!("Unsupported event type"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,6 +334,7 @@ impl GitlabEventExt for GitlabEvent {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
GitlabEvent::Other => unreachable!("Unsupported event type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
src/main.rs
12
src/main.rs
@ -185,6 +185,11 @@ async fn run() -> anyhow::Result<()> {
|
||||
let event_tx = event_tx.clone();
|
||||
|
||||
async move {
|
||||
match event {
|
||||
GitlabEvent::Other => {
|
||||
warp::reply::with_status("Unsupported Gitlab event type", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
_ => {
|
||||
let project = event.project();
|
||||
let config_key = project.web_url.replace("http://", "").replace("https://", "");
|
||||
if let Some(repo_config) = config.repo_configs.get(&config_key) {
|
||||
@ -200,7 +205,10 @@ async fn run() -> anyhow::Result<()> {
|
||||
warp::reply::with_status("OK", StatusCode::OK)
|
||||
} else {
|
||||
info!("Channel not configured for repo '{}'", config_key);
|
||||
warp::reply::with_status("Matrix room not configured for repo", StatusCode::NOT_FOUND)
|
||||
warp::reply::with_status(
|
||||
"Matrix room not configured for repo",
|
||||
StatusCode::NOT_FOUND,
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -208,6 +216,8 @@ async fn run() -> anyhow::Result<()> {
|
||||
warp::reply::with_status("Repo not configured", StatusCode::NOT_FOUND)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let routes = gitlab.with(warp::log("bebot"));
|
||||
|
Loading…
Reference in New Issue
Block a user