From f543c444110ca022fe1712d1902805d08cec1d4b Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Sat, 8 Aug 2026 08:30:31 +0200 Subject: [PATCH] =?UTF-8?q?fix(ci):=20give=20falcon-hello=20a=20per-run=20?= =?UTF-8?q?port=20pair=20=E2=80=94=20fixed=20ports=20collide?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The demo binds a FIXED UDP port pair (default 14700/14701). Several of these jobs can land on the SAME self-hosted runner concurrently, and the second one dies: error: bind 127.0.0.1:14700: Address already in use (os error 98) error: bind 127.0.0.1:14701: Address already in use (os error 98) Observed 2026-08-08 after four PRs were refreshed together. It is not rare — it happens whenever more than one PR is updated at once, which is routine when branch protection is strict and every merge puts the rest BEHIND. WHY IT IS WORTH FIXING RATHER THAN RE-RUNNING: it surfaces as a red REQUIRED check on a PR that cannot possibly have caused it — #342 changed a single workflow file — so it reads as a real regression and costs a diagnosis cycle. Worse, the "fix" that works is hitting re-run, which is exactly the habit that gets a genuine failure clicked through. The script ALREADY honours FALCON_HELLO_PORT_BASE (scripts/falcon-hello-demo.sh line 28). CI simply never set it. Derive a per-run base from GITHUB_RUN_ID. Stepping by 2 is load-bearing: the demo uses base AND base+1, so consecutive bases would still overlap on one port. base = 20000 + (GITHUB_RUN_ID % 10000) * 2 -> 20000..39998 pair = base, base+1 -> 20000/20001 .. 39998/39999 consecutive run ids differ by 2 -> no shared port GITHUB_RUN_ID is injected by Actions as a plain env var, so nothing is interpolated into the run: block. Verified locally end-to-end, not merely by reading the script: $ FALCON_HELLO_PORT_BASE=20246 bash scripts/falcon-hello-demo.sh [falcon-hello-demo] launching gcs on 127.0.0.1:20246 exit=0 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01HvusAXYbHLyv3uTzfBcMbG --- .github/workflows/ci.yml | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3bc4569..435d7c5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -101,7 +101,27 @@ jobs: - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: Run falcon-hello UDP-loopback demo - run: bash scripts/falcon-hello-demo.sh + # The demo binds a FIXED UDP port pair (default 14700/14701). Several of + # these jobs can land on the SAME self-hosted runner concurrently — which + # happens routinely whenever more than one PR is updated at once — and the + # second one dies with: + # + # error: bind 127.0.0.1:14700: Address already in use (os error 98) + # + # Observed 2026-08-08 after four PRs were refreshed together. It presents + # as a red REQUIRED check on an unrelated PR (#342 changed only a workflow + # file), so it reads as a real regression and costs a diagnosis cycle — + # and worse, it trains people to re-run a red gate. + # + # The script already honours FALCON_HELLO_PORT_BASE; CI just never set it. + # Derive a per-run base so two concurrent jobs cannot contend. Stepping by + # 2 matters: the demo uses base AND base+1, so consecutive bases would + # still overlap. GITHUB_RUN_ID is injected by Actions as a plain env var, + # so nothing is interpolated into this run: block. + run: | + export FALCON_HELLO_PORT_BASE=$(( 20000 + (GITHUB_RUN_ID % 10000) * 2 )) + echo "using port pair ${FALCON_HELLO_PORT_BASE}/$((FALCON_HELLO_PORT_BASE + 1))" + bash scripts/falcon-hello-demo.sh # The closed-loop SAFETY suite as a first-class, named gate. These are the # top-of-the-V integration tests — the whole verified cascade actually