Skip to content

Commit aabb40b

Browse files
committed
feat(trogon-sink-github): add webhook receiver that sinks events to NATS JetStream
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
1 parent 97a900c commit aabb40b

13 files changed

Lines changed: 1347 additions & 2 deletions

File tree

devops/docker/compose/compose.yml

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,51 @@ name: trogonai
22

33
services:
44
nats:
5-
image: nats:latest
5+
image: nats:alpine
66
container_name: nats
7-
command:
7+
command:
88
- "--jetstream"
99
- "--store_dir=/data"
10+
- "--http_port=8222"
11+
ports:
12+
- "4222:4222"
13+
- "8222:8222"
1014
volumes:
1115
- nats_data:/data
16+
restart: unless-stopped
17+
healthcheck:
18+
test: ["CMD", "wget", "-qO-", "http://localhost:8222/healthz"]
19+
interval: 5s
20+
timeout: 3s
21+
start_period: 5s
22+
retries: 3
23+
24+
trogon-sink-github:
25+
build:
26+
context: ../../../rsworkspace
27+
dockerfile: crates/trogon-sink-github/Dockerfile
28+
ports:
29+
- "${GITHUB_WEBHOOK_PORT:-8080}:${GITHUB_WEBHOOK_PORT:-8080}"
30+
environment:
31+
NATS_URL: "nats:4222"
32+
GITHUB_WEBHOOK_SECRET: "${GITHUB_WEBHOOK_SECRET:?GITHUB_WEBHOOK_SECRET is required}"
33+
GITHUB_WEBHOOK_PORT: "${GITHUB_WEBHOOK_PORT:-8080}"
34+
GITHUB_SUBJECT_PREFIX: "${GITHUB_SUBJECT_PREFIX:-github}"
35+
GITHUB_STREAM_NAME: "${GITHUB_STREAM_NAME:-GITHUB}"
36+
GITHUB_STREAM_MAX_AGE_SECS: "${GITHUB_STREAM_MAX_AGE_SECS:-604800}"
37+
GITHUB_NATS_ACK_TIMEOUT_SECS: "${GITHUB_NATS_ACK_TIMEOUT_SECS:-10}"
38+
GITHUB_MAX_BODY_SIZE: "${GITHUB_MAX_BODY_SIZE:-26214400}"
39+
RUST_LOG: "${RUST_LOG:-info}"
40+
depends_on:
41+
nats:
42+
condition: service_healthy
43+
restart: unless-stopped
44+
healthcheck:
45+
test: ["CMD", "curl", "-sf", "http://localhost:${GITHUB_WEBHOOK_PORT:-8080}/health"]
46+
interval: 10s
47+
timeout: 3s
48+
start_period: 10s
49+
retries: 3
1250

1351
volumes:
1452
nats_data:

rsworkspace/.dockerignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Rust build artifacts — largest offender, can be many GBs
2+
target/
3+
4+
# Dev tooling
5+
.git/
6+
.github/
7+
.cargo/
8+
9+
# Test/CI artifacts
10+
lcov.info
11+
coverage.xml
12+
*.profraw
13+
*.profdata
14+
mutants.out*/
15+
16+
# IDE / OS
17+
.idea/
18+
.vscode/
19+
.DS_Store
20+
Thumbs.db
21+
*.swp
22+
*.swo
23+
24+
# Environment files with secrets
25+
.env
26+
.env.*
27+
!.env.example

rsworkspace/Cargo.lock

Lines changed: 85 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rsworkspace/crates/acp-telemetry/src/service_name.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
pub enum ServiceName {
66
AcpNatsStdio,
77
AcpNatsWs,
8+
TrogonSinkGithub,
89
}
910

1011
impl ServiceName {
1112
pub fn as_str(self) -> &'static str {
1213
match self {
1314
Self::AcpNatsStdio => "acp-nats-stdio",
1415
Self::AcpNatsWs => "acp-nats-ws",
16+
Self::TrogonSinkGithub => "trogon-sink-github",
1517
}
1618
}
1719
}
@@ -30,11 +32,16 @@ mod tests {
3032
fn as_str_returns_expected_values() {
3133
assert_eq!(ServiceName::AcpNatsStdio.as_str(), "acp-nats-stdio");
3234
assert_eq!(ServiceName::AcpNatsWs.as_str(), "acp-nats-ws");
35+
assert_eq!(ServiceName::TrogonSinkGithub.as_str(), "trogon-sink-github");
3336
}
3437

3538
#[test]
3639
fn display_delegates_to_as_str() {
3740
assert_eq!(format!("{}", ServiceName::AcpNatsStdio), "acp-nats-stdio");
3841
assert_eq!(format!("{}", ServiceName::AcpNatsWs), "acp-nats-ws");
42+
assert_eq!(
43+
format!("{}", ServiceName::TrogonSinkGithub),
44+
"trogon-sink-github"
45+
);
3946
}
4047
}

rsworkspace/crates/trogon-nats/src/jetstream/mocks.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ impl MockJetStreamPublisher {
246246
.map(|m| m.payload.clone())
247247
.collect()
248248
}
249+
250+
pub fn published_messages(&self) -> Vec<MockPublishedJsMessage> {
251+
self.published.lock().unwrap().clone()
252+
}
249253
}
250254

251255
impl Default for MockJetStreamPublisher {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
[package]
2+
name = "trogon-sink-github"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[lints]
7+
workspace = true
8+
9+
[[bin]]
10+
name = "trogon-sink-github"
11+
path = "src/main.rs"
12+
13+
[dependencies]
14+
acp-telemetry = { workspace = true }
15+
async-nats = { workspace = true, features = ["jetstream"] }
16+
axum = { workspace = true }
17+
bytes = { workspace = true }
18+
hex = "0.4"
19+
hmac = "0.12"
20+
sha2 = "0.10"
21+
tokio = { workspace = true, features = ["full"] }
22+
tower-http = { workspace = true, features = ["limit"] }
23+
tracing = { workspace = true }
24+
trogon-nats = { workspace = true }
25+
trogon-std = { workspace = true }
26+
27+
[dev-dependencies]
28+
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
29+
tower = "0.5"
30+
tracing-subscriber = { workspace = true }
31+
trogon-nats = { workspace = true, features = ["test-support"] }
32+
trogon-std = { workspace = true, features = ["test-support"] }
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# ── Stage 1: build ────────────────────────────────────────────────────────────
2+
FROM rust:1.87-slim AS builder
3+
4+
WORKDIR /build
5+
6+
COPY Cargo.toml Cargo.lock ./
7+
COPY crates/ crates/
8+
9+
RUN cargo build --release -p trogon-sink-github
10+
11+
# ── Stage 2: runtime ──────────────────────────────────────────────────────────
12+
FROM debian:bookworm-slim AS runtime
13+
14+
RUN apt-get update && apt-get install -y --no-install-recommends \
15+
ca-certificates \
16+
curl \
17+
&& rm -rf /var/lib/apt/lists/*
18+
19+
RUN useradd --no-create-home --shell /usr/sbin/nologin trogon
20+
21+
COPY --from=builder /build/target/release/trogon-sink-github /usr/local/bin/trogon-sink-github
22+
23+
USER trogon
24+
25+
EXPOSE 8080
26+
27+
HEALTHCHECK --interval=10s --timeout=3s --start-period=5s --retries=3 \
28+
CMD ["/bin/sh", "-c", "curl -sf http://localhost:${GITHUB_WEBHOOK_PORT:-8080}/health || exit 1"]
29+
30+
ENTRYPOINT ["/usr/local/bin/trogon-sink-github"]

0 commit comments

Comments
 (0)