External CI/CD Pipeline — branch-independent test runner
Go to file
Claude BM 29621c8837 fix(webhook): accept Gitea's native bare-hex signature format
verify_signature compared the X-Gitea-Signature header against
"sha256=<hex>", which is GitHub's format. Gitea sends a bare 64-character
hex digest with no prefix, so a correctly-signed Gitea delivery could never
match and was rejected with 403 Invalid signature.

Confirmed by capturing a real Gitea delivery against a scratch listener:
  SIG_PRESENT=True  HAS_PREFIX=False  SIG_LEN=64

Now strips an optional "sha256=" prefix before comparing, so both Gitea's
native format and GitHub-style senders verify. The HMAC computation and the
constant-time comparison are unchanged — an absent, empty, or incorrect
signature is still rejected exactly as before.

This was the second of two faults blocking the webhook gate; the first was
the repository webhook pointing at the host's public IP, which Gitea's
ALLOWED_HOST_LIST denied before any request left the process.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 17:48:28 +00:00
ci-config.json Update test baseline: 1279 → 1431 2026-04-26 21:05:50 +00:00
ci-notify.sh Add PRODUCTION alert for main branch CI failures 2026-04-28 15:03:18 +00:00
ci-runner.sh Add auto-escalation: tag fail → light → heavy 2026-04-28 14:52:52 +00:00
ci-webhook.py fix(webhook): accept Gitea's native bare-hex signature format 2026-08-08 17:48:28 +00:00
README.md Rename TestMain → TestDevelop in README 2026-04-28 14:21:15 +00:00

TSHARPS-CI — External CI/CD Pipeline

Branch-independent CI runner for the TSHARPS flight training scheduler.

Branch Model

TestDevelop ──► TestStaging ──► TestProduction
  (dev)       (validate)      (live CI)
  • TestDevelop: Develop CI changes here
  • TestStaging: Validate before going live
  • TestProduction: Runs against ALL TSHARPS branches on every push

How It Works

  1. Developer pushes to any TSHARPS branch (mfg, rogue, spif, staging, main)
  2. Gitea webhook fires POST to http://127.0.0.1:9500/ci
  3. ci-webhook.py receives the event and spawns ci-runner.sh
  4. ci-runner.sh runs against the pushed branch's worktree:
    • Feature manifest verification
    • Test suite (with quarantine for known failures)
    • Package import check
  5. ci-notify.sh sends results to Telegram CICD Pipeline topic

Files

File Purpose
ci-webhook.py HTTP server listening for Gitea push webhooks
ci-runner.sh Main CI script — tests, features, packages
ci-notify.sh Telegram notification sender
ci-config.json Configuration (tokens, paths, timeouts)

Key Rules

  • Read-only: CI runner never writes to TSHARPS repos
  • Same tests for all branches: No branch-specific CI logic
  • No results stored here: Test results handled separately
  • Runner self-monitoring: Crashes send distinct alerts

Promoting CI Changes

# 1. Develop on TestDevelop
git checkout TestDevelop
# make changes
git commit -am "add new check"
git push origin TestDevelop

# 2. Promote to TestStaging
git checkout TestStaging && git merge TestDevelop && git push

# 3. Promote to live
git checkout TestProduction && git merge TestStaging && git push

# 4. Update server
ssh server "cd /srv/tsharps-ci && git pull origin TestProduction"

Switch-Back to Gitea Actions

If this doesn't work out:

  1. Re-enable Gitea Actions: TSHARPS repo → Settings → Actions → check "Active"
  2. Stop runner: sudo systemctl stop tsharps-ci
  3. Remove webhook: TSHARPS repo → Settings → Webhooks → Delete