Skip to content

fix(ci): isolate fork PR execution on ephemeral runners (#318) + runner token scope (#357) - #365

Merged
aliasfoxkde merged 11 commits into
mainfrom
fix/db-depth-unwind
Nov 3, 2026
Merged

aliasfoxkde merged 11 commits into
mainfrom
fix/db-depth-unwind

Conversation

@aliasfoxkde

Copy link
Copy Markdown
Owner

Summary

Routes GitHub Actions pull_request events from forks to disposable
ubuntu-latest runners so persistent self-hosted runners never execute
fork-supplied code. Same-repo PRs, push, tag, and schedule events keep the
gitforge-github self-hosted runner.

Also lands the #357 hardening: a dedicated registration-token scope for
runners, and webhook repo-ownership enforcement.

Commits

Validation

GitForge CI chain on 202, run cdd70c1c-85fe-4756-9344-a3d1ce37887e,
exact commit ce06089eb6a414ff00e48a8585c8627d1d809463, status succeeded:

job status
detect-changes succeeded
lint succeeded
fmt succeeded
clippy succeeded
test succeeded
coverage succeeded (line coverage 82.73%; gate fail <82%, warn <84%)
fuzz succeeded (16,063,472 runs / 61s)
release-contract succeeded (11 tests OK)

Test plan

  • GitForge CI chain green for the exact commit (above)
  • Fork PR executes on an ephemeral runner, not gitforge-github
  • Same-repo PR still runs on gitforge-github
  • Required checks report on the fork PR

🤖 Generated with Claude Code

aliasfoxkde and others added 11 commits October 30, 2026 10:56
The deployed binary on 192.168.1.202 (69245e2 bundle, Oct 29) predates
the job-level environment field; its parser rejects the key (fail-closed
per 0857218), so every push event for 7f4e8fd failed with 'unknown job
key environment'. The top-level environment: {} remains — that one the
deployed parser requires and accepts.
Clippy (rust 1.99 in dsc-ci-rust:12) flags the manual str::repeat
pattern as manual_str_repeat/manual_repeat_n under -D warnings.

Co-Authored-By: Claude <noreply@anthropic.com>
A busy branch occupied its repository's FIFO trigger lane for the
whole of each ~10-minute pipeline, leaving other refs of the same
repo starved: five main-branch trigger requests sat pending for
hours while codex-branch pushes kept re-arming the lane, and the
republish redrive could not help because it re-queued into the
same lane. Lane keys now include the ref name, so ordering holds
within a ref while cross-ref starvation is impossible.
sqlx's per-connection depth counter can desync in two directions. The
2026-10-08 fix (bare ROLLBACK probe) handles the SQLite-side orphan, but
the counter-side direction - depth stuck above zero with no live
Transaction owner - rejected every begin_with carrying a custom
statement with "attempted to call begin_with at non-zero transaction
depth" before any statement reached SQLite. Raw ROLLBACK cannot fix
that direction: the counter only moves through sqlx's managed commands.

Live 2026-11-02: every pipeline-activation trigger failed five times
with the depth error while healthy runs kept serving from the same
pool, so an OpenCodifier commit sat un-run for hours.

begin_immediate now detects the depth-error signature and unwinds the
counter with a managed begin/rollback pair (SAVEPOINT at depth > 0,
decrement on rollback) before retrying. Regression test injects the
stuck state on a single-connection pool, mirroring the deterministic
MRU re-handout that made every retry fail.
…ership (F1, F2)

F1: runner registration was an unauthenticated write surface — anyone who
could reach the API could register a runner and receive jobs. Registration
now requires the shared GITFORGE_RUNNER_REGISTRATION_TOKEN via constant-time
comparison; with the variable unset the endpoint fail-closed and rejects
every registration.

F2: the webhook trigger enqueued pipelines without checking that the
caller owns the pipelines repository, so a valid trigger token on repo A
could fire pipelines for repo B. The trigger now verifies ownership of the
target repository before enqueueing.

Both defects carry pinned regression tests in crates/gitforge-api/tests/
(runners_routes.rs, webhook_routes.rs): register_without_token_is_unauthorized,
register_without_configured_token_is_disabled, webhook_refuses_a_non_owner_of_
the_pipelines_repository, webhook_owner_trigger_is_unaffected_by_the_
authorization_check. All 27 tests across runners/webhook/admin suites pass.

Co-Authored-By: Claude <noreply@anthropic.com>
Registration (POST /runners on scheduler and gateway) now accepts the
shared runner token (back-compat) or a dedicated
GITFORGE_RUNNER_REGISTRATION_TOKEN, but the registration token no longer
authorizes job lifecycle routes. Runner config grows registration_token;
tests cover scope separation on both surfaces.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Trigger, watch, create, list, show, and delete errors were printed
with a ❌ prefix and swallowed; watch timeouts also exited 0.
Convert every pipeline error path to anyhow::bail so failures exit
non-zero, and fail a trigger whose run was never scheduled.

Co-Authored-By: Claude <noreply@anthropic.com>
Persistent self-hosted runners must never execute fork pull_request
code. Same-repo PRs and push/tag/schedule keep the gitforge-github
runner; fork PRs run the same checks on disposable ubuntu-latest.

Also fix qualityctl: pass GITFORGE_BUILD_SOCKET to the daemon it
spawns, and drop test parallelism to 2 to survive memory pressure.

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 2, 2026

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b2cc2e43-bb85-403b-aee0-3c021a2ad379
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

🤖 AI Code Review Results

AI review skipped: provider 'anthropic' is not configured; deterministic gates remain authoritative.

✅ No critical issues found.

AI Code Review powered by GitForge

@aliasfoxkde
aliasfoxkde merged commit a2618fc into main Nov 3, 2026
28 of 30 checks passed
@aliasfoxkde
aliasfoxkde deleted the fix/db-depth-unwind branch November 3, 2026 14:57
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