rman 1.0.7 → 1.0.9
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 +12 -3
- package/commands/changelog.command.js +21 -6
- package/commands/publish.command.js +68 -9
- package/commands/version.command.js +4 -2
- package/constants.js +1 -1
- package/core/config.d.ts +1 -92
- package/core/package.d.ts +1 -1
- package/index.d.ts +1 -1
- package/index.js +11 -0
- package/interfaces/rman-config.interface.d.ts +130 -0
- package/interfaces/rman-config.interface.js +1 -0
- package/package.json +1 -1
- package/rmanrc.schema.json +129 -20
- package/services/changelog.service.d.ts +24 -12
- package/services/changelog.service.js +18 -17
- package/services/docker-publish.service.js +1 -1
- package/services/github-release.service.d.ts +68 -0
- package/services/github-release.service.js +265 -0
- package/services/list.service.d.ts +1 -1
- package/services/publish.service.js +9 -1
- package/services/version.service.d.ts +15 -4
- package/services/version.service.js +74 -32
- package/services.d.ts +1 -0
- package/services.js +1 -0
- package/utils/change-hash.d.ts +21 -8
- package/utils/change-hash.js +38 -20
- package/utils/conventional-commits.d.ts +13 -0
- package/utils/conventional-commits.js +47 -0
- package/utils/git.d.ts +8 -1
- package/utils/git.js +26 -2
- package/utils/release-version.d.ts +50 -0
- package/utils/release-version.js +66 -0
package/rmanrc.schema.json
CHANGED
|
@@ -11,7 +11,12 @@
|
|
|
11
11
|
},
|
|
12
12
|
"packageManager": {
|
|
13
13
|
"type": "string",
|
|
14
|
-
"enum": [
|
|
14
|
+
"enum": [
|
|
15
|
+
"npm",
|
|
16
|
+
"yarn",
|
|
17
|
+
"pnpm",
|
|
18
|
+
"bun"
|
|
19
|
+
],
|
|
15
20
|
"default": "npm",
|
|
16
21
|
"description": "Package manager used by \"ci\"/\"publish\". Root-level only - an explicit --package-manager CLI flag wins over this."
|
|
17
22
|
},
|
|
@@ -31,7 +36,15 @@
|
|
|
31
36
|
"group": {
|
|
32
37
|
"description": "Release-versioning group for \"version\"/\"publish\": true (default) puts the package in the implicit repo-wide group; a string joins exactly the other packages sharing that string; false makes it a solo, fully independent group. Per-package cascaded.",
|
|
33
38
|
"default": true,
|
|
34
|
-
"oneOf": [
|
|
39
|
+
"oneOf": [
|
|
40
|
+
{
|
|
41
|
+
"type": "boolean"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"type": "string",
|
|
45
|
+
"minLength": 1
|
|
46
|
+
}
|
|
47
|
+
]
|
|
35
48
|
},
|
|
36
49
|
"version": {
|
|
37
50
|
"type": "object",
|
|
@@ -43,6 +56,16 @@
|
|
|
43
56
|
"default": "chore(release): v{version}",
|
|
44
57
|
"description": "Commit message for every group a \"version\" run commits. \"{version}\" is substituted when every bumped package in that commit shares one version. Root-level only."
|
|
45
58
|
},
|
|
59
|
+
"changelog": {
|
|
60
|
+
"type": "boolean",
|
|
61
|
+
"default": false,
|
|
62
|
+
"description": "Default for \"version --changelog\" when the CLI flag isn't given - an explicit --changelog/--no-changelog still wins. Root-level only."
|
|
63
|
+
},
|
|
64
|
+
"releaseTagPattern": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"default": "release-*",
|
|
67
|
+
"description": "Root-level. Tag naming the repository's own release, as opposed to the per-package/group tags \"changelog.tagPattern\" names - only created when the root is on a calendar version (a repo with more than one version line). Must NOT match any package's \"changelog.tagPattern\", or that package's changelog boundary resolves to the repository release instead of its own."
|
|
68
|
+
},
|
|
46
69
|
"script": {
|
|
47
70
|
"$ref": "#/definitions/stringOrStringArray",
|
|
48
71
|
"description": "Command(s) to run as this package's own \"version\" npm-lifecycle step, when its package.json does not define one itself."
|
|
@@ -64,7 +87,9 @@
|
|
|
64
87
|
"properties": {
|
|
65
88
|
"ignoreTypes": {
|
|
66
89
|
"type": "array",
|
|
67
|
-
"items": {
|
|
90
|
+
"items": {
|
|
91
|
+
"type": "string"
|
|
92
|
+
},
|
|
68
93
|
"default": [],
|
|
69
94
|
"description": "Conventional Commit types (e.g. \"chore\", \"ci\") dropped entirely from changelog output, instead of being folded into \"Other Changes\". Per-package cascaded."
|
|
70
95
|
},
|
|
@@ -106,27 +131,47 @@
|
|
|
106
131
|
},
|
|
107
132
|
"publish": {
|
|
108
133
|
"type": "object",
|
|
109
|
-
"description": "Options for the \"publish\" command/PublishService and
|
|
134
|
+
"description": "Options for the \"publish\" command/PublishService, DockerPublishService and GithubReleaseService. Per-package cascaded.",
|
|
110
135
|
"additionalProperties": false,
|
|
111
136
|
"properties": {
|
|
112
137
|
"target": {
|
|
113
|
-
"description": "
|
|
114
|
-
"default": [
|
|
138
|
+
"description": "Where \"publish\" releases this package to. Default [\"npm\"]. A package that only ships Docker images (typically also \"private\": true) sets [\"docker\"]; a standalone app shipped as GitHub Release assets - or deployed elsewhere, with the release only recording that it shipped - sets [\"github\"]; any combination works. Each target answers \"is this version already out there?\" against its own registry: npm via \"npm view\", docker via \"docker manifest inspect\", github via the release for that version's tag.",
|
|
139
|
+
"default": [
|
|
140
|
+
"npm"
|
|
141
|
+
],
|
|
115
142
|
"oneOf": [
|
|
116
|
-
{
|
|
117
|
-
|
|
143
|
+
{
|
|
144
|
+
"$ref": "#/definitions/publishTarget"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"type": "array",
|
|
148
|
+
"items": {
|
|
149
|
+
"$ref": "#/definitions/publishTarget"
|
|
150
|
+
}
|
|
151
|
+
}
|
|
118
152
|
]
|
|
119
153
|
},
|
|
120
154
|
"docker": {
|
|
121
155
|
"$ref": "#/definitions/dockerPublishConfig",
|
|
122
156
|
"description": "Required once \"docker\" is one of this package's \"publish.target\"s."
|
|
157
|
+
},
|
|
158
|
+
"github": {
|
|
159
|
+
"$ref": "#/definitions/githubPublishConfig",
|
|
160
|
+
"description": "Optional even when \"github\" is one of this package's \"publish.target\"s - every required fact already has a sensible default source."
|
|
161
|
+
},
|
|
162
|
+
"skip": {
|
|
163
|
+
"type": "boolean",
|
|
164
|
+
"default": false,
|
|
165
|
+
"description": "Excludes this package from \"publish\" entirely (every target), regardless of \"target\"/\"private\" - a single, explicit \"never published\" statement. \"changelog\" also skips it by default (see its own --include-skipped). Independent of \"version\", which never consults this."
|
|
123
166
|
}
|
|
124
167
|
}
|
|
125
168
|
},
|
|
126
169
|
"run": {
|
|
127
170
|
"type": "object",
|
|
128
171
|
"description": "Per-script options for \"run\"/\"build\"/\"test\"/RunService, keyed by npm script name (e.g. \"build\", \"lint\", \"test\").",
|
|
129
|
-
"additionalProperties": {
|
|
172
|
+
"additionalProperties": {
|
|
173
|
+
"$ref": "#/definitions/runScriptConfig"
|
|
174
|
+
}
|
|
130
175
|
},
|
|
131
176
|
"packages": {
|
|
132
177
|
"type": "object",
|
|
@@ -138,8 +183,18 @@
|
|
|
138
183
|
"dependencies": {
|
|
139
184
|
"description": "Extra in-repo \"dependencies\" not present in this package's real package.json, purely for rman's own dependency graph (topo-sort, --deps/--dependents, run's task scheduling). An array defaults each entry's range to \"*\"; an object gives an explicit name -> range map.",
|
|
140
185
|
"oneOf": [
|
|
141
|
-
{
|
|
142
|
-
|
|
186
|
+
{
|
|
187
|
+
"type": "array",
|
|
188
|
+
"items": {
|
|
189
|
+
"type": "string"
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"type": "object",
|
|
194
|
+
"additionalProperties": {
|
|
195
|
+
"type": "string"
|
|
196
|
+
}
|
|
197
|
+
}
|
|
143
198
|
]
|
|
144
199
|
}
|
|
145
200
|
}
|
|
@@ -149,22 +204,42 @@
|
|
|
149
204
|
"definitions": {
|
|
150
205
|
"logLevel": {
|
|
151
206
|
"type": "string",
|
|
152
|
-
"enum": [
|
|
207
|
+
"enum": [
|
|
208
|
+
"silent",
|
|
209
|
+
"error",
|
|
210
|
+
"info",
|
|
211
|
+
"verbose"
|
|
212
|
+
]
|
|
153
213
|
},
|
|
154
214
|
"stringOrStringArray": {
|
|
155
215
|
"oneOf": [
|
|
156
|
-
{
|
|
157
|
-
|
|
216
|
+
{
|
|
217
|
+
"type": "string",
|
|
218
|
+
"minLength": 1
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"type": "array",
|
|
222
|
+
"items": {
|
|
223
|
+
"type": "string",
|
|
224
|
+
"minLength": 1
|
|
225
|
+
}
|
|
226
|
+
}
|
|
158
227
|
]
|
|
159
228
|
},
|
|
160
229
|
"publishTarget": {
|
|
161
230
|
"type": "string",
|
|
162
|
-
"enum": [
|
|
231
|
+
"enum": [
|
|
232
|
+
"npm",
|
|
233
|
+
"docker",
|
|
234
|
+
"github"
|
|
235
|
+
]
|
|
163
236
|
},
|
|
164
237
|
"dockerPublishConfig": {
|
|
165
238
|
"type": "object",
|
|
166
239
|
"additionalProperties": false,
|
|
167
|
-
"required": [
|
|
240
|
+
"required": [
|
|
241
|
+
"image"
|
|
242
|
+
],
|
|
168
243
|
"properties": {
|
|
169
244
|
"image": {
|
|
170
245
|
"type": "string",
|
|
@@ -178,8 +253,12 @@
|
|
|
178
253
|
},
|
|
179
254
|
"platforms": {
|
|
180
255
|
"type": "array",
|
|
181
|
-
"items": {
|
|
182
|
-
|
|
256
|
+
"items": {
|
|
257
|
+
"type": "string"
|
|
258
|
+
},
|
|
259
|
+
"default": [
|
|
260
|
+
"linux/amd64"
|
|
261
|
+
],
|
|
183
262
|
"description": "\"docker buildx build --platform\" targets."
|
|
184
263
|
},
|
|
185
264
|
"cwd": {
|
|
@@ -188,12 +267,16 @@
|
|
|
188
267
|
},
|
|
189
268
|
"buildContexts": {
|
|
190
269
|
"type": "object",
|
|
191
|
-
"additionalProperties": {
|
|
270
|
+
"additionalProperties": {
|
|
271
|
+
"type": "string"
|
|
272
|
+
},
|
|
192
273
|
"description": "Named \"docker buildx build --build-context <name>=<path>\" entries, keyed by name - each path relative to the package's own directory (or absolute)."
|
|
193
274
|
},
|
|
194
275
|
"buildArgs": {
|
|
195
276
|
"type": "object",
|
|
196
|
-
"additionalProperties": {
|
|
277
|
+
"additionalProperties": {
|
|
278
|
+
"type": "string"
|
|
279
|
+
},
|
|
197
280
|
"description": "\"docker buildx build --build-arg <name>=<value>\" entries - a value of exactly \"$NAME\" expands to the NAME environment variable at build time."
|
|
198
281
|
},
|
|
199
282
|
"readme": {
|
|
@@ -203,6 +286,32 @@
|
|
|
203
286
|
}
|
|
204
287
|
}
|
|
205
288
|
},
|
|
289
|
+
"githubPublishConfig": {
|
|
290
|
+
"type": "object",
|
|
291
|
+
"additionalProperties": false,
|
|
292
|
+
"properties": {
|
|
293
|
+
"assets": {
|
|
294
|
+
"type": "array",
|
|
295
|
+
"items": {
|
|
296
|
+
"type": "string"
|
|
297
|
+
},
|
|
298
|
+
"description": "Files to attach to the release, as glob patterns relative to the package's own directory (e.g. [\"dist/*.tar.gz\"]). A release with no assets is still valid."
|
|
299
|
+
},
|
|
300
|
+
"repository": {
|
|
301
|
+
"type": "string",
|
|
302
|
+
"description": "\"owner/repo\". Default: parsed from the \"origin\" remote's URL."
|
|
303
|
+
},
|
|
304
|
+
"draft": {
|
|
305
|
+
"type": "boolean",
|
|
306
|
+
"default": false,
|
|
307
|
+
"description": "Create the release as an unpublished draft."
|
|
308
|
+
},
|
|
309
|
+
"prerelease": {
|
|
310
|
+
"type": "boolean",
|
|
311
|
+
"description": "Default: whether the version being released is itself a semver prerelease."
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
},
|
|
206
315
|
"runScriptConfig": {
|
|
207
316
|
"type": "object",
|
|
208
317
|
"additionalProperties": false,
|
|
@@ -11,10 +11,11 @@ export declare namespace ChangelogService {
|
|
|
11
11
|
interface Options extends PackageFilterOptions {
|
|
12
12
|
/** Generate the changelog since this commit/hash - applied the same way to every package.
|
|
13
13
|
* Default (also `"npm"` explicitly): auto-detect it per package instead, from that package's
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* own most recent release tag first - the same lookup `VersionService`/`changed` use, so this
|
|
15
|
+
* never disagrees with them - falling back to its currently-published npm version only when
|
|
16
|
+
* it has no tag yet (see `detectChangeHash`); a package this can't be resolved for either way
|
|
17
|
+
* (never tagged, unpublished, no network) has never been released at all, so its whole
|
|
18
|
+
* history counts as unreleased - the same view `version` takes. */
|
|
18
19
|
from?: string;
|
|
19
20
|
/** Generate for the whole repository even when the current directory is inside a single
|
|
20
21
|
* package (which otherwise scopes it to just that package) - see `Repository.currentPackage`. */
|
|
@@ -28,6 +29,17 @@ export declare namespace ChangelogService {
|
|
|
28
29
|
* what's actually published) doesn't get changes silently skipped over - see
|
|
29
30
|
* `detectChangeHash`'s `catchUpFile`. */
|
|
30
31
|
filePath?: string;
|
|
32
|
+
/** A package with `.rmanrc "publish.skip"` is excluded by default - little point changelogging
|
|
33
|
+
* something that's never actually released. Set true to generate for it anyway. */
|
|
34
|
+
includeSkipped?: boolean;
|
|
35
|
+
/** The version these entries are being generated *for* - what `{{version}}` renders as.
|
|
36
|
+
* Without it the version is read back from git tags (see `resolveVersion`), which is only
|
|
37
|
+
* correct once the release being described has actually been tagged. A caller generating
|
|
38
|
+
* notes for a release that doesn't exist yet - `version --changelog` writing the entry before
|
|
39
|
+
* it commits and tags, or a CI step producing release notes ahead of the bump - already knows
|
|
40
|
+
* the number and has to say so, otherwise every entry ends up labelled with the *previous*
|
|
41
|
+
* release's version. */
|
|
42
|
+
version?: string;
|
|
31
43
|
}
|
|
32
44
|
/** One package's (root included) generated changelog entry - what `getEntries`/`generate`
|
|
33
45
|
* return. */
|
|
@@ -36,7 +48,8 @@ export declare namespace ChangelogService {
|
|
|
36
48
|
/** Display name for this entry's heading - `"<repo dir name> repository"` for the root
|
|
37
49
|
* package, its own name otherwise (see `getEntries`'s doc comment on `{{package}}`). */
|
|
38
50
|
label: string;
|
|
39
|
-
/**
|
|
51
|
+
/** `options.version` when the caller gave one, otherwise resolved from git tags rather than
|
|
52
|
+
* package.json - see `resolveVersion`. */
|
|
40
53
|
version: string;
|
|
41
54
|
features: string[];
|
|
42
55
|
fixes: string[];
|
|
@@ -68,16 +81,15 @@ export declare namespace ChangelogService {
|
|
|
68
81
|
* Fixes/🔧 Other Changes on a best-effort Conventional Commits read; anything that doesn't parse
|
|
69
82
|
* just lands in Other Changes as-is, so a repo that doesn't follow that convention still gets a
|
|
70
83
|
* usable list. `.rmanrc changelog.ignoreTypes` (cascaded, e.g. `[chore, dev]`) drops commits of
|
|
71
|
-
* those types entirely instead - see `ignoreTypesConfig`. A bare version-bump
|
|
72
|
-
* (`"6.0.1"`)
|
|
73
|
-
* `
|
|
84
|
+
* those types entirely instead - see `ignoreTypesConfig`. A release marker - a bare version-bump
|
|
85
|
+
* commit (`"6.0.1"`), or any of the messages `version` itself writes - is always dropped
|
|
86
|
+
* outright, regardless of `ignoreTypes`; see `isReleaseCommit`.
|
|
74
87
|
*
|
|
75
88
|
* By default (or with `--from npm` explicitly), the boundary is auto-detected per package
|
|
76
89
|
* instead of one shared one - see `detectChangeHash`. A package that can't be resolved this way
|
|
77
|
-
* (unpublished, no network, no matching tag)
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* for a repo that's never been published or tagged at all. Packages that end up resolving to
|
|
90
|
+
* (unpublished, no network, no matching tag) has never been released at all, so its whole
|
|
91
|
+
* history counts as unreleased - the same view `version` takes, so a first-ever release still
|
|
92
|
+
* produces a real changelog. Packages that end up resolving to
|
|
81
93
|
* the same hash (an explicit one, or several packages sharing one tag under fixed versioning)
|
|
82
94
|
* only have their commits fetched once, not once per package.
|
|
83
95
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { detectChangeHash, extractVersion, findLatestTag, tagPattern } from '../utils/change-hash.js';
|
|
4
|
-
import {
|
|
4
|
+
import { isReleaseCommit, parseConventionalCommit } from '../utils/conventional-commits.js';
|
|
5
5
|
import { GitHelper } from '../utils/git.js';
|
|
6
6
|
import { filterPackages } from '../utils/package-filter.js';
|
|
7
7
|
export var ChangelogService;
|
|
@@ -33,16 +33,15 @@ export var ChangelogService;
|
|
|
33
33
|
* Fixes/🔧 Other Changes on a best-effort Conventional Commits read; anything that doesn't parse
|
|
34
34
|
* just lands in Other Changes as-is, so a repo that doesn't follow that convention still gets a
|
|
35
35
|
* usable list. `.rmanrc changelog.ignoreTypes` (cascaded, e.g. `[chore, dev]`) drops commits of
|
|
36
|
-
* those types entirely instead - see `ignoreTypesConfig`. A bare version-bump
|
|
37
|
-
* (`"6.0.1"`)
|
|
38
|
-
* `
|
|
36
|
+
* those types entirely instead - see `ignoreTypesConfig`. A release marker - a bare version-bump
|
|
37
|
+
* commit (`"6.0.1"`), or any of the messages `version` itself writes - is always dropped
|
|
38
|
+
* outright, regardless of `ignoreTypes`; see `isReleaseCommit`.
|
|
39
39
|
*
|
|
40
40
|
* By default (or with `--from npm` explicitly), the boundary is auto-detected per package
|
|
41
41
|
* instead of one shared one - see `detectChangeHash`. A package that can't be resolved this way
|
|
42
|
-
* (unpublished, no network, no matching tag)
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* for a repo that's never been published or tagged at all. Packages that end up resolving to
|
|
42
|
+
* (unpublished, no network, no matching tag) has never been released at all, so its whole
|
|
43
|
+
* history counts as unreleased - the same view `version` takes, so a first-ever release still
|
|
44
|
+
* produces a real changelog. Packages that end up resolving to
|
|
46
45
|
* the same hash (an explicit one, or several packages sharing one tag under fixed versioning)
|
|
47
46
|
* only have their commits fetched once, not once per package.
|
|
48
47
|
*
|
|
@@ -63,11 +62,12 @@ export var ChangelogService;
|
|
|
63
62
|
async function getEntries(repository, options = {}, deps = {}) {
|
|
64
63
|
const cwdScope = options.root ? undefined : repository.currentPackage;
|
|
65
64
|
const packages = repository.getPackages().filter(p => p !== repository.rootPackage);
|
|
66
|
-
const targets = cwdScope ? [cwdScope] : filterPackages([repository.rootPackage, ...packages], options);
|
|
65
|
+
const targets = (cwdScope ? [cwdScope] : filterPackages([repository.rootPackage, ...packages], options)).filter(pkg => options.includeSkipped || !pkg.config.publish?.skip);
|
|
67
66
|
const git = new GitHelper({ cwd: repository.dirname });
|
|
68
|
-
|
|
67
|
+
const commitMessage = repository.rootPackage.config?.version?.commitMessage;
|
|
68
|
+
// dropped up front, not just while grouping - a package whose only commits are release markers
|
|
69
69
|
// should get no entry at all, rather than a heading with nothing real underneath it.
|
|
70
|
-
const dropVersionBumps = (commits) => commits.filter(c => !
|
|
70
|
+
const dropVersionBumps = (commits) => commits.filter(c => !isReleaseCommit(c.subject, commitMessage));
|
|
71
71
|
// Several packages often resolve to the identical hash (an explicit --from <hash> applies to
|
|
72
72
|
// all of them the same way; under fixed versioning, npm auto-detection usually does too) - so
|
|
73
73
|
// the git fetch for a given hash is cached, run once no matter how many packages share it.
|
|
@@ -76,7 +76,10 @@ export var ChangelogService;
|
|
|
76
76
|
const key = hash ?? '';
|
|
77
77
|
let promise = commitsByHash.get(key);
|
|
78
78
|
if (!promise) {
|
|
79
|
-
|
|
79
|
+
// No boundary at all means nothing has ever been released, so everything so far is
|
|
80
|
+
// unreleased - the same fallback `VersionService` makes. (Not "not yet pushed": that reads
|
|
81
|
+
// as empty the moment a first release is pushed, and for a repo with no remote at all.)
|
|
82
|
+
promise = (hash ? git.listCommits({ hash }) : git.listAllCommits()).then(dropVersionBumps);
|
|
80
83
|
commitsByHash.set(key, promise);
|
|
81
84
|
}
|
|
82
85
|
return promise;
|
|
@@ -102,7 +105,7 @@ export var ChangelogService;
|
|
|
102
105
|
if (!grouped.features.length && !grouped.fixes.length && !grouped.other.length)
|
|
103
106
|
continue;
|
|
104
107
|
const label = pkg === repository.rootPackage ? `${path.basename(repository.dirname)} repository` : pkg.name;
|
|
105
|
-
const { version, content } = await renderEntry(repository, pkg, label, grouped, git);
|
|
108
|
+
const { version, content } = await renderEntry(repository, pkg, label, grouped, git, options.version);
|
|
106
109
|
entries.push({
|
|
107
110
|
package: pkg,
|
|
108
111
|
label,
|
|
@@ -129,8 +132,6 @@ function ignoreTypesConfig(pkg) {
|
|
|
129
132
|
function groupCommits(subjects, ignoreTypes = new Set()) {
|
|
130
133
|
const grouped = { features: [], fixes: [], other: [] };
|
|
131
134
|
for (const subject of subjects) {
|
|
132
|
-
if (VERSION_BUMP_PATTERN.test(subject))
|
|
133
|
-
continue;
|
|
134
135
|
const parsed = parseConventionalCommit(subject);
|
|
135
136
|
if (!parsed) {
|
|
136
137
|
grouped.other.push(subject);
|
|
@@ -244,9 +245,9 @@ function ownersOf(repository, commit) {
|
|
|
244
245
|
}
|
|
245
246
|
return owners;
|
|
246
247
|
}
|
|
247
|
-
async function renderEntry(repository, pkg, label, grouped, git) {
|
|
248
|
+
async function renderEntry(repository, pkg, label, grouped, git, versionOverride) {
|
|
248
249
|
const template = resolveTemplate(repository, pkg);
|
|
249
|
-
const version = await resolveVersion(git, pkg);
|
|
250
|
+
const version = versionOverride ?? (await resolveVersion(git, pkg));
|
|
250
251
|
const content = render(template, {
|
|
251
252
|
package: label,
|
|
252
253
|
version,
|
|
@@ -22,7 +22,7 @@ export var DockerPublishService;
|
|
|
22
22
|
*/
|
|
23
23
|
async function getPlan(repository, options = {}, deps = {}) {
|
|
24
24
|
const git = new GitHelper({ cwd: repository.dirname });
|
|
25
|
-
const packages = filterPackages(repository.getPackages({ toposort: true }), options).filter(targetsDocker);
|
|
25
|
+
const packages = filterPackages(repository.getPackages({ toposort: true }), options).filter(pkg => targetsDocker(pkg) && !pkg.config.publish?.skip);
|
|
26
26
|
const dirtyFiles = await git.listDirtyFiles({ absolute: true });
|
|
27
27
|
const isDirty = (pkg) => dirtyFiles.some(f => !path.relative(pkg.dirname, f).startsWith('..'));
|
|
28
28
|
const imageExists = deps.imageExists ?? defaultImageExists;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Package } from '../core/package.js';
|
|
2
|
+
import type { Repository } from '../core/repository.js';
|
|
3
|
+
export declare namespace GithubReleaseService {
|
|
4
|
+
/** Injectable "does this release already exist" check - mainly for tests, so they don't depend
|
|
5
|
+
* on network access or a real GitHub token. Same shape as `DockerPublishService.Deps`' own
|
|
6
|
+
* `imageExists`. */
|
|
7
|
+
interface Deps {
|
|
8
|
+
releaseExists?: (repository: string, tag: string) => Promise<boolean>;
|
|
9
|
+
}
|
|
10
|
+
interface Options {
|
|
11
|
+
/** Uncommitted local changes anywhere in the repository make the release `'skip'` instead of
|
|
12
|
+
* `'error'` - same as `version`/`publish`'s other targets. */
|
|
13
|
+
ignoreDirty?: boolean;
|
|
14
|
+
/** `owner/repo` override - otherwise the root's own `publish.github.repository`, falling back
|
|
15
|
+
* to the `origin` remote's URL. */
|
|
16
|
+
repository?: string;
|
|
17
|
+
}
|
|
18
|
+
/** The repository's release outcome - see `getPlan`. At most one of these: a GitHub Release
|
|
19
|
+
* belongs to the repository, not to a package. */
|
|
20
|
+
interface Entry {
|
|
21
|
+
/** Always the repository root - a release covers the whole source tree, not one package. */
|
|
22
|
+
package: Package;
|
|
23
|
+
/** The repository's own release version (see `buildRootEntry`). */
|
|
24
|
+
version: string;
|
|
25
|
+
status: 'publish' | 'skip' | 'up-to-date' | 'error';
|
|
26
|
+
/** The tag this release belongs to - the repository release tag on a calendar version, the
|
|
27
|
+
* single shared version's tag otherwise. */
|
|
28
|
+
tag?: string;
|
|
29
|
+
/** `owner/repo` this release lands in - unset only when it couldn't be resolved (an `'error'`). */
|
|
30
|
+
repository?: string;
|
|
31
|
+
reason?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Computes what `publish --target github` *would* do - **one** release per run, or none.
|
|
35
|
+
*
|
|
36
|
+
* A GitHub Release is a property of the repository, not of a package: the tag covers the whole
|
|
37
|
+
* source tree, so everything that shipped under it belongs in it. That makes the `"github"`
|
|
38
|
+
* target a repository-level opt-in (typically in the root `.rmanrc`, alongside `"npm"`); it's
|
|
39
|
+
* honored as soon as *any* package resolves it, since a per-package release would have to invent
|
|
40
|
+
* a tag no package owns.
|
|
41
|
+
*
|
|
42
|
+
* The release is identified by the repository's own version (the root's - see
|
|
43
|
+
* `VersionService`'s `buildRootEntry`): its release tag when that version is a calendar one, and
|
|
44
|
+
* otherwise the tag of the single shared version, which is the group's own tag - so a repo with
|
|
45
|
+
* one version line gets no second name for the release it already has. Whether a release exists
|
|
46
|
+
* for that tag decides `'up-to-date'` vs `'publish'`.
|
|
47
|
+
*
|
|
48
|
+
* Uncommitted changes anywhere make it `'error'` unless `options.ignoreDirty` downgrades it to
|
|
49
|
+
* `'skip'`. An unresolvable `owner/repo`, or a lookup that fails for any reason other than "no
|
|
50
|
+
* such release", is `'error'` too - a blocking misconfiguration rather than a silent "not
|
|
51
|
+
* released yet" that only fails later.
|
|
52
|
+
*/
|
|
53
|
+
function getPlan(repository: Repository, options?: Options, deps?: Deps): Promise<Entry[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Creates the repository's GitHub Release, then uploads whatever `publish.github.assets` globs
|
|
56
|
+
* match. The body covers **every** package that shipped under this release - not just the ones
|
|
57
|
+
* naming `"github"` as a target - since the tag covers all of their code either way.
|
|
58
|
+
*
|
|
59
|
+
* Each package's notes are bounded by the *previous repository release*, and headed with that
|
|
60
|
+
* package's own version, so a repo whose packages sit on different version lines still reads
|
|
61
|
+
* correctly. A package with nothing in that range simply contributes no section, which is also
|
|
62
|
+
* how a package that didn't ship in this release is left out - no ancestry arithmetic needed.
|
|
63
|
+
*
|
|
64
|
+
* An existing release for the tag is updated rather than treated as a failure, so a re-run after
|
|
65
|
+
* a partial failure converges.
|
|
66
|
+
*/
|
|
67
|
+
function applyPlan(repository: Repository, plan: Entry[]): Promise<Entry[]>;
|
|
68
|
+
}
|