Skip to content

stablekernel/cascade-example-retries

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 

Repository files navigation

cascade-example-retries

A cascade fleet example that exercises deploy retry semantics: a deploy whose first attempt fails and whose retry succeeds must leave the environment deployed and the run green, and a dependent deploy gated on that retried deploy must still run. These are runtime behaviors that only real GitHub Actions can show, because they depend on how live job results flow through the generated workflow.

What this repo proves

When a deploy declares retries, cascade emits a retry shim job (Deploy (app) - Retry 1) that re-invokes the deploy callee when the base attempt fails. Downstream jobs must key on the deploy's effective result (the base attempt or any retry succeeded), not on the immutable result of the base attempt. This repo proves both halves of that contract:

  1. A deploy that fails once and then succeeds on the retry leaves the environment deployed and the orchestrate run green: the base attempt concludes failure, the retry concludes success, the environment's deployed sha advances, and the overall run is green.
  2. A dependent deploy (notify) that depends_on the retried deploy runs rather than being skipped, because its gate reads the effective result of the base deploy, not the failed result of the first attempt.

Manifest shape

Two environments (staging, prod) and two deploys:

Deploy Role Callee
app environment deploy with retries: 1; fails once, then succeeds deploy-app.yaml
notify dependent deploy with depends_on: [app]; must still run deploy-notify.yaml

A stub build callback gives the repo a valid build and promote chain.

The fail-once marker

deploy-app.yaml fails on its first attempt and succeeds on its retry using an Actions cache entry as a one-shot marker. The cache key is deploy-app-attempted-<run id>-<environment>:

  • On the first attempt the cache misses (no marker), so the callee writes the marker, then fails. The retry shim re-invokes the same callee, the cache now hits, and the callee succeeds.
  • The key is scoped to github.run_id, so the marker is unique to a single run and resets on its own: a fresh run always starts with a cache miss, so the first attempt fails again. No state carries between runs, so the marker can never wedge a later run into a stuck state.

This marker needs no secret and no committed state; it lives entirely in the Actions cache for the duration of one run.

Scenario suite

scenario-suite.yaml merges a source change to drive an orchestrate run, then reads that run's jobs and the committed deploy state and asserts:

  • the base Deploy (app) attempt concluded failure and Deploy (app) - Retry 1 concluded success (the retry rescued the deploy);
  • the dependent Deploy (notify) job ran rather than being skipped;
  • the orchestrate run concluded success; and
  • the staging deploy sha for app advanced to the merge sha.

Every run the suite causes is recorded in the fleet ledger, and the final reconcile job fails closed on any unregistered run.

Layout

.github/manifest.yaml              cascade manifest (config plus live state)
.github/workflows/build.yaml       build callee stub
.github/workflows/deploy-app.yaml  fail-once deploy callee
.github/workflows/deploy-notify.yaml dependent deploy callee
.github/workflows/orchestrate.yaml generated CI on trunk merges
.github/workflows/promote.yaml     generated environment promotion
.github/workflows/scenario-suite.yaml driver and assertions

The orchestrate, promote, hotfix, and rollback workflows and the manage-release action are generated by cascade from the manifest. Run cascade generate-workflow after editing the manifest.

About

Cascade example: a deploy that fails once and is rescued by its retry, with a dependent deploy that still runs on the effective result.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors