Skip to content

Commit b6fbadf

Browse files
committed
feat!: modernize webhookd (fiber+huma, ddd, ci, releases)
BREAKING CHANGE: Replaced Typhon stack with Fiber + Huma, reorganized code into layered DDD, removed vendoring, and updated release pipeline.
1 parent 4f50d72 commit b6fbadf

378 files changed

Lines changed: 1455 additions & 114723 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
11
.git
2+
.github
3+
.cursor
4+
_adr
5+
6+
build
7+
dist
8+
9+
**/*.log
10+
**/*.tmp
11+
.DS_Store
12+
13+
vendor
14+
.git
215
Dockerfile
316
_adr
417
build

.github/workflows/ci.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: ["**"]
6+
pull_request:
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
test:
13+
name: test (${{ matrix.os }})
14+
runs-on: ${{ matrix.os }}
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
os: [ubuntu-latest, macos-latest]
19+
steps:
20+
- uses: actions/checkout@v4
21+
22+
- uses: actions/setup-go@v5
23+
with:
24+
go-version: "1.25.x"
25+
cache: true
26+
27+
- name: gofmt
28+
run: |
29+
test -z "$(gofmt -l .)"
30+
31+
- name: go test
32+
run: |
33+
go test ./...
34+
35+
- name: go vet
36+
run: |
37+
go vet ./...
38+
39+
- name: go mod tidy (no diff)
40+
run: |
41+
go mod tidy
42+
git diff --exit-code
43+
44+

.github/workflows/goreleaser.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: goreleaser
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
permissions:
9+
contents: write
10+
packages: write
11+
12+
jobs:
13+
goreleaser:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
20+
- uses: actions/setup-go@v5
21+
with:
22+
go-version: "1.25.x"
23+
cache: true
24+
25+
- uses: docker/setup-qemu-action@v3
26+
27+
- uses: docker/setup-buildx-action@v3
28+
29+
- uses: docker/login-action@v3
30+
with:
31+
registry: ghcr.io
32+
username: ${{ github.actor }}
33+
password: ${{ secrets.GITHUB_TOKEN }}
34+
35+
- uses: goreleaser/goreleaser-action@v6
36+
with:
37+
distribution: goreleaser
38+
version: latest
39+
args: release --clean
40+
env:
41+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42+
43+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: release-please
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- master
8+
9+
permissions:
10+
contents: write
11+
pull-requests: write
12+
13+
jobs:
14+
release-please:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: googleapis/release-please-action@v4
18+
with:
19+
release-type: go
20+
config-file: release-please-config.json
21+
manifest-file: .release-please-manifest.json
22+
23+

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
# Dependency directories (remove the comment below to include it)
2121
# vendor/
22+
vendor/
2223
build
2324
.idea
2425
.*.json

.goreleaser.yaml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
version: 2
2+
3+
project_name: webhookd
4+
5+
before:
6+
hooks:
7+
- go mod tidy
8+
9+
builds:
10+
- id: webhookd
11+
main: ./cmd/webhookd
12+
binary: webhookd
13+
env:
14+
- CGO_ENABLED=0
15+
goos:
16+
- linux
17+
- darwin
18+
goarch:
19+
- amd64
20+
- arm64
21+
ldflags:
22+
- -s -w -X webhookd/internal/buildinfo.Version={{ .Version }}
23+
24+
archives:
25+
- format: tar.gz
26+
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
27+
files:
28+
- README.md
29+
- COPYING
30+
31+
checksum:
32+
name_template: "checksums.txt"
33+
34+
snapshot:
35+
version_template: "{{ .Tag }}-next"
36+
37+
changelog:
38+
use: github
39+
40+
dockers:
41+
- id: webhookd-amd64
42+
dockerfile: Dockerfile
43+
use: buildx
44+
goos: linux
45+
goarch: amd64
46+
image_templates:
47+
- "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Version }}-amd64"
48+
- "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:latest-amd64"
49+
build_flag_templates:
50+
- "--platform=linux/amd64"
51+
- "--build-arg=VERSION={{ .Version }}"
52+
- id: webhookd-arm64
53+
dockerfile: Dockerfile
54+
use: buildx
55+
goos: linux
56+
goarch: arm64
57+
image_templates:
58+
- "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Version }}-arm64"
59+
- "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:latest-arm64"
60+
build_flag_templates:
61+
- "--platform=linux/arm64"
62+
- "--build-arg=VERSION={{ .Version }}"
63+
64+
docker_manifests:
65+
- name_template: "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Version }}"
66+
image_templates:
67+
- "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Version }}-amd64"
68+
- "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Version }}-arm64"
69+
- name_template: "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:latest"
70+
image_templates:
71+
- "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:latest-amd64"
72+
- "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:latest-arm64"
73+
74+

Dockerfile

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
1-
FROM golang
1+
FROM golang:1.25 AS build
22

3-
ENV GO111MODULE=on
3+
WORKDIR /src
44

5-
WORKDIR /app
5+
COPY go.mod go.sum ./
6+
RUN go mod download
67

78
COPY . .
89

9-
RUN scripts/before_docker.sh
10+
ARG VERSION=dev
11+
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
12+
go build -trimpath -ldflags "-s -w -X webhookd/internal/buildinfo.Version=${VERSION}" \
13+
-o /out/webhookd ./cmd/webhookd
14+
15+
FROM gcr.io/distroless/base-debian12:nonroot
16+
17+
COPY --from=build /out/webhookd /webhookd
18+
19+
EXPOSE 1337
20+
21+
USER nonroot:nonroot
22+
ENTRYPOINT ["/webhookd"]

cmd/webhookd/main.go

Lines changed: 8 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,13 @@ package main
22

33
import (
44
"context"
5-
"flag"
6-
"github.com/joho/godotenv"
7-
"github.com/logrusorgru/aurora"
8-
"github.com/monzo/typhon"
95
"log"
106
"os"
11-
"os/signal"
12-
"strconv"
13-
"syscall"
14-
"time"
15-
"webhookd/pkg/libwebhook"
16-
"webhookd/pkg/libwebhook/filters"
17-
"webhookd/pkg/libwebhook/modules/debug"
18-
"webhookd/pkg/libwebhook/modules/webhook"
7+
8+
"github.com/charmbracelet/fang"
9+
"github.com/logrusorgru/aurora"
10+
11+
"webhookd/internal/transport/cli"
1912
)
2013

2114
const (
@@ -26,57 +19,12 @@ __ _ __ ____\_ |__ | |__ ____ ____ | | __ __| _/
2619
\ /\ ___/| \_\ \ Y ( <_> | <_> ) </ /_/ |
2720
\/\_/ \___ >___ /___| /\____/ \____/|__|_ \____ |
2821
\/ \/ \/ \/ \/`
29-
version = "0.0.1"
30-
)
31-
32-
var (
33-
port = flag.Int("port", 1337, "<port> [defaults to 1337]")
34-
host = flag.String("host", "0.0.0.0", "<host> [defaults to 0.0.0.0]")
35-
configPath = flag.String("config", ".webhookdrc.json", "path to config. [defaults to .webhookdrc.json]")
36-
debugFlag = flag.Bool("debug", false, "enable replacement of <auth> with real token [defaults to false]")
37-
verbose = flag.Bool("verbose", false, "enable verbose logging [defaults to false]")
3822
)
3923

4024
func main() {
41-
flag.Parse()
42-
43-
err := godotenv.Load()
44-
if err != nil {
45-
log.Fatal("Error loading .env file. Create an empty .env file if you don't intend to use them")
46-
}
47-
4825
log.Println("\n", aurora.Magenta(banner))
49-
log.Println("\n", "👩 Version:", version)
50-
51-
config, err := libwebhook.ParseConfig(*configPath)
52-
if err != nil {
53-
log.Fatalf("could not parse the configuration because of: %s", err.Error())
54-
}
55-
addr := *host + ":" + strconv.Itoa(*port)
56-
app := libwebhook.NewApp(addr, config, *verbose, *debugFlag, debug.Module, webhook.Module)
57-
58-
svc := app.Router.Serve().
59-
Filter(typhon.ErrorFilter).
60-
Filter(typhon.H2cFilter).
61-
Filter(filters.Validation(app)).
62-
Filter(filters.Auth(app)).
63-
Filter(webhook.Validation(app))
64-
65-
srv, err := typhon.Listen(svc, addr)
66-
if err != nil {
67-
panic(err)
68-
}
69-
70-
log.Printf("🏁 Listening on %v", srv.Listener().Addr())
71-
if app.Debug {
72-
app.PrintConfig()
26+
root := cli.NewRoot()
27+
if err := fang.Execute(context.Background(), root); err != nil {
28+
os.Exit(1)
7329
}
74-
app.PrintRoutes(srv.Listener().Addr().String())
75-
done := make(chan os.Signal, 1)
76-
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
77-
<-done
78-
log.Printf("☠️ Shutting down in max 10 sec..")
79-
c, cancel := context.WithTimeout(context.Background(), 10*time.Second)
80-
defer cancel()
81-
srv.Stop(c)
8230
}

go.mod

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,48 @@
11
module webhookd
22

3-
go 1.14
3+
go 1.25
44

55
require (
6-
github.com/davecgh/go-spew v1.1.1
7-
github.com/deckarep/golang-set v1.7.1 // indirect
8-
github.com/dgrijalva/jwt-go v3.2.0+incompatible
9-
github.com/fortytw2/leaktest v1.3.0 // indirect
10-
github.com/golang/protobuf v1.4.2 // indirect
11-
github.com/google/uuid v1.1.2 // indirect
12-
github.com/joho/godotenv v1.3.0
13-
github.com/kr/pretty v0.1.0 // indirect
14-
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381
15-
github.com/monzo/slog v0.0.0-20200622142821-ebfbdb7eb55b // indirect
16-
github.com/monzo/terrors v0.0.0-20191030112059-325b9ec5dcdf // indirect
17-
github.com/monzo/typhon v0.0.0-20200505200851-d565f398c1c5
18-
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d
19-
github.com/stretchr/testify v1.6.1 // indirect
20-
github.com/valyala/fastjson v1.6.1 // indirect
21-
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect
22-
golang.org/x/text v0.3.2 // indirect
23-
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
24-
gopkg.in/dealancer/validate.v2 v2.0.0-20191007140827-2f5082b2f7fa
6+
github.com/charmbracelet/fang v0.4.4
7+
github.com/danielgtaylor/huma/v2 v2.34.1
8+
github.com/gofiber/fiber/v2 v2.52.10
9+
github.com/golang-jwt/jwt/v5 v5.3.0
10+
github.com/google/uuid v1.6.0
11+
github.com/joho/godotenv v1.5.1
12+
github.com/logrusorgru/aurora v2.0.3+incompatible
13+
github.com/spf13/cobra v1.10.2
14+
)
15+
16+
require (
17+
charm.land/lipgloss/v2 v2.0.0-beta.3.0.20251106193318-19329a3e8410 // indirect
18+
github.com/andybalholm/brotli v1.1.1 // indirect
19+
github.com/charmbracelet/colorprofile v0.3.3 // indirect
20+
github.com/charmbracelet/ultraviolet v0.0.0-20251106190538-99ea45596692 // indirect
21+
github.com/charmbracelet/x/ansi v0.11.0 // indirect
22+
github.com/charmbracelet/x/exp/charmtone v0.0.0-20250603201427-c31516f43444 // indirect
23+
github.com/charmbracelet/x/term v0.2.2 // indirect
24+
github.com/charmbracelet/x/termios v0.1.1 // indirect
25+
github.com/charmbracelet/x/windows v0.2.2 // indirect
26+
github.com/clipperhouse/displaywidth v0.4.1 // indirect
27+
github.com/clipperhouse/stringish v0.1.1 // indirect
28+
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
29+
github.com/inconshreveable/mousetrap v1.1.0 // indirect
30+
github.com/klauspost/compress v1.18.0 // indirect
31+
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
32+
github.com/mattn/go-colorable v0.1.14 // indirect
33+
github.com/mattn/go-isatty v0.0.20 // indirect
34+
github.com/mattn/go-runewidth v0.0.19 // indirect
35+
github.com/muesli/cancelreader v0.2.2 // indirect
36+
github.com/muesli/mango v0.1.0 // indirect
37+
github.com/muesli/mango-cobra v1.2.0 // indirect
38+
github.com/muesli/mango-pflag v0.1.0 // indirect
39+
github.com/muesli/roff v0.1.0 // indirect
40+
github.com/rivo/uniseg v0.4.7 // indirect
41+
github.com/spf13/pflag v1.0.9 // indirect
42+
github.com/valyala/bytebufferpool v1.0.0 // indirect
43+
github.com/valyala/fasthttp v1.62.0 // indirect
44+
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
45+
golang.org/x/sync v0.17.0 // indirect
46+
golang.org/x/sys v0.37.0 // indirect
47+
golang.org/x/text v0.25.0 // indirect
2548
)

0 commit comments

Comments
 (0)