@theholocron/astromech 5.0.0-alpha.12 → 5.0.0-alpha.120

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 CHANGED
@@ -33,7 +33,7 @@ const report = astromech.run("verification.unitTests", { passthrough: ["--watch"
33
33
  `holocron run verification.unitTests` runs your tests — you don't tell it
34
34
  turbo vs pnpm vs npm, or which runner:
35
35
 
36
- ```
36
+ ```text
37
37
  1. turbo.json defines the task → turbo run <task>
38
38
  2. package.json has a <task> script → <detected pm> run <task>
39
39
  (a "holocron run …" thin caller is skipped — no recursion)
@@ -53,28 +53,28 @@ what it actually runs, and why. Tool names never appear in
53
53
  `holocron.config.ts` — they're an implementation detail this table
54
54
  documents, not a naming convention repos need to follow.
55
55
 
56
- | Task | Runs | Notes |
57
- | ---------------------------------------- | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
58
- | `verification.unitTests` | vitest | carries the `--coverage` org default |
59
- | `verification.typeSafety` | tsc | `tsc --noEmit` |
60
- | `verification.performance` | Lighthouse CI | only runs with a `lighthouse.config.*` present |
61
- | `sourceQuality.staticAnalysis` | eslint, actionlint, git-merge-conflict-markers | a `linterGroup` — see below |
62
- | `sourceQuality.formatting` | prettier, editorconfig-checker, markdownlint-cli2 | a `linterGroup` |
63
- | `sourceQuality.structuredDataValidation` | yamllint | |
64
- | `sourceQuality.deadCodeAnalysis` | knip | |
65
- | `security.secretDetection` | gitleaks | |
66
- | `security.codeScanning` | CodeQL | no local equivalent — CI only |
67
- | `security.dependencyReview` | GitHub's native Dependabot alerts/graph | a capability-model method (`Source.enableVulnerabilityAlerts()`), not a task |
68
- | `delivery.build` | tsdown / vite / rollup / tsc, detected from the repo's own config file | |
69
- | `delivery.publish` | semantic-release | no local equivalent — CI only; carries `preview` (npm dist-tags) |
70
- | `delivery.deploy` | Cloudflare Pages / Vercel | no local equivalent — CI only; carries `preview` |
71
- | `delivery.bundleSize` | bundle-size upload to Codecov | no local equivalent — CI only |
72
- | `platform.repoSync` | `holocron sync` | keeps generated files current |
73
- | `platform.commitStandards` | commitlint | no local equivalent — enforced by the `commit-msg` hook locally, over the PR's commit range in CI |
74
- | `platform.repoValidation` | `scripts/validate-adrs.mjs`, `scripts/validate-registry.mjs`, `scripts/validate-docs-presence.mjs` | a job-bearing task — spec/ADR frontmatter, registry-doc completeness, and docs-presence, not linters |
75
- | `knowledge.wiki` | Fern | publishes `docs/wiki/*.md` — not a sync, a publish; carries `preview` |
76
- | `knowledge.docs` | Astro build | the docs site itself; carries `preview` (defaults on) |
77
- | `knowledge.components` | Storybook build | a browsable component catalog — "Storybook" is the tool, not the intent; carries `preview` (defaults on) |
56
+ | Task | Runs | Notes |
57
+ | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
58
+ | `verification.unitTests` | vitest | carries the `--coverage` org default |
59
+ | `verification.typeSafety` | tsc | `tsc --noEmit` |
60
+ | `verification.performance` | Lighthouse CI | only runs with a `lighthouse.config.*` present |
61
+ | `sourceQuality.staticAnalysis` | eslint, actionlint, git-merge-conflict-markers | a `linterGroup` — see below |
62
+ | `sourceQuality.formatting` | prettier, editorconfig-checker, markdownlint-cli2 | a `linterGroup` |
63
+ | `sourceQuality.structuredDataValidation` | yamllint | |
64
+ | `sourceQuality.deadCodeAnalysis` | knip | |
65
+ | `security.secretDetection` | gitleaks | |
66
+ | `security.codeScanning` | CodeQL | no local equivalent — CI only |
67
+ | `security.dependencyReview` | GitHub's native Dependabot alerts/graph | a capability-model method (`Source.enableVulnerabilityAlerts()`), not a task |
68
+ | `delivery.build` | tsdown / vite / rollup / tsc, detected from the repo's own config file, or `package.json`'s own `dependencies`/`devDependencies` if that config file isn't there | |
69
+ | `delivery.publish` | semantic-release | no local equivalent — CI only; carries `preview` (npm dist-tags) |
70
+ | `delivery.deploy` | Cloudflare Pages / Vercel | no local equivalent — CI only; carries `preview` |
71
+ | `delivery.bundleSize` | bundle-size upload to Codecov | no local equivalent — CI only |
72
+ | `platform.repoSync` | `holocron sync` | keeps generated files current |
73
+ | `platform.commitStandards` | commitlint | no local equivalent — enforced by the `commit-msg` hook locally, over the PR's commit range in CI |
74
+ | `platform.repoValidation` | `scripts/validate-adrs.mjs`, `scripts/validate-registry.mjs`, `scripts/validate-docs-presence.mjs` | a job-bearing task — spec/ADR frontmatter, registry-doc completeness, and docs-presence, not linters |
75
+ | `knowledge.wiki` | Fern | publishes `docs/wiki/*.md` — not a sync, a publish; carries `preview` |
76
+ | `knowledge.docs` | Astro build | the docs site itself; carries `preview` (defaults on) |
77
+ | `knowledge.components` | Storybook build | a browsable component catalog — "Storybook" is the tool, not the intent; carries `preview` (defaults on) |
78
78
 
79
79
  **`preview` is a cross-cutting feature, not a namespace.** npm has staging
80
80
  dist-tags, Cloudflare/Vercel do per-PR preview deploys, Fern previews
@@ -83,10 +83,12 @@ publish/deploy-shaped task can carry, toggled via that task's `with:`.
83
83
 
84
84
  **`linterGroup` tasks** (`sourceQuality.staticAnalysis`,
85
85
  `sourceQuality.formatting`) bundle more than one tool under a single
86
- required check. Each tool is still gated by its own detection rule (e.g.
87
- `eslint` only runs if `eslint.config.*` is present) — the
86
+ required check. Each tool is still gated by its own detection rule — e.g.
87
+ `eslint` runs when either a local `eslint.config.*` is present, or the
88
+ package has no local file but `@theholocron/eslint-config` resolves
89
+ (the same shared-config splice the `tool`/`detect` runner path uses) — the
88
90
  `tool name → detection rule → local binary` mapping lives in one place,
89
- `src/linters.ts`. A repo's choice of which of these run is just which
91
+ `src/linters.ts`. A repo's choice of which of these run is based on which
90
92
  tasks it includes in `tasks: [...]`, same as any other task.
91
93
 
92
94
  **No super-linter.** Each task above runs its own tool directly, through
@@ -116,6 +118,9 @@ export default defineConfig({
116
118
  `loadTasksConfig(cwd)` resolves the manifest: the `tasks` key of
117
119
  `holocron.config.*` (a bare item array), then a dedicated
118
120
  `astromech.config.*` merged on top (dedicated wins; arrays concatenate).
121
+ `mergeTasksLayers(parentTasks, dedicated)` is that merge step on its own,
122
+ for callers that load the two sources some other way (Sentinel reads them
123
+ through the GitHub API).
119
124
 
120
125
  | `TaskEntry` field | Effect |
121
126
  | ------------------------ | ----------------------------------------------------------- |
@@ -187,6 +192,27 @@ template. `holocron setup` writes the result via the `source` capability;
187
192
  this method never touches the filesystem beyond reading `packages/*` and
188
193
  `apps/*` under `cwd`.
189
194
 
195
+ ## Release-time deploys — `deployOnRelease`
196
+
197
+ Deploys the workspace packages whose manifest declares it (holocron#930):
198
+
199
+ ```ts
200
+ // packages/<app>/holocron.config.ts
201
+ tasks: [{ name: "delivery.deploy", with: { on: "release", channel: "alpha" } }];
202
+ ```
203
+
204
+ `holocron deploy-on-release --channel=<alpha|main> --from=<previous release commit> --to=<release commit>`
205
+ (or `deployOnRelease()` from `@theholocron/astromech`) deploys each such package
206
+ when the release is on its `channel` (default `main`, the stable release;
207
+ set `alpha` for prereleases) and changes the package or one of its `workspace:*` dependencies
208
+ (`with.paths` overrides that), once npm serves the release's new dependency
209
+ versions, by running `pnpm --filter <package> delivery.deploy`. A package
210
+ that doesn't apply to the release is skipped; a deploy that fails exits
211
+ non-zero. The shared `delivery.publish` workflow runs it as a separate `deploy`
212
+ job after the release job (opt in with `deploy-on-release: true`), so a deploy
213
+ is its own re-runnable check. A `delivery.deploy` task with `on: "release"`
214
+ generates no workflow.
215
+
190
216
  ## Development
191
217
 
192
218
  | Script | Description |
@@ -14,12 +14,31 @@ import { i as normalizeTaskEntry, n as TaskEntry, r as TasksConfig, t as TaskCon
14
14
  declare const defineConfig: <C extends TasksConfig>(config: C) => C;
15
15
  //#endregion
16
16
  //#region src/config/load.d.ts
17
+ /**
18
+ * The `tasks` value in each source. A dedicated `astromech.config.*`
19
+ * default-exports the full {@link TasksConfig} object; the `tasks` key of
20
+ * `holocron.config.*` is the bare item array (it mirrors the old
21
+ * `workflows` key). Either form is accepted from either source.
22
+ */
23
+ type TasksInput = TasksConfig | TaskConfigItem[];
17
24
  /**
18
25
  * Resolve the task manifest for a repo: the `tasks` key of
19
26
  * `holocron.config.*`, then a dedicated `astromech.config.*` merged on
20
27
  * top (dedicated wins; item arrays concatenate). Returns `{}` when
21
28
  * neither source is present.
29
+ *
30
+ * `walkUp: true` — `holocron run`/`ci` are usable from any subdirectory of
31
+ * a repo, not only its exact root (datapad walks up to the nearest `.git`
32
+ * boundary; see `@theholocron/datapad`'s own doc comment).
22
33
  */
23
34
  declare function loadTasksConfig(cwd: string): Promise<TasksConfig>;
35
+ /**
36
+ * The merge step of {@link loadTasksConfig}, for callers that load the two
37
+ * sources some other way (Sentinel reads them from the GitHub API, not
38
+ * from disk, holocron#916): `holocron.config.*`'s `tasks` value first,
39
+ * then a dedicated `astromech.config.*`'s default export merged on top.
40
+ * Either may be `undefined` (source absent); returns `{}` when both are.
41
+ */
42
+ declare function mergeTasksLayers(parentTasks: TasksInput | undefined, dedicated: TasksInput | undefined): TasksConfig;
24
43
  //#endregion
25
- export { type TaskConfigItem, type TaskEntry, type TasksConfig, defineConfig, loadTasksConfig, normalizeTaskEntry };
44
+ export { type TaskConfigItem, type TaskEntry, type TasksConfig, defineConfig, loadTasksConfig, mergeTasksLayers, normalizeTaskEntry };
@@ -1,5 +1,5 @@
1
- import { t as normalizeTaskEntry } from "../schema-Cf5dfaDO.mjs";
2
- import { createDefineConfig, loadConfigFile, mergeConfig } from "@theholocron/datapad";
1
+ import { n as mergeTasksLayers, r as normalizeTaskEntry, t as loadTasksConfig } from "../load-ytspboBj.mjs";
2
+ import { createDefineConfig } from "@theholocron/datapad";
3
3
  //#region src/config/define.ts
4
4
  /**
5
5
  * Typed identity helper for `astromech.config.ts`:
@@ -14,26 +14,4 @@ import { createDefineConfig, loadConfigFile, mergeConfig } from "@theholocron/da
14
14
  */
15
15
  const defineConfig = createDefineConfig();
16
16
  //#endregion
17
- //#region src/config/load.ts
18
- /**
19
- * Resolve the task manifest for a repo: the `tasks` key of
20
- * `holocron.config.*`, then a dedicated `astromech.config.*` merged on
21
- * top (dedicated wins; item arrays concatenate). Returns `{}` when
22
- * neither source is present.
23
- */
24
- async function loadTasksConfig(cwd) {
25
- const dedicated = await loadConfigFile({
26
- cwd,
27
- name: "astromech"
28
- });
29
- return [coerce((await loadConfigFile({
30
- cwd,
31
- name: "holocron"
32
- }))?.config.tasks), coerce(dedicated?.config)].filter((layer) => layer !== void 0).reduce((acc, layer) => mergeConfig(acc, layer), {});
33
- }
34
- function coerce(value) {
35
- if (value == null) return void 0;
36
- return Array.isArray(value) ? { tasks: value } : value;
37
- }
38
- //#endregion
39
- export { defineConfig, loadTasksConfig, normalizeTaskEntry };
17
+ export { defineConfig, loadTasksConfig, mergeTasksLayers, normalizeTaskEntry };