@proteinjs/build 2.1.0 → 2.3.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/CHANGELOG.md +22 -0
- package/dist/src/mergeToMain.d.ts +47 -0
- package/dist/src/mergeToMain.d.ts.map +1 -0
- package/dist/src/mergeToMain.js +335 -0
- package/dist/src/mergeToMain.js.map +1 -0
- package/dist/src/versionWorkspace.d.ts.map +1 -1
- package/dist/src/versionWorkspace.js +61 -46
- package/dist/src/versionWorkspace.js.map +1 -1
- package/dist/test/parseMergeToMainSpec.test.d.ts +2 -0
- package/dist/test/parseMergeToMainSpec.test.d.ts.map +1 -0
- package/dist/test/parseMergeToMainSpec.test.js +40 -0
- package/dist/test/parseMergeToMainSpec.test.js.map +1 -0
- package/package.json +2 -2
- package/src/mergeToMain.ts +229 -0
- package/src/versionWorkspace.ts +34 -13
- package/test/parseMergeToMainSpec.test.ts +43 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [2.3.0](https://github.com/proteinjs/build/compare/@proteinjs/build@2.2.0...@proteinjs/build@2.3.0) (2026-07-21)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* version-workspace release-flow idempotency guard — stop on leftover uncommitted package versions ([35aa57f](https://github.com/proteinjs/build/commit/35aa57fc0dcc3e676393dd262810b9be89b20453))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# [2.2.0](https://github.com/proteinjs/build/compare/@proteinjs/build@2.1.0...@proteinjs/build@2.2.0) (2026-07-21)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* version-workspace --merge-to-main — opt-in pre-phase merging feature branches into main before versioning ([1eda265](https://github.com/proteinjs/build/commit/1eda2655ce752d1ecd36baa4d5c76540f9a31369))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
# [2.1.0](https://github.com/proteinjs/build/compare/@proteinjs/build@2.0.2...@proteinjs/build@2.1.0) (2026-07-03)
|
|
7
29
|
|
|
8
30
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opt-in pre-phase for `version-workspace`: merge feature-branch work into `main` in each leaf git
|
|
3
|
+
* repo BEFORE versioning, so the release runs on main. Without the flag, behavior is unchanged —
|
|
4
|
+
* the workspace versions in place on whatever branch each repo is on (the "stay on feature
|
|
5
|
+
* branches and just bump deps" mode).
|
|
6
|
+
*
|
|
7
|
+
* version-workspace --merge-to-main
|
|
8
|
+
* Every leaf repo whose current branch != main merges its current branch HEAD into main.
|
|
9
|
+
*
|
|
10
|
+
* version-workspace --merge-to-main=chat:17dda73,thought:ffdc105
|
|
11
|
+
* Only the named repos (matched by git-repo directory name), each merged at the PINNED sha —
|
|
12
|
+
* work pushed to the feature branch after the pin simply isn't in this release. A bare name
|
|
13
|
+
* (no `:sha`) merges that repo's current branch HEAD.
|
|
14
|
+
*
|
|
15
|
+
* Also accepted via env: VERSION_WORKSPACE_MERGE_TO_MAIN (same syntax; `1`/`true` = bare mode).
|
|
16
|
+
*
|
|
17
|
+
* Semantics per repo: fetch; checkout main; sync with origin/main FAST-FORWARD-ONLY (never rebase
|
|
18
|
+
* — local main legitimately holds an unpushed merge commit on resume, and a rebase would
|
|
19
|
+
* linearize it; true local/origin divergence stops loudly); merge the sha with a merge commit
|
|
20
|
+
* (`--no-ff`). Already-merged shas are skipped (idempotent — safe to re-run after fixing a
|
|
21
|
+
* conflict). A conflict stops the run with the repo + conflicted files named, leaving the merge in
|
|
22
|
+
* progress in that repo for resolution; re-running continues past it. Repos are LEFT ON MAIN
|
|
23
|
+
* afterward (the feature branch itself is never modified); the workspace root/metarepos are never
|
|
24
|
+
* touched by this phase.
|
|
25
|
+
*/
|
|
26
|
+
export type MergeToMainSpec = {
|
|
27
|
+
enabled: boolean;
|
|
28
|
+
pins: Map<string, string | undefined>;
|
|
29
|
+
};
|
|
30
|
+
export declare function parseMergeToMainSpec(args: string[], envValue?: string): MergeToMainSpec;
|
|
31
|
+
export declare function mergeToMain(workspacePath: string, spec: MergeToMainSpec, planOnly: boolean): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Idempotency guard for the release flow. The versioning loop writes a package's bumped
|
|
34
|
+
* package.json to disk (versionWorkspace.ts) BEFORE it commits + pushes that package; an
|
|
35
|
+
* interruption in that window (a flaky release-build/test failure, a publish/push error) leaves an
|
|
36
|
+
* uncommitted bumped package.json. A blind re-run would then read the already-bumped DISK version
|
|
37
|
+
* as its base and double-bump it — or, for a partially-pushed multi-package repo, fail to re-flag
|
|
38
|
+
* the un-pushed package and silently SKIP it. Both produce a wrong release.
|
|
39
|
+
*
|
|
40
|
+
* So, before the versioning loop (release mode only), STOP if any leaf repo carries uncommitted
|
|
41
|
+
* package.json / package-lock.json — those can only be leftovers from a prior interrupted run
|
|
42
|
+
* (a clean merge phase commits its resolutions). Non-destructive: it names the files and the
|
|
43
|
+
* one-line reset, and never mutates — the operator resets to committed (source-of-truth) state and
|
|
44
|
+
* re-runs. On a fresh run after clean merges there is nothing uncommitted, so this is a no-op.
|
|
45
|
+
*/
|
|
46
|
+
export declare function assertNoLeftoverVersionState(workspacePath: string): Promise<void>;
|
|
47
|
+
//# sourceMappingURL=mergeToMain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mergeToMain.d.ts","sourceRoot":"","sources":["../../src/mergeToMain.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,eAAe,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;CAAE,CAAC;AAE1F,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,CAkCvF;AAED,wBAAsB,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA6FhH;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,4BAA4B,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BvF"}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
35
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
36
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
37
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
38
|
+
function step(op) {
|
|
39
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
40
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
41
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
42
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
43
|
+
switch (op[0]) {
|
|
44
|
+
case 0: case 1: t = op; break;
|
|
45
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
46
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
47
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
48
|
+
default:
|
|
49
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
50
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
51
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
52
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
53
|
+
if (t[2]) _.ops.pop();
|
|
54
|
+
_.trys.pop(); continue;
|
|
55
|
+
}
|
|
56
|
+
op = body.call(thisArg, _);
|
|
57
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
58
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
62
|
+
exports.assertNoLeftoverVersionState = exports.mergeToMain = exports.parseMergeToMainSpec = void 0;
|
|
63
|
+
var path = __importStar(require("path"));
|
|
64
|
+
var child_process_1 = require("child_process");
|
|
65
|
+
var util_node_1 = require("@proteinjs/util-node");
|
|
66
|
+
var logger_1 = require("@proteinjs/logger");
|
|
67
|
+
var logColors_1 = require("./logColors");
|
|
68
|
+
var cw = new util_node_1.LogColorWrapper();
|
|
69
|
+
var logger = new logger_1.Logger({ name: cw.color('workspace:', logColors_1.primaryLogColor) + cw.color('merge', logColors_1.secondaryLogColor) });
|
|
70
|
+
function parseMergeToMainSpec(args, envValue) {
|
|
71
|
+
var pins = new Map();
|
|
72
|
+
var enabled = false;
|
|
73
|
+
var consume = function (value) {
|
|
74
|
+
enabled = true;
|
|
75
|
+
if (value === '' || value === 'true' || value === '1') {
|
|
76
|
+
return; // bare mode: all repos at branch HEAD
|
|
77
|
+
}
|
|
78
|
+
for (var _i = 0, _a = value.split(','); _i < _a.length; _i++) {
|
|
79
|
+
var entry = _a[_i];
|
|
80
|
+
var trimmed = entry.trim();
|
|
81
|
+
if (!trimmed) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
var _b = trimmed.split(':').map(function (s) { return s.trim(); }), repo = _b[0], sha = _b[1];
|
|
85
|
+
pins.set(repo, sha || undefined);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
for (var _i = 0, args_1 = args; _i < args_1.length; _i++) {
|
|
89
|
+
var arg = args_1[_i];
|
|
90
|
+
if (arg === '--merge-to-main') {
|
|
91
|
+
consume('');
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
var match = arg.match(/^--merge-to-main=(.*)$/);
|
|
95
|
+
if (match) {
|
|
96
|
+
consume(match[1]);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (!enabled && envValue) {
|
|
101
|
+
consume(envValue);
|
|
102
|
+
}
|
|
103
|
+
return { enabled: enabled, pins: pins };
|
|
104
|
+
}
|
|
105
|
+
exports.parseMergeToMainSpec = parseMergeToMainSpec;
|
|
106
|
+
function mergeToMain(workspacePath, spec, planOnly) {
|
|
107
|
+
var _a;
|
|
108
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
109
|
+
var repoRoots, _i, repoRoots_1, repoRoot, repoName, pinned, branch, sha, _b, _c, _d, _e, originIsAncestor, alreadyMerged, error_1, conflicted;
|
|
110
|
+
return __generator(this, function (_f) {
|
|
111
|
+
switch (_f.label) {
|
|
112
|
+
case 0:
|
|
113
|
+
if (!spec.enabled) {
|
|
114
|
+
return [2 /*return*/];
|
|
115
|
+
}
|
|
116
|
+
return [4 /*yield*/, leafRepoRoots(workspacePath)];
|
|
117
|
+
case 1:
|
|
118
|
+
repoRoots = _f.sent();
|
|
119
|
+
_i = 0, repoRoots_1 = repoRoots;
|
|
120
|
+
_f.label = 2;
|
|
121
|
+
case 2:
|
|
122
|
+
if (!(_i < repoRoots_1.length)) return [3 /*break*/, 26];
|
|
123
|
+
repoRoot = repoRoots_1[_i];
|
|
124
|
+
repoName = path.basename(repoRoot);
|
|
125
|
+
pinned = spec.pins.size > 0;
|
|
126
|
+
if (pinned && !spec.pins.has(repoName)) {
|
|
127
|
+
return [3 /*break*/, 25];
|
|
128
|
+
}
|
|
129
|
+
return [4 /*yield*/, git(repoRoot, 'rev-parse --abbrev-ref HEAD')];
|
|
130
|
+
case 3:
|
|
131
|
+
branch = _f.sent();
|
|
132
|
+
if (!((_a = spec.pins.get(repoName)) !== null && _a !== void 0)) return [3 /*break*/, 4];
|
|
133
|
+
_b = _a;
|
|
134
|
+
return [3 /*break*/, 8];
|
|
135
|
+
case 4:
|
|
136
|
+
if (!(branch === 'main')) return [3 /*break*/, 5];
|
|
137
|
+
_c = undefined;
|
|
138
|
+
return [3 /*break*/, 7];
|
|
139
|
+
case 5: return [4 /*yield*/, git(repoRoot, 'rev-parse HEAD')];
|
|
140
|
+
case 6:
|
|
141
|
+
_c = _f.sent();
|
|
142
|
+
_f.label = 7;
|
|
143
|
+
case 7:
|
|
144
|
+
_b = (_c);
|
|
145
|
+
_f.label = 8;
|
|
146
|
+
case 8:
|
|
147
|
+
sha = _b;
|
|
148
|
+
if (!sha) {
|
|
149
|
+
// Bare mode and already on main with no pin: nothing to merge.
|
|
150
|
+
return [3 /*break*/, 25];
|
|
151
|
+
}
|
|
152
|
+
if (planOnly) {
|
|
153
|
+
logger.info({
|
|
154
|
+
message: "(".concat(cw.color(repoName), ") would merge ").concat(sha.slice(0, 9), " (").concat(branch, ") into main. NOTE: plan-only bump levels below reflect PRE-merge state; run with --dry-run after merging for post-merge planning."),
|
|
155
|
+
});
|
|
156
|
+
return [3 /*break*/, 25];
|
|
157
|
+
}
|
|
158
|
+
return [4 /*yield*/, (0, util_node_1.cmd)('git', ['fetch', '-q'], { cwd: repoRoot }, { logPrefix: "[".concat(cw.color(repoName), "] ") })];
|
|
159
|
+
case 9:
|
|
160
|
+
_f.sent();
|
|
161
|
+
_f.label = 10;
|
|
162
|
+
case 10:
|
|
163
|
+
_f.trys.push([10, 12, , 13]);
|
|
164
|
+
return [4 /*yield*/, git(repoRoot, "cat-file -e ".concat(sha, "^{commit}"))];
|
|
165
|
+
case 11:
|
|
166
|
+
_f.sent();
|
|
167
|
+
return [3 /*break*/, 13];
|
|
168
|
+
case 12:
|
|
169
|
+
_d = _f.sent();
|
|
170
|
+
throw new Error("(".concat(repoName, ") --merge-to-main sha ").concat(sha, " is not a commit in this repo"));
|
|
171
|
+
case 13:
|
|
172
|
+
if (!(branch !== 'main')) return [3 /*break*/, 15];
|
|
173
|
+
return [4 /*yield*/, (0, util_node_1.cmd)('git', ['checkout', 'main'], { cwd: repoRoot }, { logPrefix: "[".concat(cw.color(repoName), "] ") })];
|
|
174
|
+
case 14:
|
|
175
|
+
_f.sent();
|
|
176
|
+
_f.label = 15;
|
|
177
|
+
case 15:
|
|
178
|
+
_f.trys.push([15, 17, , 19]);
|
|
179
|
+
return [4 /*yield*/, (0, util_node_1.cmd)('git', ['merge', '--ff-only', 'origin/main'], { cwd: repoRoot }, { logPrefix: "[".concat(cw.color(repoName), "] ") })];
|
|
180
|
+
case 16:
|
|
181
|
+
_f.sent();
|
|
182
|
+
return [3 /*break*/, 19];
|
|
183
|
+
case 17:
|
|
184
|
+
_e = _f.sent();
|
|
185
|
+
return [4 /*yield*/, git(repoRoot, 'merge-base --is-ancestor origin/main HEAD')
|
|
186
|
+
.then(function () { return true; })
|
|
187
|
+
.catch(function () { return false; })];
|
|
188
|
+
case 18:
|
|
189
|
+
originIsAncestor = _f.sent();
|
|
190
|
+
if (!originIsAncestor) {
|
|
191
|
+
throw new Error("(".concat(repoName, ") local main and origin/main have DIVERGED (local holds unpushed commits AND origin moved). ") +
|
|
192
|
+
"Reconcile manually (e.g. merge origin/main into main), then re-run.");
|
|
193
|
+
}
|
|
194
|
+
logger.info({
|
|
195
|
+
message: "(".concat(cw.color(repoName), ") local main is ahead of origin (unpushed merge from a prior run) \u2014 continuing"),
|
|
196
|
+
});
|
|
197
|
+
return [3 /*break*/, 19];
|
|
198
|
+
case 19: return [4 /*yield*/, git(repoRoot, "merge-base --is-ancestor ".concat(sha, " HEAD"))
|
|
199
|
+
.then(function () { return true; })
|
|
200
|
+
.catch(function () { return false; })];
|
|
201
|
+
case 20:
|
|
202
|
+
alreadyMerged = _f.sent();
|
|
203
|
+
if (alreadyMerged) {
|
|
204
|
+
logger.info({ message: "(".concat(cw.color(repoName), ") ").concat(sha.slice(0, 9), " already on main \u2014 skipping merge") });
|
|
205
|
+
return [3 /*break*/, 25];
|
|
206
|
+
}
|
|
207
|
+
logger.info({ message: "(".concat(cw.color(repoName), ") merging ").concat(sha.slice(0, 9), " (").concat(branch, ") into main") });
|
|
208
|
+
_f.label = 21;
|
|
209
|
+
case 21:
|
|
210
|
+
_f.trys.push([21, 23, , 25]);
|
|
211
|
+
return [4 /*yield*/, (0, util_node_1.cmd)('git', [
|
|
212
|
+
'merge',
|
|
213
|
+
'--no-ff',
|
|
214
|
+
'-m',
|
|
215
|
+
"merge: ".concat(branch, " @ ").concat(sha.slice(0, 9), " -> main (version-workspace --merge-to-main)"),
|
|
216
|
+
sha,
|
|
217
|
+
], { cwd: repoRoot }, { logPrefix: "[".concat(cw.color(repoName), "] ") })];
|
|
218
|
+
case 22:
|
|
219
|
+
_f.sent();
|
|
220
|
+
return [3 /*break*/, 25];
|
|
221
|
+
case 23:
|
|
222
|
+
error_1 = _f.sent();
|
|
223
|
+
return [4 /*yield*/, git(repoRoot, 'diff --name-only --diff-filter=U').catch(function () { return ''; })];
|
|
224
|
+
case 24:
|
|
225
|
+
conflicted = _f.sent();
|
|
226
|
+
throw new Error("(".concat(repoName, ") merge of ").concat(sha.slice(0, 9), " into main has conflicts: [").concat(conflicted.split('\n').filter(Boolean).join(', '), "]. ") +
|
|
227
|
+
"Resolve + commit the merge in ".concat(repoRoot, ", then re-run \u2014 already-merged repos are skipped."));
|
|
228
|
+
case 25:
|
|
229
|
+
_i++;
|
|
230
|
+
return [3 /*break*/, 2];
|
|
231
|
+
case 26: return [2 /*return*/];
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
exports.mergeToMain = mergeToMain;
|
|
237
|
+
/**
|
|
238
|
+
* Idempotency guard for the release flow. The versioning loop writes a package's bumped
|
|
239
|
+
* package.json to disk (versionWorkspace.ts) BEFORE it commits + pushes that package; an
|
|
240
|
+
* interruption in that window (a flaky release-build/test failure, a publish/push error) leaves an
|
|
241
|
+
* uncommitted bumped package.json. A blind re-run would then read the already-bumped DISK version
|
|
242
|
+
* as its base and double-bump it — or, for a partially-pushed multi-package repo, fail to re-flag
|
|
243
|
+
* the un-pushed package and silently SKIP it. Both produce a wrong release.
|
|
244
|
+
*
|
|
245
|
+
* So, before the versioning loop (release mode only), STOP if any leaf repo carries uncommitted
|
|
246
|
+
* package.json / package-lock.json — those can only be leftovers from a prior interrupted run
|
|
247
|
+
* (a clean merge phase commits its resolutions). Non-destructive: it names the files and the
|
|
248
|
+
* one-line reset, and never mutates — the operator resets to committed (source-of-truth) state and
|
|
249
|
+
* re-runs. On a fresh run after clean merges there is nothing uncommitted, so this is a no-op.
|
|
250
|
+
*/
|
|
251
|
+
function assertNoLeftoverVersionState(workspacePath) {
|
|
252
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
253
|
+
var repoRoots, dirty, _i, repoRoots_2, repoRoot, out, _a, _b, line, file, base;
|
|
254
|
+
return __generator(this, function (_c) {
|
|
255
|
+
switch (_c.label) {
|
|
256
|
+
case 0: return [4 /*yield*/, leafRepoRoots(workspacePath)];
|
|
257
|
+
case 1:
|
|
258
|
+
repoRoots = _c.sent();
|
|
259
|
+
dirty = [];
|
|
260
|
+
_i = 0, repoRoots_2 = repoRoots;
|
|
261
|
+
_c.label = 2;
|
|
262
|
+
case 2:
|
|
263
|
+
if (!(_i < repoRoots_2.length)) return [3 /*break*/, 5];
|
|
264
|
+
repoRoot = repoRoots_2[_i];
|
|
265
|
+
return [4 /*yield*/, git(repoRoot, 'status --porcelain').catch(function () { return ''; })];
|
|
266
|
+
case 3:
|
|
267
|
+
out = _c.sent();
|
|
268
|
+
for (_a = 0, _b = out
|
|
269
|
+
.split('\n')
|
|
270
|
+
.map(function (l) { return l.trim(); })
|
|
271
|
+
.filter(Boolean); _a < _b.length; _a++) {
|
|
272
|
+
line = _b[_a];
|
|
273
|
+
file = line.replace(/^.. /, '');
|
|
274
|
+
base = path.basename(file);
|
|
275
|
+
if (base === 'package.json' || base === 'package-lock.json') {
|
|
276
|
+
dirty.push("".concat(path.basename(repoRoot), ": ").concat(line));
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
_c.label = 4;
|
|
280
|
+
case 4:
|
|
281
|
+
_i++;
|
|
282
|
+
return [3 /*break*/, 2];
|
|
283
|
+
case 5:
|
|
284
|
+
if (dirty.length > 0) {
|
|
285
|
+
throw new Error("Refusing to version: uncommitted package.json/package-lock.json detected \u2014 almost certainly " +
|
|
286
|
+
"leftovers from a PRIOR INTERRUPTED release run. Re-running blindly could double-bump or skip " +
|
|
287
|
+
"these packages. Reset each to its committed (source-of-truth) state and re-run:\n" +
|
|
288
|
+
dirty.map(function (d) { return " ".concat(d); }).join('\n') +
|
|
289
|
+
"\n (per repo: git checkout -- <file>, or git checkout -- . after confirming there is no " +
|
|
290
|
+
"unrelated work)");
|
|
291
|
+
}
|
|
292
|
+
return [2 /*return*/];
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
exports.assertNoLeftoverVersionState = assertNoLeftoverVersionState;
|
|
298
|
+
/** Unique git-repo roots that directly contain workspace packages — never the workspace root. */
|
|
299
|
+
function leafRepoRoots(workspacePath) {
|
|
300
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
301
|
+
var _a, packageMap, sortedPackageNames, roots, _i, sortedPackageNames_1, packageName, localPackage, packageDir, repoRoot;
|
|
302
|
+
return __generator(this, function (_b) {
|
|
303
|
+
switch (_b.label) {
|
|
304
|
+
case 0: return [4 /*yield*/, util_node_1.PackageUtil.getWorkspaceMetadata(workspacePath)];
|
|
305
|
+
case 1:
|
|
306
|
+
_a = _b.sent(), packageMap = _a.packageMap, sortedPackageNames = _a.sortedPackageNames;
|
|
307
|
+
roots = new Set();
|
|
308
|
+
_i = 0, sortedPackageNames_1 = sortedPackageNames;
|
|
309
|
+
_b.label = 2;
|
|
310
|
+
case 2:
|
|
311
|
+
if (!(_i < sortedPackageNames_1.length)) return [3 /*break*/, 5];
|
|
312
|
+
packageName = sortedPackageNames_1[_i];
|
|
313
|
+
localPackage = packageMap[packageName];
|
|
314
|
+
packageDir = path.dirname(localPackage.filePath);
|
|
315
|
+
return [4 /*yield*/, git(packageDir, 'rev-parse --show-toplevel').catch(function () { return undefined; })];
|
|
316
|
+
case 3:
|
|
317
|
+
repoRoot = _b.sent();
|
|
318
|
+
if (repoRoot && path.resolve(repoRoot) !== path.resolve(workspacePath)) {
|
|
319
|
+
roots.add(repoRoot);
|
|
320
|
+
}
|
|
321
|
+
_b.label = 4;
|
|
322
|
+
case 4:
|
|
323
|
+
_i++;
|
|
324
|
+
return [3 /*break*/, 2];
|
|
325
|
+
case 5: return [2 /*return*/, Array.from(roots).sort()];
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
function git(cwd, args) {
|
|
331
|
+
return new Promise(function (resolve, reject) {
|
|
332
|
+
(0, child_process_1.exec)("git ".concat(args), { cwd: cwd }, function (error, stdout) { return (error ? reject(error) : resolve(stdout.trim())); });
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=mergeToMain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mergeToMain.js","sourceRoot":"","sources":["../../src/mergeToMain.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"versionWorkspace.d.ts","sourceRoot":"","sources":["../../src/versionWorkspace.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"versionWorkspace.d.ts","sourceRoot":"","sources":["../../src/versionWorkspace.ts"],"names":[],"mappings":"AAcA,wBAAsB,gBAAgB,kBAiLrC;AA40BD,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAcrD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAsB1F;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAuB7E;AAED,wBAAsB,aAAa,CAAC,aAAa,EAAE,MAAM,iBAUxD"}
|