@git.zone/cli 5.0.0 → 6.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/assets/templates/ci_default/.gitea/workflows/default_tags.yaml +0 -21
- package/assets/templates/ci_default_gitlab/.gitlab-ci.yml +0 -13
- package/assets/templates/ci_default_private/.gitea/workflows/default_tags.yaml +0 -21
- package/assets/templates/ci_default_private_gitlab/.gitlab-ci.yml +0 -13
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/helpers.climode.js +31 -2
- package/dist_ts/helpers.workflow.d.ts +10 -0
- package/dist_ts/helpers.workflow.js +80 -8
- package/dist_ts/mod_release/classes.releasejournal.d.ts +78 -0
- package/dist_ts/mod_release/classes.releasejournal.js +511 -0
- package/dist_ts/mod_release/helpers.npmartifact.d.ts +32 -0
- package/dist_ts/mod_release/helpers.npmartifact.js +358 -0
- package/dist_ts/mod_release/helpers.releasebranch.d.ts +1 -0
- package/dist_ts/mod_release/helpers.releasebranch.js +54 -6
- package/dist_ts/mod_release/helpers.releasepublication.d.ts +24 -0
- package/dist_ts/mod_release/helpers.releasepublication.js +293 -0
- package/dist_ts/mod_release/index.d.ts +1 -11
- package/dist_ts/mod_release/index.js +410 -288
- package/package.json +1 -1
- package/readme.hints.md +47 -1
- package/readme.md +61 -26
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/helpers.climode.ts +34 -1
- package/ts/helpers.workflow.ts +114 -7
- package/ts/mod_release/classes.releasejournal.ts +740 -0
- package/ts/mod_release/helpers.npmartifact.ts +553 -0
- package/ts/mod_release/helpers.releasebranch.ts +67 -5
- package/ts/mod_release/helpers.releasepublication.ts +641 -0
- package/ts/mod_release/index.ts +576 -411
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@git.zone/cli",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "6.0.0",
|
|
5
5
|
"description": "A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
7
7
|
"typings": "dist_ts/index.d.ts",
|
package/readme.hints.md
CHANGED
|
@@ -104,11 +104,57 @@ The commit module no longer bumps versions, creates tags, or publishes packages.
|
|
|
104
104
|
- Release publishing is target-based under `@git.zone/cli.release.targets`.
|
|
105
105
|
- NPM registries only live under `@git.zone/cli.release.targets.npm.registries`.
|
|
106
106
|
|
|
107
|
+
### Exact artifact release journal v1
|
|
108
|
+
|
|
109
|
+
Every release that reaches final Git/npm publication atomically installs
|
|
110
|
+
canonical state below the Git common directory at
|
|
111
|
+
`gitzone/releases/v1/v<version>/`. npm releases contain exactly one
|
|
112
|
+
`package.tgz`; the journal binds that file's package identity, byte length,
|
|
113
|
+
SHA-1, SHA-256, SHA-512 integrity, release commit, annotated tag object, hashed
|
|
114
|
+
Git destination, registry list, and target attempts. The state is deliberately
|
|
115
|
+
outside the worktree so build cleanliness checks do not conflict with durable
|
|
116
|
+
recovery.
|
|
117
|
+
|
|
118
|
+
Journal writes are fsynced same-directory replacements under the shared
|
|
119
|
+
atomic-mkdir lock and require the caller's exact prior revision. Transactions
|
|
120
|
+
may update target attempts and completion state but cannot alter release,
|
|
121
|
+
artifact, destination, or target identity. A malformed, noncanonical, future,
|
|
122
|
+
or manually reformatted journal fails closed.
|
|
123
|
+
|
|
124
|
+
Selected Git publication requires a canonical remote name and validates its
|
|
125
|
+
single resolved push URL before remote contact, including during planning.
|
|
126
|
+
Embedded HTTP(S) credentials, passwords, parameters, and unsupported protocols
|
|
127
|
+
fail closed. Git publication then probes the exact branch, annotated tag
|
|
128
|
+
object, and peeled tag commit before and after an atomic leased push. npm publication always uses the
|
|
129
|
+
stored tarball and verifies each public registry anonymously with redirects
|
|
130
|
+
disabled. Verification covers metadata identity, integrity and shasum, bounded
|
|
131
|
+
downloaded bytes, SHA-256, and the `latest` dist-tag.
|
|
132
|
+
|
|
133
|
+
`gitzone release inspect [version]` is read-only. `gitzone release resume
|
|
134
|
+
<version>` rejects fresh-release overrides and never rebuilds or repacks. It
|
|
135
|
+
also rejects changed journaled configuration. A target left in `publishing`
|
|
136
|
+
state first reconciles exact remote
|
|
137
|
+
state. If the remote still looks absent, recovery requires the exact recorded
|
|
138
|
+
attempt ID and independent proof that its process stopped; no timeout or PID
|
|
139
|
+
guess reclaims publication authority.
|
|
140
|
+
|
|
141
|
+
Schema v1 recovery begins only after atomic journal installation. Local
|
|
142
|
+
version, changelog, commit, tag, build, and pack failures before that point, as
|
|
143
|
+
well as the pre-release `--merge` integration push, require explicit operator
|
|
144
|
+
reconciliation; they are not represented as publication attempts.
|
|
145
|
+
|
|
146
|
+
Schema v1 supports Git and public npm only and requires resolved pnpm 11.21.0.
|
|
147
|
+
Private npm cannot be anonymously verified. Docker releases remain blocked
|
|
148
|
+
until tSDocker returns structured immutable digest qualification and promotion
|
|
149
|
+
results. Legacy tag-triggered `npmci npm publish` jobs must be removed because
|
|
150
|
+
they bypass journal ownership.
|
|
151
|
+
|
|
107
152
|
**Benefits:**
|
|
108
153
|
|
|
109
154
|
- Commit is safer and has no publishing side effects.
|
|
110
155
|
- Multiple source commits can accumulate into one release via `Pending`.
|
|
111
|
-
-
|
|
156
|
+
- Durable target states distinguish pending, publishing, verified, failed,
|
|
157
|
+
conflicting, and skipped publication while retaining exact attempt evidence.
|
|
112
158
|
|
|
113
159
|
### Auto-Accept Flag for Commits
|
|
114
160
|
|
package/readme.md
CHANGED
|
@@ -137,7 +137,7 @@ Commit flags:
|
|
|
137
137
|
|
|
138
138
|
`--merge` is intentionally strict: the source and existing `main` worktree must be clean, the source must be linearly rebased onto current remote `main`, and the Git target must push both the branch and tag. GitZone pins the single configured push URL, compare-and-swap fast-forwards local `main`, updates its verified worktree, and lease-pushes that exact source commit before creating release metadata. It rejects diverged or merged history, local replacement refs or grafts, stale worktrees, incomplete shallow history, changed destinations, and remote races. If the pre-release push fails, GitZone restores local `main` only when doing so cannot overwrite concurrent work. This plumbing-level integration intentionally does not run merge hooks or write `ORIG_HEAD`.
|
|
139
139
|
|
|
140
|
-
`gitzone release` performs the release core once, then publishes to configured targets. An active Git target must succeed before npm
|
|
140
|
+
`gitzone release` performs the release core once, then publishes to configured targets. An active Git target must succeed and be verified before npm publication can start.
|
|
141
141
|
|
|
142
142
|
The release core is not configurable plumbing. It always follows the same professional release transaction:
|
|
143
143
|
|
|
@@ -149,14 +149,15 @@ The release core is not configurable plumbing. It always follows the same profes
|
|
|
149
149
|
6. Move pending changelog entries into the new version section.
|
|
150
150
|
7. Create the local release commit and tag on `main`.
|
|
151
151
|
8. Run the configured release build, require a clean tree, and revalidate the release checkout.
|
|
152
|
+
9. When npm is selected, pack it once into an exact tarball. Atomically install a durable journal for Git-only and npm releases before final Git release-ref or npm publication.
|
|
152
153
|
|
|
153
154
|
Targets decide what happens after that:
|
|
154
155
|
|
|
155
156
|
| Target | What it does |
|
|
156
157
|
| --- | --- |
|
|
157
158
|
| `git` | Atomically pushes the exact `main` release commit and new tag, often triggering remote CI release builds |
|
|
158
|
-
| `npm` | Publishes the
|
|
159
|
-
| `docker` |
|
|
159
|
+
| `npm` | Publishes the same journaled tarball to every configured registry and verifies its bytes anonymously |
|
|
160
|
+
| `docker` | Fails closed in journal schema v1 until tSDocker provides structured digest-qualified publication results |
|
|
160
161
|
|
|
161
162
|
```bash
|
|
162
163
|
# Preview the resolved release plan
|
|
@@ -171,10 +172,7 @@ gitzone release --merge
|
|
|
171
172
|
# Release only to npm
|
|
172
173
|
gitzone release --target npm
|
|
173
174
|
|
|
174
|
-
#
|
|
175
|
-
gitzone release --target git,docker
|
|
176
|
-
|
|
177
|
-
# Skip package/container publishing and keep only git target
|
|
175
|
+
# Remove npm and Docker from the resolved targets; Git remains only if configured
|
|
178
176
|
gitzone release --no-publish
|
|
179
177
|
|
|
180
178
|
# Override inferred semver level
|
|
@@ -188,15 +186,57 @@ Release flags:
|
|
|
188
186
|
| `-y`, `--yes` | Run without interactive confirmation |
|
|
189
187
|
| `-t`, `--test` | Enable preflight tests |
|
|
190
188
|
| `-b`, `--build` | Enable the release build after local release metadata is created |
|
|
191
|
-
| `-p`, `--push` |
|
|
192
|
-
| `--target <csv>` |
|
|
193
|
-
| `--npm` |
|
|
194
|
-
| `--docker` |
|
|
195
|
-
| `--no-publish` |
|
|
189
|
+
| `-p`, `--push` | Explicitly select the `git` target; combine with other target flags as needed |
|
|
190
|
+
| `--target <csv>` | Replace configured targets with a non-empty comma-separated subset of `git`, `npm`, and `docker`; empty or unknown elements fail |
|
|
191
|
+
| `--npm` | Explicitly select the `npm` target; combine with other target flags as needed |
|
|
192
|
+
| `--docker` | Explicitly select `docker`; planning is supported, but a mutating schema v1 release fails before integration or release metadata |
|
|
193
|
+
| `--no-publish` | Remove npm and Docker from the resolved target set without implicitly enabling Git |
|
|
196
194
|
| `--no-build` | Disable the post-metadata release build for this run |
|
|
197
195
|
| `--merge` | Fast-forward and lease-push a cleanly rebased feature branch into `main`, then release from `main` |
|
|
198
196
|
| `--major`, `--minor`, `--patch` | Override inferred semver level |
|
|
199
197
|
| `--plan` | Show the resolved workflow without fetching or mutating refs, files, the index, or worktrees |
|
|
198
|
+
| `inspect [version]` | Read one or all durable release journals; add `--json` for machine-readable output |
|
|
199
|
+
| `resume <version>` | Resume only journaled Git/npm publication; fresh-release overrides, including negated forms, are rejected, and `--json` remains inspect-only |
|
|
200
|
+
| `--recover-attempt <id>` | Recover the exact 32-character lowercase hexadecimal `attempt.id` shown by `inspect --json`, after independently proving its publisher stopped |
|
|
201
|
+
|
|
202
|
+
### Exact npm artifacts and release journals
|
|
203
|
+
|
|
204
|
+
Journal schema v1 supports Git and public npm publication. Fresh and resumed npm publication requires the resolved `pnpm` binary to be exactly the version pinned by this package (`11.21.0`). Registries must be unique canonical credential-free HTTP(S) URLs, and `release.targets.npm.accessLevel` must be `public` so verification does not depend on publisher credentials.
|
|
205
|
+
|
|
206
|
+
A selected Git target requires a canonical remote name and exactly one resolved push URL. Before any remote contact, including during `--plan`, GitZone rejects HTTP(S) usernames or passwords, embedded passwords, query strings, fragments, and unsupported protocols. Canonical local paths and SSH destinations may retain their required SSH username.
|
|
207
|
+
|
|
208
|
+
Every release that reaches final Git/npm publication stores `journal.json` under the repository's Git common directory. npm releases additionally run `pnpm pack` once and store the resulting `package.tgz` beside it:
|
|
209
|
+
|
|
210
|
+
```text
|
|
211
|
+
<git-common-dir>/gitzone/releases/v1/v<version>/package.tgz
|
|
212
|
+
<git-common-dir>/gitzone/releases/v1/v<version>/journal.json
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The canonical journal binds the release commit, annotated tag object, hashed Git destination, npm registries, per-target attempt states, and, when npm is selected, the package identity, tarball size, SHA-1, SHA-256, and SHA-512 integrity. Journal updates use revision compare-and-swap under an interprocess lock. Release identity and destinations cannot change after journal creation. Inspect and resume reject malformed, future, noncanonical, duplicate-key, or merely reformatted journal JSON rather than repairing or normalizing it.
|
|
216
|
+
|
|
217
|
+
Packing must leave the release tree clean. Each registry receives that exact stored tarball through `pnpm publish <tarball> --ignore-scripts`, so publish lifecycle scripts do not run. Success is recorded only after anonymous no-redirect probes verify version metadata, SHA-1 and integrity fields, the downloaded tarball bytes, and the `latest` dist-tag. A matching pre-existing version follows `release.targets.npm.alreadyPublished`; conflicting bytes always stop the release, while transient responses and dist-tag propagation remain retryable.
|
|
218
|
+
|
|
219
|
+
Independent tag-triggered npm publishers are incompatible with this transaction. GitZone rejects a release while `.gitea/workflows/default_tags.yaml` or `.gitlab-ci.yml` still contains the legacy `npmci npm publish` command. Apply the v6 Gitea workflow template or remove the legacy GitLab job and commit that change first.
|
|
220
|
+
|
|
221
|
+
Inspect and resume without regenerating release identity:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# List journals or inspect one exact version
|
|
225
|
+
gitzone release inspect
|
|
226
|
+
gitzone release inspect 6.0.0 --json
|
|
227
|
+
|
|
228
|
+
# Reconcile remote state, then continue only unfinished targets
|
|
229
|
+
gitzone release resume 6.0.0 -y
|
|
230
|
+
|
|
231
|
+
# Only after proving the recorded publisher process has stopped
|
|
232
|
+
gitzone release resume 6.0.0 -y --recover-attempt="$ATTEMPT_ID"
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Resume requires the local `main` commit, annotated release tag, and each journaled destination setting to remain exact. The Git remote must still match when Git is journaled; npm registry, access, and already-published settings must still match when npm is journaled. Non-journaled target configuration is ignored, so releases created with a target subset remain resumable. Fresh-release overrides such as targets, integration, build, test, and version flags are rejected even in negated forms such as `--no-git`, `--no-publish`, and `--no-build`; JSON output is available only through `inspect --json`. Resume probes remote state before acting. Exact remote state is accepted without republishing; positive byte, metadata, or ref conflicts fail closed, while absent, pending, inconclusive, and dist-tag propagation results do not overwrite a previously verified state. A target left in `publishing` state is never reclaimed from an absent remote result unless the exact recorded 32-character lowercase hexadecimal `attempt.id` from `git.attempt` or an npm registry attempt is supplied.
|
|
236
|
+
|
|
237
|
+
Schema v1 resumes only final Git release-ref and npm publication after the journal is atomically installed. It does not recover local version, changelog, commit, tag, build, or pack failures that occur before installation, nor the pre-release `--merge` integration push. Those failures stop before the final release commit/tag or npm artifact is published and require explicit operator reconciliation.
|
|
238
|
+
|
|
239
|
+
Docker target configuration remains available for planning and future journal schemas, but a mutating v6 release with an active Docker target stops before release integration or metadata changes. This restriction remains until tSDocker owns structured immutable digest qualification and promotion.
|
|
200
240
|
|
|
201
241
|
## Standard Changelog
|
|
202
242
|
|
|
@@ -218,7 +258,7 @@ The standard buckets are `Breaking Changes`, `Features`, `Fixes`, `Documentation
|
|
|
218
258
|
|
|
219
259
|
## Configuration
|
|
220
260
|
|
|
221
|
-
CLI workflow config lives under `@git.zone/cli` in `.smartconfig.json`. Docker build and registry
|
|
261
|
+
CLI workflow config lives under `@git.zone/cli` in `.smartconfig.json`. Dormant Docker build and registry settings remain under `@git.zone/tsdocker` for the later journal schema that will restore Docker publication.
|
|
222
262
|
|
|
223
263
|
```json
|
|
224
264
|
{
|
|
@@ -249,7 +289,7 @@ CLI workflow config lives under `@git.zone/cli` in `.smartconfig.json`. Docker b
|
|
|
249
289
|
"alreadyPublished": "success"
|
|
250
290
|
},
|
|
251
291
|
"docker": {
|
|
252
|
-
"enabled":
|
|
292
|
+
"enabled": false,
|
|
253
293
|
"engine": "tsdocker",
|
|
254
294
|
"registry": "registry.gitlab.com",
|
|
255
295
|
"buildRegistries": ["registry.gitlab.com"],
|
|
@@ -284,23 +324,18 @@ values should be hosts without `http://` or `https://`:
|
|
|
284
324
|
@git.zone/tsdocker.registries
|
|
285
325
|
```
|
|
286
326
|
|
|
287
|
-
|
|
288
|
-
`pnpm exec
|
|
327
|
+
Docker release configuration uses the project's pinned `@git.zone/tsdocker`
|
|
328
|
+
through `pnpm exec`. Install it in each Docker-producing project, but keep the
|
|
329
|
+
target disabled while release journal schema v1 is active:
|
|
289
330
|
|
|
290
331
|
```bash
|
|
291
332
|
pnpm add --save-dev @git.zone/tsdocker
|
|
292
333
|
```
|
|
293
334
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
only the configured registries used by private base images; an empty list keeps
|
|
299
|
-
the compatibility default of authenticating every configured registry. Bounded
|
|
300
|
-
build authentication requires project-local `@git.zone/tsdocker` 3.3.0 or newer.
|
|
301
|
-
Set `release.targets.docker.test` to `true` to require every selected image test
|
|
302
|
-
to pass before destination publication. This requires project-local
|
|
303
|
-
`@git.zone/tsdocker` 3.4.0 or newer.
|
|
335
|
+
The dormant `release.targets.docker.registry`, `buildRegistries`, and `test`
|
|
336
|
+
settings describe the intended tSDocker destination, bounded base-image
|
|
337
|
+
authentication, and pre-publication image tests. They do not execute while
|
|
338
|
+
journal schema v1 is active.
|
|
304
339
|
|
|
305
340
|
Useful config commands:
|
|
306
341
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@git.zone/cli',
|
|
6
|
-
version: '
|
|
6
|
+
version: '6.0.0',
|
|
7
7
|
description: 'A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.'
|
|
8
8
|
}
|
package/ts/helpers.climode.ts
CHANGED
|
@@ -24,6 +24,29 @@ interface ICliConfigSettings {
|
|
|
24
24
|
|
|
25
25
|
type TArgSource = Record<string, any> & { _?: string[] };
|
|
26
26
|
|
|
27
|
+
const booleanLongFlags = new Set([
|
|
28
|
+
"agent",
|
|
29
|
+
"allow-breaking",
|
|
30
|
+
"allow-empty",
|
|
31
|
+
"build",
|
|
32
|
+
"check-updates",
|
|
33
|
+
"docker",
|
|
34
|
+
"help",
|
|
35
|
+
"interactive",
|
|
36
|
+
"json",
|
|
37
|
+
"major",
|
|
38
|
+
"merge",
|
|
39
|
+
"minor",
|
|
40
|
+
"npm",
|
|
41
|
+
"patch",
|
|
42
|
+
"plain",
|
|
43
|
+
"plan",
|
|
44
|
+
"push",
|
|
45
|
+
"quiet",
|
|
46
|
+
"test",
|
|
47
|
+
"yes",
|
|
48
|
+
]);
|
|
49
|
+
|
|
27
50
|
const camelCase = (value: string): string => {
|
|
28
51
|
return value.replace(/-([a-z])/g, (_match, group: string) =>
|
|
29
52
|
group.toUpperCase(),
|
|
@@ -55,13 +78,23 @@ const parseRawArgv = (argv: string[]): TArgSource => {
|
|
|
55
78
|
|
|
56
79
|
if (currentArg.startsWith("--")) {
|
|
57
80
|
const withoutPrefix = currentArg.slice(2);
|
|
58
|
-
const
|
|
81
|
+
const equalsIndex = withoutPrefix.indexOf("=");
|
|
82
|
+
const rawKey =
|
|
83
|
+
equalsIndex === -1 ? withoutPrefix : withoutPrefix.slice(0, equalsIndex);
|
|
84
|
+
const inlineValue =
|
|
85
|
+
equalsIndex === -1 ? undefined : withoutPrefix.slice(equalsIndex + 1);
|
|
59
86
|
if (inlineValue !== undefined) {
|
|
60
87
|
parsedArgv[rawKey] = inlineValue;
|
|
61
88
|
parsedArgv[camelCase(rawKey)] = inlineValue;
|
|
62
89
|
continue;
|
|
63
90
|
}
|
|
64
91
|
|
|
92
|
+
if (booleanLongFlags.has(rawKey)) {
|
|
93
|
+
parsedArgv[rawKey] = true;
|
|
94
|
+
parsedArgv[camelCase(rawKey)] = true;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
|
|
65
98
|
const nextArg = argv[i + 1];
|
|
66
99
|
if (nextArg && !nextArg.startsWith("-")) {
|
|
67
100
|
parsedArgv[rawKey] = nextArg;
|
package/ts/helpers.workflow.ts
CHANGED
|
@@ -127,6 +127,13 @@ export interface IResolvedReleaseWorkflow {
|
|
|
127
127
|
dockerNoBuild: boolean;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
export interface IResolvedReleaseResumeConfiguration {
|
|
131
|
+
gitRemote: string;
|
|
132
|
+
npmRegistries: string[];
|
|
133
|
+
npmAccessLevel: "public" | "private";
|
|
134
|
+
npmAlreadyPublished: "success" | "error";
|
|
135
|
+
}
|
|
136
|
+
|
|
130
137
|
interface ICliWorkflowConfig {
|
|
131
138
|
commit?: ICommitWorkflowConfig;
|
|
132
139
|
release?: IReleaseWorkflowConfig;
|
|
@@ -339,12 +346,31 @@ const normalizeCommitSteps = (rawSteps: TCommitStep[]): TCommitStep[] => {
|
|
|
339
346
|
|
|
340
347
|
const getTargetOverride = (argvArg: any): TReleaseTarget[] | undefined => {
|
|
341
348
|
const validTargets: TReleaseTarget[] = ["git", "npm", "docker"];
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
|
|
349
|
+
const targetKey = ["target", "targets"].find((keyArg) =>
|
|
350
|
+
Object.prototype.hasOwnProperty.call(argvArg, keyArg),
|
|
351
|
+
);
|
|
352
|
+
if (targetKey) {
|
|
353
|
+
const rawTargets = argvArg[targetKey];
|
|
354
|
+
if (typeof rawTargets !== "string" || !rawTargets.trim()) {
|
|
355
|
+
throw new Error(
|
|
356
|
+
"--target requires a non-empty comma-separated list of release targets.",
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
const requestedTargets = rawTargets
|
|
345
360
|
.split(",")
|
|
346
|
-
.map((target) => target.trim())
|
|
347
|
-
|
|
361
|
+
.map((target) => target.trim());
|
|
362
|
+
if (requestedTargets.some((target) => !target)) {
|
|
363
|
+
throw new Error(
|
|
364
|
+
"--target requires a non-empty comma-separated list of release targets.",
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
const invalidTargets = requestedTargets.filter(
|
|
368
|
+
(target) => !validTargets.includes(target as TReleaseTarget),
|
|
369
|
+
);
|
|
370
|
+
if (invalidTargets.length > 0) {
|
|
371
|
+
throw new Error(`Unknown release target: ${invalidTargets.join(", ")}`);
|
|
372
|
+
}
|
|
373
|
+
return requestedTargets as TReleaseTarget[];
|
|
348
374
|
}
|
|
349
375
|
|
|
350
376
|
const targets: TReleaseTarget[] = [];
|
|
@@ -369,6 +395,8 @@ const buildReleasePlan = (options: {
|
|
|
369
395
|
}
|
|
370
396
|
plan.push("core.version", "core.changelog", "core.commit", "core.tag");
|
|
371
397
|
if (options.runBuild) plan.push("core.build");
|
|
398
|
+
if (options.targets.includes("npm")) plan.push("core.packNpmArtifact");
|
|
399
|
+
plan.push("core.writeReleaseJournal");
|
|
372
400
|
for (const target of options.targets) {
|
|
373
401
|
plan.push(`target.${target}`);
|
|
374
402
|
}
|
|
@@ -435,8 +463,11 @@ export const resolveReleaseWorkflow = async (argvArg: any): Promise<IResolvedRel
|
|
|
435
463
|
const gitConfig = targetConfig.git || {};
|
|
436
464
|
const npmConfig = targetConfig.npm || {};
|
|
437
465
|
const dockerConfig = targetConfig.docker || {};
|
|
438
|
-
const
|
|
439
|
-
const
|
|
466
|
+
const rawNpmRegistries = npmConfig.registries;
|
|
467
|
+
const npmRegistryConfigurationPresent = Array.isArray(rawNpmRegistries)
|
|
468
|
+
? rawNpmRegistries.length > 0
|
|
469
|
+
: rawNpmRegistries !== undefined;
|
|
470
|
+
const npmEnabled = npmConfig.enabled ?? npmRegistryConfigurationPresent;
|
|
440
471
|
const gitEnabled = gitConfig.enabled ?? true;
|
|
441
472
|
const dockerEnabled = dockerConfig.enabled ?? false;
|
|
442
473
|
const pushBranch = resolveGitPushSetting(
|
|
@@ -479,6 +510,22 @@ export const resolveReleaseWorkflow = async (argvArg: any): Promise<IResolvedRel
|
|
|
479
510
|
targets = releaseTargetOrder.filter((target) =>
|
|
480
511
|
selectedTargets.includes(target),
|
|
481
512
|
);
|
|
513
|
+
let npmRegistries: string[] = [];
|
|
514
|
+
if (targets.includes("npm")) {
|
|
515
|
+
if (
|
|
516
|
+
rawNpmRegistries !== undefined &&
|
|
517
|
+
(!Array.isArray(rawNpmRegistries) ||
|
|
518
|
+
rawNpmRegistries.some((registryArg) => typeof registryArg !== "string"))
|
|
519
|
+
) {
|
|
520
|
+
throw new Error("release.targets.npm.registries must be an array of strings");
|
|
521
|
+
}
|
|
522
|
+
npmRegistries = (rawNpmRegistries || []).map(normalizeRegistryUrl);
|
|
523
|
+
if (new Set(npmRegistries).size !== npmRegistries.length) {
|
|
524
|
+
throw new Error(
|
|
525
|
+
"release.targets.npm.registries must be unique after normalization",
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
482
529
|
const mergeRequested = argvArg.merge === true;
|
|
483
530
|
|
|
484
531
|
return {
|
|
@@ -521,3 +568,63 @@ export const resolveReleaseWorkflow = async (argvArg: any): Promise<IResolvedRel
|
|
|
521
568
|
dockerNoBuild: dockerConfig.noBuild ?? false,
|
|
522
569
|
};
|
|
523
570
|
};
|
|
571
|
+
|
|
572
|
+
export const resolveReleaseResumeConfiguration = async (optionsArg: {
|
|
573
|
+
git: boolean;
|
|
574
|
+
npm: boolean;
|
|
575
|
+
}): Promise<IResolvedReleaseResumeConfiguration> => {
|
|
576
|
+
const cliConfig = await readCliWorkflowConfig();
|
|
577
|
+
const releaseConfig = cliConfig.release || {};
|
|
578
|
+
const targetConfig = releaseConfig.targets || {};
|
|
579
|
+
const gitConfig = targetConfig.git || {};
|
|
580
|
+
const npmConfig = targetConfig.npm || {};
|
|
581
|
+
|
|
582
|
+
const gitRemote = optionsArg.git ? gitConfig.remote || "origin" : "origin";
|
|
583
|
+
if (typeof gitRemote !== "string" || !gitRemote.trim()) {
|
|
584
|
+
throw new Error("release.targets.git.remote must be a non-empty string");
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
let npmRegistries: string[] = [];
|
|
588
|
+
let npmAccessLevel: "public" | "private" = "public";
|
|
589
|
+
let npmAlreadyPublished: "success" | "error" = "success";
|
|
590
|
+
if (optionsArg.npm) {
|
|
591
|
+
if (
|
|
592
|
+
npmConfig.registries !== undefined &&
|
|
593
|
+
(!Array.isArray(npmConfig.registries) ||
|
|
594
|
+
npmConfig.registries.some((registryArg) => typeof registryArg !== "string"))
|
|
595
|
+
) {
|
|
596
|
+
throw new Error("release.targets.npm.registries must be an array of strings");
|
|
597
|
+
}
|
|
598
|
+
npmRegistries = (npmConfig.registries || []).map(normalizeRegistryUrl);
|
|
599
|
+
if (new Set(npmRegistries).size !== npmRegistries.length) {
|
|
600
|
+
throw new Error(
|
|
601
|
+
"release.targets.npm.registries must be unique after normalization",
|
|
602
|
+
);
|
|
603
|
+
}
|
|
604
|
+
if (
|
|
605
|
+
npmConfig.accessLevel !== undefined &&
|
|
606
|
+
npmConfig.accessLevel !== "public" &&
|
|
607
|
+
npmConfig.accessLevel !== "private"
|
|
608
|
+
) {
|
|
609
|
+
throw new Error("release.targets.npm.accessLevel must be public or private");
|
|
610
|
+
}
|
|
611
|
+
if (
|
|
612
|
+
npmConfig.alreadyPublished !== undefined &&
|
|
613
|
+
npmConfig.alreadyPublished !== "success" &&
|
|
614
|
+
npmConfig.alreadyPublished !== "error"
|
|
615
|
+
) {
|
|
616
|
+
throw new Error(
|
|
617
|
+
"release.targets.npm.alreadyPublished must be success or error",
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
npmAccessLevel = npmConfig.accessLevel || "public";
|
|
621
|
+
npmAlreadyPublished = npmConfig.alreadyPublished || "success";
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
return {
|
|
625
|
+
gitRemote,
|
|
626
|
+
npmRegistries,
|
|
627
|
+
npmAccessLevel,
|
|
628
|
+
npmAlreadyPublished,
|
|
629
|
+
};
|
|
630
|
+
};
|