ci(railway): retry service resolution to survive the bootstrap→configure race - #5322
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@coderabbitai review |
📝 WalkthroughWalkthroughRailway service-variable configuration now refreshes status data, retries service discovery and CLI updates, and falls back to CLI variable setting when GraphQL service resolution remains unavailable. ChangesRailway variable configuration resilience
Estimated code review effort: 3 (Moderate) | ~20 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
✅ Action performedReview finished.
|
…gure race The release preview deploy failed with "Service 'cron' not found" seconds after bootstrap created the service: configure.sh resolves service ids from a single 'railway status --json' snapshot, and a service created moments earlier by the setup job may not be visible in it yet. The CLI fallback then hit the same eventual-consistency window and hard-failed the deploy. Re-fetch the status snapshot and retry id resolution a few times (bounded, short sleeps) before falling back to the CLI, and let the CLI fallback retry the specific 'not found' failure a couple of times instead of exiting on the first hit. First-try hits cost zero extra API calls, so the happy path is unchanged. Claude-Session: https://claude.ai/code/session_01Hyn9365BLPXDmNZShrQkmH
b670d1d to
b46eb2a
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
hosting/railway/oss/scripts/configure.sh (1)
134-135: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider using a distinct delay variable for CLI retries.
_cli_set_varsreusesRAILWAY_SERVICE_RESOLVE_DELAY. To maintain configuration consistency withRAILWAY_CLI_SET_ATTEMPTS, consider providing a dedicated delay variable.♻️ Proposed refactor
local attempts="${RAILWAY_CLI_SET_ATTEMPTS:-3}" - local delay="${RAILWAY_SERVICE_RESOLVE_DELAY:-5}" + local delay="${RAILWAY_CLI_SET_DELAY:-5}"
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 012c6cf9-61f4-48cb-87b6-8073ffb706cb
📒 Files selected for processing (1)
hosting/railway/oss/scripts/configure.sh
| done | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Return failure if the retry loop is skipped.
If RAILWAY_CLI_SET_ATTEMPTS evaluates to 0 or an invalid non-numeric string, the loop won't execute, and the function will fall through to implicitly return 0 (success) without doing any work. Adding return 1 ensures a failure is properly reported in this edge case.
🛡️ Proposed fix
done
+ return 1
}| _cli_set_vars "$service" "$@" | ||
| return 0 |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Propagate the exit code of the CLI fallback.
Both CLI fallback paths explicitly return 0 after calling _cli_set_vars. If the CLI variable update fails, its non-zero exit code is masked, causing the function to incorrectly report success. This can lead to silent deployment failures with missing configuration variables.
hosting/railway/oss/scripts/configure.sh#L177-L178: Replacereturn 0withreturn $?to correctly propagate the exit status.hosting/railway/oss/scripts/configure.sh#L188-L189: Replacereturn 0withreturn $?to correctly propagate the exit status.
📍 Affects 1 file
hosting/railway/oss/scripts/configure.sh#L177-L178(this comment)hosting/railway/oss/scripts/configure.sh#L188-L189
Railway Preview Environment
Updated at 2026-07-14T21:03:48.248Z |
Context
The v0.105.0 release PR's preview deploy (run 29363754807) failed with
Service 'cron' not foundabout 40 seconds into the deploy job. The setup job's bootstrap had created thecronservice 17 seconds earlier and reported success.configure.shresolves service ids from a singlerailway status --jsonsnapshot taken at startup, and a service created seconds before by a different job can be missing from that snapshot (Railway's API is eventually consistent). The CLI fallback (railway variable set --service cron) hit the same window, andrailway_callclassifies its "not found" as a deterministic error, so nothing retried and the deploy hard-failed. The dependent eu/acceptance web tests were skipped with it. The same job flips between green and red on unchanged branches, which is how this was diagnosed as a race rather than a regression.Changes
Two bounded retries in
configure.sh, both no-ops on the happy path:_service_id_with_retry: when a service id is missing from the cached status snapshot, re-fetchrailway status --jsonand retry resolution (6 attempts total, 5s sleeps; tunable viaRAILWAY_SERVICE_RESOLVE_ATTEMPTS/RAILWAY_SERVICE_RESOLVE_DELAY) before falling back to the CLI path. A first-try hit costs zero extra API calls and zero sleeps. The default is 6 because in the observed incident the service was still invisible more than 35 seconds after bootstrap completed, so the retry budget (25s of resolve retries, roughly 35s including the CLI fallback) is sized to cover it; unneeded retries cost nothing._cli_set_vars: the CLI fallback now retries specifically the "not found" failure (3 attempts,RAILWAY_CLI_SET_ATTEMPTS) instead of failing the deploy on the first hit. Any other failure surfaces immediately; transient network errors keep being handled insiderailway_callas before.Before: one status snapshot, one CLI attempt,
Service 'cron' not found, deploy dead.After: the snapshot is re-fetched while the just-created service becomes visible; the deploy only fails after both paths exhaust their bounded retries.
Tests / notes
bash -npasses. shellcheck was not available locally.railway_callharness (not committed): first-try hit makes no extra calls; an id appearing after a snapshot re-fetch resolves; exhaustion returns empty and falls back to the CLI; the CLI fallback retries "not found" and succeeds on the second attempt; deterministic errors (unauthorized) are not retried; a permanent "not found" still fails after the bounded 3 attempts. All 10 assertions pass.configure.sh.deploy-gateway.shfailed on another PR withProject "agenta-oss-pr-5319" not found in workspaceatrailway link. That is a different script and failure point (rawrailway link, project-level visibility), not the same one-line retry shape, so it is left for a follow-up if it recurs.https://claude.ai/code/session_01Hyn9365BLPXDmNZShrQkmH