Skip to content

Make test-product retention configurable - #532

Open
ianrahman wants to merge 1 commit into
getsentry:mainfrom
ianrahman:codex/configurable-test-products-retention
Open

ianrahman wants to merge 1 commit into
getsentry:mainfrom
ianrahman:codex/configurable-test-products-retention

Conversation

@ianrahman

@ianrahman ianrahman commented Sep 11, 2026 •

Copy link
Copy Markdown

What changed

  • make managed .xctestproducts retention configurable through XCODEBUILDMCP_TEST_PRODUCTS_MAX_COUNT and XCODEBUILDMCP_TEST_PRODUCTS_MAX_AGE_DAYS
  • lower the defaults from 100 bundles / 3 days to 3 bundles / 1 day
  • prune before and after managed build-for-testing and source-based test operations under the shared workspace lifecycle lock
  • protect bundles with active readers from both automatic cleanup and explicit purge
  • leave caller-owned and cross-workspace portable bundles untouched
  • fail loudly when a successful build does not create its requested managed output
  • inject filesystem, clock, PID/liveness, UUID, lock, and sleep dependencies for deterministic lifecycle coverage
  • cover lock exhaustion, finalization failures, stale reader cleanup, active-reader races, missing output, and fresh post-operation time

Why

Source-based test runs stage full .xctestproducts bundles in workspace storage. Multi-gigabyte products made the previous 100-bundle default capable of retaining hundreds of gigabytes, while concurrent readers and writers require cleanup to remain process-safe.

Validation

  • npm run typecheck
  • npm run lint (0 errors; existing warnings remain)
  • npm run format:check
  • npm run build
  • focused lifecycle/build/test coverage: 97 tests passed
  • full npm test: 2,611 passed; one unchanged environment-sensitive init --dest ~/... test failed because this machine already has the CLI skill installed in the real home directory
  • git diff --check

Snapshot and smoke suites were not run because repository policy requires explicit permission.

Fixes #524.

AI assistance: Heavy AI use. Human skimmed, but I don't have deep experience with TS.

@ianrahman
ianrahman marked this pull request as draft September 11, 2026 21:01
@ianrahman
ianrahman force-pushed the codex/configurable-test-products-retention branch from fd7ba73 to a13bedb Compare September 21, 2026 20:17
@ianrahman
ianrahman marked this pull request as ready for review September 21, 2026 20:35

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a13bedb. Configure here.

if (operationFailed) {
throw operationError;
}
return result as T;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleanup errors delete successful products

High Severity

Source-based tests nest withManagedTestProductsReader inside withManagedTestProductsOutput. After the test already finished, the reader still takes the shared lifecycle lock and prunes. A lock timeout or prune error then bubbles out as an operation failure, so isSuccessful is skipped and withManagedTestProductsOutput deletes the bundle it just built. Callers lose a completed test result and its multi-gigabyte products.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a13bedb. Configure here.

Comment thread src/utils/test-common.ts
Comment on lines +228 to +231
const preparedSourcePath = params.testProductsPath ?? params.xctestrunPath;
return preparedSourcePath
? withManagedTestProductsReader(resolvePathFromCwd(preparedSourcePath), execute)
: execute();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The resolveFromLayers calls for testProductsMaxCount and testProductsMaxAgeDays are missing the fileConfig parameter, preventing configuration from project files.
Severity: MEDIUM

Suggested Fix

Add the fileConfig: opts.fileConfig parameter to the resolveFromLayers calls for both testProductsMaxCount and testProductsMaxAgeDays in src/utils/config-store.ts to allow configuration from project files.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: src/utils/test-common.ts#L228-L231

Potential issue: The configuration values for `testProductsMaxCount` and
`testProductsMaxAgeDays` are resolved using the `resolveFromLayers` function but are
missing the `fileConfig: opts.fileConfig` parameter. This is inconsistent with how other
configuration values are handled. As a result, users cannot configure these test product
retention settings through project configuration files like `.xcodebuildmcp.json`. The
settings can only be configured through environment variables or direct code overrides,
which breaks the intended configuration mechanism for this new feature.

Did we get this right? 👍 / 👎 to inform future reviews.

This branch has not been deployed

No deployments
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.

Test-products retention is unbounded in practice (100 bundles / 3 days, no config knob) — can fill a disk

1 participant