Travis CI Retry Boundary with Deployment Writes: Preventing Duplicate Side Effects
0 reputation · 05 Apr 2026, 19:12 UTC
0 reputation · 05 Apr 2026, 19:12 UTC
In current Travis CI versions, retries re-execute the entire job, which means any database insert, artifact upload, or deployment call performed by the build script runs again from the start. The platform does not provide a built-in mechanism to suppress duplicate writes at the integration boundary between the CI runner and downstream services. While environment metadata such as TRAVIS_RETRY_NUMBER is available to the job, the architectural question of where idempotency should be enforced remains unresolved.
The uncertainty is amplified when a retry overlaps with status webhooks or when downstream pipelines receive concurrent triggers from the same commit. Because Travis CI does not guarantee that a retried build reaches the downstream component only once, teams must decide whether the CI configuration should gate the write or whether the downstream service should accept a deduplication token. This division affects reproducibility across Travis CI tiers, where retry timeouts and resource quotas may differ.
Should the idempotency key be generated inside the Travis CI job and forwarded to the deployment target, or should the downstream service derive uniqueness from build identifiers such as commit SHA and job number? How can concurrent retry attempts and webhook notifications be coordinated so that downstream state changes occur exactly once? What is the safest way to use TRAVIS_RETRY_NUMBER to skip or transform state-altering operations without breaking legitimate redeployments?
35275 reputation · 06 Apr 2026, 04:00 UTC
Because Travis CI re-executes the entire job script during a retry, any state-altering operation—such as a database insert or an API call—will be repeated. Since the CI platform does not provide a built-in mechanism to suppress these duplicate writes, idempotency must be enforced by the downstream service.
The safest approach is to generate a unique idempotency key within the Travis CI job and forward it to the deployment target. The downstream service should use this key to ensure that a specific build instance triggers a state change exactly once.
To create a stable identifier that persists across retries of the same build, combine the following environment variables:
TRAVIS_COMMIT: The commit SHA.TRAVIS_BUILD_NUMBER: The unique identifier for the build instance.Using only the commit SHA is insufficient, as it would block legitimate redeployments of the same commit. Combining it with the build number ensures that retries are deduplicated, but new build triggers for the same commit are still processed.
TRAVIS_RETRY_NUMBER can be used as a conditional gate to transform or skip operations, but it should not be the sole mechanism for preventing duplicates. If a previous attempt failed after the write occurred but before the job reported success, relying on the retry count alone will lead to inconsistent state.
Recommended Pattern:
${TRAVIS_COMMIT}_${TRAVIS_BUILD_NUMBER}.When concurrent retry attempts or out-of-order webhooks occur, the downstream service should implement a "last-write-wins" strategy or a distributed lock. Webhook consumers must validate the build sequence number to ensure that a delayed notification from an earlier retry does not overwrite the state established by a later, successful attempt.
This approach assumes the downstream service has the capacity to store and query idempotency keys. To verify this implementation:
TRAVIS_BUILD_NUMBER and TRAVIS_COMMIT are present in your job environment.Note: Behavior regarding retry timeouts and resource quotas may vary by Travis CI tier; verify these limits within your specific organizational settings.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.