feat(webhook): implement Forgejo webhook receiver #142
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
thwap/thwap-pagesd!142
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/webhook-receiver"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Implement the
POST /webhookreceiver that triggers site publication on Forgejo push events:internal/webhook/webhook.go—Parsedecodes the push payload (ref, repo name, after);VerifySignaturechecks theX-Gitea-SignatureHMAC-SHA256 header againstwebhook.secret(empty secret skips verification).internal/webhook/receiver.go—Receiver.Handlelooks up the site by repository name and delegates toSiteService.Publish.SiteService.Publish(#72, #73) — lists the repository's tags (ForgejoClient.ListTags), selects the highestv*viapkg/version.Highest, updates the Kubernetes resources (KubernetesClient.PublishSite), and records an activeDeploymentin a new in-memoryDeploymentRepository(internal/site/memory_deployments.go).internal/httpapi—POST /webhookhandler (#70, #74):200on success,401bad signature,400malformed payload,404unknown site,500processing failure.NewRouternow takes aDepsstruct carrying the sites service and webhook receiver.main.gowires the webhook receiver into the router.Why
Phase 5 task #75 — the trigger for publishing a site's latest tagged version when its repository changes.
Testing
go build ./...go vet ./...go test -race ./...— webhook (7 tests), httpapi webhook handler (4), site Publish (3) + existing suite all passgofmt -l ./cmd ./internal ./pkgcleangolangci-lint run— 0 issuesBreaking Changes
None.
Notes
SITE_VERSIONhardcoded).CommitSHAon the recorded Deployment is left empty —ListTagsreturns names only; a richer tag lookup can fill it later.Closes #70
Closes #71
Closes #72
Closes #73
Closes #74
Closes #75
Review Summary
Verified locally on the PR head (
01d3628):go build,go vet,gofmt,golangci-lint runall clean; full suite passes with-race(webhook 7, httpapi webhook handler 4, site Publish 3 + existing).The webhook receiver is well-built.
VerifySignatureuses constant-timehmac.Equalwith correct hex decoding and clean skip-on-empty-secret semantics; the handler verifies the signature before parsing, so unauthenticated bodies are rejected before touching the decoder.Receiver.Handlecorrectly distinguishes unknown-site (404) from processing failures (500), andPublishcomposes the existing pieces cleanly:ListTags→version.Highest→k8s.PublishSite→ deployment record. TheDepsstruct is a tidy evolution of the router wiring, and the in-memoryDeploymentRepositoryhas correct mutexed semantics.No blocking issues.
Non-blocking observations:
Receiver.Handlefires on any push event — branch pushes, tag deletions, etc. — re-selecting the highestv*tag and re-publishing even when nothing changed. The payload'sRefis already parsed; filtering onrefs/tags/(orrefs/tags/+deleted) would avoid redundant publishes. Worth doing before the endpoint sees real traffic.webhook.secret(the config default) means the endpoint is effectively unauthenticated — anyone who can reach/webhookcan trigger publishes. Impact is limited (publish only re-deploys the repo's own latest tag; no content injection), but worth documenting that a secret should be set in production.Publishrecords the deployment version but doesn't yet plumb it through to Kubernetes (SITE_VERSIONremains hardcodedv0.0.0) or write content into the serving volume — acknowledged deferral, but the "active" record won't match what's actually served until that lands.MemoryDeploymentRepository.Createappends without dedupe — repeated publishes of the same tag produce duplicate history entries. Minor.Approving.