@anolilab/multi-semantic-release 1.1.6 → 1.1.8
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/CHANGELOG.md +15 -0
- package/README.md +69 -69
- package/package.json +1 -74
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## @anolilab/multi-semantic-release [1.1.8](https://github.com/anolilab/semantic-release/compare/@anolilab/multi-semantic-release@1.1.7...@anolilab/multi-semantic-release@1.1.8) (2025-01-16)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Dependencies
|
|
5
|
+
|
|
6
|
+
* **@anolilab/semantic-release-clean-package-json:** upgraded to 1.0.0
|
|
7
|
+
* **@anolilab/semantic-release-pnpm:** upgraded to 1.1.8
|
|
8
|
+
|
|
9
|
+
## @anolilab/multi-semantic-release [1.1.7](https://github.com/anolilab/semantic-release/compare/@anolilab/multi-semantic-release@1.1.6...@anolilab/multi-semantic-release@1.1.7) (2025-01-14)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Dependencies
|
|
13
|
+
|
|
14
|
+
* **@anolilab/semantic-release-pnpm:** upgraded to 1.1.7
|
|
15
|
+
|
|
1
16
|
## @anolilab/multi-semantic-release [1.1.6](https://github.com/anolilab/semantic-release/compare/@anolilab/multi-semantic-release@1.1.5...@anolilab/multi-semantic-release@1.1.6) (2024-12-15)
|
|
2
17
|
|
|
3
18
|
### Bug Fixes
|
package/README.md
CHANGED
|
@@ -38,12 +38,12 @@ written into `package.json` at release time. This means there's no need to hard-
|
|
|
38
38
|
|
|
39
39
|
### Key features
|
|
40
40
|
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
41
|
+
- CLI & JS API
|
|
42
|
+
- Automated & configurable cross-pkg version bumping
|
|
43
|
+
- Provides alpha & beta-branched release flow
|
|
44
|
+
- Supports npm (v7+), yarn, pnpm, bolt-based monorepos
|
|
45
|
+
- Optional packages ignoring
|
|
46
|
+
- Linux/MacOs/Windows support
|
|
47
47
|
|
|
48
48
|
## Install
|
|
49
49
|
|
|
@@ -67,8 +67,8 @@ multi-semantic-release
|
|
|
67
67
|
|
|
68
68
|
## Requirements
|
|
69
69
|
|
|
70
|
-
-
|
|
71
|
-
-
|
|
70
|
+
- Node.js >= 20.6.1
|
|
71
|
+
- [git-notes enabled](https://github.com/semantic-release/semantic-release/blob/2e4b901c4f412980a425469fae49cfaef500d47a/docs/support/troubleshooting.md#release-not-found-release-branch-after-git-push---force)
|
|
72
72
|
|
|
73
73
|
### yarn / npm (v7+)
|
|
74
74
|
|
|
@@ -138,9 +138,9 @@ For example, let's say your project has 4 packages (i.e. a, b, c and d) and you
|
|
|
138
138
|
|
|
139
139
|
multi-semantic-release can be configured a number of ways:
|
|
140
140
|
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
-
-
|
|
141
|
+
- A `.multi-releaserc` file, written in YAML or JSON, with optional extensions: `.yaml`/ `.yml`/ `.json`/ `.js`
|
|
142
|
+
- A `multi-release.config.js` file that exports an object
|
|
143
|
+
- A `multi-release` key in the workspace root package.json
|
|
144
144
|
|
|
145
145
|
Alternatively some options may be set via CLI flags.
|
|
146
146
|
|
|
@@ -173,7 +173,7 @@ Alternatively some options may be set via CLI flags.
|
|
|
173
173
|
|
|
174
174
|
### Examples
|
|
175
175
|
|
|
176
|
-
-
|
|
176
|
+
- Via multi-release key in the project's package.json file:
|
|
177
177
|
|
|
178
178
|
```json
|
|
179
179
|
{
|
|
@@ -186,7 +186,7 @@ Alternatively some options may be set via CLI flags.
|
|
|
186
186
|
}
|
|
187
187
|
```
|
|
188
188
|
|
|
189
|
-
-
|
|
189
|
+
- Via `.multi-releaserc` file:
|
|
190
190
|
|
|
191
191
|
```json
|
|
192
192
|
{
|
|
@@ -197,7 +197,7 @@ Alternatively some options may be set via CLI flags.
|
|
|
197
197
|
}
|
|
198
198
|
```
|
|
199
199
|
|
|
200
|
-
-
|
|
200
|
+
- Via CLI:
|
|
201
201
|
|
|
202
202
|
```sh
|
|
203
203
|
$ multi-semantic-release --ignore-packages=packages/a/**,packages/b/** --deps.bump=inherit
|
|
@@ -249,11 +249,11 @@ You can also combine the CLI ignore options with the `!` operator at each packag
|
|
|
249
249
|
|
|
250
250
|
We use this tool to release our JS platform code inhouse (GitHub Enterprise + JB TeamCity) and for our OSS (GitHub + Travis CI). Guaranteed working configurations available in projects.
|
|
251
251
|
|
|
252
|
-
-
|
|
253
|
-
-
|
|
254
|
-
-
|
|
255
|
-
-
|
|
256
|
-
-
|
|
252
|
+
- [anolilab/multi-semantic-release](https://github.com/anolilab/semantic-release)
|
|
253
|
+
- [visulima/visulima](https://github.com/visulima/visulima)
|
|
254
|
+
- [qiwi/substrate](https://github.com/qiwi/substrate)
|
|
255
|
+
- [qiwi/json-rpc](https://github.com/qiwi/json-rpc)
|
|
256
|
+
- [qiwi/lint-config-qiwi](https://github.com/qiwi/lint-config-qiwi)
|
|
257
257
|
|
|
258
258
|
## Troubleshooting
|
|
259
259
|
|
|
@@ -274,8 +274,8 @@ The npm token (https://github.com/semantic-release/npm/blob/master/README.md#npm
|
|
|
274
274
|
|
|
275
275
|
Do not rush to change your token. _Perhaps_ this is related to [`npm whoami` request](https://github.com/semantic-release/npm/blob/master/lib/verify-auth.js#L21) throttling on your registry (just a hypothesis: https://github.com/semantic-release/npm/pull/416). At this point you can:
|
|
276
276
|
|
|
277
|
-
-
|
|
278
|
-
-
|
|
277
|
+
- Rerun your build as many times as necessary. You may get lucky in a new attempt.
|
|
278
|
+
- Use [semrel-extra/npm plugin](https://github.com/semrel-extra/npm) for npm publishing (recommended).
|
|
279
279
|
|
|
280
280
|
### git: connection reset by peer
|
|
281
281
|
|
|
@@ -288,10 +288,10 @@ Anyway we've added a special [`--sequental-init`](#cli) flag to queue up these c
|
|
|
288
288
|
|
|
289
289
|
Automatically finds packages as long as workspaces are configured as-per the workspace-feature of one of the support package managers.
|
|
290
290
|
|
|
291
|
-
-
|
|
292
|
-
-
|
|
293
|
-
-
|
|
294
|
-
-
|
|
291
|
+
- [Yarn workspaces](https://yarnpkg.com/lang/en/docs/workspaces/).
|
|
292
|
+
- [Npm workspaces (Version 7.x)](https://docs.npmjs.com/cli/v7/using-npm/workspaces)
|
|
293
|
+
- [pnpm workspace](https://pnpm.js.org/workspaces/)
|
|
294
|
+
- [bolt workspaces](https://github.com/boltpkg/bolt#configuration)
|
|
295
295
|
|
|
296
296
|
I'm aware Lerna is the best-known tool right now, but in future it seems clear it will be replaced by functionality in Yarn and NPM directly. If you use Yarn workspaces today (January 2019), then publishing is the only remaining feature Lerna is _really_ required for (though it'd be lovely if Yarn added parallel script execution). Thus using multi-semantic-release means you can probably remove Lerna entirely from your project.
|
|
297
297
|
|
|
@@ -299,17 +299,17 @@ I'm aware Lerna is the best-known tool right now, but in future it seems clear i
|
|
|
299
299
|
|
|
300
300
|
Other packages that enable semantic-release for monorepos work by iterating into each package and running the `semantic-release` command. This is conceptually simple but unfortunately not viable because:
|
|
301
301
|
|
|
302
|
-
-
|
|
303
|
-
-
|
|
302
|
+
- If a package is published that depends on minor changes that have been made in a sibling package it could cause extremely subtle errors (the worst kind!) — if the project follows semver religiously this should never happen, but it's better to eliminate the _potential_ for errors
|
|
303
|
+
- Dependency version numbers need to reflect the _next_ release at time of publishing, so a package needs to know the state of _all other packages_ before it can publish correctly — this central state needs to be coordinated by something
|
|
304
304
|
|
|
305
305
|
### Local dependencies and version numbers
|
|
306
306
|
|
|
307
307
|
A key requirement is handling local dep version numbers elegantly. multi-semantic-release does the following:
|
|
308
308
|
|
|
309
|
-
-
|
|
310
|
-
-
|
|
311
|
-
-
|
|
312
|
-
-
|
|
309
|
+
- The next version number of all packages is established first
|
|
310
|
+
- If a release has not changed but has local deps that _have_ changed... do a `patch` bump on that package too
|
|
311
|
+
- Before packages are released (in semantic-release's prepare step), the correct current/next version number of _all_ local dependencies is written into the `package.json` file (overwriting any existing value)
|
|
312
|
+
- This ensures the package at the time of publishing will be atomically correct with all other packages in the monorepo.
|
|
313
313
|
|
|
314
314
|
The above means that, possibly, if someone upgrades dependencies and pulls down a package from NPM _during the multirelease_ (before all its deps have been published at their next versions), then their `npm install` will fail (it will work if they try again in a few minutes). On balance I thought it was more important to be atomically correct (this situation should be fairly rare assuming projects commit their lockfiles).
|
|
315
315
|
|
|
@@ -323,22 +323,22 @@ The plugin starts all release at once, then pauses them (using Promises) at vari
|
|
|
323
323
|
|
|
324
324
|
The inline plugin does the following:
|
|
325
325
|
|
|
326
|
-
-
|
|
327
|
-
-
|
|
328
|
-
-
|
|
329
|
-
-
|
|
330
|
-
-
|
|
331
|
-
-
|
|
332
|
-
-
|
|
333
|
-
-
|
|
334
|
-
-
|
|
335
|
-
-
|
|
336
|
-
-
|
|
337
|
-
-
|
|
338
|
-
-
|
|
339
|
-
-
|
|
340
|
-
-
|
|
341
|
-
-
|
|
326
|
+
- **verifyConditions:** _not used_
|
|
327
|
+
- **analyzeCommits:**
|
|
328
|
+
- Replaces `context.commits` with a list of commits filtered to the folder only
|
|
329
|
+
- Calls `plugins.analyzeCommits()` to get the next release type (e.g. from @semantic-release/commit-analyzer)
|
|
330
|
+
- Waits for _all_ packages to catch up to this point.
|
|
331
|
+
- For packages that haven't bumped, checks if it has local deps (or deps of deps) that have bumped and returns `patch` if that's true
|
|
332
|
+
- **verifyRelease:** _not used_
|
|
333
|
+
- **generateNotes:**
|
|
334
|
+
- Calls `plugins.generateNotes()` to get the notes (e.g. from @semantic-release/release-notes-generator)
|
|
335
|
+
- Appends a section listing any local deps bumps (e.g. "my-pkg-2: upgraded to 1.2.1")
|
|
336
|
+
- **prepare:**
|
|
337
|
+
- Writes in the correct version for local deps in `dependencies`, `devDependencies`, `peerDependencies` in `package.json`
|
|
338
|
+
- Serialize the releases so they happen one-at-a-time (because semantic-release calls `git push` asynchronously, multiple releases at once fail because Git refs aren't locked — semantic-release should use `execa.sync()` so Git operations are atomic)
|
|
339
|
+
- **publish:** _not used_
|
|
340
|
+
- **success:** _not used_
|
|
341
|
+
- **fail:** _not used_
|
|
342
342
|
|
|
343
343
|
### Jank
|
|
344
344
|
|
|
@@ -346,28 +346,28 @@ The integration with semantic release is pretty janky — this is a quick summar
|
|
|
346
346
|
|
|
347
347
|
1. Had to filter `context.commits` object before it was used by `@semantic-release/commit-analyzer` (so it only lists commits for the corresponding directory).
|
|
348
348
|
|
|
349
|
-
-
|
|
350
|
-
-
|
|
351
|
-
-
|
|
352
|
-
-
|
|
349
|
+
- The actual Git filtering is easy peasy: see [getCommitsFiltered.js](https://github.com/dhoulb/multi-semantic-release/blob/master/lib/getCommitsFiltered.js)
|
|
350
|
+
- But overriding `context.commits` was very difficult! I did it eventually creating an _inline plugin_ and passing it into `semanticRelease()` via `options.plugins`
|
|
351
|
+
- The inline plugin proxies between semantic release and other configured plugins. It does what it needs to then calls e.g. `plugins.analyzeCommits()` with an overridden `context.commits` — see [createInlinePluginCreator.js](https://github.com/dhoulb/multi-semantic-release/blob/master/lib/createInlinePluginCreator.js)
|
|
352
|
+
- I think this is messy — inline plugins aren't even documented :(
|
|
353
353
|
|
|
354
354
|
2. Need to run the analyze commit step on _all_ plugins before any proceed to the publish step
|
|
355
355
|
|
|
356
|
-
-
|
|
357
|
-
-
|
|
358
|
-
-
|
|
356
|
+
- The inline plugin returns a Promise for every package then waits for all packages to analyze their commits before resolving them one at a time
|
|
357
|
+
- If packages have local deps (e.g. `dependencies` in package.json points to an internal package) this step also does a `patch` bump if any of them did a bump.
|
|
358
|
+
- This has to work recursively! See [hasChangedDeep.js](https://github.com/dhoulb/multi-semantic-release/blob/master/lib/hasChangedDeep.js)
|
|
359
359
|
|
|
360
360
|
3. The configuration can be layered (i.e. global `.releaserc` and then per-directory overrides for individual packages).
|
|
361
361
|
|
|
362
|
-
-
|
|
362
|
+
- Had to duplicate the internal cosmiconfig setup from semantic release to get this working :(
|
|
363
363
|
|
|
364
364
|
4. I found Git getting itself into weird states because e.g. `git tag` is done asynchronously
|
|
365
365
|
|
|
366
|
-
-
|
|
367
|
-
-
|
|
368
|
-
-
|
|
369
|
-
-
|
|
370
|
-
-
|
|
366
|
+
- To get around this I had to stagger package publishing so they were done one at a time (which slows things down)
|
|
367
|
+
- I think calls to `execa()` in semantic release should be replaced with `execa.sync()` to ensure Git's internal state is atomic.
|
|
368
|
+
- Fortunately, another workaround has been implemented. `Synchronizer` is the neat part. It is critical to make the tag and commit publishing phases strictly sequential. [Event emitter allows](https://github.com/dhoulb/multi-semantic-release/blob/master/lib/getSynchronizer.js):
|
|
369
|
+
- To synchronize release stages for all packages.
|
|
370
|
+
- To ensure the completeness of checks and the sufficiency of conditions for a conflict-free process.
|
|
371
371
|
|
|
372
372
|
### Git tags
|
|
373
373
|
|
|
@@ -377,9 +377,9 @@ I can personally see the potential for this option in coordinating a semantic-re
|
|
|
377
377
|
|
|
378
378
|
To make the `tagFormat` option work as intended the following would need to happen:
|
|
379
379
|
|
|
380
|
-
-
|
|
381
|
-
-
|
|
382
|
-
-
|
|
380
|
+
- semantic-release needs to check if a given tag already exists at a given commit, and not create it / push it if that's true
|
|
381
|
+
- Release notes for multiple package releases need to be merged BUT the Github release only done once (by having the notes merged at the semantic-release level but only published once, or having the Github plugin merge them)
|
|
382
|
+
- Make it clear in documentation that the default tag `v1.0.0` will have the same effect as Lerna's fixed mode (all changed monorepo packages released at same time)
|
|
383
383
|
|
|
384
384
|
## Supported Node.js Versions
|
|
385
385
|
|
|
@@ -395,12 +395,12 @@ If you would like to help take a look at the [list of issues](https://github.com
|
|
|
395
395
|
|
|
396
396
|
## Credits
|
|
397
397
|
|
|
398
|
-
-
|
|
399
|
-
-
|
|
400
|
-
-
|
|
401
|
-
-
|
|
402
|
-
-
|
|
403
|
-
-
|
|
398
|
+
- [Daniel Bannert](https://github.com/prisis)
|
|
399
|
+
- [All Contributors](https://github.com/anolilab/semantic-release/graphs/contributors)
|
|
400
|
+
- [hanseltime](https://github.com/hanseltime) -> https://github.com/qiwi/multi-semantic-release/pull/96
|
|
401
|
+
- [lyh543](https://github.com/lyh543) -> https://github.com/dhoulb/multi-semantic-release/issues/111
|
|
402
|
+
- [dhoub/multi-semantic-release](https://github.com/dhoulb/multi-semantic-release)
|
|
403
|
+
- [qiwi/multi-semantic-release](https://github.com/qiwi/multi-semantic-release)
|
|
404
404
|
|
|
405
405
|
## License
|
|
406
406
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anolilab/multi-semantic-release",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"description": "A multi semantic release tool for a monorepo.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -9,12 +9,6 @@
|
|
|
9
9
|
},
|
|
10
10
|
"license": "0BSD",
|
|
11
11
|
"author": "Dave Houlbrooke <dave@shax.com>",
|
|
12
|
-
"maintainers": [
|
|
13
|
-
{
|
|
14
|
-
"name": "Daniel Bannert",
|
|
15
|
-
"email": "d.bannert@anolilab.de"
|
|
16
|
-
}
|
|
17
|
-
],
|
|
18
12
|
"type": "module",
|
|
19
13
|
"exports": {
|
|
20
14
|
".": "./lib/multi-semantic-release.js",
|
|
@@ -46,44 +40,6 @@
|
|
|
46
40
|
"stream-buffers": "^3.0.3",
|
|
47
41
|
"yargs": "^17.7.2"
|
|
48
42
|
},
|
|
49
|
-
"devDependencies": {
|
|
50
|
-
"@anolilab/eslint-config": "^15.0.3",
|
|
51
|
-
"@anolilab/prettier-config": "^5.0.14",
|
|
52
|
-
"@anolilab/semantic-release-pnpm": "1.1.6",
|
|
53
|
-
"@babel/core": "^7.26.0",
|
|
54
|
-
"@rushstack/eslint-plugin-security": "^0.8.3",
|
|
55
|
-
"@secretlint/secretlint-rule-preset-recommend": "^9.0.0",
|
|
56
|
-
"@semantic-release/changelog": "^6.0.3",
|
|
57
|
-
"@semantic-release/commit-analyzer": "13.0.0",
|
|
58
|
-
"@semantic-release/exec": "^6.0.3",
|
|
59
|
-
"@semantic-release/git": "^10.0.1",
|
|
60
|
-
"@semantic-release/github": "^11.0.1",
|
|
61
|
-
"@semantic-release/release-notes-generator": "14.0.1",
|
|
62
|
-
"@types/node": "18.19.68",
|
|
63
|
-
"@vitest/coverage-v8": "^2.1.8",
|
|
64
|
-
"@vitest/ui": "^2.1.8",
|
|
65
|
-
"conventional-changelog-conventionalcommits": "8.0.0",
|
|
66
|
-
"cross-env": "^7.0.3",
|
|
67
|
-
"eslint": "^8.57.1",
|
|
68
|
-
"eslint-plugin-deprecation": "^3.0.0",
|
|
69
|
-
"eslint-plugin-etc": "^2.0.3",
|
|
70
|
-
"eslint-plugin-import": "npm:eslint-plugin-i@^2.29.1",
|
|
71
|
-
"eslint-plugin-mdx": "^3.1.5",
|
|
72
|
-
"eslint-plugin-n": "^17.15.0",
|
|
73
|
-
"eslint-plugin-vitest": "^0.4.1",
|
|
74
|
-
"eslint-plugin-vitest-globals": "^1.5.0",
|
|
75
|
-
"eslint-plugin-you-dont-need-lodash-underscore": "^6.14.0",
|
|
76
|
-
"file-url": "^4.0.0",
|
|
77
|
-
"prettier": "^3.4.2",
|
|
78
|
-
"publint": "^0.2.12",
|
|
79
|
-
"rimraf": "^6.0.1",
|
|
80
|
-
"secretlint": "9.0.0",
|
|
81
|
-
"semantic-release": "^24.2.0",
|
|
82
|
-
"sort-package-json": "^2.12.0",
|
|
83
|
-
"tempy": "^3.1.0",
|
|
84
|
-
"typescript": "^5.7.2",
|
|
85
|
-
"vitest": "^2.1.8"
|
|
86
|
-
},
|
|
87
43
|
"peerDependencies": {
|
|
88
44
|
"semantic-release": "^20.0 || ^21.0 || >=22.0.3"
|
|
89
45
|
},
|
|
@@ -98,34 +54,5 @@
|
|
|
98
54
|
"publishConfig": {
|
|
99
55
|
"access": "public",
|
|
100
56
|
"provenance": true
|
|
101
|
-
},
|
|
102
|
-
"anolilab": {
|
|
103
|
-
"eslint-config": {
|
|
104
|
-
"plugin": {},
|
|
105
|
-
"warn_on_unsupported_typescript_version": false,
|
|
106
|
-
"info_on_disabling_jsx_react_rule": false,
|
|
107
|
-
"info_on_disabling_prettier_conflict_rule": false,
|
|
108
|
-
"info_on_disabling_jsonc_sort_keys_rule": false,
|
|
109
|
-
"import_ignore_exports": [
|
|
110
|
-
"**/*.cjs",
|
|
111
|
-
"**/__tests__/**/*.js"
|
|
112
|
-
]
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
"scripts": {
|
|
116
|
-
"build": "echo 'There is no need for build' && exit 0",
|
|
117
|
-
"build:prod": "echo 'There is no need for build' && exit 0",
|
|
118
|
-
"clean": "rimraf node_modules dist .eslintcache",
|
|
119
|
-
"dev": "echo 'There is no need for dev' && exit 0",
|
|
120
|
-
"lint:eslint": "eslint . --ext js,cjs,mjs,jsx,ts,tsx,json,yaml,yml,md,mdx --max-warnings=0 --config .eslintrc.cjs",
|
|
121
|
-
"lint:eslint:fix": "eslint . --ext js,cjs,mjs,jsx,ts,tsx,json,yaml,yml,md,mdx --max-warnings=0 --config .eslintrc.cjs --fix",
|
|
122
|
-
"lint:packagejson": "publint --strict",
|
|
123
|
-
"lint:prettier": "prettier --config=.prettierrc.cjs --check .",
|
|
124
|
-
"lint:prettier:fix": "prettier --config=.prettierrc.cjs --write .",
|
|
125
|
-
"lint:types": "tsc --noEmit || exit 0",
|
|
126
|
-
"test": "vitest run",
|
|
127
|
-
"test:coverage": "vitest run --coverage",
|
|
128
|
-
"test:ui": "vitest --ui --coverage.enabled=true",
|
|
129
|
-
"test:watch": "vitest"
|
|
130
57
|
}
|
|
131
58
|
}
|