diff --git a/README.md b/README.md index 75e8cb0..5a36778 100644 --- a/README.md +++ b/README.md @@ -359,7 +359,7 @@ Full flag reference: [CLI reference](https://stablekernel.github.io/cascade/cli- | Document | Description | |---|---| -| [Stage Graph](https://stablekernel.github.io/cascade/stage-graph/) | The mental model - start here to see how the stages fit together | +| [Stage Graph](https://stablekernel.github.io/cascade/stage-graph/) | The mental model. Start here to see how the stages fit together | | [Getting Started](https://stablekernel.github.io/cascade/getting-started/) | Step-by-step setup guide | | [Configuration](https://stablekernel.github.io/cascade/configuration/) | Full manifest reference | | [Workflows](https://stablekernel.github.io/cascade/workflows/) | Orchestrate and Promote explained | diff --git a/docs/src/content/docs/adoption.md b/docs/src/content/docs/adoption.md index 1b206b9..40366d1 100644 --- a/docs/src/content/docs/adoption.md +++ b/docs/src/content/docs/adoption.md @@ -1,6 +1,6 @@ --- title: Adoption Guide -description: A journey-oriented guide to adopting cascade - the mental model, building a pipeline from scratch, migrating an existing one, and wiring tools like release-please and goreleaser into reusable-workflow callbacks. +description: A journey-oriented guide to adopting cascade. It covers the mental model, building a pipeline from scratch, migrating an existing one, and wiring tools like release-please and goreleaser into reusable-workflow callbacks. --- This guide ties the reference docs together into one path: how to think about cascade, how to build a pipeline from nothing, and how to migrate an existing pipeline (and existing tools) onto it. If you have never run cascade, start with [Getting Started](/cascade/getting-started/) for installation, then come back here for the bigger picture. @@ -16,7 +16,7 @@ The flow in one line: you write a manifest plus callback workflows, run `cascade ## Prerequisites - **GitHub Actions enabled** on the repository, with trunk-based development (a single primary branch). -- **Conventional Commits - required.** cascade derives the semver bump, the changelog, and breaking-change detection entirely from Conventional Commit messages. This is not optional. Commits that do not follow the convention are not processed correctly and version derivation can fail. See [Versioning and schema compatibility](/cascade/versioning/). +- **Conventional Commits are required.** cascade derives the semver bump, the changelog, and breaking-change detection entirely from Conventional Commit messages. This is not optional. Commits that do not follow the convention are not processed correctly and version derivation can fail. See [Versioning and schema compatibility](/cascade/versioning/). - **GitHub setup**: environments for each deploy stage, branch and tag protection, the secrets your callbacks consume, and scoped tokens. The [Security and Hardening](/cascade/security/hardening/) checklist is the authoritative list; wire it up before your first production promotion. - The `cascade` CLI for local generation (Go 1.25+ to `go install`; in Actions, the setup action installs it for you). See [Getting Started](/cascade/getting-started/). @@ -209,9 +209,9 @@ The full, ordered checklist is in [Security and Hardening](/cascade/security/har Environment count is structural. Pick the shape that matches your project: -- **No-env (release-only)** - omit `environments`. For libraries and CLIs that publish releases without deploying anywhere. -- **2-env** - `dev` + `prod`. Smallest promotion chain with a prerelease stage. -- **3-env** - `dev` + `staging` + `prod` (or `pre` + `staging` + `prod`). The common default. -- **4-env** - `dev` + `staging` + `pre` + `prod`. Adds a dedicated prerelease stage before production. +- **No-env (release-only)**: omit `environments`. For libraries and CLIs that publish releases without deploying anywhere. +- **2-env**: `dev` + `prod`. Smallest promotion chain with a prerelease stage. +- **3-env**: `dev` + `staging` + `prod` (or `pre` + `staging` + `prod`). The common default. +- **4-env**: `dev` + `staging` + `pre` + `prod`. Adds a dedicated prerelease stage before production. Worked example repositories are not published yet (examples TBD). Until then, the [Getting Started](/cascade/getting-started/) walkthrough and the [Callback Contract](/cascade/callback-contract/) skeletons are the reference implementations. diff --git a/docs/src/content/docs/architecture.md b/docs/src/content/docs/architecture.md index 623fdd0..c7780a5 100644 --- a/docs/src/content/docs/architecture.md +++ b/docs/src/content/docs/architecture.md @@ -554,11 +554,11 @@ For satellite repos with notify config: ## Extension Points -1. **Custom Changelog** - Override with `changelog.workflow` -2. **Custom Release** - Override with `release.tag` for external tools -3. **Custom Inputs** - Pass arbitrary inputs via `inputs`/`env_inputs` -4. **Output Chaining** - Outputs auto-discovered and passed to dependents -5. **GitHub Environments** - `environment_config` per-env settings emitted by `cascade environments`; see [GitHub Deployments API and Environments REST](#github-deployments-api-and-environments-rest) below +1. **Custom Changelog**: override with `changelog.workflow` +2. **Custom Release**: override with `release.tag` for external tools +3. **Custom Inputs**: pass arbitrary inputs via `inputs`/`env_inputs` +4. **Output Chaining**: outputs auto-discovered and passed to dependents +5. **GitHub Environments**: `environment_config` per-env settings emitted by `cascade environments`; see [GitHub Deployments API and Environments REST](#github-deployments-api-and-environments-rest) below ## GitHub Deployments API and Environments REST diff --git a/docs/src/content/docs/configuration.md b/docs/src/content/docs/configuration.md index 1e1628d..ae21f34 100644 --- a/docs/src/content/docs/configuration.md +++ b/docs/src/content/docs/configuration.md @@ -356,7 +356,7 @@ The framework only carries metadata. The publish workflow performs the registry For repositories that coordinate deployments owned by satellite repos. -`external:` is designed for the **satellite/sibling-repo artifact coordination** pattern: a separate repo (the satellite) owns its own build and deploys to its first environment, then notifies the primary via `workflow_dispatch`. The primary records the satellite's SHA and version in the shared manifest and includes the satellite's deploys in every subsequent promotion. `external:` is **not** a GitOps mirror mechanism - it does not push rendered manifests to a target repo or track a pushed commit in a foreign repo. The first-class (reserved) home for the GitOps mirror pattern is a deploy's `deploy_target:` block with `mode: gitops`, which reserves the shape for pushing a rendered field into a dedicated config repo and recording the pushed commit (see [Reserved shape: GitOps deploy target](./versioning#reserved-shape-gitops-deploy-target)). +`external:` is designed for the **satellite/sibling-repo artifact coordination** pattern: a separate repo (the satellite) owns its own build and deploys to its first environment, then notifies the primary via `workflow_dispatch`. The primary records the satellite's SHA and version in the shared manifest and includes the satellite's deploys in every subsequent promotion. `external:` is **not** a GitOps mirror mechanism. It does not push rendered manifests to a target repo or track a pushed commit in a foreign repo. The first-class (reserved) home for the GitOps mirror pattern is a deploy's `deploy_target:` block with `mode: gitops`, which reserves the shape for pushing a rendered field into a dedicated config repo and recording the pushed commit (see [Reserved shape: GitOps deploy target](./versioning#reserved-shape-gitops-deploy-target)). ```yaml ci: diff --git a/docs/src/content/docs/getting-started.md b/docs/src/content/docs/getting-started.md index c32d7c2..5ddba7b 100644 --- a/docs/src/content/docs/getting-started.md +++ b/docs/src/content/docs/getting-started.md @@ -3,7 +3,7 @@ title: Getting Started description: A step-by-step guide to installing the cascade CLI, creating a manifest, wiring callback workflows, and generating orchestration workflows in your repository. --- -This guide walks through setting up `cascade` in your repository. For the big picture first - how trunk, your environments, and the release boundary fit together - read the [Stage Graph](/cascade/stage-graph/). +This guide walks through setting up `cascade` in your repository. For the big picture first, read the [Stage Graph](/cascade/stage-graph/) to see how trunk, your environments, and the release boundary fit together. ## Prerequisites diff --git a/docs/src/content/docs/security/hardening.md b/docs/src/content/docs/security/hardening.md index 8d97d1d..d62ee72 100644 --- a/docs/src/content/docs/security/hardening.md +++ b/docs/src/content/docs/security/hardening.md @@ -1,6 +1,6 @@ --- title: Security and hardening -description: Cascade's security model and a shared-responsibility guide to deploying it safely - what cascade provides secure by construction versus what your organization configures in GitHub and your cloud - plus a concrete hardening checklist. +description: Cascade's security model and a shared-responsibility guide to deploying it safely. It covers what cascade provides secure by construction versus what your organization configures in GitHub and your cloud, plus a concrete hardening checklist. --- Cascade generates GitHub Actions workflow definitions and coordinates promotion across environments. Those workflows are committed to, and run inside, your own repositories, under your own runners, branch protection, and environment gates. Security is shared: cascade emits sound, reviewable workflow definitions, and your organization configures the GitHub and cloud controls that decide what those workflows are allowed to do. diff --git a/docs/src/content/docs/stage-graph.md b/docs/src/content/docs/stage-graph.md index 3a2c093..be02a98 100644 --- a/docs/src/content/docs/stage-graph.md +++ b/docs/src/content/docs/stage-graph.md @@ -1,9 +1,9 @@ --- title: Stage Graph -description: The mental model for cascade - how trunk, the environment chain, and the prerelease/release boundary fit together, with rollback and hotfix off-ramps, and the manifest field and generated workflow behind each stage. +description: The mental model for cascade. How trunk, the environment chain, and the prerelease/release boundary fit together, with rollback and hotfix off-ramps, and the manifest field and generated workflow behind each stage. --- -Cascade turns one manifest into a chain of stages. A change starts on trunk, moves through your environments in order, and crosses a prerelease/release boundary near the top of the chain. Two off-ramps - rollback and hotfix - branch off that line when something needs to move backward or sideways. This page is the map. It names every stage, ties each to the manifest field that turns it on and the generated workflow file that runs it, and says when it fires. Once the shape is clear, the deeper pages fill in the detail. +Cascade turns one manifest into a chain of stages. A change starts on trunk, moves through your environments in order, and crosses a prerelease/release boundary near the top of the chain. Two off-ramps, rollback and hotfix, branch off that line when something needs to move backward or sideways. This page is the map. It names every stage, ties each to the manifest field that turns it on and the generated workflow file that runs it, and says when it fires. Once the shape is clear, the deeper pages fill in the detail. ## The graph @@ -122,7 +122,7 @@ Fails a pull request when the committed workflows fall out of sync with the mani This page is the entry point. Follow the threads from here: -- [Manifest Reference](/cascade/configuration/) - every field behind every stage above. -- [Workflows](/cascade/workflows/) - what orchestrate, promote, and release do step by step. -- [Architecture](/cascade/architecture/) - how the generator turns the manifest into these files. -- [CLI Reference](/cascade/cli-reference/) - `generate-workflow`, `verify`, and the rest of the commands. +- [Manifest Reference](/cascade/configuration/): every field behind every stage above. +- [Workflows](/cascade/workflows/): what orchestrate, promote, and release do step by step. +- [Architecture](/cascade/architecture/): how the generator turns the manifest into these files. +- [CLI Reference](/cascade/cli-reference/): `generate-workflow`, `verify`, and the rest of the commands. diff --git a/docs/src/content/docs/testing.md b/docs/src/content/docs/testing.md index dc28787..edf02eb 100644 --- a/docs/src/content/docs/testing.md +++ b/docs/src/content/docs/testing.md @@ -1,6 +1,6 @@ --- title: How cascade is tested -description: How cascade verifies its generated pipelines across two complementary layers - a hermetic act plus gitea harness that runs on every pull request and a live fleet that exercises real GitHub Actions across every supported topology - plus the reconcile gate that makes fleet results trustworthy and the platform ceiling that is validated by design rather than execution. +description: How cascade verifies its generated pipelines across two complementary layers. A hermetic act plus gitea harness runs on every pull request, and a live fleet exercises real GitHub Actions across every supported topology. The reconcile gate makes fleet results trustworthy, and the platform ceiling is validated by design rather than execution. --- Cascade generates GitHub Actions workflows that promote a single artifact across environments. Because those workflows are the product, cascade does not stop at unit tests on its Go packages. It runs each generated pipeline end to end and asserts the behavior it produces: the releases it cuts, the state it writes, the labels and comments it posts, and the gates it refuses to cross. @@ -15,11 +15,11 @@ Every feature is covered in the layer where it can actually be exercised. The tw The harness in `e2e/` stands up a local [gitea](https://about.gitea.com/) server and runs the generated workflows in a real [act](https://github.com/nektos/act) runner, inside testcontainers. It is hermetic and fast enough to run on every pull request, with no dependency on github.com. -Each scenario generates the full workflow set from a manifest, commits it, drives a trigger (a push, a dispatch, a merged pull request), and then asserts the outcome - either a runtime `action` plus `expect` pair against the resulting state, or a structural `contains` assertion against the emitted YAML. +Each scenario generates the full workflow set from a manifest, commits it, drives a trigger (a push, a dispatch, a merged pull request), and then asserts the outcome. That outcome is either a runtime `action` plus `expect` pair against the resulting state, or a structural `contains` assertion against the emitted YAML. Because the harness owns the whole environment, it can drive paths the live fleet cannot synthesize on demand: -- **Emission and structural shape.** Whether a flag lands the right `on:` trigger, the right `concurrency:` block, the right `permissions:` map, or the right reusable-workflow reference - asserted directly against the emitted bytes. +- **Emission and structural shape.** Whether a flag lands the right `on:` trigger, the right `concurrency:` block, the right `permissions:` map, or the right reusable-workflow reference, asserted directly against the emitted bytes. - **Conflict and retry injection.** A hotfix cherry-pick that is guaranteed to conflict, so the conflict label and the halted downstream lane are exercised deterministically. - **State-write contention.** The retry-on-conflict loop on the state commit, driven without needing two real runs to collide. - **Reserved-shape round-trips.** Manifest blocks that are parsed and validated but not yet generated are confirmed to round-trip cleanly through verify. @@ -32,13 +32,13 @@ The fleet proves the things that only real GitHub can prove: a real release obje ### Unit tests (pure logic) -Underneath both layers, the Go packages carry conventional unit tests for the pure logic - version calculation, change detection, changelog assembly, manifest parsing and validation. These run on every build and are the fastest feedback loop. +Underneath both layers, the Go packages carry conventional unit tests for the pure logic: version calculation, change detection, changelog assembly, manifest parsing and validation. These run on every build and are the fastest feedback loop. ## The reconcile gate: why a green fleet means something -A live suite that dispatches runs and walks away would prove nothing - a fire-and-forget run could fail silently and the suite would still pass. The reconcile gate closes that hole and is what makes fleet coverage trustworthy. +A live suite that dispatches runs and walks away would prove nothing, because a fire-and-forget run could fail silently and the suite would still pass. The reconcile gate closes that hole and is what makes fleet coverage trustworthy. -Every run a suite causes - both runs it dispatches and side-effect runs it triggers, such as a `pull_request: closed` finalize - is registered through the `register-run` action with the conclusion it is expected to reach. That includes **registered negatives**: a guard that must refuse, such as a divergence-promote block, is registered with an expected conclusion of `failure`, so a guard that silently stops refusing is caught. +Every run a suite causes is registered through the `register-run` action with the conclusion it is expected to reach. That covers both runs it dispatches and side-effect runs it triggers, such as a `pull_request: closed` finalize. It also includes **registered negatives**: a guard that must refuse, such as a divergence-promote block, is registered with an expected conclusion of `failure`, so a guard that silently stops refusing is caught. At the end of a suite, a fail-closed reconcile job (`fleet-reconcile.yaml`) enumerates every run the repository produced in the scenario window and fails if any run is in the window but missing from the suite's ledger, or reached a conclusion other than the one registered. The gate is deliberately fail-closed: a ledger that merely failed to download is treated as a failure rather than as "no registered runs", so an expected-failure run can never slip through as benign. @@ -65,17 +65,17 @@ The `no-environment` library shape is covered today in the act plus gitea harnes Cascade does not claim full live coverage of every feature. It claims full coverage across the layers, with a documented ceiling. - **Features run live in the fleet** wherever they are live-drivable: real releases, promotion chains, hotfix and rollback flows, cross-repo coordination, and state writes. -- **Features are asserted in the act plus gitea harness** when they are about emitted structure, or when a live suite cannot synthesize the condition on demand - a merge-queue lane without a configured queue, a commit guaranteed to break, a concurrent state-write race. +- **Features are asserted in the act plus gitea harness** when they are about emitted structure, or when a live suite cannot synthesize the condition on demand, such as a merge-queue lane without a configured queue, a commit guaranteed to break, or a concurrent state-write race. - **Pure logic is covered by unit tests.** ### The real-GitHub platform ceiling Some behavior depends on GitHub platform features and real cloud outcomes that neither layer fakes. These are validated by design and inspection rather than by execution, and that is a deliberate, honest boundary: -- **GitHub Environment protection** - required reviewers and wait timers. These are account-level protection rules, not generated YAML. Cascade emits the `environment:` reference; whether an approval gate fires is GitHub enforcing your configured rule. +- **GitHub Environment protection** covers required reviewers and wait timers. These are account-level protection rules, not generated YAML. Cascade emits the `environment:` reference; whether an approval gate fires is GitHub enforcing your configured rule. - **Native Deployments API objects.** The deployment create, in-progress, and status calls are asserted at the emission level; the resulting Deployment objects are GitHub-side. - **The Verified signed-commit badge.** Cascade can drive a signed state commit, but the Verified badge is awarded by GitHub against your key, not something a local runner can produce. - **GitHub App token minting.** The release-token and state-token app-mint steps are guarded to the real platform and asserted at emission; an installation token can only be minted against github.com. - **Real cloud deploy outcomes.** Cascade orchestrates your build and deploy callbacks; what those callbacks do against your cloud is yours to test. -For each of these, cascade asserts the part it owns - the generated workflow structure and the orchestration around the call - and treats the platform-enforced outcome as a contract validated by review, because executing it would require faking the platform rather than testing cascade. +For each of these, cascade asserts the part it owns: the generated workflow structure and the orchestration around the call. It treats the platform-enforced outcome as a contract validated by review, because executing it would require faking the platform rather than testing cascade.