Skip to content

ci(integration): serialize live-DB jobs to stop host-port collisions#641

Open
coderdan wants to merge 1 commit into
feat/eql-v3-text-search-schemafrom
ci/integration-port-collision-guard
Open

ci(integration): serialize live-DB jobs to stop host-port collisions#641
coderdan wants to merge 1 commit into
feat/eql-v3-text-search-schemafrom
ci/integration-port-collision-guard

Conversation

@coderdan

Copy link
Copy Markdown
Contributor

Problem

The Supabase v3 integration job on #586 failed CI — but not on anything in the PR. It died in the Start step, before any test ran:

Error response from daemon: failed to set up container networking:
failed to bind host port for 0.0.0.0:55430:172.18.0.3:3000/tcp: address already in use

Both integration-supabase.yml and integration-drizzle.yml bring up docker-compose stacks that bind fixed host ports (55430 / 55432 / 55433) on shared Blacksmith runners, with no concurrency guard. When two such jobs land on the same host at once — or a container leaks onto a reused runner from a hard-killed prior run — the second one can't bind the port and the whole job fails. A re-run of #586's job passed with no code change, confirming the flake.

The contention isn't just within one workflow: the Drizzle supabase matrix leg brings up the same supabase compose (55430/55433) as the Supabase workflow, so they can collide with each other too.

Fix

Job-level concurrency keyed by the compose variant on both workflows:

concurrency:
  group: integration-live-db-${{ matrix.db }}
  cancel-in-progress: false
  • Keyed by the compose/port group, not the ref — two different PRs contend for a host port just as much as two pushes to one PR, so it must serialize across refs.
  • The Drizzle supabase leg shares the Supabase workflow's key (integration-live-db-supabase), so those two queue instead of colliding on 55430/55433. The Drizzle postgres leg (55432) has its own key and still runs in parallel.
  • cancel-in-progress: false queues rather than cancels — a live-DB job that shares one ZeroKMS workspace should finish, not be interrupted mid-run.

Pre-up cleanup on both (belt-and-braces for a container leaked onto a reused runner by a hard-killed run that skipped its down):

- name: Clear any leaked containers from a prior run
  run: docker compose -f local/docker-compose.${{ matrix.db }}.yml down -v --remove-orphans || true

Notes

  • CI-tooling only — no changeset (no published-package behaviour changes) and no skill updates (not a supply-chain-policy change).
  • The fully robust fix would be to stop binding fixed host ports (per-run compose project + ephemeral ports, read the mapped port in the harness). That's a larger change; this pair of guards resolves the observed flake cheaply.

…flakes

The Supabase and Drizzle EQL v3 integration jobs bring up docker-compose
stacks that bind fixed host ports (55430 / 55432 / 55433) on shared
Blacksmith runners, with no concurrency guard. Two jobs binding the same
port on one host fail at `docker compose up` with "address already in
use" — a transient flake unrelated to the code under test (e.g. the
Supabase job on #586).

Add a job-level concurrency group keyed by the compose variant
(`integration-live-db-<db>`, NOT the ref, since two PRs contend for a
host port as much as two pushes to one PR). The Drizzle `supabase` leg
shares the Supabase workflow's key, so those two queue instead of
colliding on 55430/55433; the Drizzle `postgres` leg (55432) keeps its
own key and still runs in parallel. `cancel-in-progress: false` queues —
a live-DB job sharing one ZeroKMS workspace should finish, not be cut off.

Also add a pre-`up` `docker compose down -v --remove-orphans || true` to
clear any container leaked onto a reused runner by a hard-killed prior
run that skipped its teardown.
@coderdan coderdan requested a review from a team as a code owner July 13, 2026 11:03
@changeset-bot

changeset-bot Bot commented Jul 13, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: d02bf63

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4abca060-d197-43f5-a7bb-db51c6922ba5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/integration-port-collision-guard

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

Comment @coderabbitai help to get the list of available commands.

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