automata-cli 0.8.0-develop.346 → 0.8.0-develop.353
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 +2 -2
- package/dist/{ConfigWizard-D6NYL2E6.js → ConfigWizard-GULICHML.js} +19 -1
- package/dist/index.js +206 -43
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -74,12 +74,12 @@ Checks that the PR exists and is merged, the working tree is clean, and the remo
|
|
|
74
74
|
Execute the full GitFlow release sequence and push to `origin`. Only requires `git`.
|
|
75
75
|
|
|
76
76
|
```bash
|
|
77
|
-
automata git publish-release # auto-detect version from
|
|
77
|
+
automata git publish-release # auto-detect version from the trunk tag
|
|
78
78
|
automata git publish-release 2.0.0 # explicit version
|
|
79
79
|
automata git publish-release --dry-run # preview without executing
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
When no version is given, the latest semver tag on `
|
|
82
|
+
When no version is given, the trunk branch is resolved from `origin` (`main`, `master` or whatever the remote calls it), tags are fetched, and the latest semver tag on `origin/<trunk>` is detected and the minor segment incremented (e.g. `1.2.0 → 1.3.0`). See [docs/git.md](docs/git.md#automata-git-publish-release).
|
|
83
83
|
|
|
84
84
|
---
|
|
85
85
|
|
|
@@ -36,7 +36,7 @@ var EXECUTOR_OPTIONS = [
|
|
|
36
36
|
{ label: "Claude Code", value: "claude" },
|
|
37
37
|
{ label: "Codex", value: "codex" }
|
|
38
38
|
];
|
|
39
|
-
var MAIN_MENU_OPTIONS = ["Remote / Mode", "Implement-Next", "Prompts", "Issue Watch", "Do Work"];
|
|
39
|
+
var MAIN_MENU_OPTIONS = ["Remote / Mode", "Implement-Next", "Prompts", "Issue Watch", "Do Work", "Git"];
|
|
40
40
|
var PROMPTS_MENU_OPTIONS = [
|
|
41
41
|
"Sonar",
|
|
42
42
|
"Fix-Comments",
|
|
@@ -173,6 +173,7 @@ function ConfigWizard() {
|
|
|
173
173
|
const [doWorkPrOrphanPrompt, setDoWorkPrOrphanPrompt] = useState(
|
|
174
174
|
existing.doWork?.prompts?.prOrphan ?? DEFAULT_DO_WORK_PR_ORPHAN_PROMPT
|
|
175
175
|
);
|
|
176
|
+
const [gitTrunkBranch, setGitTrunkBranch] = useState(existing.git?.trunkBranch ?? "");
|
|
176
177
|
const [pendingRemote, setPendingRemote] = useState(existing.remoteType ?? "gh");
|
|
177
178
|
const [pendingTechnique, setPendingTechnique] = useState(
|
|
178
179
|
existing.issueDiscoveryTechnique ?? "label"
|
|
@@ -379,6 +380,16 @@ function ConfigWizard() {
|
|
|
379
380
|
setScreen("prompts-menu");
|
|
380
381
|
},
|
|
381
382
|
onBack: () => setScreen("prompts-menu")
|
|
383
|
+
},
|
|
384
|
+
"git-trunk-branch": {
|
|
385
|
+
setValue: setGitTrunkBranch,
|
|
386
|
+
onSubmit: () => {
|
|
387
|
+
const branch = gitTrunkBranch.trim();
|
|
388
|
+
const current = readRawConfig();
|
|
389
|
+
writeConfig({ ...current, git: { ...current.git, trunkBranch: branch || void 0 } });
|
|
390
|
+
exit();
|
|
391
|
+
},
|
|
392
|
+
onBack: () => setScreen("main")
|
|
382
393
|
}
|
|
383
394
|
};
|
|
384
395
|
const menus = {
|
|
@@ -392,6 +403,7 @@ function ConfigWizard() {
|
|
|
392
403
|
else if (chosen === "Implement-Next") setScreen("technique");
|
|
393
404
|
else if (chosen === "Issue Watch") setScreen("allowed-users");
|
|
394
405
|
else if (chosen === "Do Work") setScreen("do-work-base-branch");
|
|
406
|
+
else if (chosen === "Git") setScreen("git-trunk-branch");
|
|
395
407
|
else setScreen("prompts-menu");
|
|
396
408
|
}
|
|
397
409
|
},
|
|
@@ -550,6 +562,12 @@ function ConfigWizard() {
|
|
|
550
562
|
label: "Instructions for a pull request with no linked issue:",
|
|
551
563
|
value: doWorkPrOrphanPrompt,
|
|
552
564
|
hint: `Type prompt \xB7 Enter to save \xB7 ${BACK}`
|
|
565
|
+
},
|
|
566
|
+
"git-trunk-branch": {
|
|
567
|
+
title: "Git \u2014 Trunk Branch",
|
|
568
|
+
label: "Branch publish-release releases to (blank = detect it from the remote):",
|
|
569
|
+
value: gitTrunkBranch,
|
|
570
|
+
hint: `Type branch \xB7 Enter to save \xB7 ${BACK}`
|
|
553
571
|
}
|
|
554
572
|
};
|
|
555
573
|
const menuViews = {
|
package/dist/index.js
CHANGED
|
@@ -214,12 +214,23 @@ var configSetDoWorkPrompt = new Command("do-work-prompt").description("Set the t
|
|
|
214
214
|
process.stdout.write(`do-work ${turnKind} prompt set.
|
|
215
215
|
`);
|
|
216
216
|
});
|
|
217
|
-
var
|
|
217
|
+
var configSetGitTrunkBranch = new Command("git-trunk-branch").description("Pin the branch `publish-release` releases to, instead of detecting it").argument("<value>", "Branch name (unset = detect it from the remote)").action((value) => {
|
|
218
|
+
const branch = value.trim();
|
|
219
|
+
if (branch.length === 0) {
|
|
220
|
+
process.stderr.write("Error: git-trunk-branch requires a non-empty branch name.\n");
|
|
221
|
+
process.exit(1);
|
|
222
|
+
}
|
|
223
|
+
const current = readRawConfig();
|
|
224
|
+
writeConfig({ ...current, git: { ...current.git, trunkBranch: branch } });
|
|
225
|
+
process.stdout.write(`git trunk branch set to: ${branch}
|
|
226
|
+
`);
|
|
227
|
+
});
|
|
228
|
+
var configSet = new Command("set").description("Set a configuration value").addCommand(configSetType).addCommand(configSetIssueDiscoveryTechnique).addCommand(configSetIssueDiscoveryValue).addCommand(configSetClaudeSystemPrompt).addCommand(configSetAllowedUsers).addCommand(configSetAgentUser).addCommand(configSetDoWorkBaseBranch).addCommand(configSetDoWorkProtectedBranches).addCommand(configSetDoWorkExecutor).addCommand(configSetDoWorkModel).addCommand(configSetDoWorkEffort).addCommand(configSetDoWorkMaxRuns).addCommand(configSetDoWorkLockStaleMinutes).addCommand(configSetDoWorkPrompt).addCommand(configSetGitTrunkBranch);
|
|
218
229
|
var configCommand = new Command("config").description("Configure automata settings").addCommand(configSet).action(async () => {
|
|
219
230
|
const [{ render }, React, { ConfigWizard }] = await Promise.all([
|
|
220
231
|
import("ink"),
|
|
221
232
|
import("react"),
|
|
222
|
-
import("./ConfigWizard-
|
|
233
|
+
import("./ConfigWizard-GULICHML.js")
|
|
223
234
|
]);
|
|
224
235
|
const { waitUntilExit } = render(React.createElement(ConfigWizard));
|
|
225
236
|
await waitUntilExit();
|
|
@@ -280,6 +291,44 @@ function getPrInfo() {
|
|
|
280
291
|
};
|
|
281
292
|
}
|
|
282
293
|
|
|
294
|
+
// src/git/trunkDetection.ts
|
|
295
|
+
var TRUNK_CANDIDATES = ["main", "master"];
|
|
296
|
+
var TRUNK_BRANCH_CONFIG_KEY = "git.trunkBranch";
|
|
297
|
+
var ORIGIN_HEAD_PREFIX = "refs/remotes/origin/";
|
|
298
|
+
var SYMREF_PREFIX = "ref: refs/heads/";
|
|
299
|
+
function parseOriginHeadRef(stdout) {
|
|
300
|
+
const ref = stdout.trim();
|
|
301
|
+
if (!ref.startsWith(ORIGIN_HEAD_PREFIX)) return null;
|
|
302
|
+
const branch = ref.slice(ORIGIN_HEAD_PREFIX.length);
|
|
303
|
+
return branch.length > 0 ? branch : null;
|
|
304
|
+
}
|
|
305
|
+
function parseLsRemoteSymref(stdout) {
|
|
306
|
+
for (const line of stdout.split("\n")) {
|
|
307
|
+
const trimmed2 = line.trim();
|
|
308
|
+
if (!trimmed2.startsWith(SYMREF_PREFIX)) continue;
|
|
309
|
+
const branch = trimmed2.slice(SYMREF_PREFIX.length).split(/\s+/)[0];
|
|
310
|
+
if (branch.length > 0) return branch;
|
|
311
|
+
}
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
function describeTrunkSource(source, branch) {
|
|
315
|
+
switch (source) {
|
|
316
|
+
case "config":
|
|
317
|
+
return `configured as ${TRUNK_BRANCH_CONFIG_KEY}`;
|
|
318
|
+
case "origin-head":
|
|
319
|
+
return "from origin/HEAD";
|
|
320
|
+
case "ls-remote":
|
|
321
|
+
return "from the remote's advertised HEAD";
|
|
322
|
+
case "probe":
|
|
323
|
+
return `probed as origin/${branch}`;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
function unresolvedTrunkMessage(attempted) {
|
|
327
|
+
return `Could not determine the trunk branch of 'origin'.
|
|
328
|
+
Tried: ${attempted.join(", ")}.
|
|
329
|
+
Set it explicitly with: automata config set git-trunk-branch <branch>`;
|
|
330
|
+
}
|
|
331
|
+
|
|
283
332
|
// src/git/gitService.ts
|
|
284
333
|
function run2(cmd, args) {
|
|
285
334
|
const result = spawnSync2(cmd, args, { encoding: "utf8" });
|
|
@@ -963,7 +1012,63 @@ function resolveCurrentBranchComments() {
|
|
|
963
1012
|
return { ok: true, branch, comments: raw };
|
|
964
1013
|
}
|
|
965
1014
|
var SEMVER_RE = /^v?(\d+)\.(\d+)\.(\d+)$/;
|
|
966
|
-
function
|
|
1015
|
+
function remoteBranchExists(branch) {
|
|
1016
|
+
return !isUpstreamGone(branch);
|
|
1017
|
+
}
|
|
1018
|
+
function resolveTrunkBranch() {
|
|
1019
|
+
const configured = readRawConfig().git?.trunkBranch?.trim();
|
|
1020
|
+
if (configured) {
|
|
1021
|
+
return { ok: true, branch: configured, source: "config" };
|
|
1022
|
+
}
|
|
1023
|
+
const attempted = [];
|
|
1024
|
+
attempted.push("origin/HEAD");
|
|
1025
|
+
const head = run2("git", ["symbolic-ref", "--quiet", "refs/remotes/origin/HEAD"]);
|
|
1026
|
+
if (head.status === 0) {
|
|
1027
|
+
const branch = parseOriginHeadRef(head.stdout);
|
|
1028
|
+
if (branch !== null) return { ok: true, branch, source: "origin-head" };
|
|
1029
|
+
}
|
|
1030
|
+
attempted.push("git ls-remote --symref origin HEAD");
|
|
1031
|
+
const symref = run2("git", ["ls-remote", "--symref", "origin", "HEAD"]);
|
|
1032
|
+
if (symref.status === 0) {
|
|
1033
|
+
const branch = parseLsRemoteSymref(symref.stdout);
|
|
1034
|
+
if (branch !== null) return { ok: true, branch, source: "ls-remote" };
|
|
1035
|
+
}
|
|
1036
|
+
for (const candidate of TRUNK_CANDIDATES) {
|
|
1037
|
+
attempted.push(`origin/${candidate}`);
|
|
1038
|
+
if (remoteBranchExists(candidate)) {
|
|
1039
|
+
return { ok: true, branch: candidate, source: "probe" };
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
return { ok: false, attempted };
|
|
1043
|
+
}
|
|
1044
|
+
function fetchTrunkAndTags(trunk) {
|
|
1045
|
+
const { status, stderr } = run2("git", [
|
|
1046
|
+
"fetch",
|
|
1047
|
+
"--tags",
|
|
1048
|
+
"origin",
|
|
1049
|
+
`+refs/heads/${trunk}:refs/remotes/origin/${trunk}`
|
|
1050
|
+
]);
|
|
1051
|
+
if (status !== 0) {
|
|
1052
|
+
return { ok: false, message: stderr.trim() || `git fetch --tags origin ${trunk} failed.` };
|
|
1053
|
+
}
|
|
1054
|
+
return { ok: true };
|
|
1055
|
+
}
|
|
1056
|
+
function localBranchExists(branch) {
|
|
1057
|
+
const { status } = run2("git", ["rev-parse", "--verify", "--quiet", `refs/heads/${branch}`]);
|
|
1058
|
+
return status === 0;
|
|
1059
|
+
}
|
|
1060
|
+
function trunkBehindCount(trunk) {
|
|
1061
|
+
if (!localBranchExists(trunk)) return 0;
|
|
1062
|
+
const { stdout, status } = run2("git", [
|
|
1063
|
+
"rev-list",
|
|
1064
|
+
"--count",
|
|
1065
|
+
`refs/heads/${trunk}..refs/remotes/origin/${trunk}`
|
|
1066
|
+
]);
|
|
1067
|
+
if (status !== 0) return 0;
|
|
1068
|
+
const count = Number.parseInt(stdout.trim(), 10);
|
|
1069
|
+
return Number.isNaN(count) ? 0 : count;
|
|
1070
|
+
}
|
|
1071
|
+
function getLatestTagOnTrunk(ref) {
|
|
967
1072
|
const { stdout, status } = run2("git", [
|
|
968
1073
|
"describe",
|
|
969
1074
|
"--tags",
|
|
@@ -972,7 +1077,7 @@ function getLatestTagOnMaster() {
|
|
|
972
1077
|
"[0-9]*.[0-9]*.[0-9]*",
|
|
973
1078
|
"--match",
|
|
974
1079
|
"v[0-9]*.[0-9]*.[0-9]*",
|
|
975
|
-
|
|
1080
|
+
ref
|
|
976
1081
|
]);
|
|
977
1082
|
if (status !== 0) return null;
|
|
978
1083
|
const tag = stdout.trim();
|
|
@@ -993,17 +1098,45 @@ ${stderr.trim()}`);
|
|
|
993
1098
|
}
|
|
994
1099
|
return stdout.trim().length > 0;
|
|
995
1100
|
}
|
|
996
|
-
function
|
|
1101
|
+
function checkReleasePreconditions() {
|
|
1102
|
+
let branch;
|
|
1103
|
+
try {
|
|
1104
|
+
branch = getCurrentBranch();
|
|
1105
|
+
} catch (err) {
|
|
1106
|
+
return { ok: false, message: err.message };
|
|
1107
|
+
}
|
|
1108
|
+
if (branch !== "develop") {
|
|
1109
|
+
return {
|
|
1110
|
+
ok: false,
|
|
1111
|
+
message: `publish-release must be run from the 'develop' branch (currently on '${branch}').`
|
|
1112
|
+
};
|
|
1113
|
+
}
|
|
1114
|
+
if (hasUncommittedChanges()) {
|
|
1115
|
+
return {
|
|
1116
|
+
ok: false,
|
|
1117
|
+
message: "You have uncommitted changes. Commit or stash them before publishing a release."
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
return { ok: true };
|
|
1121
|
+
}
|
|
1122
|
+
function publishRelease(version2, dryRun, trunk) {
|
|
997
1123
|
const releaseBranch = `release/${version2}`;
|
|
1124
|
+
const checkoutTrunk = localBranchExists(trunk) ? { args: ["checkout", trunk], desc: `git checkout ${trunk}` } : {
|
|
1125
|
+
args: ["checkout", "-b", trunk, `origin/${trunk}`],
|
|
1126
|
+
desc: `git checkout -b ${trunk} origin/${trunk}`
|
|
1127
|
+
};
|
|
998
1128
|
const steps = [
|
|
999
1129
|
{ args: ["checkout", "-b", releaseBranch], desc: `git checkout -b ${releaseBranch}` },
|
|
1000
|
-
|
|
1130
|
+
checkoutTrunk,
|
|
1001
1131
|
{ args: ["merge", "--no-ff", releaseBranch], desc: `git merge --no-ff ${releaseBranch}` },
|
|
1002
1132
|
{ args: ["tag", version2], desc: `git tag ${version2}` },
|
|
1003
1133
|
{ args: ["checkout", "develop"], desc: `git checkout develop` },
|
|
1004
1134
|
{ args: ["merge", "--no-ff", releaseBranch], desc: `git merge --no-ff ${releaseBranch}` },
|
|
1005
1135
|
{ args: ["branch", "-d", releaseBranch], desc: `git branch -d ${releaseBranch}` },
|
|
1006
|
-
{
|
|
1136
|
+
{
|
|
1137
|
+
args: ["push", "origin", "develop", trunk, version2],
|
|
1138
|
+
desc: `git push origin develop ${trunk} ${version2}`
|
|
1139
|
+
}
|
|
1007
1140
|
];
|
|
1008
1141
|
for (const step of steps) {
|
|
1009
1142
|
if (dryRun) {
|
|
@@ -1019,6 +1152,29 @@ ${stderr.trim()}`);
|
|
|
1019
1152
|
}
|
|
1020
1153
|
}
|
|
1021
1154
|
|
|
1155
|
+
// src/git/releaseVersion.ts
|
|
1156
|
+
var SEMVER_ARG_RE = /^\d+\.\d+\.\d+$/;
|
|
1157
|
+
function resolveReleaseVersion(requested, trunkRef, latestTag) {
|
|
1158
|
+
if (requested !== void 0) {
|
|
1159
|
+
if (!SEMVER_ARG_RE.test(requested)) {
|
|
1160
|
+
return {
|
|
1161
|
+
ok: false,
|
|
1162
|
+
message: `Version '${requested}' is not valid semver. Use X.Y.Z format (e.g. 1.2.0).`
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
return { ok: true, version: requested, notice: null };
|
|
1166
|
+
}
|
|
1167
|
+
const latest = latestTag();
|
|
1168
|
+
if (latest === null) {
|
|
1169
|
+
return {
|
|
1170
|
+
ok: false,
|
|
1171
|
+
message: `No semver tag found on ${trunkRef}. Pass a version explicitly: automata git publish-release <X.Y.Z>`
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
const version2 = bumpMinorVersion(latest);
|
|
1175
|
+
return { ok: true, version: version2, notice: `Auto-detected version: ${latest} \u2192 ${version2}` };
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1022
1178
|
// src/commands/git.ts
|
|
1023
1179
|
var FAIL_CONCLUSIONS = /* @__PURE__ */ new Set(["FAILURE", "TIMED_OUT", "ACTION_REQUIRED", "CANCELLED"]);
|
|
1024
1180
|
var SKIP_CONCLUSIONS = /* @__PURE__ */ new Set(["SKIPPED", "NEUTRAL"]);
|
|
@@ -1383,59 +1539,58 @@ var finishFeatureCmd = new Command2("finish-feature").description("Clean up a me
|
|
|
1383
1539
|
process.exit(1);
|
|
1384
1540
|
}
|
|
1385
1541
|
});
|
|
1386
|
-
var
|
|
1387
|
-
var publishReleaseCmd = new Command2("publish-release").description("Execute the full GitFlow release sequence and push to origin").argument("[version]", "Release version in X.Y.Z format (auto-detected from master tag if omitted)").option("--dry-run", "Print git commands without executing them").addHelpText(
|
|
1542
|
+
var publishReleaseCmd = new Command2("publish-release").description("Execute the full GitFlow release sequence and push to origin").argument("[version]", "Release version in X.Y.Z format (auto-detected from the trunk tag if omitted)").option("--dry-run", "Print git commands without executing them").addHelpText(
|
|
1388
1543
|
"after",
|
|
1389
1544
|
`
|
|
1390
1545
|
Release sequence:
|
|
1391
1546
|
1. git checkout -b release/<version>
|
|
1392
|
-
2. git checkout
|
|
1547
|
+
2. git checkout <trunk> && git merge --no-ff release/<version>
|
|
1393
1548
|
3. git tag <version>
|
|
1394
1549
|
4. git checkout develop && git merge --no-ff release/<version>
|
|
1395
1550
|
5. git branch -d release/<version>
|
|
1396
|
-
6. git push origin develop
|
|
1551
|
+
6. git push origin develop <trunk> <version>
|
|
1552
|
+
|
|
1553
|
+
<trunk> is resolved from origin \u2014 git.trunkBranch in .automata/config.json if
|
|
1554
|
+
set, else origin/HEAD, the remote's advertised HEAD, or a probe of main/master.
|
|
1555
|
+
Tags are fetched from origin first, in --dry-run too, so the version a dry run
|
|
1556
|
+
prints is the one a real run would use.
|
|
1397
1557
|
|
|
1398
|
-
When [version] is omitted the latest semver tag on
|
|
1399
|
-
minor segment is incremented (e.g. 1.2.0 \u2192 1.3.0).`
|
|
1558
|
+
When [version] is omitted the latest semver tag on origin/<trunk> is detected
|
|
1559
|
+
and the minor segment is incremented (e.g. 1.2.0 \u2192 1.3.0).`
|
|
1400
1560
|
).action((version2, options) => {
|
|
1401
1561
|
const dryRun = options.dryRun ?? false;
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
} catch (err) {
|
|
1406
|
-
process.stderr.write(`Error: ${err.message}
|
|
1562
|
+
const preconditions = checkReleasePreconditions();
|
|
1563
|
+
if (!preconditions.ok) {
|
|
1564
|
+
process.stderr.write(`Error: ${preconditions.message}
|
|
1407
1565
|
`);
|
|
1408
1566
|
process.exit(1);
|
|
1409
1567
|
}
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
`
|
|
1414
|
-
);
|
|
1568
|
+
const trunk = resolveTrunkBranch();
|
|
1569
|
+
if (!trunk.ok) {
|
|
1570
|
+
process.stderr.write(`Error: ${unresolvedTrunkMessage(trunk.attempted)}
|
|
1571
|
+
`);
|
|
1415
1572
|
process.exit(1);
|
|
1416
1573
|
}
|
|
1417
|
-
|
|
1418
|
-
|
|
1574
|
+
const trunkBranch = trunk.branch;
|
|
1575
|
+
const trunkRef = `origin/${trunkBranch}`;
|
|
1576
|
+
process.stdout.write(`Trunk branch: ${trunkBranch} (${describeTrunkSource(trunk.source, trunkBranch)})
|
|
1577
|
+
`);
|
|
1578
|
+
const fetched = fetchTrunkAndTags(trunkBranch);
|
|
1579
|
+
if (!fetched.ok) {
|
|
1580
|
+
process.stderr.write(`Error: Failed to fetch ${trunkBranch} and tags from origin.
|
|
1581
|
+
${fetched.message}
|
|
1582
|
+
`);
|
|
1419
1583
|
process.exit(1);
|
|
1420
1584
|
}
|
|
1421
|
-
|
|
1422
|
-
if (
|
|
1423
|
-
|
|
1424
|
-
process.stderr.write(`Error: Version '${version2}' is not valid semver. Use X.Y.Z format (e.g. 1.2.0).
|
|
1585
|
+
const versionResult = resolveReleaseVersion(version2, trunkRef, () => getLatestTagOnTrunk(trunkRef));
|
|
1586
|
+
if (!versionResult.ok) {
|
|
1587
|
+
process.stderr.write(`Error: ${versionResult.message}
|
|
1425
1588
|
`);
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
if (latest === null) {
|
|
1432
|
-
process.stderr.write(
|
|
1433
|
-
"Error: No semver tag found on master. Pass a version explicitly: automata git publish-release <X.Y.Z>\n"
|
|
1434
|
-
);
|
|
1435
|
-
process.exit(1);
|
|
1436
|
-
}
|
|
1437
|
-
resolvedVersion = bumpMinorVersion(latest);
|
|
1438
|
-
process.stdout.write(`Auto-detected version: ${latest} \u2192 ${resolvedVersion}
|
|
1589
|
+
process.exit(1);
|
|
1590
|
+
}
|
|
1591
|
+
const resolvedVersion = versionResult.version;
|
|
1592
|
+
if (versionResult.notice !== null) {
|
|
1593
|
+
process.stdout.write(`${versionResult.notice}
|
|
1439
1594
|
`);
|
|
1440
1595
|
}
|
|
1441
1596
|
if (tagExists(resolvedVersion)) {
|
|
@@ -1443,6 +1598,14 @@ minor segment is incremented (e.g. 1.2.0 \u2192 1.3.0).`
|
|
|
1443
1598
|
`);
|
|
1444
1599
|
process.exit(1);
|
|
1445
1600
|
}
|
|
1601
|
+
const behind = trunkBehindCount(trunkBranch);
|
|
1602
|
+
if (behind > 0) {
|
|
1603
|
+
process.stderr.write(
|
|
1604
|
+
`Error: Local branch '${trunkBranch}' is ${String(behind)} commit(s) behind ${trunkRef}. Update it (git checkout ${trunkBranch} && git merge --ff-only ${trunkRef}) or delete it, then re-run.
|
|
1605
|
+
`
|
|
1606
|
+
);
|
|
1607
|
+
process.exit(1);
|
|
1608
|
+
}
|
|
1446
1609
|
if (dryRun) {
|
|
1447
1610
|
process.stdout.write(`Dry-run: release ${resolvedVersion}
|
|
1448
1611
|
`);
|
|
@@ -1451,7 +1614,7 @@ minor segment is incremented (e.g. 1.2.0 \u2192 1.3.0).`
|
|
|
1451
1614
|
`);
|
|
1452
1615
|
}
|
|
1453
1616
|
try {
|
|
1454
|
-
publishRelease(resolvedVersion, dryRun);
|
|
1617
|
+
publishRelease(resolvedVersion, dryRun, trunkBranch);
|
|
1455
1618
|
} catch (err) {
|
|
1456
1619
|
process.stderr.write(`Error: ${err.message}
|
|
1457
1620
|
`);
|