diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1057631..d2673b9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,7 +65,7 @@ A new adapter family is the same check from the other side: every service needs | Change | Reaches an existing project | | --- | --- | | `common/` or an adapter | When someone runs `scaffold update` in it ([ADR-0023](docs/decisions/0023-a-project-records-what-generated-it.md)) | -| A reusable workflow in *you/.github* | On its next run, once `v1` moves (ADR-0005) | +| A reusable workflow in *you/.github* | On its next run, once `v1` moves ([ADR-0005](docs/decisions/0005-share-ci-through-reusable-workflows.md)) | ## Commits and versions diff --git a/README.md b/README.md index da49bc8..200bd6f 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ A database or cache is a directory under `services/`, not an adapter ([ADR-0019] | `--db` | `mysql`, `postgres`, `mongodb`, `none` | `mysql` with `--api` or `--app`, otherwise `none` ([ADR-0020](docs/decisions/0020-database-default-is-derived-from-requested-adapters.md)) | | `--cache` | `redis`, `none` | `none` | -No DynamoDB: `compose.yaml` ships with every release for a client to run (ADR-0014), and the only DynamoDB that fits a compose file is an emulator with no production counterpart. +No DynamoDB: `compose.yaml` ships with every release for a client to run ([ADR-0014](docs/decisions/0014-deployment-deferred-with-seams.md)), and the only DynamoDB that fits a compose file is an emulator with no production counterpart. ## Documentation diff --git a/docs/README.md b/docs/README.md index 5592943..e11b39d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -94,9 +94,10 @@ Measured on `scaffold new demo --api nestjs --web nextjs --db postgres`: 101 tra | When | Read | | --- | --- | -| Day one | This page, then [01-toolchain](tour/01-toolchain.md) through [03-ci](tour/03-ci.md) | -| First week | [04-guardrails](tour/04-guardrails.md) through [09-wizard](tour/09-wizard.md); ADR-0001, ADR-0003, ADR-0011 | -| On demand | The [runbook](runbook/) that names the situation | +| Day one | This page; [first-project-walkthrough](runbook/first-project-walkthrough.md); [01-toolchain](tour/01-toolchain.md), [02-task-contract](tour/02-task-contract.md), [03-ci](tour/03-ci.md) | +| First week | [04-guardrails](tour/04-guardrails.md), [05-release](tour/05-release.md), [06-docs-site](tour/06-docs-site.md), [07-containers](tour/07-containers.md), [08-adapters](tour/08-adapters.md), [09-wizard](tour/09-wizard.md); [ADR-0001](decisions/0001-use-mise-tasks-as-the-task-runner.md), [ADR-0003](decisions/0003-adapter-overlay-instead-of-vendored-presets.md), [ADR-0011](decisions/0011-task-contract-names-follow-immich.md) | +| On demand | The runbook that names the situation: [add-an-adapter](runbook/add-an-adapter.md), [bump-a-toolchain-version](runbook/bump-a-toolchain-version.md), [ci-is-red](runbook/ci-is-red.md), [cut-a-release](runbook/cut-a-release.md), [publish-a-project](runbook/publish-a-project.md), [rotate-a-leaked-secret](runbook/rotate-a-leaked-secret.md), [sync-with-upstream-immich](runbook/sync-with-upstream-immich.md), [update-a-project](runbook/update-a-project.md) | +| Why a choice was made | [decisions/](decisions/); where borrowed code came from: [PROVENANCE](PROVENANCE.md) | | Before a project's first push | [publish-a-project](runbook/publish-a-project.md) | | When the toolbox changed under an existing project | [update-a-project](runbook/update-a-project.md) | diff --git a/docs/runbook/ci-is-red.md b/docs/runbook/ci-is-red.md index c02d593..39d9733 100644 --- a/docs/runbook/ci-is-red.md +++ b/docs/runbook/ci-is-red.md @@ -7,7 +7,7 @@ When: a check is red on a generated project or on this toolbox. 1. Read the failing job's name and find it in the tables below. 2. Reproduce with the command in the table, on a clean clone. 3. Fix the cause in the file the task names: the app's `mise.toml`, the source file, the test. Do not edit the workflow to hide what the task caught. -4. Before calling it done, ask what else reaches the code you changed. A fix checked only against the one repro that prompted it has missed adjacent paths four times in this project's history. +4. Before calling it done, ask what else reaches the code you changed. ### A generated project diff --git a/docs/runbook/publish-a-project.md b/docs/runbook/publish-a-project.md index 7e7a7ea..abf809d 100644 --- a/docs/runbook/publish-a-project.md +++ b/docs/runbook/publish-a-project.md @@ -47,7 +47,7 @@ When: a project from `scaffold new` has no GitHub repository yet, or its reposit | Create `/` and push `main` | `create_repo` | `cmd_publish`: skipped when the repository exists | | Allow Actions to open pull requests | `allow_actions_to_open_pull_requests` | Never skipped | | Secret scanning and push protection | `enable_secret_scanning` | `apply_repo_settings`: warns when the plan lacks it | -| Ruleset `main`: pull request required, no force-push, no deletion | `protect_main` | `protect_main_branch`: skipped on `--no-protect` or an existing ruleset named `main` (`main_is_protected`); warns when the plan lacks it | +| Ruleset `main`: pull request required, no force-push, no deletion | `protect_main` | `apply_repo_settings`: skipped on `--no-protect`. `protect_main_branch`: skipped when a ruleset named `main` exists (`main_is_protected`); warns when the plan lacks it | | Set `RELEASE_APP_ID` and `RELEASE_APP_PRIVATE_KEY` | `set_release_secrets` | `apply_repo_settings`: warns when either variable is unset | `/` is read from `[vars] image` in the project's `mise.toml` (`repo_slug`). There is no flag to change it. diff --git a/docs/tour/03-ci.md b/docs/tour/03-ci.md index 8c8c932..ce061fe 100644 --- a/docs/tour/03-ci.md +++ b/docs/tour/03-ci.md @@ -14,7 +14,7 @@ | `common/.github/workflows/ci.yml` | The whole call site: `uses:` plus `roots:` | | `lib/manifest.sh` | `config_roots` and `sync_ci_roots` | | `.github/workflows/ci.yml` | The toolbox's own CI | -| `docs/runbook/ci-is-red.md` | What a red job means | +| [`docs/runbook/ci-is-red.md`](../runbook/ci-is-red.md) | What a red job means | ## Delete test diff --git a/lib/publish.sh b/lib/publish.sh index bee2c24..650fda2 100644 --- a/lib/publish.sh +++ b/lib/publish.sh @@ -45,7 +45,7 @@ main_is_protected() { grep -qx main <<<"$rulesets" } -# ADR-0004. No required status checks: their names (`ci (apps/api)`) differ per +# ADR-0024. No required status checks: their names (`ci (apps/api)`) differ per # project and change with every application added. A free account's private # repository answers 403 "Upgrade to GitHub Pro". protect_main() { diff --git a/lib/update.sh b/lib/update.sh index 53eb7c2..9c4b001 100644 --- a/lib/update.sh +++ b/lib/update.sh @@ -135,9 +135,9 @@ update_patch() { } # The CI matrix and build targets are computed, so the patch brings their -# template form (`roots: '[]'`, `images: "[]"`), which builds nothing. Re-derived -# rather than excluded, which would drop every other change to those files; and -# only when empty, so correct targets are never rewritten. +# template form (`roots: '["docs"]'`, `images: "[]"`), which covers no app. +# Re-derived rather than excluded, which would drop every other change to those +# files; images only when empty, so correct targets are never rewritten. resync_derived_files() { local -r project="$1" local rel diff --git a/scaffold b/scaffold index ca42691..67e3977 100755 --- a/scaffold +++ b/scaffold @@ -46,10 +46,11 @@ usage: [--db ] [--cache ] scaffold add --adapter scaffold update [dir] [--dry-run] - scaffold publish [dir] [--public] [--no-protect] [--dry-run] + scaffold publish [dir] [--public | --private] [--no-protect] [--dry-run] scaffold list [--adapters] [--services] scaffold lint - scaffold --version + scaffold -h, --help + scaffold -v, --version EOF } @@ -678,7 +679,7 @@ protect_main_branch() { protect_main "$slug" || status=$? case "$status" in 0) log "protected main: pull request required, no force-push, no deletion" ;; - "$PUBLISH_UNSUPPORTED") warn "main is unprotected: this account's plan does not allow rulesets on a private repository. Make it public, or upgrade, then run this again — ADR-0004 counts branch protection as one of four guardrails, and it is the only one that is not a file" ;; + "$PUBLISH_UNSUPPORTED") warn "main is unprotected: this account's plan does not allow rulesets on a private repository. Make it public, or upgrade, then run this again — branch protection is the only guardrail that is not a file (ADR-0024)" ;; *) die "could not protect main on ${slug}" ;; esac } diff --git a/tests/publish.bats b/tests/publish.bats index 99605b1..20afee3 100644 --- a/tests/publish.bats +++ b/tests/publish.bats @@ -223,7 +223,7 @@ _project() { GH_SCENARIO=plan-limit run scaffold publish "$PROJECT" assert_ok [[ "$output" == *"main is unprotected"* ]] - [[ "$output" == *"ADR-0004"* ]] + [[ "$output" == *"ADR-0024"* ]] } @test "--no-protect asks nothing about rulesets" {