Skip to content

feat(ci): add PR gate, daily live canary verification, and fix SOCKS port - #5

Merged
hapheus merged 6 commits into
mainfrom
feature/qa-automation-and-bugfixes
Oct 9, 2026
Merged

hapheus merged 6 commits into
mainfrom
feature/qa-automation-and-bugfixes

Conversation

@hapheus

@hapheus hapheus commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Summary

This PR establishes automated CI/CD quality assurance for hapheus/torproxy, addresses the SOCKS port configuration bug, and brings the repository into full compliance with architectural standards (ADR-001, ADR-004, ADR-005, ADR-009, ADR-010).

All CI workflows exclusively use free standard GitHub runners (runs-on: ubuntu-latest).


1. Workflows & CI Architecture

  • PR Quality & Smoke Gate (.github/workflows/pr-gate.yml):
    • Triggers on PRs to main and pushes to main.
    • Runs Ruff linter and ShellCheck for static analysis.
    • Runs hermetic unit tests with Pytest (< 1s, zero external network calls).
    • Builds the Docker image and performs automated container smoke testing:
      • Non-root user execution assertion (UID != 0).
      • Multi-daemon process tree verification (tor, privoxy, api.py).
      • Graceful SIGTERM shutdown within 5s SLA.
  • Daily Live Image Verification (.github/workflows/daily-image-verification.yml):
    • Scheduled daily at 04:00 UTC (plus workflow_dispatch trigger).
    • Pulls and runs the published hapheus/torproxy:latest image.
    • Live tests against the Tor network:
      • Waits for 100% Tor bootstrap via /status endpoint (max 180s).
      • Privoxy HTTP Proxy (:8118) egress & anonymity check (IsTor: true, Anti-Leak Exit IP != Runner Host IP).
      • Tor SOCKS5 Proxy (:9050) remote DNS resolution & egress check.
      • Tor Circuit rotation test (POST /reconnect -> 15s cooldown -> verify circuit refresh).
    • Automated alerting: automatically opens/updates a GitHub Issue with label canary-alert upon failure.

2. Bug Fixes & Improvements

  • Fix Hardcoded SOCKS Port:
    • docker/privoxy.config.template: Replaced hardcoded 127.0.0.1:9050 with 127.0.0.1:__TORPROXY_SOCKS_PORT__.
    • docker/start.sh: Added sed replacement for __TORPROXY_SOCKS_PORT__ in privoxy config generation, allowing custom SOCKS ports to route correctly.
  • Code Cleanups & Type Fixes:
    • docker/api.py: Fixed os.environ.get default argument types for TORPROXY_API_PORT and TORPROXY_LISTEN_PORT, sorted imports, and added proper shebang execution bit.

3. Architecture & Standards Compliance

  • ADR-001 (devenv & direnv): Added devenv.nix, devenv.yaml, and .envrc.
  • ADR-004 (TDD & Automated Testing): Added 27 hermetic unit tests in tests/unit/test_api.py and tests/unit/test_config.py.
  • ADR-005 (Pre-Commit QA Gate): Added .pre-commit-config.yaml (Ruff, ShellCheck, trailing whitespace, yaml checks).
  • ADR-009 (Python venv & Package Management): Added pyproject.toml with project metadata, ruff configuration, and pytest marks.
  • Repository Hygiene:
    • Removed tracked docker/__pycache__/api.cpython-310.pyc.
    • Expanded root .gitignore and docker/.dockerignore to block all Python cache and environment artifacts.

@hapheus

hapheus commented Oct 9, 2026

Copy link
Copy Markdown
Owner Author

🔍 QA Gate Report & Edge-Case Discovery (ADR-005)

Status: ⚠️ QA HOLD (Defekt im Daily Canary Workflow entdeckt)
Evaluated Commit: aa802584d5bb2215294f17b8943ffa7621e03143
Workflow Run: PR Quality & Smoke Gate #37985202617


1. PR CI Pipeline-Status

  • Job 1: Lint & Static Analysis ✅ PASSED (Ruff, bash -n, ShellCheck)
  • Job 2: Hermetic Unit Tests ✅ PASSED (27 Unit-Tests grün, < 1s)
  • Job 3: Docker Build & Container Smoke Test ✅ PASSED
    • Non-Root UID Assertion: ✅ (UID != 0)
    • Multi-Daemon Process Check: ✅ (tor, privoxy, api.py aktiv)
    • SIGTERM Graceful Shutdown: ✅ (< 5s SLA)

2. Standards- & ADR-Audit

  • ADR-001 (devenv/direnv): ✅ Vollständig umgesetzt.
  • ADR-004 (TDD): ✅ Hermetische Pytest-Suite vorhanden.
  • ADR-005 (QA Gate): ✅ Pre-Commit Konfiguration & Smoke Gate implementiert.
  • ADR-009 / ADR-010: ✅ Saubere Abhängigkeiten & pyproject.toml.
  • Bugfix SOCKS-Port: ✅ Template-Ersetzung __TORPROXY_SOCKS_PORT__ in privoxy.config.template und start.sh verifiziert.

3. 🚨 Blackbox Discovery: Latenter Breaking Bug in daily-image-verification.yml

Während der PR-Gate-Workflow grün ist, enthält der neue Workflow .github/workflows/daily-image-verification.yml (Step 3: Wait for Tor 100% Bootstrap) einen kritischen Mismatch mit der REST-API:

Befund:

Im Workflow-Skript wird folgender JSON-Check ausgeführt:

STATUS_JSON=$(curl -s --connect-timeout 5 http://localhost:8080/status || echo "{}")
IS_BOOTSTRAPPED=$(echo "$STATUS_JSON" | jq -r '.tor.bootstrapped // false')
STATUS=$(echo "$STATUS_JSON" | jq -r '.status // "unknown"')

if [ "$IS_BOOTSTRAPPED" = "true" ] && [ "$STATUS" = "connected" ]; then

docker/api.py (/status) liefert bei erfolgreicher Verbindung jedoch:

{
  "status": "connected",
  "ip": "<exit-ip>"
}

Es gibt keinen Subkey .tor.bootstrapped in der Response!

Auswirkung:

  • IS_BOOTSTRAPPED evaluiert immer zu false.
  • Die Schleife wartet volle 180 Sekunden (36 Attempts) ab und schlägt unweigerlich mit exit 1 fehl:
    ❌ ERROR: Tor failed to reach 100% bootstrap within 180 seconds.
  • Step 9 löst anschließend jeden Morgen um 04:00 UTC einen False-Alarm aus und erstellt ein GitHub Issue (canary-alert).

4. Empfohlene Behebung

Entweder im Workflow:

if [ "$STATUS" = "connected" ]; then

oder in docker/api.py das Tor-Bootstrap-Objekt direkt in die Response aufnehmen:

"tor": {
    "bootstrapped": True,
    "bootstrap_phase": "done"
}

5. QA Sign-Off Gate

Der PR ist qualitativ hochwertig, wird aber bis zur Korrektur dieses Mismatchs im Daily-Workflow auf HOLD gesetzt, um nächtliche Fehlalarme nach dem Merge zu verhindern. Sobald gefixt, erfolgt der finale QA Sign-off für den Code Reviewer.

Resolves QA edge-case finding where jq query for .tor.bootstrapped failed against api.py /status schema.
@hapheus

hapheus commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner Author

🛠️ Fix Applied: Canary Bootstrap Check Aligned

Thank you to the QA Engineer for the excellent blackbox and edge-case analysis!

Cause & Resolution

The key .tor.bootstrapped did not exist in the /status REST API response (which returns a lightweight schema: {"status": "connected"|"connecting"|"disconnected", "ip": "...", "detail": "..."}).
Additionally, the daily canary tests the published production Docker Hub image (hapheus/torproxy:latest), meaning extending api.py would only take effect after a new release is pushed to Docker Hub.

The check in .github/workflows/daily-image-verification.yml was corrected in commit 8030142:

  • The loop now evaluates if [ "$STATUS" = "connected" ]; then as recommended by QA.
  • This is 100% consistent with docker/healthcheck.sh (grep -Eq '"status"[[:space:]]*:[[:space:]]*"connected"'), as status: connected is only emitted once Tor is 100% bootstrapped and the Privoxy egress traffic has been successfully verified.
  • Optional logging continues to extract $DETAIL (.detail // "") during the connecting phase.

The fix has been pushed to the feature branch feature/qa-automation-and-bugfixes. Ready for final QA sign-off and review!

@hapheus

hapheus commented Oct 9, 2026

Copy link
Copy Markdown
Owner Author

🛡️ QA Engineer Sign-off & Verification Report (ADR-005)

Status: ✅ QA SIGN-OFF APPROVED (Pre-Merge Quality Gate Passed)
Target: feature/qa-automation-and-bugfixes (Head SHA: 056c75be1a30845c1ea0e76ae308d350279de08a)
CI Pipeline: Run #37990290807 (Status: 100% GREEN)


1. Re-Evaluation & Verification of Edge-Case Discoveries

  • Daily Canary Bootstrap Check Fixed (Commit 8030142):
    • Mismatch im Workflow .github/workflows/daily-image-verification.yml (.tor.bootstrapped) wurde behoben.
    • Abfrage prüft nun direkt [ "$STATUS" = "connected" ], passend zur REST-API-Spezifikation (docker/api.py).
    • Nächtliche False-Alarms / unberechtigte Issue-Spams sind damit zuverlässig verhindert.
  • Docker Hub Rate Limit Hardening (Commits 1715c1f, 056c75b):
    • Optionale Authentifizierung via secrets.DOCKERHUB_TOKEN implementiert.
    • 5-fache Retry-Schleife mit Backoff für docker build fängt temporäre 429-Throttlings auf Ubuntu-Runnern robust ab.

2. Pipeline- & Testmatrix-Ergebnisse

Teststufe Werkzeug / Check Ergebnis Details
Lint & Syntax Ruff, bash -n, ShellCheck ✅ PASSED Keine Lint- oder Shell-Syntax-Fehler
Hermetische Unit-Tests Pytest (27 Tests) ✅ PASSED SOCKS-Port-Templating, Env-Parsing, API-Routing in < 1s
Container Smoke Gate Docker Build & Run ✅ PASSED Non-Root UID != 0 verifiziert
Multi-Daemon Isolation Process Inspection ✅ PASSED tor, privoxy, api.py laufen isoliert
Graceful Shutdown SIGTERM Handling ✅ PASSED Container stoppt sauber innerhalb des 5s-SLAs

3. QA Verdict gemäß ADR-005

Alle Anforderungen gemäß ADR-001 (devenv), ADR-004 (TDD), ADR-005 (QA Gate), ADR-009 (Python Tooling) und ADR-010 (Minimal Dependencies) sind erfüllt.

Der PR wird hiermit offiziell für das abschließende Review und den Merge-Gate durch den Code Reviewer (ADR-006) freigegeben.

@hapheus hapheus left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Senior Code Review & Gatekeeper Approval (ADR-006)

Target PR: hapheus/torproxy#5 (feature/qa-automation-and-bugfixes)
Commit SHA: 056c75be1a30845c1ea0e76ae308d350279de08a
Verdict: APPROVED & CLEARED FOR MERGE 🚀


1. Architectural & Standards Compliance

  • ADR-001 (devenv & direnv): Fully implemented with clean hermetic environments (devenv.nix, devenv.yaml, .envrc).
  • ADR-003 (SOLID & Single Responsibility): Privoxy template replacement (__TORPROXY_SOCKS_PORT__) cleanly separates configuration generation from runtime execution.
  • ADR-004 & ADR-009 (TDD & Python Standards): Hermetic test suite comprising 27 Pytest unit tests in tests/unit/ executing in < 1s with zero network dependencies. pyproject.toml is modern and well-structured.
  • ADR-005 (QA Gate): Pre-commit configuration (.pre-commit-config.yaml) enforces Ruff, ShellCheck, and syntax validations.
  • ADR-010 (Minimal Dependencies): Container footprint remains lean; process verification runs via host-native docker top instead of bloat packages like procps.
  • Repository Hygiene & English-Only Policy: Cache files (__pycache__) removed, .gitignore hardened, and all code, identifiers, and comments strictly in English.

2. CI Pipeline & Actions Verification

  • GitHub Actions Run: #37990290807 — 100% SUCCESS
    • Lint & Static Analysis: Ruff, bash -n, ShellCheck passed without warnings.
    • Hermetic Unit Tests: 27/27 passed.
    • Docker Build & Container Smoke Test: Non-root UID validation (UID != 0), multi-daemon process tree (tor, privoxy, api.py), and graceful SIGTERM shutdown (< 5s SLA) verified.

3. Edge-Case & Defect Resolution

  • Canary jq Schema Mismatch (Fixed in 8030142): Resolved the latent bug in .github/workflows/daily-image-verification.yml by aligning the bootstrap check to [ "$STATUS" = "connected" ], preventing false canary alerts.
  • DockerHub Throttling Resilience (Added in 056c75b): Docker login and retry mechanisms prevent sporadic HTTP 429 rate limits on shared GitHub runners.

4. QA Sign-Off (ADR-005 Gate)

  • QA Sign-off Received: Confirmed by QA Engineer in Comment #6089210725.
  • All blackbox, multi-daemon, and edge-case requirements verified.

Proceeding with autonomous merge per ADR-006 gatekeeper policy.

@hapheus
hapheus merged commit 56c3e8a into main Oct 9, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant