Skip to content

balyakin/forge-link

Repository files navigation

ForgeLink

ForgeLink is a self-hosted automation bridge for Forgejo/Gitea users who want to leave GitHub without breaking deploy hooks, external CI triggers, and commit status reporting.

ForgeLink accepts Forgejo/Gitea webhooks, verifies HMAC signatures, normalizes events, matches YAML rules, queues delivery attempts, calls external providers and writes commit statuses back to the forge.

Forgejo/Gitea webhook
  -> POST /hooks/forgejo/{repo_config_id}
  -> verify HMAC
  -> normalize event
  -> match rules
  -> enqueue deliveries
  -> worker
  -> provider adapter
  -> update delivery state
  -> report commit status

What It Is

  • A single Go binary for a VPS or homelab.
  • A bridge for deploy hooks and external automation.
  • A visible history of webhook events, deliveries, attempts and status reports.

What It Is Not

  • Not a GitHub clone.
  • Not a full GitHub-compatible API.
  • Not a CI runner.
  • Not a GitHub Actions converter.
  • Not a hosted SaaS relay.

Quick Start

go build ./cmd/forgelink
./forgelink init
cp .env.example .env
export FORGELINK_DASHBOARD_PASSWORD=change-me
export FORGELINK_SITE_WEBHOOK_SECRET=change-me
export GENERIC_CI_WEBHOOK_URL=http://localhost:9090/build
./forgelink config validate --config ./forgelink.yml
./forgelink serve --config ./forgelink.yml

Dashboard: http://localhost:8080.

Example Config

Start from examples/config.example.yml for local testing or provider-specific examples:

  • examples/vercel-only.yml
  • examples/netlify-only.yml
  • examples/digitalocean-only.yml
  • examples/multi-destination.yml
  • examples/pr-preview.yml

Secrets are referenced by environment variable names only. Do not put deploy hook URLs, tokens or webhook secrets directly into YAML.

Forgejo Webhook Setup

Create a repository webhook:

  • URL: https://forgelink.example.com/hooks/forgejo/site
  • Content type: application/json
  • Secret: value of FORGELINK_SITE_WEBHOOK_SECRET
  • Events: push, tag push and pull request as needed

ForgeLink accepts X-Forgejo-Signature and X-Gitea-Signature HMAC SHA-256 signatures.

Provider Setup

Vercel:

adapter: "vercel_deploy_hook"
hook_url_env: "VERCEL_SITE_PROD_DEPLOY_HOOK"

Netlify:

adapter: "netlify_build_hook"
hook_url_env: "NETLIFY_SITE_PROD_BUILD_HOOK"

DigitalOcean App Platform:

adapter: "digitalocean_app_platform"
app_id_env: "DO_APP_ID_SITE"
token_env: "DIGITALOCEAN_TOKEN"
force_build: true

Vercel, Netlify and generic webhook statuses mean "trigger accepted", not "deployment finished". DigitalOcean polling is optional and bounded by queue.worker_max_delivery_seconds; keep poll: false if you only need trigger-accepted semantics.

Commit Statuses

Set set_commit_status: true, configure status_context, and set the forge account token env var. ForgeLink posts to:

POST /api/v1/repos/{owner}/{repo}/statuses/{sha}

CLI

forgelink doctor --config ./forgelink.yml
forgelink simulate push --config ./forgelink.yml --repo site --payload examples/forgejo-webhook-push.json
forgelink events list --config ./forgelink.yml
forgelink events show <event_id> --config ./forgelink.yml
forgelink deliveries replay <delivery_id> --config ./forgelink.yml --confirm
forgelink destinations test site vercel-prod --config ./forgelink.yml --dry-run
forgelink lint-actions --path .
forgelink db prune --config ./forgelink.yml --dry-run

Actions Linter

forgelink lint-actions --path . scans .forgejo/workflows and .github/workflows and reports GitHub-specific workflow features that need review before running under Forgejo Actions. It is a linter, not a converter.

Use machine-readable output in CI:

forgelink lint-actions --path . --json

Delivery Replay

Replay creates a new delivery linked to the original row. It never overwrites historical delivery state.

forgelink deliveries replay <delivery_id> --config ./forgelink.yml --confirm

Use --dry-run first to inspect what would be replayed.

Metrics And Dashboard

  • GET /metrics: Prometheus text exposition.
  • GET /api/v1/metrics: JSON metrics.
  • Dashboard pages: /, /events, /deliveries, /config, /health.

Enable Basic Auth before exposing the dashboard outside loopback.

Security Notes

  • HMAC verification uses constant-time comparison.
  • Body size and source IP allowlists are configurable.
  • Provider calls use timeouts.
  • Raw payload storage can be disabled with security.store_raw_payloads: false.
  • Secrets are not stored in the config summary or dashboard.

Troubleshooting

Start with:

forgelink doctor --config ./forgelink.yml
curl -i http://localhost:8080/readyz
curl -s http://localhost:8080/api/v1/metrics

More detail: docs/troubleshooting.md.

Roadmap

Post-v1 work includes provider result polling for Vercel/Netlify, safer setup automation and a narrow compatibility facade only for proven external-tool needs.

License

MIT.

Releases

No releases published

Packages

 
 
 

Contributors