@exadev/semantic-release-workspace 3.0.1 → 3.0.3
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 +8 -0
- package/dist/cli.js +52 -2
- package/dist/index.cjs +51 -1
- package/dist/index.js +51 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -76,6 +76,14 @@ Set it via the `--commit-strategy <mode>` CLI flag, the `commitStrategy` field i
|
|
|
76
76
|
|
|
77
77
|
`'single'` mode still runs each package's own configured publish plugins afterward (npm publish with provenance, GitHub releases), scoped per package exactly as `'per-package'` mode does — it just runs their `verifyConditions`/`publish`/`success` steps directly against the already-committed-and-tagged repository state, since by that point semantic-release's own top-level orchestrator would misread the tag this mode already created as an existing release. `addChannel` and `fail` are not called in this mode (pre-release channel promotion and posting an automated failure comment/issue, respectively) — a deliberate scope boundary, not a silent gap: raise an issue if your workflow needs them.
|
|
78
78
|
|
|
79
|
+
### When the release branch moves during a run
|
|
80
|
+
|
|
81
|
+
Under `commitStrategy: 'per-package'` a release is a sequence of independent pushes, so a commit landing on the release branch mid-run can interrupt it between packages. The orchestrator integrates the new tip and carries on with the packages that have not released yet, and packages already published are never republished, since their tags record them. Where semantic-release declines to release a package while the branch is moving underneath it, which is indistinguishable from that package genuinely having nothing to release, the package is released again against the integrated tip rather than assumed finished; a run that can never establish the answer fails rather than finishing as though the package had nothing, which would leave it and every package after it silently unreleased.
|
|
82
|
+
|
|
83
|
+
One window is outside this tool's control: semantic-release pushes a package's tag before running its publish plugins, and that push is not atomic, so a rejection there can leave a tag on the remote for a version that never reached npm. Nothing is corrupted and no later release is blocked, but that version number is skipped. If it happens, find the tag with no matching published version (`npm view <name> versions`) and either publish from it by hand or delete the tag locally and on the remote and let the next run recompute it.
|
|
84
|
+
|
|
85
|
+
If you need a run to be strictly all-or-nothing, use `commitStrategy: 'single'`, which makes one commit and one atomic push before anything publishes, and which retries the whole attempt against the new tip when that push loses a race.
|
|
86
|
+
|
|
79
87
|
## Gating publish
|
|
80
88
|
|
|
81
89
|
`commitStrategy` changes how a release is committed; `gatePublish` changes *when* it gets published relative to being tagged and pushed -- a different, orthogonal axis. With `gatePublish: true`, each due package is tagged and pushed via [@exadev/release-gate](https://www.npmjs.com/package/@exadev/release-gate) (a real dependency of this package -- no separate install needed) but never published: nothing calls `npm publish`, creates a GitHub Release, or runs any other configured publish step, until a separate `resume` step does so explicitly -- from the same process, or a completely different one (a later CI job, once a deploy or smoke test has confirmed the release should actually go out).
|
package/dist/cli.js
CHANGED
|
@@ -14,7 +14,7 @@ import { generateNotes } from "@semantic-release/release-notes-generator";
|
|
|
14
14
|
import semanticRelease from "semantic-release";
|
|
15
15
|
import { pathToFileURL } from "node:url";
|
|
16
16
|
//#region package.json
|
|
17
|
-
var version = "3.0.
|
|
17
|
+
var version = "3.0.3";
|
|
18
18
|
//#endregion
|
|
19
19
|
//#region src/errors.ts
|
|
20
20
|
/**
|
|
@@ -309,6 +309,14 @@ async function isAncestor(ancestor, descendant, options) {
|
|
|
309
309
|
throw error;
|
|
310
310
|
}
|
|
311
311
|
}
|
|
312
|
+
/** Advances the current branch to `ref`, refusing unless that is a fast-forward. Used where every local commit is already on the remote, so anything that is not a fast-forward means the checkout holds work the remote does not, and stopping is better than the alternative of discarding it. */
|
|
313
|
+
async function fastForwardTo(ref, options) {
|
|
314
|
+
await git([
|
|
315
|
+
"merge",
|
|
316
|
+
"--ff-only",
|
|
317
|
+
ref
|
|
318
|
+
], options);
|
|
319
|
+
}
|
|
312
320
|
/** Discards every commit and working-tree change the current attempt made, putting the checkout back on exactly `ref`. */
|
|
313
321
|
async function resetHardTo(ref, options) {
|
|
314
322
|
await git([
|
|
@@ -902,6 +910,26 @@ function parsePublishPluginSpec(spec) {
|
|
|
902
910
|
const [name, config] = spec;
|
|
903
911
|
return [name, config ?? {}];
|
|
904
912
|
}
|
|
913
|
+
/**
|
|
914
|
+
* Releases one package, integrating the release branch first and again whenever it moves under the attempt.
|
|
915
|
+
*
|
|
916
|
+
* This exists because semantic-release cannot tell the orchestrator apart the two reasons it declines to release. When the branch has moved since the run began, its `verifyAuth` fails, `isBranchUpToDate` reports the branch behind, and it returns the same "no release" the orchestrator gets for a package that genuinely had nothing to publish. Taking that at face value is how a run used to finish green having released only the packages that happened to come before the branch moved.
|
|
917
|
+
*
|
|
918
|
+
* The ambiguity is resolved by observation rather than by reading semantic-release's logs: if the branch did not move while the package was being released, "no release" is true. If it did, the answer is not trustworthy, so the branch is integrated and the package is released again against the new tip. That is safe to repeat because a package that really has nothing to release still has nothing after a fast-forward, and a package that does release is recorded by its tag, which every later run reads as the release having happened.
|
|
919
|
+
*
|
|
920
|
+
* A package whose answer is never established fails the run. Returning "nothing to release" for it would be a guess, and the guess that loses is exactly the silent partial release this loop exists to stop.
|
|
921
|
+
*/
|
|
922
|
+
async function releasePackageAcrossBranchMoves(name, branch, attempt, log) {
|
|
923
|
+
for (let moves = 1;; moves += 1) {
|
|
924
|
+
const tipBefore = await branch.integrate();
|
|
925
|
+
const outcome = await attempt();
|
|
926
|
+
if (outcome.released) return outcome;
|
|
927
|
+
const tipAfter = await branch.tip();
|
|
928
|
+
if (tipAfter === tipBefore) return outcome;
|
|
929
|
+
if (moves >= 3) throw new WorkspaceStateError(`${packageName}: ${name} reported no release ${String(moves)} times, each time while the release branch was moving underneath it, so whether it had anything to release was never established. Failing rather than finishing the run as though it had nothing, which would leave this package and every one after it silently unreleased. Re-running once the branch is quieter is safe: packages that already released are recorded by their tags and are not released again.`);
|
|
930
|
+
log(`${name}: reported no release while the branch moved from ${tipBefore} to ${tipAfter}, which is also what a stale branch looks like; integrating and releasing it again.`);
|
|
931
|
+
}
|
|
932
|
+
}
|
|
905
933
|
//#endregion
|
|
906
934
|
//#region src/pnpm.ts
|
|
907
935
|
/**
|
|
@@ -1333,7 +1361,7 @@ async function runReleaseLoop(graph, order, workspace, dryRun, log, releaseOne)
|
|
|
1333
1361
|
const pkg = mustGet(graph.packages, name, "package");
|
|
1334
1362
|
const bumpsForThisPackage = pendingBumps.get(name) ?? [];
|
|
1335
1363
|
log(`Releasing ${name} from ${pkg.relativeDirectory}${bumpsForThisPackage.length > 0 ? ` (dependency ranges already bumped: ${bumpsForThisPackage.map((bump) => bump.dependency).join(", ")})` : ""}`);
|
|
1336
|
-
const { released, version, result } = await releaseOne(pkg, bumpsForThisPackage);
|
|
1364
|
+
const { released, version, result } = dryRun ? await releaseOne(pkg, bumpsForThisPackage) : await releasePackageAcrossBranchMoves(name, branchTracker(workspace, log), async () => await releaseOne(pkg, bumpsForThisPackage), log);
|
|
1337
1365
|
entries.push({
|
|
1338
1366
|
name,
|
|
1339
1367
|
directory: pkg.directory,
|
|
@@ -1430,6 +1458,28 @@ async function bumpDependents(released, version, graph, options) {
|
|
|
1430
1458
|
}
|
|
1431
1459
|
return applied;
|
|
1432
1460
|
}
|
|
1461
|
+
/**
|
|
1462
|
+
* Brings the checkout up to the release branch's current tip, and reports where that tip is.
|
|
1463
|
+
*
|
|
1464
|
+
* At a package boundary every commit this run has made is already on the remote (each release commit by `@semantic-release/git`'s own prepare push, each tag by semantic-release's own, each dependency bump by `pushHead`), so advancing onto a moved branch is a fast-forward and loses nothing. `fastForwardTo` refuses anything else rather than discarding local work, which would mean the assumption above had broken.
|
|
1465
|
+
*/
|
|
1466
|
+
async function integrateBranchTip(workspace, log) {
|
|
1467
|
+
const cwd = workspace.root;
|
|
1468
|
+
const branch = await currentBranch({ cwd });
|
|
1469
|
+
const tip = await fetchBranchTip(branch, { cwd });
|
|
1470
|
+
if (await isAncestor(tip, "HEAD", { cwd })) return tip;
|
|
1471
|
+
if (!await isAncestor("HEAD", tip, { cwd })) throw new WorkspaceStateError(`${packageName}: ${branch} has moved to ${tip}, which this checkout has not and cannot reach by fast-forward, so the two have diverged. A release run expects every commit it has made to already be on the remote at this point; stopping rather than discarding whatever is here.`);
|
|
1472
|
+
await fastForwardTo(tip, { cwd });
|
|
1473
|
+
log(`${packageName}: ${branch} advanced to ${tip} during this run; integrated it before continuing.`);
|
|
1474
|
+
return tip;
|
|
1475
|
+
}
|
|
1476
|
+
/** The release branch as `releasePackageAcrossBranchMoves` needs to see it, backed by the real repository. */
|
|
1477
|
+
function branchTracker(workspace, log) {
|
|
1478
|
+
return {
|
|
1479
|
+
integrate: async () => await integrateBranchTip(workspace, log),
|
|
1480
|
+
tip: async () => await fetchBranchTip(await currentBranch({ cwd: workspace.root }), { cwd: workspace.root })
|
|
1481
|
+
};
|
|
1482
|
+
}
|
|
1433
1483
|
//#endregion
|
|
1434
1484
|
//#region src/gate-publish.ts
|
|
1435
1485
|
/**
|
package/dist/index.cjs
CHANGED
|
@@ -316,6 +316,14 @@ async function isAncestor(ancestor, descendant, options) {
|
|
|
316
316
|
throw error;
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
|
+
/** Advances the current branch to `ref`, refusing unless that is a fast-forward. Used where every local commit is already on the remote, so anything that is not a fast-forward means the checkout holds work the remote does not, and stopping is better than the alternative of discarding it. */
|
|
320
|
+
async function fastForwardTo(ref, options) {
|
|
321
|
+
await git([
|
|
322
|
+
"merge",
|
|
323
|
+
"--ff-only",
|
|
324
|
+
ref
|
|
325
|
+
], options);
|
|
326
|
+
}
|
|
319
327
|
/** Discards every commit and working-tree change the current attempt made, putting the checkout back on exactly `ref`. */
|
|
320
328
|
async function resetHardTo(ref, options) {
|
|
321
329
|
await git([
|
|
@@ -900,6 +908,26 @@ function parsePublishPluginSpec(spec) {
|
|
|
900
908
|
const [name, config] = spec;
|
|
901
909
|
return [name, config ?? {}];
|
|
902
910
|
}
|
|
911
|
+
/**
|
|
912
|
+
* Releases one package, integrating the release branch first and again whenever it moves under the attempt.
|
|
913
|
+
*
|
|
914
|
+
* This exists because semantic-release cannot tell the orchestrator apart the two reasons it declines to release. When the branch has moved since the run began, its `verifyAuth` fails, `isBranchUpToDate` reports the branch behind, and it returns the same "no release" the orchestrator gets for a package that genuinely had nothing to publish. Taking that at face value is how a run used to finish green having released only the packages that happened to come before the branch moved.
|
|
915
|
+
*
|
|
916
|
+
* The ambiguity is resolved by observation rather than by reading semantic-release's logs: if the branch did not move while the package was being released, "no release" is true. If it did, the answer is not trustworthy, so the branch is integrated and the package is released again against the new tip. That is safe to repeat because a package that really has nothing to release still has nothing after a fast-forward, and a package that does release is recorded by its tag, which every later run reads as the release having happened.
|
|
917
|
+
*
|
|
918
|
+
* A package whose answer is never established fails the run. Returning "nothing to release" for it would be a guess, and the guess that loses is exactly the silent partial release this loop exists to stop.
|
|
919
|
+
*/
|
|
920
|
+
async function releasePackageAcrossBranchMoves(name, branch, attempt, log) {
|
|
921
|
+
for (let moves = 1;; moves += 1) {
|
|
922
|
+
const tipBefore = await branch.integrate();
|
|
923
|
+
const outcome = await attempt();
|
|
924
|
+
if (outcome.released) return outcome;
|
|
925
|
+
const tipAfter = await branch.tip();
|
|
926
|
+
if (tipAfter === tipBefore) return outcome;
|
|
927
|
+
if (moves >= 3) throw new WorkspaceStateError(`${packageName}: ${name} reported no release ${String(moves)} times, each time while the release branch was moving underneath it, so whether it had anything to release was never established. Failing rather than finishing the run as though it had nothing, which would leave this package and every one after it silently unreleased. Re-running once the branch is quieter is safe: packages that already released are recorded by their tags and are not released again.`);
|
|
928
|
+
log(`${name}: reported no release while the branch moved from ${tipBefore} to ${tipAfter}, which is also what a stale branch looks like; integrating and releasing it again.`);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
903
931
|
//#endregion
|
|
904
932
|
//#region src/pnpm.ts
|
|
905
933
|
/**
|
|
@@ -1481,7 +1509,7 @@ async function runReleaseLoop(graph, order, workspace, dryRun, log, releaseOne)
|
|
|
1481
1509
|
const pkg = mustGet(graph.packages, name, "package");
|
|
1482
1510
|
const bumpsForThisPackage = pendingBumps.get(name) ?? [];
|
|
1483
1511
|
log(`Releasing ${name} from ${pkg.relativeDirectory}${bumpsForThisPackage.length > 0 ? ` (dependency ranges already bumped: ${bumpsForThisPackage.map((bump) => bump.dependency).join(", ")})` : ""}`);
|
|
1484
|
-
const { released, version, result } = await releaseOne(pkg, bumpsForThisPackage);
|
|
1512
|
+
const { released, version, result } = dryRun ? await releaseOne(pkg, bumpsForThisPackage) : await releasePackageAcrossBranchMoves(name, branchTracker(workspace, log), async () => await releaseOne(pkg, bumpsForThisPackage), log);
|
|
1485
1513
|
entries.push({
|
|
1486
1514
|
name,
|
|
1487
1515
|
directory: pkg.directory,
|
|
@@ -1578,6 +1606,28 @@ async function bumpDependents(released, version, graph, options) {
|
|
|
1578
1606
|
}
|
|
1579
1607
|
return applied;
|
|
1580
1608
|
}
|
|
1609
|
+
/**
|
|
1610
|
+
* Brings the checkout up to the release branch's current tip, and reports where that tip is.
|
|
1611
|
+
*
|
|
1612
|
+
* At a package boundary every commit this run has made is already on the remote (each release commit by `@semantic-release/git`'s own prepare push, each tag by semantic-release's own, each dependency bump by `pushHead`), so advancing onto a moved branch is a fast-forward and loses nothing. `fastForwardTo` refuses anything else rather than discarding local work, which would mean the assumption above had broken.
|
|
1613
|
+
*/
|
|
1614
|
+
async function integrateBranchTip(workspace, log) {
|
|
1615
|
+
const cwd = workspace.root;
|
|
1616
|
+
const branch = await currentBranch({ cwd });
|
|
1617
|
+
const tip = await fetchBranchTip(branch, { cwd });
|
|
1618
|
+
if (await isAncestor(tip, "HEAD", { cwd })) return tip;
|
|
1619
|
+
if (!await isAncestor("HEAD", tip, { cwd })) throw new WorkspaceStateError(`${packageName}: ${branch} has moved to ${tip}, which this checkout has not and cannot reach by fast-forward, so the two have diverged. A release run expects every commit it has made to already be on the remote at this point; stopping rather than discarding whatever is here.`);
|
|
1620
|
+
await fastForwardTo(tip, { cwd });
|
|
1621
|
+
log(`${packageName}: ${branch} advanced to ${tip} during this run; integrated it before continuing.`);
|
|
1622
|
+
return tip;
|
|
1623
|
+
}
|
|
1624
|
+
/** The release branch as `releasePackageAcrossBranchMoves` needs to see it, backed by the real repository. */
|
|
1625
|
+
function branchTracker(workspace, log) {
|
|
1626
|
+
return {
|
|
1627
|
+
integrate: async () => await integrateBranchTip(workspace, log),
|
|
1628
|
+
tip: async () => await fetchBranchTip(await currentBranch({ cwd: workspace.root }), { cwd: workspace.root })
|
|
1629
|
+
};
|
|
1630
|
+
}
|
|
1581
1631
|
//#endregion
|
|
1582
1632
|
exports.DEFAULT_PUBLISH_PLUGINS = DEFAULT_PUBLISH_PLUGINS;
|
|
1583
1633
|
exports.DependencyCycleError = DependencyCycleError;
|
package/dist/index.js
CHANGED
|
@@ -291,6 +291,14 @@ async function isAncestor(ancestor, descendant, options) {
|
|
|
291
291
|
throw error;
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
|
+
/** Advances the current branch to `ref`, refusing unless that is a fast-forward. Used where every local commit is already on the remote, so anything that is not a fast-forward means the checkout holds work the remote does not, and stopping is better than the alternative of discarding it. */
|
|
295
|
+
async function fastForwardTo(ref, options) {
|
|
296
|
+
await git([
|
|
297
|
+
"merge",
|
|
298
|
+
"--ff-only",
|
|
299
|
+
ref
|
|
300
|
+
], options);
|
|
301
|
+
}
|
|
294
302
|
/** Discards every commit and working-tree change the current attempt made, putting the checkout back on exactly `ref`. */
|
|
295
303
|
async function resetHardTo(ref, options) {
|
|
296
304
|
await git([
|
|
@@ -875,6 +883,26 @@ function parsePublishPluginSpec(spec) {
|
|
|
875
883
|
const [name, config] = spec;
|
|
876
884
|
return [name, config ?? {}];
|
|
877
885
|
}
|
|
886
|
+
/**
|
|
887
|
+
* Releases one package, integrating the release branch first and again whenever it moves under the attempt.
|
|
888
|
+
*
|
|
889
|
+
* This exists because semantic-release cannot tell the orchestrator apart the two reasons it declines to release. When the branch has moved since the run began, its `verifyAuth` fails, `isBranchUpToDate` reports the branch behind, and it returns the same "no release" the orchestrator gets for a package that genuinely had nothing to publish. Taking that at face value is how a run used to finish green having released only the packages that happened to come before the branch moved.
|
|
890
|
+
*
|
|
891
|
+
* The ambiguity is resolved by observation rather than by reading semantic-release's logs: if the branch did not move while the package was being released, "no release" is true. If it did, the answer is not trustworthy, so the branch is integrated and the package is released again against the new tip. That is safe to repeat because a package that really has nothing to release still has nothing after a fast-forward, and a package that does release is recorded by its tag, which every later run reads as the release having happened.
|
|
892
|
+
*
|
|
893
|
+
* A package whose answer is never established fails the run. Returning "nothing to release" for it would be a guess, and the guess that loses is exactly the silent partial release this loop exists to stop.
|
|
894
|
+
*/
|
|
895
|
+
async function releasePackageAcrossBranchMoves(name, branch, attempt, log) {
|
|
896
|
+
for (let moves = 1;; moves += 1) {
|
|
897
|
+
const tipBefore = await branch.integrate();
|
|
898
|
+
const outcome = await attempt();
|
|
899
|
+
if (outcome.released) return outcome;
|
|
900
|
+
const tipAfter = await branch.tip();
|
|
901
|
+
if (tipAfter === tipBefore) return outcome;
|
|
902
|
+
if (moves >= 3) throw new WorkspaceStateError(`${packageName}: ${name} reported no release ${String(moves)} times, each time while the release branch was moving underneath it, so whether it had anything to release was never established. Failing rather than finishing the run as though it had nothing, which would leave this package and every one after it silently unreleased. Re-running once the branch is quieter is safe: packages that already released are recorded by their tags and are not released again.`);
|
|
903
|
+
log(`${name}: reported no release while the branch moved from ${tipBefore} to ${tipAfter}, which is also what a stale branch looks like; integrating and releasing it again.`);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
878
906
|
//#endregion
|
|
879
907
|
//#region src/pnpm.ts
|
|
880
908
|
/**
|
|
@@ -1456,7 +1484,7 @@ async function runReleaseLoop(graph, order, workspace, dryRun, log, releaseOne)
|
|
|
1456
1484
|
const pkg = mustGet(graph.packages, name, "package");
|
|
1457
1485
|
const bumpsForThisPackage = pendingBumps.get(name) ?? [];
|
|
1458
1486
|
log(`Releasing ${name} from ${pkg.relativeDirectory}${bumpsForThisPackage.length > 0 ? ` (dependency ranges already bumped: ${bumpsForThisPackage.map((bump) => bump.dependency).join(", ")})` : ""}`);
|
|
1459
|
-
const { released, version, result } = await releaseOne(pkg, bumpsForThisPackage);
|
|
1487
|
+
const { released, version, result } = dryRun ? await releaseOne(pkg, bumpsForThisPackage) : await releasePackageAcrossBranchMoves(name, branchTracker(workspace, log), async () => await releaseOne(pkg, bumpsForThisPackage), log);
|
|
1460
1488
|
entries.push({
|
|
1461
1489
|
name,
|
|
1462
1490
|
directory: pkg.directory,
|
|
@@ -1553,5 +1581,27 @@ async function bumpDependents(released, version, graph, options) {
|
|
|
1553
1581
|
}
|
|
1554
1582
|
return applied;
|
|
1555
1583
|
}
|
|
1584
|
+
/**
|
|
1585
|
+
* Brings the checkout up to the release branch's current tip, and reports where that tip is.
|
|
1586
|
+
*
|
|
1587
|
+
* At a package boundary every commit this run has made is already on the remote (each release commit by `@semantic-release/git`'s own prepare push, each tag by semantic-release's own, each dependency bump by `pushHead`), so advancing onto a moved branch is a fast-forward and loses nothing. `fastForwardTo` refuses anything else rather than discarding local work, which would mean the assumption above had broken.
|
|
1588
|
+
*/
|
|
1589
|
+
async function integrateBranchTip(workspace, log) {
|
|
1590
|
+
const cwd = workspace.root;
|
|
1591
|
+
const branch = await currentBranch({ cwd });
|
|
1592
|
+
const tip = await fetchBranchTip(branch, { cwd });
|
|
1593
|
+
if (await isAncestor(tip, "HEAD", { cwd })) return tip;
|
|
1594
|
+
if (!await isAncestor("HEAD", tip, { cwd })) throw new WorkspaceStateError(`${packageName}: ${branch} has moved to ${tip}, which this checkout has not and cannot reach by fast-forward, so the two have diverged. A release run expects every commit it has made to already be on the remote at this point; stopping rather than discarding whatever is here.`);
|
|
1595
|
+
await fastForwardTo(tip, { cwd });
|
|
1596
|
+
log(`${packageName}: ${branch} advanced to ${tip} during this run; integrated it before continuing.`);
|
|
1597
|
+
return tip;
|
|
1598
|
+
}
|
|
1599
|
+
/** The release branch as `releasePackageAcrossBranchMoves` needs to see it, backed by the real repository. */
|
|
1600
|
+
function branchTracker(workspace, log) {
|
|
1601
|
+
return {
|
|
1602
|
+
integrate: async () => await integrateBranchTip(workspace, log),
|
|
1603
|
+
tip: async () => await fetchBranchTip(await currentBranch({ cwd: workspace.root }), { cwd: workspace.root })
|
|
1604
|
+
};
|
|
1605
|
+
}
|
|
1556
1606
|
//#endregion
|
|
1557
1607
|
export { DEFAULT_PUBLISH_PLUGINS, DependencyCycleError, GitCommandError, ReleaseConfigurationError, SINGLE_COMMIT_DEFAULT_PUBLISH_PLUGINS, UnsupportedDependencyRangeError, WorkspaceDiscoveryError, WorkspaceReleaseError, WorkspaceStateError, buildDependencyGraph, classifyDependencyRange, createScopedPlugins, discoverWorkspace, filterCommitsToDirectory, orderedPackages, packageName, readManifest, releaseWorkspace, resolvePublishPlugins, resolveWorkspacePublishPlugins, resumeWorkspaceRelease, topologicalOrder, updateDependencyRange, writeDependencyRange };
|
package/package.json
CHANGED