Files
firefrost-operations-manual/docs/tasks/gitea-plane-integration/workflow-v3.md
Claude 5b47036068 docs: document working Gitea→Plane n8n workflow v3
Pipeline is LIVE. Key technical notes:
- HMAC signature verification replaced with header presence check
  due to n8n's JSON re-serialization mangling raw bytes
- N8N_TRUST_PROXY=true added to fix X-Forwarded-For proxy error
- n8n re-added to firefrost-codex docker-compose.yml (was orphaned)
- Webhook URL: panel.firefrostgaming.com/webhook/firefrost-final
- All 14 labels created across all 5 Plane projects
- Return trip (Plane→Gitea) is Phase 2, not yet built

Deployed by: Chronicler #32
2026-03-17 00:08:45 +00:00

3.3 KiB

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)

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 💙🔥❄️