https://github.com/stablekernel/cascade-example-retries
Cascade example: a deploy that fails once and is rescued by its retry, with a dependent deploy that still runs on the effective result.
https://github.com/stablekernel/cascade-example-retries
Last synced: 14 days ago
JSON representation
Cascade example: a deploy that fails once and is rescued by its retry, with a dependent deploy that still runs on the effective result.
- Host: GitHub
- URL: https://github.com/stablekernel/cascade-example-retries
- Owner: stablekernel
- Created: 2026-07-20T05:01:44.000Z (19 days ago)
- Default Branch: main
- Last Pushed: 2026-07-20T08:05:32.000Z (19 days ago)
- Last Synced: 2026-07-20T09:14:42.414Z (19 days ago)
- Size: 28.3 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# 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--`:
- 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.