Skip to content

ci: isolate integration tests in per-run CF spaces#1215

Open
kbarnold wants to merge 5 commits intoci/docker-image-buildsfrom
ci/cf-test-isolation
Open

ci: isolate integration tests in per-run CF spaces#1215
kbarnold wants to merge 5 commits intoci/docker-image-buildsfrom
ci/cf-test-isolation

Conversation

@kbarnold
Copy link
Copy Markdown
Collaborator

Summary

  • Creates a unique mbt-ci-<CIRCLE_BUILD_NUM> CF space per pipeline run, eliminating race conditions when concurrent pipelines share a space
  • Cleans up the space after the test run with when: always, so it is deleted even on test failure
  • Guards the cleanup step against an empty TEST_SPACE (e.g. if space creation failed), avoiding a cf delete-space "" -f call
  • Adds a nightly cleanup-ci-cf-spaces job that deletes orphaned mbt-ci-* spaces, skipping any space younger than 2 hours to avoid racing with a currently running pipeline
  • Resolves the deployed app route dynamically via cf app node output instead of a hardcoded NODE_APP_ROUTE env var (the route now includes the dynamic space name)
  • Updates the test job Docker image from cimg/go:1.21-node to cimg/go:1.24-node to match the Go version used in the project Dockerfile
  • Fixes malformed CF CLI download URL: &&version=&version=

Why

Every CI run previously deployed to the same CF space. When two pipelines ran concurrently, their cf undeploy / cf delete calls raced against each other, causing random test failures. Per-run spaces provide full isolation.

Test plan

  • Trigger two concurrent pipeline runs and confirm they do not interfere with each other
  • Cancel a pipeline mid-run and confirm the nightly cleanup job removes the orphaned space the following night
  • Confirm the cleanup step exits cleanly when space creation fails (empty TEST_SPACE)
  • Confirm CI passes on this branch

Note: This is PR 3 of 3 refactoring #1209. Depends on #1214.
Merge order: ci/drop-eol-nodeci/docker-image-builds → this PR

Concurrent pipeline runs (PR builds, master merges, release tags) all
deployed to the same hardcoded CF space, causing race conditions where
one run's cleanup tore down another's deployment mid-flight. The test
job now creates a unique mbt-ci-<build-num> space, passes it to the
test process, and deletes it with when: always to prevent orphaned
spaces.
Cancelled pipeline runs can leave mbt-ci-* spaces behind because the
always-run cleanup step never executes. This adds a cleanup-ci-cf-spaces
job that deletes any leftover mbt-ci-* spaces and a nightly-cleanup
workflow triggered via cron at 02:00 UTC.
The cleanup job was incorrectly placed inside a workflow definition
block instead of the top-level jobs section, making it invisible to
the nightly-cleanup workflow that references it.
The NODE_APP_ROUTE env var contained a hardcoded URL with the old
fixed space name. Since CF routes now include the dynamic space name,
the test queries the actual route from cf app output after deployment
instead of relying on the environment variable.
- Guard the cleanup step against empty TEST_SPACE: if space creation
  failed (e.g. quota exceeded) TEST_SPACE is never written to BASH_ENV,
  causing `cf delete-space "" -f` to fail or match incorrectly; skip
  gracefully instead
- Nightly cleanup now skips spaces younger than 2 hours to avoid
  deleting the space of a currently running integration-test pipeline;
  uses portable date arithmetic (GNU and BSD date both supported)
- Update test job Docker image from cimg/go:1.21-node to cimg/go:1.24-node
  to match the Go 1.24 version used in the project's Dockerfile
- Fix malformed CF CLI download URL: replace `&&version=` with `&version=`
@kbarnold kbarnold force-pushed the ci/docker-image-builds branch from 864403e to c213374 Compare March 27, 2026 14:28
@kbarnold kbarnold force-pushed the ci/cf-test-isolation branch from 2ffe622 to 092e70a Compare March 27, 2026 14:28
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