Skip to content

fix: align turbo cache keys between CI and Cypress workflows#2043

Merged
nick-inkeep merged 4 commits intomainfrom
fix/turbo-cache-alignment
Feb 16, 2026
Merged

fix: align turbo cache keys between CI and Cypress workflows#2043
nick-inkeep merged 4 commits intomainfrom
fix/turbo-cache-alignment

Conversation

@nick-inkeep
Copy link
Collaborator

@nick-inkeep nick-inkeep commented Feb 16, 2026

Summary

Enable turbo remote cache reuse between the CI and Cypress workflows by aligning their cache key inputs. Also fixes a DoltGres readiness race condition that caused intermittent Cypress failures.

Impact: Cypress turbo build goes from 0% to 75% cache hit rate (3 of 4 packages: agents-core, agents-sdk, agents-cli). agents-manage-ui remains uncacheable across workflows because Next.js embeds environment variables at build time.

Problem

Turbo computes different task hashes in CI vs Cypress due to three mismatches:

  1. globalEnv divergenceANTHROPIC_API_KEY, OPENAI_API_KEY, and ENVIRONMENT are set in CI but not in Cypress. Since globalEnv entries are hashed into every task, any difference invalidates the entire cache.
  2. globalDependencies divergence.env is listed as a global dependency. Cypress creates it via setup-dev; CI does not. The file is gitignored, so its presence/absence varies by workflow.
  3. Build input divergence — The .env* glob in build task inputs matches the gitignored .env in Cypress but finds nothing in CI, producing different input hashes.

Separately, DoltGres health checks used SELECT 1 (connectivity only), which could pass before Dolt system tables were available — causing setup-dev migrations to fail on dolt_status.

Changes

turbo.json:

  • Remove globalDependencies: [".env"] — gitignored file causes cross-workflow hash mismatch
  • Remove ANTHROPIC_API_KEY and OPENAI_API_KEY from globalEnv — these are runtime-only values that do not affect build outputs; moved to test task env where they belong
  • Change .env* to .env.example in build task inputs — tracks the committed schema file, not the gitignored instance

cypress.yml:

  • Add ENVIRONMENT: test to match CI (turbo hash alignment)
  • Strengthen DoltGres health check: SELECT count(*) FROM dolt_status validates system table readiness, not just TCP connectivity
  • Increase health-retries (5 → 10) and health-start-period (20s → 30s)

ci.yml:

  • Align DoltGres health check with Cypress (dolt_status query)

cypress-e2e/action.yml:

  • Add explicit DoltGres readiness polling before setup-dev (defense-in-depth against container health check races)
  • Override ENVIRONMENT=development on setup-dev and API server steps — the workflow-level ENVIRONMENT=test is for turbo hash computation only; application code must see development so createAgentsManageDatabaseClient() connects to real DoltGres instead of returning an in-memory PGLite client

Notes

  • One-time cache rebuild: Changing turbo.json invalidates all existing remote cache entries. The first CI and Cypress runs after merge will rebuild the cache (~16 min). Subsequent runs return to normal.
  • No security or test coverage changes: API keys are not used during builds (only at runtime via env.ts Zod validation). Removing .env from tracking has no effect — CI never creates it, and next build sets NODE_ENV=production which skips .env loading. The ENVIRONMENT=development overrides preserve the same database connectivity behavior Cypress had before this PR.

Test plan

  • Verified ANTHROPIC_API_KEY and OPENAI_API_KEY are not used during any build task (runtime-only via env.ts)
  • Verified .env is not read at build time (next.config.ts skips env loading when NODE_ENV=production)
  • Confirmed turbo config is valid (turbo build --dry-run)
  • Confirmed API keys are scoped to test tasks only (turbo test --dry-run=json)
  • CI workflow passes with all checks green
  • Cypress workflow passes with DoltGres readiness + ENVIRONMENT override working correctly
  • Cypress turbo build shows 3/4 cache hits in CI logs
  • No changes to local dev experience

🤖 Generated with Claude Code

The Cypress workflow gets 0% turbo cache hits (~101s rebuild) despite CI
achieving 100% cache hits (~17s) for the same code. Three root causes of
cache key divergence:

1. globalEnv includes ANTHROPIC_API_KEY and OPENAI_API_KEY, which are set
   in CI but not Cypress. These are runtime-only (env.ts loaded at service
   start, not during build) and don't affect build outputs.

2. globalDependencies includes ".env", a gitignored file that setup-dev
   creates in Cypress but never exists in CI. Different file existence
   produces different global hashes.

3. Build task inputs use ".env*" glob, which matches 2 files in CI but 3
   in Cypress (because setup-dev created .env). Confirmed via dry-run:
   different task hashes (cbcb775e vs e03ac1ed).

Fix:
- Remove ANTHROPIC_API_KEY and OPENAI_API_KEY from globalEnv
- Move them to test task env (tests may depend on mock provider behavior)
- Remove .env from globalDependencies (all vars tracked via globalEnv)
- Change build inputs from ".env*" to ".env.example" (committed file only)
- Add ENVIRONMENT: test to Cypress workflow (matches CI)

Expected: Cypress turbo build drops from ~101s to ~17s via cache hits.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Feb 16, 2026

⚠️ No Changeset found

Latest commit: 1edd21a

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

@vercel
Copy link

vercel bot commented Feb 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agents-api Ready Ready Preview, Comment Feb 16, 2026 8:08pm
agents-docs Ready Ready Preview, Comment Feb 16, 2026 8:08pm
agents-manage-ui Ready Ready Preview, Comment Feb 16, 2026 8:08pm

Request Review

Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

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

PR Review Summary

(0) Total Issues | Risk: Low

This PR correctly addresses turbo cache key divergence between CI and Cypress workflows through three targeted fixes:

  1. Scoping runtime-only env varsANTHROPIC_API_KEY and OPENAI_API_KEY are moved from globalEnv to the test task's env. These keys are loaded at runtime via env.ts (imported in agents-api/src/index.ts), not at build time, so they should not affect build cache keys.

  2. Removing gitignored file from inputs — Changing .env* glob to .env.example eliminates the hash mismatch caused by .env existing in Cypress (created by setup-dev) but not in CI.

  3. Aligning environment variable — Adding ENVIRONMENT: test to Cypress workflow ensures globalEnv hashes match CI.

🔴❗ Critical (0) ❗🔴

None.

🟠⚠️ Major (0) 🟠⚠️

None.

🟡 Minor (0) 🟡

None.

💭 Consider (0) 💭

None.


✅ APPROVE

Summary: Clean, well-researched fix with solid evidence (dry-run verification, runtime vs build-time analysis). The three changes are logically correct and should achieve the expected ~6x speedup in Cypress builds. Ship it! 🚀

Discarded (2)
Location Issue Reason Discarded
create-agents-template/turbo.json Template uses different env strategy (API keys in globalEnv, .env* glob) Pre-existing pattern difference, not introduced by this PR. Template is for customer projects with real .env files locally — divergence is intentional.
.github/workflows/cypress.yml:53 GitHub Actions use mutable tags (@v4, @v5) instead of SHA pins Pre-existing repo-wide pattern across all 35+ action references. Not a regression and out of scope for this cache alignment fix.
Reviewers (1)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
pr-review-devops 5 0 0 0 0 0 2
Total 5 0 0 0 0 0 2

Note: 3 findings were positive validations (INFO severity confirming correctness), not issues.

@github-actions github-actions bot deleted a comment from claude bot Feb 16, 2026
The DoltGres health check uses `SELECT 1` which only validates basic
connectivity. The `dolt_status` system table may not be initialized yet,
causing intermittent failures in `setup-dev` migrations:

  DrizzleQueryError: relation "dolt_status" does not exist

Fix: Change health check to `SELECT count(*) FROM dolt_status` which
verifies the DoltGres repository is fully initialized before marking
the container as healthy. Also align Cypress health check params with
CI (retries: 10, start-period: 30s).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

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

PR Review Summary

(0) Total Issues | Risk: Low

Re-review Scope

This is a delta review covering 1 new commit (f2517a55) since the prior automated review. The turbo.json cache alignment changes were already reviewed and approved.

Delta Changes Reviewed

  1. DoltGres health check improvement — Changed from SELECT 1 to SELECT count(*) FROM dolt_status in both CI and Cypress workflows. This is a more robust readiness check that verifies DoltGres system tables are initialized, not just that postgres accepts connections.

  2. Cypress retry/timeout alignment — Aligned Cypress workflow settings with CI:

    • health-retries: 5 → 10
    • health-start-period: 20s → 30s

Both changes are correct and improve reliability:

  • The dolt_status check ensures Dolt's versioning layer is ready, preventing race conditions where postgres is up but Dolt isn't fully initialized
  • The retry/timeout alignment matches the existing CI settings (lines 153-157 in ci.yml), ensuring consistent behavior across workflows

🔴❗ Critical (0) ❗🔴

None.

🟠⚠️ Major (0) 🟠⚠️

None.

🟡 Minor (0) 🟡

None.

💭 Consider (0) 💭

None.


✅ APPROVE

Summary: The delta changes improve DoltGres health check reliability and align Cypress workflow settings with CI. Combined with the already-approved turbo cache alignment changes, this PR should achieve the expected ~6x speedup in Cypress builds while also improving container readiness detection. Ship it! 🚀

Discarded (1)
Location Issue Reason Discarded
docker-compose*.yml files Docker Compose files still use SELECT 1 for DoltGres health checks instead of dolt_status Pre-existing pattern for local development, not introduced by this PR. The PR scope is CI/Cypress workflow alignment; local dev docker-compose files are a separate concern and could be addressed in a follow-up if desired.
Reviewers (2)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
pr-review-devops 0 0 0 0 0 0 0
pr-review-standards 0 0 0 0 0 0 1
Total 0 0 0 0 0 0 1

Note: Both reviewers confirmed the delta changes are correct with no issues.

@github-actions github-actions bot deleted a comment from claude bot Feb 16, 2026
The GHA service container health check is insufficient — GitHub Actions
may proceed even with unhealthy containers. Add an explicit readiness
poll that blocks until DoltGres system tables (dolt_status) are available
before running setup-dev migrations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

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

PR Review Summary

(0) Total Issues | Risk: Low

Re-review Scope

This is a delta review covering 1 new commit (36143d94) since the prior automated review. The turbo.json cache alignment changes and container health check improvements were already reviewed and approved.

Delta Changes Reviewed

Commit 36143d94: Add explicit DoltGres readiness wait before setup-dev

The new step (lines 28-43 in cypress-e2e/action.yml) adds a shell-based readiness wait loop that:

  • Queries SELECT count(*) FROM dolt_status up to 30 times with 2-second intervals (60s max)
  • Exits early on first successful connection
  • Provides clear timeout messaging if DoltGres isn't ready

This is a belt-and-suspenders approach alongside the container health check. While the container health check uses the same query, there are known edge cases where GitHub Actions reports a service container as healthy before the network path from the runner is fully established. The explicit wait step provides an additional layer of reliability for migration operations that follow.

🔴❗ Critical (0) ❗🔴

None.

🟠⚠️ Major (0) 🟠⚠️

None.

🟡 Minor (0) 🟡

None.

💭 Consider (0) 💭

None.


✅ APPROVE

Summary: The delta commit adds a defensive readiness check that follows established CI patterns (similar to the SpiceDB wait loop at ci.yml:239-246). Combined with the already-approved turbo cache alignment and container health check changes, this PR should achieve the expected ~6x speedup in Cypress builds while improving DoltGres initialization reliability. Ship it! 🚀

Discarded (3)
Location Issue Reason Discarded
cypress-e2e/action.yml:28-43 Redundant readiness check duplicates container health check query Intentional belt-and-suspenders approach; addresses known GitHub Actions edge cases where container health check passes but network path isn't fully established. Minimal latency impact (exits early on success).
cypress-e2e/action.yml:33 Missing psql dependency check / 2>/dev/null hides errors The dependency is implicitly satisfied by ubuntu-latest runners. The 2>/dev/null suppresses expected "connection refused" errors during retries; timeout provides clear failure path if psql is truly missing.
cypress-e2e/action.yml:38-39 Timeout message hardcodes "60 seconds" INFO-level maintainability nitpick; current arithmetic is correct. Adding dynamic computation would add bash complexity without meaningful benefit.
Reviewers (1)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
pr-review-devops 3 0 0 0 0 0 3
Total 3 0 0 0 0 0 3

Note: All findings were valid observations but assessed as acceptable tradeoffs for CI reliability.

@github-actions github-actions bot deleted a comment from claude bot Feb 16, 2026
When ENVIRONMENT=test (needed for turbo cache alignment), the
createAgentsManageDatabaseClient function returns an in-memory PGLite
client instead of connecting to real DoltGres. This causes
migrate-dolt.ts to fail with 'relation dolt_status does not exist'
because PGLite doesn't have DoltGres system tables.

Override ENVIRONMENT=development for setup-dev (which runs migrations)
and the API server (which needs real DoltGres at runtime). The
ENVIRONMENT=test value is still used by turbo for cache key computation
during the build step.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

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

PR Review Summary

(0) Total Issues | Risk: Low

Re-review Scope

This is a delta review covering 1 new commit (1edd21ae) since the prior automated review. The turbo.json cache alignment changes, DoltGres health check improvements, and explicit readiness wait loop were already reviewed and approved.

Delta Changes Reviewed

Commit 1edd21ae: Add step-level ENVIRONMENT=development overrides

The delta adds 3 lines to .github/composite-actions/cypress-e2e/action.yml:

  • Line 47-48: env: ENVIRONMENT: development for the "Setup development environment" step
  • Line 54: ENVIRONMENT: development for the "Start backend API server" step

Why this is correct:

  1. Workflow-level ENVIRONMENT: test (cypress.yml:128) is required for turbo cache key alignment — turbo includes ENVIRONMENT in its globalEnv hash, so Cypress must match CI's value during the build phase.

  2. Step-level ENVIRONMENT: development overrides are required because:

    • packages/agents-core/src/db/manage/manage-client.ts selects the database client based on ENVIRONMENT
    • When ENVIRONMENT=test: returns in-memory PGLite (JavaScript SQLite) — which does NOT have DoltGres system tables
    • When ENVIRONMENT=development: connects to real PostgreSQL (DoltGres) via node-postgres
    • The setup-dev step runs migrations that query dolt_status — this requires the real DoltGres connection
    • The API server step needs real database connections at runtime
  3. Scope isolation: Step-level environment variables in GitHub Actions override workflow-level values only for that specific process. The turbo cache key is computed during the build step (before these steps), so the override doesn't affect cache alignment.

This is the correct resolution for the interaction between turbo cache requirements and database client selection.

🔴❗ Critical (0) ❗🔴

None.

🟠⚠️ Major (0) 🟠⚠️

None.

🟡 Minor (0) 🟡

None.

💭 Consider (0) 💭

None.


✅ APPROVE

Summary: The delta commit correctly resolves the interaction between workflow-level ENVIRONMENT: test (needed for turbo cache alignment) and step-level database connection requirements (needs real DoltGres, not PGLite). Combined with the already-approved turbo cache alignment, DoltGres health check, and readiness wait changes, this PR should achieve the expected ~6x speedup in Cypress builds while ensuring reliable database operations. Well-reasoned fix — ship it! 🚀

Discarded (0)

No discarded findings.

Reviewers (1)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
pr-review-devops 0 0 0 0 0 0 0
Total 0 0 0 0 0 0 0

Note: Delta changes confirmed correct with no issues. The reviewer validated that step-level env overrides are the appropriate pattern for this use case.

@github-actions github-actions bot deleted a comment from claude bot Feb 16, 2026
@nick-inkeep nick-inkeep merged commit da9ce85 into main Feb 16, 2026
11 checks passed
@nick-inkeep nick-inkeep deleted the fix/turbo-cache-alignment branch February 16, 2026 20:45
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