-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit baf5e86
Showing
54 changed files
with
18,973 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
target | ||
docs | ||
ui/node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
name: Pull request | ||
|
||
on: | ||
pull_request: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v1 | ||
- name: Build | ||
run: cargo build | ||
- name: Run tests | ||
run: cargo test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
name: Publish release | ||
|
||
on: | ||
release: | ||
types: [published] | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
if: "!contains(github.event.head_commit.message, 'skip-ci')" | ||
steps: | ||
- uses: actions/checkout@v1 | ||
|
||
- name: Get the version | ||
id: get_version | ||
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//} | ||
|
||
- name: Build Docker image | ||
run: | | ||
docker build -t spectresystems/duck:latest -t spectresystems/duck:${{ steps.get_version.outputs.VERSION }} . | ||
- name: Publish Docker image | ||
env: | ||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} | ||
DOCKER_PASSWORD: ${{ secrets.DOCKER_TOKEN }} | ||
run: | | ||
docker login -u ${DOCKER_USERNAME} -p "${DOCKER_PASSWORD}" | ||
docker push spectresystems/duck:latest | ||
docker push spectresystems/duck:${{ steps.get_version.outputs.VERSION }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Rust | ||
/target | ||
**/*.rs.bk | ||
|
||
# Configuration | ||
config.json |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
[package] | ||
name = "duck" | ||
version = "0.1.0" | ||
authors = ["Patrik Svensson <[email protected]>"] | ||
edition = "2018" | ||
|
||
[features] | ||
docker = [] | ||
|
||
[[bin]] | ||
name = "duck" | ||
path = "src/main.rs" | ||
|
||
[dependencies] | ||
failure = "0.1.6" | ||
serde = { version = "1.0", features = ["derive"] } | ||
serde_json = "1.0" | ||
url = "2.1.0" | ||
reqwest = "0.9.22" | ||
waithandle = "0.1.0" | ||
actix-web = "1.0.8" | ||
actix-files = "0.1.7" | ||
structopt = "0.3" | ||
log = "0.4" | ||
env_logger = "0.7.1" | ||
actix-cors = "0.1.0" | ||
chrono = "0.4.10" | ||
regex = "1.3.3" | ||
|
||
[profile.release] | ||
panic = 'abort' | ||
lto = true | ||
codegen-units = 1 | ||
incremental = false | ||
opt-level = "z" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Build server | ||
FROM ekidd/rust-musl-builder:stable AS server-builder | ||
ADD . ./ | ||
RUN sudo chown -R rust:rust . | ||
RUN cargo build --release --target x86_64-unknown-linux-musl --features docker | ||
|
||
# Build UI | ||
FROM node:lts-alpine as ui-builder | ||
WORKDIR /app | ||
ENV VUE_APP_MY_DUCK_SERVER= | ||
COPY ./ui/package*.json ./ | ||
RUN npm install | ||
COPY ./ui . | ||
RUN npm run build | ||
|
||
# Copy to Alpine container | ||
FROM alpine:latest | ||
EXPOSE 15825 | ||
RUN apk --no-cache add ca-certificates | ||
COPY --from=server-builder /home/rust/src/target/x86_64-unknown-linux-musl/release/duck /usr/local/bin/ | ||
COPY --from=ui-builder /app/dist /usr/local/bin/ui | ||
WORKDIR /usr/local/bin | ||
ENTRYPOINT ["duck"] | ||
CMD ["--help"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
# Duck | ||
|
||
Duck is a build system agnostic build monitor written in Rust (backend server) and Vue (frontend). It also support sending messages to Slack and controlling [Philips Hue](https://www2.meethue.com/) lights. | ||
|
||
 | ||
|
||
## Running | ||
|
||
The absolute easiest way of getting started with Duck is to use the docker image. You will have to provide a configuration file for it to work. | ||
|
||
``` | ||
> docker run --rm -it -v ./data:/data -p 8080:15825 spectresystems/duck:latest --config /data/duck.json | ||
``` | ||
|
||
## How it works | ||
|
||
The server part is responsible for collecting information from different `collectors` and forward interesting events to `observers`. The aggregated information is available for other services (such as the Vue frontend) via a HTTP API. | ||
|
||
Observers can either be dependent on events from all collectors, or opt in to one or more collectors. This makes it easy to setup team specific build lights or Slack integration that's only dependent on specific collectors. | ||
|
||
 | ||
|
||
## Configuration | ||
|
||
Below is an example configuration that specifies multiple collectors and observers. By specifying the schema you will get autocomplete support in editors that support it like Visual Studio Code. | ||
|
||
```json | ||
{ | ||
"$schema": "https://raw.githubusercontent.com/spectresystems/duck/master/config/schema.json", | ||
"interval": 30, | ||
"collectors": [ | ||
{ | ||
"teamcity": { | ||
"id": "teamcity_local", | ||
"serverUrl": "http://127.0.0.1:8111/", | ||
"credentials": "guest", | ||
"builds": [ | ||
"My_Project_Definition", | ||
"My_Other_Build_Definition" | ||
] | ||
} | ||
}, | ||
{ | ||
"teamcity": { | ||
"id": "teamcity_other", | ||
"enabled": false, | ||
"serverUrl": "192.168.0.1:8111", | ||
"credentials": { | ||
"basic": { | ||
"username": "foo", | ||
"password": "bar" | ||
} | ||
}, | ||
"builds": [ | ||
"My_Third_Build_Definition" | ||
] | ||
} | ||
}, | ||
{ | ||
"azure": { | ||
"id": "azure_cake", | ||
"enabled": false, | ||
"organization": "cake-build", | ||
"project": "Cake", | ||
"credentials": "anonymous", | ||
"definitions": [ "1", "3", "5" ], | ||
"branches": [ | ||
"refs/heads/develop", | ||
"refs/heads/main" | ||
] | ||
} | ||
}, | ||
{ | ||
"azure": { | ||
"id": "azure_private", | ||
"enabled": false, | ||
"organization": "some-organization", | ||
"project": "some-project", | ||
"credentials": { | ||
"pat": "SUPER-SECRET-PERSONAL-ACCESS-TOKEN" | ||
}, | ||
"definitions": [ "1" ], | ||
"branches": [ | ||
"refs/heads/master" | ||
] | ||
} | ||
} | ||
], | ||
"observers": [ | ||
{ | ||
"hue": { | ||
"id": "hue_team_1_builds", | ||
"collectors": [ | ||
"teamcity_local" | ||
], | ||
"hubUrl": "http://192.168.1.99", | ||
"username": "THE-HUE-USERNAME", | ||
"lights": [ "1" ] | ||
} | ||
}, | ||
{ | ||
"hue": { | ||
"id": "hue_all_builds_dimmed", | ||
"hubUrl": "http://192.168.1.99", | ||
"username": "THE-HUE-USERNAME", | ||
"brightness": 50, | ||
"lights": [ "2", "3" ] | ||
} | ||
}, | ||
{ | ||
"slack": { | ||
"id": "slack_team1", | ||
"collectors": [ "teamcity_local" ], | ||
"credentials": { | ||
"webhook": { | ||
"url": "https://hooks.slack.com/services/MY-WEBHOOK-URL" | ||
} | ||
} | ||
} | ||
}, | ||
{ | ||
"mattermost": { | ||
"id": "mattermost", | ||
"channel": "build-status", | ||
"credentials": { | ||
"webhook": { | ||
"url": "https://mattermost.example.com" | ||
} | ||
} | ||
} | ||
} | ||
] | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
{ | ||
"$schema": "./schema.json", | ||
"interval": 30, | ||
"collectors": [ | ||
{ | ||
"teamcity": { | ||
"id": "teamcity_local", | ||
"serverUrl": "http://127.0.0.1:8111/", | ||
"credentials": "guest", | ||
"builds": [ | ||
"My_Project_Definition", | ||
"My_Other_Build_Definition" | ||
] | ||
} | ||
}, | ||
{ | ||
"teamcity": { | ||
"id": "teamcity_other", | ||
"enabled": false, | ||
"serverUrl": "192.168.0.1:8111", | ||
"credentials": { | ||
"basic": { | ||
"username": "foo", | ||
"password": "bar" | ||
} | ||
}, | ||
"builds": [ | ||
"My_Third_Build_Definition" | ||
] | ||
} | ||
}, | ||
{ | ||
"azure": { | ||
"id": "azure_cake", | ||
"enabled": false, | ||
"organization": "cake-build", | ||
"project": "Cake", | ||
"credentials": "anonymous", | ||
"definitions": [ "1", "3", "5" ], | ||
"branches": [ | ||
"refs/heads/develop", | ||
"refs/heads/main" | ||
] | ||
} | ||
}, | ||
{ | ||
"azure": { | ||
"id": "azure_private", | ||
"enabled": false, | ||
"organization": "some-organization", | ||
"project": "some-project", | ||
"credentials": { | ||
"pat": "SUPER-SECRET-PERSONAL-ACCESS-TOKEN" | ||
}, | ||
"definitions": [ "1" ], | ||
"branches": [ | ||
"refs/heads/master" | ||
] | ||
} | ||
} | ||
], | ||
"observers": [ | ||
{ | ||
"hue": { | ||
"id": "hue_team_1_builds", | ||
"collectors": [ | ||
"teamcity_local" | ||
], | ||
"hubUrl": "http://192.168.1.99", | ||
"username": "THE-HUE-USERNAME", | ||
"lights": [ "1" ] | ||
} | ||
}, | ||
{ | ||
"hue": { | ||
"id": "hue_all_builds_dimmed", | ||
"hubUrl": "http://192.168.1.99", | ||
"username": "THE-HUE-USERNAME", | ||
"brightness": 50, | ||
"lights": [ "2", "3" ] | ||
} | ||
}, | ||
{ | ||
"slack": { | ||
"id": "slack_team1", | ||
"collectors": [ "teamcity_local" ], | ||
"credentials": { | ||
"webhook": { | ||
"url": "https://hooks.slack.com/services/MY-WEBHOOK-URL" | ||
} | ||
} | ||
} | ||
}, | ||
{ | ||
"mattermost": { | ||
"id": "mattermost", | ||
"channel": "build-status", | ||
"credentials": { | ||
"webhook": { | ||
"url": "https://mattermost.example.com" | ||
} | ||
} | ||
} | ||
} | ||
] | ||
} |
Oops, something went wrong.