@davidvornholt/standards 0.9.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -4
- package/package.json +12 -2
- package/src/cli.ts +224 -187
- package/src/dependabot-compose-input.ts +136 -0
- package/src/dependabot-compose.ts +188 -0
- package/src/dependabot-inspect.ts +181 -0
- package/src/dependabot-update.ts +156 -0
- package/src/github-api.ts +47 -0
- package/src/github-apply.ts +20 -4
- package/src/github-command-shared.ts +36 -2
- package/src/github-commands.ts +12 -78
- package/src/github-diff.ts +5 -5
- package/src/github-live-drift.ts +99 -0
- package/src/github-settings-parse.ts +3 -0
- package/src/structure-profile.ts +2 -0
- package/src/yaml-emit.ts +67 -0
- package/src/yaml-parse.ts +25 -0
package/README.md
CHANGED
|
@@ -8,20 +8,25 @@ standards sync
|
|
|
8
8
|
standards check
|
|
9
9
|
standards doctor
|
|
10
10
|
standards structure
|
|
11
|
+
standards dependabot --check
|
|
12
|
+
standards dependabot --write
|
|
11
13
|
standards github --check
|
|
12
14
|
standards github --apply
|
|
13
15
|
```
|
|
14
16
|
|
|
15
|
-
`
|
|
17
|
+
`dependabot --write` regenerates the composed `.github/dependabot.yml` from the canonical `.github/dependabot.base.yml` and the optional repo-owned `.github/dependabot.local.yml`; `init` and `sync` do the same automatically. `dependabot --check` verifies the generated file still matches its sources, and `doctor`/`check` include the same verification. The overlay is deliberately lean and additive only: new update blocks for repo-specific ecosystems, top-level private registry definitions, and `ignore` or `registries` entries appended by repeating a canonical block's normalized target. Matching blocks cannot add labels, groups, cooldowns, pull-request limits, or other policy.
|
|
18
|
+
|
|
19
|
+
`github --check` compares the live GitHub repository (merge settings and rulesets) against the merged declaration in `.github/settings.json` + `.github/settings.local.json`; `github --apply` converges the live repository to exactly the declared state. `check` runs the same comparison whenever `.github/settings.json` is present, and fails closed: declared state the token cannot see fails the gate with a message naming the token fix instead of passing unverified. `--apply` re-diffs the PATCH response, so a setting GitHub accepts with HTTP 200 but silently ignores (plan-unavailable features) is a reported failure, not a false success. A repository whose GitHub plan cannot enforce rulesets can declare that in the seam (see `rulesetEnforcement` below); both commands then skip rulesets and plan-gated repository settings, converge the rest, and print an unprotected-branch notice on every run.
|
|
16
20
|
|
|
17
21
|
`structure` enforces the canonical monorepo structure contract: workspace scripts (`check-types`, `lint`, `lint:fix`, `test`), root gate scripts, filtered Turbo convenience aliases, internal `0.0.0`/`workspace:*` versioning, package `exports`, shared tsconfig inheritance, and browser a11y wiring. Only a workspace containing an explicit `*.a11y.ts` suite must provide a `test:a11y` script and direct `@axe-core/playwright` and `@playwright/test` dependencies. `check` includes `structure`, so these rules gate every consumer PR.
|
|
18
22
|
|
|
19
|
-
`structure --profile source` validates the standards source repository itself, which is deliberately not a consumer. The profile pins its intentional exceptions so they cannot drift silently: exact, ordered root gate scripts that run this CLI from the local checkout (`structure --profile source`, `github --check`, and the Turbo gate) instead of a recursive `standards check`, and a non-private published bin-only CLI workspace that carries a stable release SemVer and exactly maps the `standards` bin to `src/cli.ts` without `exports`. Every other consumer rule still applies.
|
|
23
|
+
`structure --profile source` validates the standards source repository itself, which is deliberately not a consumer. The profile pins its intentional exceptions so they cannot drift silently: exact, ordered root gate scripts that run this CLI from the local checkout (`structure --profile source`, `dependabot --check` or `dependabot --write`, `github --check`, and the Turbo gate) instead of a recursive `standards check`, and a non-private published bin-only CLI workspace that carries a stable release SemVer and exactly maps the `standards` bin to `src/cli.ts` without `exports`. Every other consumer rule still applies.
|
|
20
24
|
|
|
21
25
|
## Configuration
|
|
22
26
|
|
|
27
|
+
- **`.github/dependabot.local.yml`** (optional) — repo-owned Dependabot extension composed with the canonical `.github/dependabot.base.yml` into the generated `.github/dependabot.yml`. May define `updates` and top-level `registries`; a block matching a canonical normalized target may only add `ignore` and/or `registries` entries. Other matching-block policy is rejected deliberately. A missing or comments-only file means no additions. CLI 0.10.1 requires the selected content ref to contain the canonical base and rejects older refs before mutation.
|
|
23
28
|
- **`sync-standards.local.json`** (optional) — consumer-owned sync policy at the repo root, validated by `doctor`/`check` and every `init`/`sync` even when an explicit ref or local source makes its `"ref"` irrelevant. All fields optional; a missing file means the defaults. `"ref"` is a non-empty single-line string that pins a tag, branch, or full commit sha to sync from instead of `main` (an explicit `--ref` overrides it; a local-path `--from` source is used as-is and ignores only the validated pin). `"autoSync": false` is read by the standards-sync workflow, not the CLI, and skips the weekly scheduled run. Version 0.7.0 removes the legacy `STANDARDS_AUTO_SYNC` and `STANDARDS_SYNC_REF` variable behavior; consumers must upgrade the package and lockfile before adopting a policy file.
|
|
24
|
-
- **`.github/settings.local.json` `"rulesetEnforcement": "unavailable-on-plan"`** (optional) — declares that the repository's GitHub plan cannot enforce rulesets (private repositories on GitHub Free, both personal accounts and organizations). `github --check` and `--apply` then skip rulesets instead of comparing them, because a comparison cannot be trusted there: personal accounts answer ruleset reads with HTTP 403, and free-plan organizations report declared rulesets as active while silently not enforcing them.
|
|
25
|
-
- **`GH_TOKEN` / `GITHUB_TOKEN`** (optional) — GitHub API token for the `github` command and the GitHub portion of `check`. When neither is set, the token from the local `gh` CLI is used; with no token at all, reads still work on public repositories. `--apply`
|
|
29
|
+
- **`.github/settings.local.json` `"rulesetEnforcement": "unavailable-on-plan"`** (optional) — declares that the repository's GitHub plan cannot enforce rulesets (private repositories on GitHub Free, both personal accounts and organizations). `github --check` and `--apply` then skip rulesets instead of comparing them, because a comparison cannot be trusted there: personal accounts answer ruleset reads with HTTP 403, and free-plan organizations report declared rulesets as active while silently not enforcing them. Plan-gated repository settings that only function alongside branch protection (`allow_auto_merge`) are skipped for the same reason — GitHub accepts a PATCH for them with HTTP 200 and silently keeps the old value. The remaining repository merge settings are still checked and converged, and both commands print an unprotected-branch notice on every run. The only accepted value is `"unavailable-on-plan"` (enforcement is the default; omit the key on paid plans), and combining the opt-out with additional local rulesets is rejected. After upgrading the plan, remove the declaration and run `bun standards github --apply` to restore enforcement.
|
|
30
|
+
- **`GH_TOKEN` / `GITHUB_TOKEN`** (optional) — GitHub API token for the `github` command and the GitHub portion of `check`. When neither is set, the token from the local `gh` CLI is used; with no token at all, reads still work on public repositories. `--apply` needs an admin token. GitHub's REST API reveals repo merge settings only to write-capable viewers — `check` retries REST-hidden keys over GraphQL, which serves them to read-only tokens — and ruleset `bypass_actors` requires repository Administration read; a token that still cannot see declared state fails the check rather than passing unverified. In CI, where the workflow token can never hold that permission, the canonical workflow decrypts `ci.github_settings_read_token` from the SOPS-encrypted `secrets/ci.yaml` — a fine-grained PAT with read-only "Administration" access to the repository.
|
|
26
31
|
|
|
27
32
|
See the standards repository README for the ownership model and adoption workflow.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@davidvornholt/standards",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Bootstrap, synchronize, and validate davidvornholt/standards consumers",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -20,17 +20,24 @@
|
|
|
20
20
|
"LICENSE",
|
|
21
21
|
"README.md",
|
|
22
22
|
"src/cli.ts",
|
|
23
|
+
"src/dependabot-compose-input.ts",
|
|
24
|
+
"src/dependabot-compose.ts",
|
|
25
|
+
"src/dependabot-inspect.ts",
|
|
26
|
+
"src/dependabot-update.ts",
|
|
23
27
|
"src/github-api.ts",
|
|
24
28
|
"src/github-apply.ts",
|
|
25
29
|
"src/github-command-shared.ts",
|
|
26
30
|
"src/github-commands.ts",
|
|
27
31
|
"src/github-diff.ts",
|
|
32
|
+
"src/github-live-drift.ts",
|
|
28
33
|
"src/github-settings-parse.ts",
|
|
29
34
|
"src/github-settings.ts",
|
|
30
35
|
"src/structure-check.ts",
|
|
31
36
|
"src/structure-profile.ts",
|
|
32
37
|
"src/structure-script.ts",
|
|
33
|
-
"src/structure-workspace.ts"
|
|
38
|
+
"src/structure-workspace.ts",
|
|
39
|
+
"src/yaml-emit.ts",
|
|
40
|
+
"src/yaml-parse.ts"
|
|
34
41
|
],
|
|
35
42
|
"scripts": {
|
|
36
43
|
"lint": "biome check --error-on-warnings .",
|
|
@@ -48,5 +55,8 @@
|
|
|
48
55
|
},
|
|
49
56
|
"publishConfig": {
|
|
50
57
|
"access": "public"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"yaml": "^2.9.0"
|
|
51
61
|
}
|
|
52
62
|
}
|