ci: give each runner on a shared host its own E2E ports

Two Linux runners live on the same host. Every Web E2E job first frees
"stale" listeners on the fixed ports 3110, 3111, 5180 and 4321 with
fuser -k, so a job starting on the second runner killed the Vite server
of the job already running on the first one. The victim died with
SIGKILL (exit 137), and its remaining tests failed on reloads that could
no longer reach a server. This is what made the Web E2E run on this PR
red, and it explains the recurring reload failures on main whenever two
runs overlapped.

The workflow now derives API_PORT, WEB_PORT and WWW_PORT from the runner
name (suffix -N means an offset of N times 100), and the port-freeing
script follows those settings instead of a hard-coded list. The harness,
Vite, the API and the marketing site already read these variables.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MRtGG9ARfqqhma3t85Ro2u
This commit is contained in:
Claude 2026-10-02 15:41:55 +00:00
parent 9c42cbcc17
commit 2f05ab6a81
No known key found for this signature in database
2 changed files with 28 additions and 1 deletions

View File

@ -111,6 +111,22 @@ jobs:
env: env:
BOX_API_KEY: ${{ secrets.BOX_API_KEY }} BOX_API_KEY: ${{ secrets.BOX_API_KEY }}
run: test -n "$BOX_API_KEY" run: test -n "$BOX_API_KEY"
- name: Pick E2E ports for this runner
# Several runners share one host. Each runner gets its own port set so the
# port-freeing steps and the harness never touch another job's servers.
run: |
set -euo pipefail
suffix="${RUNNER_NAME##*-}"
offset=0
if [[ "$suffix" =~ ^[0-9]+$ ]]; then
offset=$((suffix * 100))
fi
{
echo "API_PORT=$((3110 + offset))"
echo "WEB_PORT=$((5180 + offset))"
echo "WWW_PORT=$((4321 + offset))"
} >> "$GITHUB_ENV"
echo "E2E ports for ${RUNNER_NAME}: api $((3110 + offset)), web $((5180 + offset)), www $((4321 + offset))"
- name: Free stale E2E ports - name: Free stale E2E ports
run: bash scripts/free-e2e-ports.sh run: bash scripts/free-e2e-ports.sh
- name: Run Playwright tests - name: Run Playwright tests

View File

@ -1,11 +1,22 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Free stale listeners on dedicated Playwright/E2E ports before harness bind. # Free stale listeners on dedicated Playwright/E2E ports before harness bind.
# Never touches live dev stack ports 3100 (API) or 5173 (web). # Never touches live dev stack ports 3100 (API) or 5173 (web).
# The ports follow API_PORT, WEB_PORT and WWW_PORT so that runners sharing one host,
# each with its own port set, never kill another job's servers.
set -euo pipefail set -euo pipefail
for setting in API_PORT WEB_PORT WWW_PORT; do
value="${!setting:-}"
if [[ -n "$value" && ! "$value" =~ ^[0-9]+$ ]]; then
echo "free-e2e-ports: $setting must be a port number, got: $value" >&2
exit 1
fi
done
readonly LIVE_PORTS=(3100 5173) readonly LIVE_PORTS=(3100 5173)
readonly E2E_PORTS=(3110 3111 5180 4321) api_port="${API_PORT:-3110}"
readonly E2E_PORTS=("$api_port" "$((api_port + 1))" "${WEB_PORT:-5180}" "${WWW_PORT:-4321}")
if [[ "$(uname -s)" != "Linux" ]]; then if [[ "$(uname -s)" != "Linux" ]]; then
echo "free-e2e-ports: skip (not Linux)" echo "free-e2e-ports: skip (not Linux)"