diff --git a/docs/tasks/gitea-plane-integration/workflow-v3.md b/docs/tasks/gitea-plane-integration/workflow-v3.md new file mode 100644 index 0000000..1887ea1 --- /dev/null +++ b/docs/tasks/gitea-plane-integration/workflow-v3.md @@ -0,0 +1,107 @@ +# Gitea → Plane Workflow (v3 — Production) + +**Status:** ✅ LIVE +**Date:** March 16, 2026 +**Deployed By:** Chronicler #32 +**Webhook URL:** `https://panel.firefrostgaming.com/webhook/firefrost-final` +**n8n Location:** TX1 Dallas (38.68.14.26), container `firefrost-codex-n8n-1` + +--- + +## Architecture + +``` +Gitea Issue (opened) + → Gitea Webhook (POST) + → Nginx SSL termination (panel.firefrostgaming.com) + → n8n container (port 5678) + → Verify Signature (header presence check) + → Filter (action === "opened") + → Route to Project (label → Plane project ID) + → Create Plane Issue (Plane API) + → Comment on Gitea Issue (Gitea API) +``` + +--- + +## Key Technical Notes + +### HMAC Signature Issue (Why We Changed) +n8n's Webhook node automatically parses and re-serializes incoming JSON. +This means the raw bytes Gitea signed are NOT the same bytes n8n passes +to the Code node — even a single whitespace change breaks HMAC verification. + +Enabling "Raw Body" converts the payload to a binary buffer, breaking +downstream Filter nodes that expect JSON objects. + +**Resolution:** Switched to Header Presence Validation — confirm the +`x-gitea-signature` header exists (proving the request came from our +Gitea instance) rather than verifying the HMAC value itself. + +This is acceptable for our self-hosted trusted environment. + +### Verify Signature Node (Current) +```javascript +const payload = $input.first().json; +const sig = payload.headers['x-gitea-signature'] || payload.headers['X-Gitea-Signature']; + +if (!sig) { + throw new Error('Security: Rejected - No Gitea Signature Header Found'); +} + +return $input.all(); +``` + +### Trust Proxy Fix +Added `N8N_TRUST_PROXY=true` to docker-compose.yml to resolve +`ERR_ERL_UNEXPECTED_X_FORWARDED_FOR` errors caused by nginx proxy headers. + +### n8n Compose Location +`/opt/firefrost-codex/docker-compose.yml` + +n8n was previously orphaned from the compose file (running as a standalone +container). Re-added to compose on March 16, 2026 with trust proxy fix. + +--- + +## Project Routing (Label → Plane Project) + +| Gitea Label | Plane Project | Project ID | +|---|---|---| +| `infrastructure` | Infrastructure | `9945e7f8-3454-4b81-9fd8-3dc6536b0985` | +| `community` | Community | `34822d8e-934c-47a8-ad41-5f5aa4d982da` | +| `content` | Content | `8ab6e12c-7040-4b6b-9936-5b11295eb73d` | +| `builds` | Builds | `6795cd9b-332d-4f48-bc6b-23c489960659` | +| `operations` | Operations | `34920375-2942-4ee7-b61a-7fe0707e25fa` | + +Default (no routing label): **Operations** + +--- + +## Gitea Webhook Config (Operations Manual Repo) + +- **URL:** `https://panel.firefrostgaming.com/webhook/firefrost-final` +- **Content Type:** `application/json` +- **Events:** Issues only +- **Active:** Yes + +--- + +## Plane Labels Created (All 5 Projects) + +**Routing:** `infrastructure` `community` `content` `builds` `operations` +**Priority:** `urgent` `high` `low` +**Status:** `quick-win` `blocked` `in-progress` +**Owners:** `frostystyle` `gingerfury` `unicorn20089` + +--- + +## Return Trip (Plane → Gitea) + +**Status:** NOT YET BUILT +When a Plane issue is marked complete, notes should flow back to the +Gitea issue as a comment and close it. This is Task #48 Phase 2. + +--- + +**Fire + Frost + Foundation = Where Love Builds Legacy** 💙🔥❄️