@mannyc1/ts-release 0.0.0
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 +249 -0
- package/SPEC.md +254 -0
- package/dist/cli/command.d.ts +4 -0
- package/dist/cli/command.d.ts.map +1 -0
- package/dist/cli/command.js +90 -0
- package/dist/cli/command.js.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +12 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/programmatic.d.ts +25 -0
- package/dist/cli/programmatic.d.ts.map +1 -0
- package/dist/cli/programmatic.js +48 -0
- package/dist/cli/programmatic.js.map +1 -0
- package/dist/config/errors.d.ts +23 -0
- package/dist/config/errors.d.ts.map +1 -0
- package/dist/config/errors.js +18 -0
- package/dist/config/errors.js.map +1 -0
- package/dist/config/load.d.ts +9 -0
- package/dist/config/load.d.ts.map +1 -0
- package/dist/config/load.js +27 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/schema.d.ts +8 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +6 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/domain/artifact.d.ts +36 -0
- package/dist/domain/artifact.d.ts.map +1 -0
- package/dist/domain/artifact.js +29 -0
- package/dist/domain/artifact.js.map +1 -0
- package/dist/domain/evidence.d.ts +58 -0
- package/dist/domain/evidence.d.ts.map +1 -0
- package/dist/domain/evidence.js +50 -0
- package/dist/domain/evidence.js.map +1 -0
- package/dist/domain/operation.d.ts +98 -0
- package/dist/domain/operation.d.ts.map +1 -0
- package/dist/domain/operation.js +133 -0
- package/dist/domain/operation.js.map +1 -0
- package/dist/domain/release.d.ts +66 -0
- package/dist/domain/release.d.ts.map +1 -0
- package/dist/domain/release.js +56 -0
- package/dist/domain/release.js.map +1 -0
- package/dist/domain/target.d.ts +75 -0
- package/dist/domain/target.d.ts.map +1 -0
- package/dist/domain/target.js +67 -0
- package/dist/domain/target.js.map +1 -0
- package/dist/host/bun.d.ts +9 -0
- package/dist/host/bun.d.ts.map +1 -0
- package/dist/host/bun.js +156 -0
- package/dist/host/bun.js.map +1 -0
- package/dist/host/host.d.ts +47 -0
- package/dist/host/host.d.ts.map +1 -0
- package/dist/host/host.js +42 -0
- package/dist/host/host.js.map +1 -0
- package/dist/host/test.d.ts +19 -0
- package/dist/host/test.d.ts.map +1 -0
- package/dist/host/test.js +76 -0
- package/dist/host/test.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/planner/create-release-plan.d.ts +5 -0
- package/dist/planner/create-release-plan.d.ts.map +1 -0
- package/dist/planner/create-release-plan.js +25 -0
- package/dist/planner/create-release-plan.js.map +1 -0
- package/dist/planner/errors.d.ts +37 -0
- package/dist/planner/errors.d.ts.map +1 -0
- package/dist/planner/errors.js +30 -0
- package/dist/planner/errors.js.map +1 -0
- package/dist/planner/evidence-recorder.d.ts +18 -0
- package/dist/planner/evidence-recorder.d.ts.map +1 -0
- package/dist/planner/evidence-recorder.js +95 -0
- package/dist/planner/evidence-recorder.js.map +1 -0
- package/dist/planner/executor.d.ts +19 -0
- package/dist/planner/executor.d.ts.map +1 -0
- package/dist/planner/executor.js +59 -0
- package/dist/planner/executor.js.map +1 -0
- package/dist/planner/normalize-release.d.ts +7 -0
- package/dist/planner/normalize-release.d.ts.map +1 -0
- package/dist/planner/normalize-release.js +101 -0
- package/dist/planner/normalize-release.js.map +1 -0
- package/dist/planner/render-plan.d.ts +5 -0
- package/dist/planner/render-plan.d.ts.map +1 -0
- package/dist/planner/render-plan.js +49 -0
- package/dist/planner/render-plan.js.map +1 -0
- package/dist/targets/adapter.d.ts +15 -0
- package/dist/targets/adapter.d.ts.map +1 -0
- package/dist/targets/adapter.js +2 -0
- package/dist/targets/adapter.js.map +1 -0
- package/dist/targets/github.d.ts +11 -0
- package/dist/targets/github.d.ts.map +1 -0
- package/dist/targets/github.js +174 -0
- package/dist/targets/github.js.map +1 -0
- package/dist/targets/homebrew.d.ts +11 -0
- package/dist/targets/homebrew.d.ts.map +1 -0
- package/dist/targets/homebrew.js +153 -0
- package/dist/targets/homebrew.js.map +1 -0
- package/dist/targets/live.d.ts +5 -0
- package/dist/targets/live.d.ts.map +1 -0
- package/dist/targets/live.js +31 -0
- package/dist/targets/live.js.map +1 -0
- package/dist/targets/npm.d.ts +11 -0
- package/dist/targets/npm.d.ts.map +1 -0
- package/dist/targets/npm.js +105 -0
- package/dist/targets/npm.js.map +1 -0
- package/dist/targets/registry.d.ts +25 -0
- package/dist/targets/registry.d.ts.map +1 -0
- package/dist/targets/registry.js +34 -0
- package/dist/targets/registry.js.map +1 -0
- package/dist/types/effect-internal.d.ts +5 -0
- package/dist/types/effect-internal.d.ts.map +1 -0
- package/dist/types/effect-internal.js +2 -0
- package/dist/types/effect-internal.js.map +1 -0
- package/examples/README.md +15 -0
- package/examples/github-release/artifacts/release-example-github-0.1.0.tgz +1 -0
- package/examples/github-release/release.config.json +31 -0
- package/examples/homebrew-tap/artifacts/release-example-homebrew-0.1.0.tgz +1 -0
- package/examples/homebrew-tap/release.config.json +34 -0
- package/examples/non-strict-skips/artifacts/release-example-skips-0.1.0.tgz +1 -0
- package/examples/non-strict-skips/release.config.json +29 -0
- package/examples/npm-only/index.js +1 -0
- package/examples/npm-only/package.json +8 -0
- package/examples/npm-only/release.config.json +30 -0
- package/package.json +176 -0
package/README.md
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# release
|
|
2
|
+
|
|
3
|
+
`@mannyc1/ts-release` turns release intent into explicit, inspectable, repeatable publishing operations.
|
|
4
|
+
|
|
5
|
+
The default workflow is plan-first:
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
bun run cli plan --config release.config.json --format text
|
|
9
|
+
bun run cli render --config release.config.json --execute
|
|
10
|
+
bun run cli validate --config release.config.json
|
|
11
|
+
bun run cli print --config release.config.json
|
|
12
|
+
bun run cli execute --config release.config.json --execute --approve-irreversible
|
|
13
|
+
bun run cli verify --config release.config.json
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Rendering writes generated target files locally and records `render.json` evidence. Publishing is blocked unless execution is explicitly approved. Irreversible operations require a second approval flag.
|
|
17
|
+
|
|
18
|
+
## Imports
|
|
19
|
+
|
|
20
|
+
The package intentionally avoids aggregate library barrels. The root `release` export is intentionally empty; import the exact module you need from an explicit subpath.
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import * as Effect from "effect/Effect"
|
|
24
|
+
import * as Layer from "effect/Layer"
|
|
25
|
+
import { type ReleaseIntent } from "@mannyc1/ts-release/domain/release"
|
|
26
|
+
import { BunReleaseHostLayer } from "@mannyc1/ts-release/host/bun"
|
|
27
|
+
import { createReleasePlan } from "@mannyc1/ts-release/planner/create-release-plan"
|
|
28
|
+
import { validatePlan } from "@mannyc1/ts-release/planner/executor"
|
|
29
|
+
import { LiveTargetRegistryLayer } from "@mannyc1/ts-release/targets/live"
|
|
30
|
+
|
|
31
|
+
const planAndValidate = (intent: ReleaseIntent) =>
|
|
32
|
+
Effect.gen(function*() {
|
|
33
|
+
const plan = yield* createReleasePlan(intent)
|
|
34
|
+
const evidence = yield* validatePlan(plan)
|
|
35
|
+
return { plan, evidence }
|
|
36
|
+
}).pipe(
|
|
37
|
+
Effect.provide(Layer.mergeAll(BunReleaseHostLayer, LiveTargetRegistryLayer))
|
|
38
|
+
)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`createReleasePlan` needs a `TargetRegistry` layer. Workflows that read files, run commands, or write evidence also need a `ReleaseHost` layer. Internal Effect imports use deep module paths such as `effect/Effect` and `effect/Layer` to keep bundlers from depending on broad root-package analysis.
|
|
42
|
+
|
|
43
|
+
## Programmatic CLI
|
|
44
|
+
|
|
45
|
+
Applications can run the CLI command path without spawning the executable:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import * as Effect from "effect/Effect"
|
|
49
|
+
import {
|
|
50
|
+
PlanReleaseConfigOptions,
|
|
51
|
+
planReleaseConfig,
|
|
52
|
+
ReleaseCliOptions,
|
|
53
|
+
runReleaseCli
|
|
54
|
+
} from "@mannyc1/ts-release/cli/programmatic"
|
|
55
|
+
|
|
56
|
+
await Effect.runPromise(
|
|
57
|
+
runReleaseCli([
|
|
58
|
+
"plan",
|
|
59
|
+
"--config",
|
|
60
|
+
"release.config.json",
|
|
61
|
+
"--format",
|
|
62
|
+
"text"
|
|
63
|
+
], ReleaseCliOptions.make({ root: "/path/to/release-workspace" }))
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
const plan = await Effect.runPromise(
|
|
67
|
+
planReleaseConfig(
|
|
68
|
+
PlanReleaseConfigOptions.make({
|
|
69
|
+
root: "/path/to/release-workspace",
|
|
70
|
+
configPath: "release.config.json"
|
|
71
|
+
})
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The helper provides the Bun host and live target registry internally, so callers do not need to import `effect/unstable/cli/Command` or assemble CLI layers by hand.
|
|
77
|
+
|
|
78
|
+
## Example Config
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"identity": {
|
|
83
|
+
"name": "@mannyc1/ts-release",
|
|
84
|
+
"version": "0.1.0",
|
|
85
|
+
"commit": "abc123",
|
|
86
|
+
"tag": "v0.1.0",
|
|
87
|
+
"notes": "Release notes"
|
|
88
|
+
},
|
|
89
|
+
"artifacts": [
|
|
90
|
+
{
|
|
91
|
+
"id": "package",
|
|
92
|
+
"path": ".",
|
|
93
|
+
"format": "directory",
|
|
94
|
+
"consumers": ["npm"]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "github-asset",
|
|
98
|
+
"path": "artifacts/mannyc1-ts-release-0.1.0.tgz",
|
|
99
|
+
"format": "tarball",
|
|
100
|
+
"consumers": ["github"]
|
|
101
|
+
}
|
|
102
|
+
],
|
|
103
|
+
"targets": [
|
|
104
|
+
{
|
|
105
|
+
"_tag": "NpmRegistryTarget",
|
|
106
|
+
"id": "npm",
|
|
107
|
+
"registry": "https://registry.npmjs.org",
|
|
108
|
+
"packagePath": ".",
|
|
109
|
+
"tokenEnv": "NPM_TOKEN",
|
|
110
|
+
"access": "public",
|
|
111
|
+
"provenance": true,
|
|
112
|
+
"dryRunSupport": "native",
|
|
113
|
+
"mutability": "immutable",
|
|
114
|
+
"recovery": "publish-new-version"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"_tag": "GitHubReleaseTarget",
|
|
118
|
+
"id": "github",
|
|
119
|
+
"repository": "owner/repo",
|
|
120
|
+
"draft": true,
|
|
121
|
+
"dryRunSupport": "native",
|
|
122
|
+
"mutability": "mutable-release",
|
|
123
|
+
"recovery": "delete-and-recreate"
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"strict": true,
|
|
127
|
+
"evidenceDirectory": ".release/evidence"
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Paths are release-workspace relative and may not be absolute or contain parent traversal.
|
|
132
|
+
|
|
133
|
+
Homebrew tap targets model catalog updates as generated files plus an approval-gated push:
|
|
134
|
+
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"_tag": "HomebrewTapTarget",
|
|
138
|
+
"id": "homebrew",
|
|
139
|
+
"repository": "owner/homebrew-tap",
|
|
140
|
+
"formulaName": "release",
|
|
141
|
+
"formulaPath": ".release/generated/release.rb",
|
|
142
|
+
"artifactId": "github-asset",
|
|
143
|
+
"url": "https://github.com/owner/repo/releases/download/v0.1.0/mannyc1-ts-release-0.1.0.tgz",
|
|
144
|
+
"installPath": "bin/release",
|
|
145
|
+
"dryRunSupport": "simulated",
|
|
146
|
+
"mutability": "mutable-index",
|
|
147
|
+
"recovery": "manual"
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Use `plan`, `render --execute`, `validate`, `print`, `execute --execute`, and `verify` so generated formulas are reviewable before any tap update is pushed.
|
|
152
|
+
|
|
153
|
+
## Plan Review
|
|
154
|
+
|
|
155
|
+
Text plans include the release identity, evidence directory, artifact inventory, target capabilities, operation commands, validation notes, and execution gates.
|
|
156
|
+
|
|
157
|
+
```text
|
|
158
|
+
@mannyc1/ts-release@0.1.0
|
|
159
|
+
commit: abc123
|
|
160
|
+
evidence: .release/evidence
|
|
161
|
+
artifacts: 2
|
|
162
|
+
targets: 2
|
|
163
|
+
operations: 13
|
|
164
|
+
|
|
165
|
+
targets:
|
|
166
|
+
- github [GitHubReleaseTarget] auth=cli-auth dry-run=native strategy=simulated-plan mutability=mutable-release recovery=delete-and-recreate
|
|
167
|
+
- npm [NpmRegistryTarget] auth=env-token dry-run=native strategy=native-command mutability=immutable recovery=publish-new-version
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
JSON plans include the same data in a stable, CI-artifact-friendly shape, including `targetCapabilities`.
|
|
171
|
+
|
|
172
|
+
GitHub release verification checks the release tag, title, draft flag, prerelease flag, and each uploaded artifact name.
|
|
173
|
+
|
|
174
|
+
## Public API
|
|
175
|
+
|
|
176
|
+
The intentional public API is the explicit subpath list in `package.json`. `release/cli` and `release/cli/command` are public so applications can embed the CLI command, while the executable remains available through the `release` binary.
|
|
177
|
+
|
|
178
|
+
The package export checker fails if a new export is added without being added to the intentional API list.
|
|
179
|
+
|
|
180
|
+
## Examples
|
|
181
|
+
|
|
182
|
+
Runnable example configs live in `examples/`:
|
|
183
|
+
|
|
184
|
+
- `examples/npm-only`
|
|
185
|
+
- `examples/github-release`
|
|
186
|
+
- `examples/homebrew-tap`
|
|
187
|
+
- `examples/non-strict-skips`
|
|
188
|
+
|
|
189
|
+
Build the package first, then plan an example from its directory:
|
|
190
|
+
|
|
191
|
+
```sh
|
|
192
|
+
bun run build
|
|
193
|
+
cd examples/github-release
|
|
194
|
+
bun ../../dist/cli/main.js plan --config release.config.json --format text
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Evidence
|
|
198
|
+
|
|
199
|
+
Validation and execution evidence is written as JSON bundles. Failed commands still preserve partial evidence before the command failure is returned.
|
|
200
|
+
|
|
201
|
+
```json
|
|
202
|
+
{
|
|
203
|
+
"schemaVersion": "release-evidence/v1",
|
|
204
|
+
"releaseName": "release",
|
|
205
|
+
"releaseVersion": "0.1.0",
|
|
206
|
+
"records": [
|
|
207
|
+
{
|
|
208
|
+
"id": "npm:npm-pack-dry-run:command",
|
|
209
|
+
"operationId": "npm:npm-pack-dry-run",
|
|
210
|
+
"status": "passed",
|
|
211
|
+
"severity": "info",
|
|
212
|
+
"exitCode": 0
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Non-strict mode records missing validators as visible skipped evidence instead of silently dropping them.
|
|
219
|
+
|
|
220
|
+
## Readiness
|
|
221
|
+
|
|
222
|
+
Normal verification stays deterministic and does not require live external services:
|
|
223
|
+
|
|
224
|
+
```sh
|
|
225
|
+
bun run check:release
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
CI runs the portable package checks on Linux, macOS, and Windows. The Ubuntu release-readiness lane also runs the self-release config guard.
|
|
229
|
+
|
|
230
|
+
Real-tool integration checks are opt-in:
|
|
231
|
+
|
|
232
|
+
```sh
|
|
233
|
+
bun run test:integration:tools
|
|
234
|
+
RELEASE_INTEGRATION_GITHUB=1 bun run test:integration:tools
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
The first command validates npm adapter operations against the real `npm` CLI. The second also validates GitHub adapter readiness checks against the real `gh` CLI and requires `gh auth status` to succeed.
|
|
238
|
+
|
|
239
|
+
Example configs are checked through the same programmatic CLI command path:
|
|
240
|
+
|
|
241
|
+
```sh
|
|
242
|
+
bun run check:examples
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
This repository also includes a first release config at `release.config.json` that targets both npm and GitHub for the scoped `@mannyc1/ts-release` package. The self-release config must pass `bun run check:self-release-config` before release checks proceed. Its `identity.commit` may be the explicit current short commit, or `HEAD` to mean the current committed checkout for a stored self-release config. The local first-release config uses a local `NPM_TOKEN` for npm and GitHub CLI authentication for GitHub; enable npm provenance for CI-based publishes where the registry can generate provenance.
|
|
246
|
+
|
|
247
|
+
```sh
|
|
248
|
+
bun run check:self-release-config
|
|
249
|
+
```
|
package/SPEC.md
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Release Package Spec
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
The `release` package is a small TypeScript library for turning release intent into explicit, inspectable, and repeatable publishing operations.
|
|
6
|
+
|
|
7
|
+
It should not be a build system, a package-manager wrapper, or a generic task runner. Its job is to model what is being released, where it is being published, what must be true before publication, and which irreversible actions require deliberate approval.
|
|
8
|
+
|
|
9
|
+
The package should make release work boring: the same inputs should produce the same plan, the same validations should produce auditable evidence, and the same publish operation should be understandable before anything is executed.
|
|
10
|
+
|
|
11
|
+
## Core Idea
|
|
12
|
+
|
|
13
|
+
A release is a data flow:
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
release intent
|
|
17
|
+
-> normalized release model
|
|
18
|
+
-> target-specific operations
|
|
19
|
+
-> validation evidence
|
|
20
|
+
-> gated execution
|
|
21
|
+
-> post-publish verification
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The package owns the model and the orchestration. Ecosystem tools remain the source of truth for ecosystem-specific behavior.
|
|
25
|
+
|
|
26
|
+
For example, npm, PyPI, GitHub Releases, Homebrew taps, OCI registries, app stores, or other targets may each need different commands, credentials, artifacts, and validators. The release package should describe those differences directly instead of hiding them behind one fake universal publish abstraction.
|
|
27
|
+
|
|
28
|
+
## Design Goals
|
|
29
|
+
|
|
30
|
+
### Plan-first
|
|
31
|
+
|
|
32
|
+
The primary output of the package is a release plan, not a side effect.
|
|
33
|
+
|
|
34
|
+
A plan should be serializable, reviewable, and suitable for CI artifacts. It should explain:
|
|
35
|
+
|
|
36
|
+
- release identity: name, version, commit, tag, notes, and source metadata
|
|
37
|
+
- artifact inventory: files, checksums, sizes, formats, and intended consumers
|
|
38
|
+
- target operations: what each target will do and what inputs it needs
|
|
39
|
+
- validation steps: which checks must run before publishing
|
|
40
|
+
- execution gates: which operations are irreversible or require explicit approval
|
|
41
|
+
- evidence paths: where validation and publish results will be recorded
|
|
42
|
+
|
|
43
|
+
### Explicit target semantics
|
|
44
|
+
|
|
45
|
+
Different distribution targets have different shapes. The package should model those shapes instead of flattening them.
|
|
46
|
+
|
|
47
|
+
Examples:
|
|
48
|
+
|
|
49
|
+
- A release host publish creates or updates a release record and uploads assets.
|
|
50
|
+
- A registry publish creates immutable package versions.
|
|
51
|
+
- A catalog update changes a repository or index that points at artifacts.
|
|
52
|
+
- A deployment promotes already-built assets into an environment.
|
|
53
|
+
|
|
54
|
+
Each target should declare its required inputs, auth requirements, dry-run support, validation strategy, mutability rules, and recovery behavior.
|
|
55
|
+
|
|
56
|
+
### Evidence-driven validation
|
|
57
|
+
|
|
58
|
+
Validation should produce structured evidence, not just console output.
|
|
59
|
+
|
|
60
|
+
Evidence should be machine-readable enough for CI and human-readable enough for debugging. It should include command invocations, tool versions where practical, exit statuses, important paths, skipped checks, warnings, failures, and timestamps.
|
|
61
|
+
|
|
62
|
+
Strict mode should fail on missing required validators. Non-strict mode may record skips, but skips must be visible in the evidence.
|
|
63
|
+
|
|
64
|
+
### Gated irreversible actions
|
|
65
|
+
|
|
66
|
+
Operations that publish immutable versions, create public releases, overwrite indexes, or otherwise affect users must be marked as irreversible or externally visible.
|
|
67
|
+
|
|
68
|
+
The default behavior should be dry-run or print-only. Execution should require an explicit execute flag, and irreversible operations should require a second confirmation flag or equivalent programmatic approval.
|
|
69
|
+
|
|
70
|
+
The package should make it hard to accidentally publish and easy to see exactly what would be published.
|
|
71
|
+
|
|
72
|
+
### Library-first, CLI-second
|
|
73
|
+
|
|
74
|
+
The core package should be a reusable library. A CLI can exist as an adapter, but it should not contain the release logic.
|
|
75
|
+
|
|
76
|
+
The library should expose APIs for:
|
|
77
|
+
|
|
78
|
+
- loading and normalizing config
|
|
79
|
+
- constructing a release plan
|
|
80
|
+
- rendering target files or generated metadata
|
|
81
|
+
- validating plans and artifacts
|
|
82
|
+
- preparing executable operations
|
|
83
|
+
- running approved operations through an injected host interface
|
|
84
|
+
- recording evidence
|
|
85
|
+
|
|
86
|
+
The CLI should mainly parse arguments, call the library, and format output.
|
|
87
|
+
|
|
88
|
+
### Host abstraction without pretending the world is pure
|
|
89
|
+
|
|
90
|
+
The package should isolate filesystem, environment, process execution, network calls, and time behind a narrow host interface where that improves testability and portability.
|
|
91
|
+
|
|
92
|
+
The host boundary should not become a full application framework. It exists so core planning logic can be deterministic and so execution can be tested without touching real registries or release hosts.
|
|
93
|
+
|
|
94
|
+
### Composable, not magical
|
|
95
|
+
|
|
96
|
+
The package should compose with existing tools rather than replace them.
|
|
97
|
+
|
|
98
|
+
Builders, packagers, changelog generators, signing tools, registry CLIs, provenance tools, and ecosystem validators should be treated as inputs or adapters. The release package should coordinate them, capture their evidence, and enforce release policy around them.
|
|
99
|
+
|
|
100
|
+
## Non-goals
|
|
101
|
+
|
|
102
|
+
The package should not try to:
|
|
103
|
+
|
|
104
|
+
- build every artifact itself
|
|
105
|
+
- replace ecosystem-native publishing tools
|
|
106
|
+
- invent a universal package format
|
|
107
|
+
- hide target-specific auth requirements
|
|
108
|
+
- guarantee semantic versioning policy for the project using it
|
|
109
|
+
- own changelog generation as a core requirement
|
|
110
|
+
- require a monorepo
|
|
111
|
+
- require a specific CI provider
|
|
112
|
+
- treat dry-run output as equivalent to successful publication
|
|
113
|
+
|
|
114
|
+
These may be integrated through adapters, but they should not define the core.
|
|
115
|
+
|
|
116
|
+
## Core Concepts
|
|
117
|
+
|
|
118
|
+
### Release Intent
|
|
119
|
+
|
|
120
|
+
User-authored input describing what should be released.
|
|
121
|
+
|
|
122
|
+
It should be concise but complete enough to identify the release, locate artifacts, choose targets, and declare policy.
|
|
123
|
+
|
|
124
|
+
### Release Model
|
|
125
|
+
|
|
126
|
+
A normalized internal representation with defaults resolved, paths normalized, targets expanded, and invalid combinations rejected.
|
|
127
|
+
|
|
128
|
+
The model should be deterministic and independent of terminal formatting or CLI flags.
|
|
129
|
+
|
|
130
|
+
### Release Plan
|
|
131
|
+
|
|
132
|
+
A serializable plan derived from the release model.
|
|
133
|
+
|
|
134
|
+
The plan is the contract between planning, validation, execution, and CI review. It should be stable enough to diff in tests and inspect in logs.
|
|
135
|
+
|
|
136
|
+
### Target Adapter
|
|
137
|
+
|
|
138
|
+
A module that knows how to plan, validate, and execute operations for one distribution target.
|
|
139
|
+
|
|
140
|
+
Adapters should expose capabilities clearly: dry-run support, required credentials, validation commands, generated files, publish commands, and expected evidence.
|
|
141
|
+
|
|
142
|
+
### Operation
|
|
143
|
+
|
|
144
|
+
A concrete action that may be rendered, validated, executed, or skipped.
|
|
145
|
+
|
|
146
|
+
Operations should carry enough metadata to explain their risk level, inputs, outputs, and execution requirements.
|
|
147
|
+
|
|
148
|
+
### Evidence
|
|
149
|
+
|
|
150
|
+
Structured records produced by validation, rendering, execution, and verification.
|
|
151
|
+
|
|
152
|
+
Evidence should survive outside the process as JSON or another stable format. It should be useful for CI summaries, release audits, and debugging failed publishes.
|
|
153
|
+
|
|
154
|
+
## Expected Public Surface
|
|
155
|
+
|
|
156
|
+
The package should make these workflows straightforward:
|
|
157
|
+
|
|
158
|
+
- create a plan from config
|
|
159
|
+
- inspect the plan without executing anything
|
|
160
|
+
- render target-specific files
|
|
161
|
+
- validate artifacts and target readiness
|
|
162
|
+
- produce evidence artifacts
|
|
163
|
+
- print publish operations
|
|
164
|
+
- execute approved operations
|
|
165
|
+
- verify published state after execution
|
|
166
|
+
|
|
167
|
+
The API should favor explicit functions and typed data over hidden global state.
|
|
168
|
+
|
|
169
|
+
## Configuration Principles
|
|
170
|
+
|
|
171
|
+
Configuration should be declarative and boring.
|
|
172
|
+
|
|
173
|
+
It should describe release facts and target policy, not arbitrary scripts. Escape hatches can exist, but they should be visible in the plan and evidence.
|
|
174
|
+
|
|
175
|
+
Good config answers:
|
|
176
|
+
|
|
177
|
+
- What is the release?
|
|
178
|
+
- Which artifacts are part of it?
|
|
179
|
+
- Which targets receive it?
|
|
180
|
+
- What credentials or environment are required?
|
|
181
|
+
- What must be validated first?
|
|
182
|
+
- Which generated files or indexes will change?
|
|
183
|
+
- Which operations are allowed to execute in this environment?
|
|
184
|
+
|
|
185
|
+
## Testing Strategy
|
|
186
|
+
|
|
187
|
+
The core should be heavily testable without real external services.
|
|
188
|
+
|
|
189
|
+
Important test categories:
|
|
190
|
+
|
|
191
|
+
- config parsing and normalization
|
|
192
|
+
- invalid config diagnostics
|
|
193
|
+
- deterministic plan generation
|
|
194
|
+
- adapter capability modeling
|
|
195
|
+
- dry-run behavior
|
|
196
|
+
- irreversible-operation gating
|
|
197
|
+
- evidence recording
|
|
198
|
+
- command construction without execution
|
|
199
|
+
- execution through fake host implementations
|
|
200
|
+
- target adapter contract tests
|
|
201
|
+
|
|
202
|
+
Real integration tests can exist for official validators and sandbox registries, but the core should not depend on live services to prove its behavior.
|
|
203
|
+
|
|
204
|
+
## Success Criteria
|
|
205
|
+
|
|
206
|
+
The rewrite is successful when:
|
|
207
|
+
|
|
208
|
+
- a user can define release intent in a small config
|
|
209
|
+
- the package produces a reviewable release plan with no side effects
|
|
210
|
+
- target differences are explicit in the plan
|
|
211
|
+
- validation emits structured evidence
|
|
212
|
+
- publish operations are blocked by default
|
|
213
|
+
- irreversible operations require deliberate approval
|
|
214
|
+
- core behavior is covered with deterministic tests
|
|
215
|
+
- a CLI can be rebuilt as a thin adapter over the library
|
|
216
|
+
- adding a new target does not require rewriting the core planner
|
|
217
|
+
|
|
218
|
+
## Biases
|
|
219
|
+
|
|
220
|
+
Prefer:
|
|
221
|
+
|
|
222
|
+
- explicit data over implicit conventions
|
|
223
|
+
- small target adapters over a large universal abstraction
|
|
224
|
+
- official ecosystem validators over homegrown approximations
|
|
225
|
+
- deterministic planning over clever runtime discovery
|
|
226
|
+
- evidence artifacts over terminal-only output
|
|
227
|
+
- hard failures for unsafe ambiguity
|
|
228
|
+
- dry-run as the default mode
|
|
229
|
+
|
|
230
|
+
Avoid:
|
|
231
|
+
|
|
232
|
+
- hook-runner architecture as the core design
|
|
233
|
+
- hidden publish side effects during validation
|
|
234
|
+
- target adapters that silently shell out without modeling risk
|
|
235
|
+
- global process state in the planning layer
|
|
236
|
+
- special cases that only work for one repository shape
|
|
237
|
+
- abstractions that erase important ecosystem differences
|
|
238
|
+
|
|
239
|
+
## Rewrite Direction
|
|
240
|
+
|
|
241
|
+
Start from the data model.
|
|
242
|
+
|
|
243
|
+
Define the smallest set of types needed to represent release identity, artifacts, targets, operations, validation results, execution gates, and evidence. Then implement one or two target adapters end to end to prove that the abstractions carry real differences without becoming generic mush.
|
|
244
|
+
|
|
245
|
+
The first working version should be narrow but honest:
|
|
246
|
+
|
|
247
|
+
1. Load config.
|
|
248
|
+
2. Normalize into a release model.
|
|
249
|
+
3. Generate a serializable plan.
|
|
250
|
+
4. Validate with structured evidence.
|
|
251
|
+
5. Print executable operations.
|
|
252
|
+
6. Execute only when explicitly approved.
|
|
253
|
+
|
|
254
|
+
Everything else should be added only after it has a clear place in that flow.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import * as Command from "effect/unstable/cli/Command";
|
|
2
|
+
export type * from "../types/effect-internal.js";
|
|
3
|
+
export declare const cli: Command.Command<"release", {}, {}, import("../domain/operation.js").ExecutionApprovalError | import("../config/errors.js").ConfigParseError | import("../config/errors.js").ConfigValidationError | import("../host/host.js").HostError | import("../planner/errors.js").ReleaseNormalizationError | import("../planner/errors.js").PlanConstructionError | import("../planner/errors.js").EvidenceWriteError | import("../planner/errors.js").OperationFailedError | import("../targets/registry.js").MissingTargetAdapterError, never>;
|
|
4
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/cli/command.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,OAAO,MAAM,6BAA6B,CAAA;AAatD,mBAAmB,6BAA6B,CAAA;AA+IhD,eAAO,MAAM,GAAG,0gBAEf,CAAA"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as Console from "effect/Console";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Command from "effect/unstable/cli/Command";
|
|
4
|
+
import * as Flag from "effect/unstable/cli/Flag";
|
|
5
|
+
import { parseReleaseIntent } from "../config/load.js";
|
|
6
|
+
import { DEFAULT_CONFIG_PATH } from "../config/schema.js";
|
|
7
|
+
import { ExecutionApproval } from "../domain/operation.js";
|
|
8
|
+
import { ReleaseHost } from "../host/host.js";
|
|
9
|
+
import { createReleasePlan } from "../planner/create-release-plan.js";
|
|
10
|
+
import { executePlan, renderPlan, validatePlan, verifyPlan } from "../planner/executor.js";
|
|
11
|
+
import { renderEvidenceJson, writeEvidenceBundle } from "../planner/evidence-recorder.js";
|
|
12
|
+
import { renderPlanJson, renderPlanText } from "../planner/render-plan.js";
|
|
13
|
+
const configFlag = Flag.string("config").pipe(Flag.withDefault(DEFAULT_CONFIG_PATH));
|
|
14
|
+
const outputFlag = Flag.string("out").pipe(Flag.withDefault(""));
|
|
15
|
+
const formatFlag = Flag.choice("format", ["json", "text"]).pipe(Flag.withDefault("json"));
|
|
16
|
+
const executeFlag = Flag.boolean("execute").pipe(Flag.withDefault(false));
|
|
17
|
+
const approveIrreversibleFlag = Flag.boolean("approve-irreversible").pipe(Flag.withDefault(false));
|
|
18
|
+
const loadPlanFromConfig = Effect.fn("loadPlanFromConfig")(function* (configPath) {
|
|
19
|
+
const host = yield* ReleaseHost;
|
|
20
|
+
const contents = yield* host.readFileString(configPath);
|
|
21
|
+
const intent = yield* parseReleaseIntent(contents, configPath);
|
|
22
|
+
return yield* createReleasePlan(intent, ".", configPath);
|
|
23
|
+
});
|
|
24
|
+
const writeOrPrint = Effect.fn("writeOrPrint")(function* (out, contents) {
|
|
25
|
+
if (out.length === 0) {
|
|
26
|
+
return yield* Console.log(contents.trimEnd());
|
|
27
|
+
}
|
|
28
|
+
const host = yield* ReleaseHost;
|
|
29
|
+
return yield* host.writeFileString(out, contents);
|
|
30
|
+
});
|
|
31
|
+
const planCommand = Command.make("plan", {
|
|
32
|
+
config: configFlag,
|
|
33
|
+
out: outputFlag,
|
|
34
|
+
format: formatFlag
|
|
35
|
+
}, Effect.fn("cli.plan")(function* ({ config, out, format }) {
|
|
36
|
+
const plan = yield* loadPlanFromConfig(config);
|
|
37
|
+
const contents = format === "json" ? renderPlanJson(plan) : renderPlanText(plan);
|
|
38
|
+
yield* writeOrPrint(out, contents);
|
|
39
|
+
}));
|
|
40
|
+
const printCommand = Command.make("print", {
|
|
41
|
+
config: configFlag
|
|
42
|
+
}, Effect.fn("cli.print")(function* ({ config }) {
|
|
43
|
+
const plan = yield* loadPlanFromConfig(config);
|
|
44
|
+
yield* Console.log(renderPlanText(plan).trimEnd());
|
|
45
|
+
}));
|
|
46
|
+
const evidencePath = (plan, name) => `${plan.evidenceDirectory}/${name}.json`;
|
|
47
|
+
const writeAndPrintEvidence = Effect.fn("writeAndPrintEvidence")(function* (plan, name, evidence) {
|
|
48
|
+
yield* writeEvidenceBundle(evidencePath(plan, name), evidence);
|
|
49
|
+
yield* Console.log(renderEvidenceJson(evidence).trimEnd());
|
|
50
|
+
});
|
|
51
|
+
const writeFailedEvidence = Effect.fn("writeFailedEvidence")(function* (plan, name, error) {
|
|
52
|
+
if (error.evidence !== undefined) {
|
|
53
|
+
yield* writeAndPrintEvidence(plan, name, error.evidence);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
const validateCommand = Command.make("validate", {
|
|
57
|
+
config: configFlag
|
|
58
|
+
}, Effect.fn("cli.validate")(function* ({ config }) {
|
|
59
|
+
const plan = yield* loadPlanFromConfig(config);
|
|
60
|
+
const evidence = yield* validatePlan(plan).pipe(Effect.catchTag("OperationFailedError", (error) => writeFailedEvidence(plan, "validation", error).pipe(Effect.flatMap(() => Effect.fail(error)))));
|
|
61
|
+
yield* writeAndPrintEvidence(plan, "validation", evidence);
|
|
62
|
+
}));
|
|
63
|
+
const renderCommand = Command.make("render", {
|
|
64
|
+
config: configFlag,
|
|
65
|
+
execute: executeFlag
|
|
66
|
+
}, Effect.fn("cli.render")(function* ({ config, execute }) {
|
|
67
|
+
const plan = yield* loadPlanFromConfig(config);
|
|
68
|
+
const approval = ExecutionApproval.make({ execute, approveIrreversible: false });
|
|
69
|
+
const evidence = yield* renderPlan(plan, approval).pipe(Effect.catchTag("OperationFailedError", (error) => writeFailedEvidence(plan, "render", error).pipe(Effect.flatMap(() => Effect.fail(error)))));
|
|
70
|
+
yield* writeAndPrintEvidence(plan, "render", evidence);
|
|
71
|
+
}));
|
|
72
|
+
const executeCommand = Command.make("execute", {
|
|
73
|
+
config: configFlag,
|
|
74
|
+
execute: executeFlag,
|
|
75
|
+
approveIrreversible: approveIrreversibleFlag
|
|
76
|
+
}, Effect.fn("cli.execute")(function* ({ config, execute, approveIrreversible }) {
|
|
77
|
+
const plan = yield* loadPlanFromConfig(config);
|
|
78
|
+
const approval = ExecutionApproval.make({ execute, approveIrreversible });
|
|
79
|
+
const evidence = yield* executePlan(plan, approval).pipe(Effect.catchTag("OperationFailedError", (error) => writeFailedEvidence(plan, "execution", error).pipe(Effect.flatMap(() => Effect.fail(error)))));
|
|
80
|
+
yield* writeAndPrintEvidence(plan, "execution", evidence);
|
|
81
|
+
}));
|
|
82
|
+
const verifyCommand = Command.make("verify", {
|
|
83
|
+
config: configFlag
|
|
84
|
+
}, Effect.fn("cli.verify")(function* ({ config }) {
|
|
85
|
+
const plan = yield* loadPlanFromConfig(config);
|
|
86
|
+
const evidence = yield* verifyPlan(plan).pipe(Effect.catchTag("OperationFailedError", (error) => writeFailedEvidence(plan, "verification", error).pipe(Effect.flatMap(() => Effect.fail(error)))));
|
|
87
|
+
yield* writeAndPrintEvidence(plan, "verification", evidence);
|
|
88
|
+
}));
|
|
89
|
+
export const cli = Command.make("release").pipe(Command.withSubcommands([planCommand, renderCommand, validateCommand, printCommand, executeCommand, verifyCommand]));
|
|
90
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/cli/command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":""}
|
package/dist/cli/main.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import * as BunRuntime from "@effect/platform-bun/BunRuntime";
|
|
3
|
+
import * as BunServices from "@effect/platform-bun/BunServices";
|
|
4
|
+
import * as Effect from "effect/Effect";
|
|
5
|
+
import * as Layer from "effect/Layer";
|
|
6
|
+
import * as Command from "effect/unstable/cli/Command";
|
|
7
|
+
import { BunReleaseHostLayer } from "../host/bun.js";
|
|
8
|
+
import { LiveTargetRegistryLayer } from "../targets/live.js";
|
|
9
|
+
import { cli } from "./command.js";
|
|
10
|
+
const MainLayer = Layer.mergeAll(BunReleaseHostLayer, LiveTargetRegistryLayer, BunServices.layer);
|
|
11
|
+
Command.run(cli, { version: "0.0.0" }).pipe(Effect.provide(MainLayer), BunRuntime.runMain);
|
|
12
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,UAAU,MAAM,iCAAiC,CAAA;AAC7D,OAAO,KAAK,WAAW,MAAM,kCAAkC,CAAA;AAC/D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,OAAO,MAAM,6BAA6B,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAA;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAElC,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAC9B,mBAAmB,EACnB,uBAAuB,EACvB,WAAW,CAAC,KAAK,CAClB,CAAA;AAED,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,CACzC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EACzB,UAAU,CAAC,OAAO,CACnB,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import { ReleasePlan } from "../domain/release.js";
|
|
4
|
+
export type * from "../types/effect-internal.js";
|
|
5
|
+
export declare const DEFAULT_RELEASE_CLI_VERSION = "0.0.0";
|
|
6
|
+
export declare const ReleasePlanFormat: Schema.Literals<readonly ["json", "text"]>;
|
|
7
|
+
export type ReleasePlanFormat = typeof ReleasePlanFormat.Type;
|
|
8
|
+
declare const ReleaseCliOptions_base: Schema.Class<ReleaseCliOptions, Schema.Struct<{
|
|
9
|
+
readonly root: Schema.optionalKey<Schema.String>;
|
|
10
|
+
readonly version: Schema.optionalKey<Schema.String>;
|
|
11
|
+
}>, {}>;
|
|
12
|
+
export declare class ReleaseCliOptions extends ReleaseCliOptions_base {
|
|
13
|
+
}
|
|
14
|
+
declare const PlanReleaseConfigOptions_base: Schema.Class<PlanReleaseConfigOptions, Schema.Struct<{
|
|
15
|
+
readonly root: Schema.optionalKey<Schema.String>;
|
|
16
|
+
readonly configPath: Schema.optionalKey<Schema.String>;
|
|
17
|
+
readonly format: Schema.optionalKey<Schema.Literals<readonly ["json", "text"]>>;
|
|
18
|
+
}>, {}>;
|
|
19
|
+
export declare class PlanReleaseConfigOptions extends PlanReleaseConfigOptions_base {
|
|
20
|
+
}
|
|
21
|
+
export declare const planReleaseConfig: (options?: PlanReleaseConfigOptions | undefined) => Effect.Effect<ReleasePlan, import("../config/errors.js").ConfigParseError | import("../config/errors.js").ConfigValidationError | import("../host/host.js").HostError | import("../planner/errors.js").ReleaseNormalizationError | import("../planner/errors.js").PlanConstructionError | import("../targets/registry.js").MissingTargetAdapterError, never>;
|
|
22
|
+
export declare const renderReleaseConfigPlan: (options?: PlanReleaseConfigOptions | undefined) => Effect.Effect<string, import("../config/errors.js").ConfigParseError | import("../config/errors.js").ConfigValidationError | import("../host/host.js").HostError | import("../planner/errors.js").ReleaseNormalizationError | import("../planner/errors.js").PlanConstructionError | import("../targets/registry.js").MissingTargetAdapterError, never>;
|
|
23
|
+
export declare const runReleaseCli: (args: readonly string[], options?: ReleaseCliOptions | undefined) => Effect.Effect<void, import("effect/unstable/cli/CliError").CliError | import("../domain/operation.js").ExecutionApprovalError | import("../config/errors.js").ConfigParseError | import("../config/errors.js").ConfigValidationError | import("../host/host.js").HostError | import("../planner/errors.js").ReleaseNormalizationError | import("../planner/errors.js").PlanConstructionError | import("../planner/errors.js").EvidenceWriteError | import("../planner/errors.js").OperationFailedError | import("../targets/registry.js").MissingTargetAdapterError, never>;
|
|
24
|
+
export type ProgrammaticReleasePlan = ReleasePlan;
|
|
25
|
+
//# sourceMappingURL=programmatic.d.ts.map
|