@open-tomato/rafa 0.24.0 → 0.24.1
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/dist/cli.js
CHANGED
|
@@ -1787,7 +1787,7 @@ function restoreRunningCommand(previous) {
|
|
|
1787
1787
|
var running = null;
|
|
1788
1788
|
|
|
1789
1789
|
// package.json
|
|
1790
|
-
var name = "@open-tomato/rafa", version = "0.24.
|
|
1790
|
+
var name = "@open-tomato/rafa", version = "0.24.1";
|
|
1791
1791
|
var init_package = () => {};
|
|
1792
1792
|
|
|
1793
1793
|
// src/cli/version.ts
|
|
@@ -21780,7 +21780,7 @@ function readMergeRefusal(reading2) {
|
|
|
21780
21780
|
return held.length === 0 ? null : worktreeRefusal(reading2.branch, held);
|
|
21781
21781
|
}
|
|
21782
21782
|
function cleanUpSteps(plan) {
|
|
21783
|
-
const { base, branch, remote = DEFAULT_REMOTE2, remoteBranchPresent } = plan;
|
|
21783
|
+
const { base, branch, remote = DEFAULT_REMOTE2, localBranchPresent, remoteBranchPresent } = plan;
|
|
21784
21784
|
const steps = [
|
|
21785
21785
|
{ id: "switch-base", label: `switch to ${base}`, argv: ["git", "switch", base] },
|
|
21786
21786
|
{
|
|
@@ -21791,7 +21791,8 @@ function cleanUpSteps(plan) {
|
|
|
21791
21791
|
{
|
|
21792
21792
|
id: "delete-local",
|
|
21793
21793
|
label: `delete the local branch ${branch}`,
|
|
21794
|
-
argv: ["git", "branch", "-D", branch]
|
|
21794
|
+
argv: ["git", "branch", "-D", branch],
|
|
21795
|
+
...localBranchPresent ? {} : { skip: `no local branch ${branch}; nothing to delete` }
|
|
21795
21796
|
}
|
|
21796
21797
|
];
|
|
21797
21798
|
if (remoteBranchPresent) {
|
|
@@ -21816,7 +21817,7 @@ function commandLine(step) {
|
|
|
21816
21817
|
}
|
|
21817
21818
|
function remainingFrom(steps, failed2) {
|
|
21818
21819
|
const at = steps.findIndex((step) => step.id === failed2);
|
|
21819
|
-
return at === -1 ? Object.freeze([]) : Object.freeze(steps.slice(at));
|
|
21820
|
+
return at === -1 ? Object.freeze([]) : Object.freeze(steps.slice(at).filter((step) => step.skip === undefined));
|
|
21820
21821
|
}
|
|
21821
21822
|
var REFUSAL_PREFIX = "rafa pr merge refuses", MAX_LISTED_CHANGES = 10, DEFAULT_REMOTE2 = "origin", BRANCH_REF_PREFIX = "refs/heads/", INDENT2 = " ";
|
|
21822
21823
|
var init_merge2 = __esm(() => {
|
|
@@ -42118,6 +42119,16 @@ function remoteHoldsBranch(git, branch, warn3) {
|
|
|
42118
42119
|
warn3(`${REMOTE3} could not be asked whether it still holds ${branch}, so it is left alone: ${gitSaid(probe2)}`);
|
|
42119
42120
|
return false;
|
|
42120
42121
|
}
|
|
42122
|
+
function localHoldsBranch(git, branch, warn3) {
|
|
42123
|
+
const probe2 = git(["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
|
|
42124
|
+
if (probe2.ok)
|
|
42125
|
+
return true;
|
|
42126
|
+
const said = gitSaid(probe2);
|
|
42127
|
+
if (said === "")
|
|
42128
|
+
return false;
|
|
42129
|
+
warn3(`could not read whether this checkout holds a local branch ${branch}, so its delete runs: ${said}`);
|
|
42130
|
+
return true;
|
|
42131
|
+
}
|
|
42121
42132
|
function textOf4(path7) {
|
|
42122
42133
|
try {
|
|
42123
42134
|
return readFileSync52(path7, "utf8");
|
|
@@ -42195,25 +42206,34 @@ async function reportTick(context, pr, seams, detail) {
|
|
|
42195
42206
|
}
|
|
42196
42207
|
return tick;
|
|
42197
42208
|
}
|
|
42198
|
-
function readyLine(base, branch,
|
|
42199
|
-
const
|
|
42200
|
-
|
|
42209
|
+
function readyLine(base, branch, present) {
|
|
42210
|
+
const pulled = `${base} is checked out and pulled`;
|
|
42211
|
+
if (present.local) {
|
|
42212
|
+
return present.remote ? `${pulled}, and ${branch} is gone locally and on ${REMOTE3}.` : `${pulled}, and ${branch} is gone locally; ${REMOTE3} had already deleted it.`;
|
|
42213
|
+
}
|
|
42214
|
+
return present.remote ? `${pulled}, and ${branch} is gone on ${REMOTE3}; there was no local branch to delete.` : `${pulled}; ${branch} had no local branch, and ${REMOTE3} had already deleted it.`;
|
|
42201
42215
|
}
|
|
42202
42216
|
function quotedLines3(said) {
|
|
42203
42217
|
return said === "" ? [] : said.split(`
|
|
42204
42218
|
`).map((line) => `${INDENT10}${line}`);
|
|
42205
42219
|
}
|
|
42206
|
-
function runCleanUp(context, git, detail,
|
|
42220
|
+
function runCleanUp(context, git, detail, present) {
|
|
42207
42221
|
const steps = cleanUpSteps({
|
|
42208
42222
|
branch: detail.headRefName,
|
|
42209
42223
|
base: detail.baseRefName,
|
|
42210
42224
|
remote: REMOTE3,
|
|
42211
|
-
|
|
42225
|
+
localBranchPresent: present.local,
|
|
42226
|
+
remoteBranchPresent: present.remote
|
|
42212
42227
|
});
|
|
42213
42228
|
const reports = [];
|
|
42214
42229
|
for (const step2 of steps) {
|
|
42230
|
+
if (step2.skip !== undefined) {
|
|
42231
|
+
reports.push({ id: step2.id, label: step2.label, command: commandLine(step2), ok: true, skipped: true });
|
|
42232
|
+
context.output.info(`${step2.label}: skipped \u2014 ${step2.skip}`);
|
|
42233
|
+
continue;
|
|
42234
|
+
}
|
|
42215
42235
|
const result = git(step2.argv.slice(1));
|
|
42216
|
-
reports.push({ id: step2.id, label: step2.label, command: commandLine(step2), ok: result.ok });
|
|
42236
|
+
reports.push({ id: step2.id, label: step2.label, command: commandLine(step2), ok: result.ok, skipped: false });
|
|
42217
42237
|
if (result.ok) {
|
|
42218
42238
|
context.output.info(`${step2.label}: done`);
|
|
42219
42239
|
continue;
|
|
@@ -42309,11 +42329,15 @@ async function runMerge(context, seams) {
|
|
|
42309
42329
|
context.output.info(`Merged #${detail.number} into ${detail.baseRefName} (${method}).`);
|
|
42310
42330
|
const commentUrl = await commentIfUnchecked(context, pr, detail.number, answer4.unchecked);
|
|
42311
42331
|
const roadmapTicks = await reportTick(context, pr, seams, detail);
|
|
42312
|
-
const
|
|
42332
|
+
const warn3 = (message) => {
|
|
42313
42333
|
context.output.warn(message);
|
|
42314
|
-
}
|
|
42315
|
-
const
|
|
42316
|
-
|
|
42334
|
+
};
|
|
42335
|
+
const present = {
|
|
42336
|
+
remote: remoteHoldsBranch(git, detail.headRefName, warn3),
|
|
42337
|
+
local: localHoldsBranch(git, detail.headRefName, warn3)
|
|
42338
|
+
};
|
|
42339
|
+
const steps = runCleanUp(context, git, detail, present);
|
|
42340
|
+
context.output.info(readyLine(detail.baseRefName, detail.headRefName, present));
|
|
42317
42341
|
const followUps = followUpsFor(pr, git);
|
|
42318
42342
|
if (followUps.length > 0) {
|
|
42319
42343
|
context.output.info("Follow-ups:");
|
|
@@ -42340,7 +42364,7 @@ function createPrMergeCommand(seams = DEFAULT_MERGE_SEAMS) {
|
|
|
42340
42364
|
subject: "pr",
|
|
42341
42365
|
action: "merge",
|
|
42342
42366
|
summary: "merge a pull request and clean up both branches",
|
|
42343
|
-
description: "Merges one pull request through the GitHub CLI and then, in code, switches to the base branch," + " pulls it fast-forward only, deletes the head branch locally and on the remote where it is still there," + " and prunes, reporting each step. Refuses before it asks anything on a dirty working tree, on a pull" + " request that is not green or does not merge, and on a head branch checked out in another worktree. It" + " shows the pull request, its branches and the method and asks `Merge? [y/N]`; `--yes` skips the question," + " and without a terminal and without `--yes` it refuses. A pull request that reports no checks at all is" + " refused unless `--skip-checks` is given, which is refused on any pull request that does report checks;" + " with it the command reads how many workflows the repository defines, prints a warning for that case, asks" + " `Merge #<n> with no checks? [y/N]` (which `--yes` answers only where the repository defines no workflow)," + " and after the merge posts one comment on the pull request saying so. A step that fails never undoes the merge: it" + " prints what is left as commands to paste and exits 1. After the merge it ticks the `Closes #<n>` line of" + " every issue the pull request closes on every open board whose checklist lists it, or on the roadmap issue while no issue carries `type:roadmap`, warning rather than failing when that write" + ' does not land. It ends by reading every open issue whose "Blocked by:" line names an issue this pull' + " request closes, asking whether to remove `spec:blocked` from each one whose blockers have all closed;" + " `--yes` does not answer that question, and every failure of that reading is a warning. With" + " `--output=json` the pull request, the method, the steps that ran, the follow-ups, the roadmap tick and" + " the unblock reading are the data of the terminal result event. Refuses with exit code 2 where" + " `pr.provider` is not `gh`.",
|
|
42367
|
+
description: "Merges one pull request through the GitHub CLI and then, in code, switches to the base branch," + " pulls it fast-forward only, deletes the head branch locally and on the remote where it is still there," + " and prunes, reporting each step; a head branch this checkout has no local branch for is reported as a" + " skipped local delete, and the rest still run. Refuses before it asks anything on a dirty working tree, on a pull" + " request that is not green or does not merge, and on a head branch checked out in another worktree. It" + " shows the pull request, its branches and the method and asks `Merge? [y/N]`; `--yes` skips the question," + " and without a terminal and without `--yes` it refuses. A pull request that reports no checks at all is" + " refused unless `--skip-checks` is given, which is refused on any pull request that does report checks;" + " with it the command reads how many workflows the repository defines, prints a warning for that case, asks" + " `Merge #<n> with no checks? [y/N]` (which `--yes` answers only where the repository defines no workflow)," + " and after the merge posts one comment on the pull request saying so. A step that fails never undoes the merge: it" + " prints what is left as commands to paste and exits 1. After the merge it ticks the `Closes #<n>` line of" + " every issue the pull request closes on every open board whose checklist lists it, or on the roadmap issue while no issue carries `type:roadmap`, warning rather than failing when that write" + ' does not land. It ends by reading every open issue whose "Blocked by:" line names an issue this pull' + " request closes, asking whether to remove `spec:blocked` from each one whose blockers have all closed;" + " `--yes` does not answer that question, and every failure of that reading is a warning. With" + " `--output=json` the pull request, the method, the steps that ran, the follow-ups, the roadmap tick and" + " the unblock reading are the data of the terminal result event. Refuses with exit code 2 where" + " `pr.provider` is not `gh`.",
|
|
42344
42368
|
args: [
|
|
42345
42369
|
{
|
|
42346
42370
|
name: "n",
|
|
@@ -44923,6 +44947,46 @@ var init_wait = __esm(() => {
|
|
|
44923
44947
|
wait_default = createPrWaitCommand();
|
|
44924
44948
|
});
|
|
44925
44949
|
|
|
44950
|
+
// src/commands/release/release-commit.ts
|
|
44951
|
+
function unread2(reason, message) {
|
|
44952
|
+
return { commit: null, ahead: 0, problem: { reason, message } };
|
|
44953
|
+
}
|
|
44954
|
+
function versionAt(git, commit, path7) {
|
|
44955
|
+
const shown2 = git(["show", `${commit}:./${path7}`]);
|
|
44956
|
+
return shown2.ok ? readManifestVersion(shown2.stdout) : null;
|
|
44957
|
+
}
|
|
44958
|
+
function readReleaseCommit(git, path7, version2) {
|
|
44959
|
+
const log = git(["log", "--first-parent", "--format=%H", "HEAD", "--", `./${path7}`]);
|
|
44960
|
+
if (!log.ok)
|
|
44961
|
+
return unread2("git", `the history of ${path7} could not be read: ${gitSaid(log)}`);
|
|
44962
|
+
const changed = log.stdout.split(`
|
|
44963
|
+
`).map((line) => line.trim()).filter((line) => line !== "");
|
|
44964
|
+
if (changed.length === 0) {
|
|
44965
|
+
return unread2("version", `no commit on this branch holds ${path7}; commit it before tagging`);
|
|
44966
|
+
}
|
|
44967
|
+
let release = null;
|
|
44968
|
+
let newest;
|
|
44969
|
+
for (const commit of changed) {
|
|
44970
|
+
const declared = versionAt(git, commit, path7);
|
|
44971
|
+
if (newest === undefined)
|
|
44972
|
+
newest = declared;
|
|
44973
|
+
if (declared !== version2)
|
|
44974
|
+
break;
|
|
44975
|
+
release = commit;
|
|
44976
|
+
}
|
|
44977
|
+
if (release === null) {
|
|
44978
|
+
return unread2("version", `${path7} says ${version2}, and the last commit on this branch that changed it` + ` says ${newest ?? "no version"}; commit the version before tagging it`);
|
|
44979
|
+
}
|
|
44980
|
+
const count2 = git(["rev-list", "--count", "--first-parent", `${release}..HEAD`]);
|
|
44981
|
+
if (!count2.ok)
|
|
44982
|
+
return unread2("git", `the commits past ${release} could not be counted: ${gitSaid(count2)}`);
|
|
44983
|
+
return { commit: release, ahead: Number.parseInt(count2.stdout.trim(), 10), problem: null };
|
|
44984
|
+
}
|
|
44985
|
+
var init_release_commit = __esm(() => {
|
|
44986
|
+
init_pr();
|
|
44987
|
+
init_version2();
|
|
44988
|
+
});
|
|
44989
|
+
|
|
44926
44990
|
// src/commands/release/tag.ts
|
|
44927
44991
|
import { readFileSync as readFileSync54 } from "fs";
|
|
44928
44992
|
import { join as join63 } from "path";
|
|
@@ -44996,18 +45060,21 @@ function readPublishTarget(text2) {
|
|
|
44996
45060
|
isPrivate: fields["private"] === true
|
|
44997
45061
|
};
|
|
44998
45062
|
}
|
|
44999
|
-
function followUpsFor2(tag, version2, target) {
|
|
45063
|
+
function followUpsFor2(tag, version2, target, place2 = ON_HEAD) {
|
|
45000
45064
|
const push = {
|
|
45001
45065
|
command: `git push ${RELEASE_REMOTE2} ${tag}`,
|
|
45002
45066
|
why: `the tag is local until ${RELEASE_REMOTE2} has it`
|
|
45003
45067
|
};
|
|
45004
45068
|
if (target.name === null || target.isPrivate)
|
|
45005
45069
|
return [push];
|
|
45070
|
+
const publishes = `publishes ${target.name}@${version2} to ${target.registry}`;
|
|
45071
|
+
if (place2.ahead === 0)
|
|
45072
|
+
return [push, { command: `${target.manager} publish`, why: publishes }];
|
|
45006
45073
|
return [
|
|
45007
45074
|
push,
|
|
45008
45075
|
{
|
|
45009
|
-
command:
|
|
45010
|
-
why:
|
|
45076
|
+
command: `git switch --detach ${tag} && ${target.manager} publish && git switch ${place2.branch}`,
|
|
45077
|
+
why: `${publishes} from the tagged commit, not HEAD; skip it if ${target.registry} has that version already`
|
|
45011
45078
|
}
|
|
45012
45079
|
];
|
|
45013
45080
|
}
|
|
@@ -45047,7 +45114,14 @@ function decideTag(inputs) {
|
|
|
45047
45114
|
const disagrees = changelogRefusal(inputs, version2);
|
|
45048
45115
|
if (disagrees !== null)
|
|
45049
45116
|
return disagrees;
|
|
45050
|
-
|
|
45117
|
+
const release = inputs.release;
|
|
45118
|
+
if (release === null)
|
|
45119
|
+
return refuse7("version", `${inputs.version.path} was not looked up in the history`);
|
|
45120
|
+
if (release.problem !== null)
|
|
45121
|
+
return refuse7(release.problem.reason, release.problem.message);
|
|
45122
|
+
if (release.commit === null)
|
|
45123
|
+
return refuse7("git", `no commit could be named for ${version2}`);
|
|
45124
|
+
return { kind: "ready", version: version2, tag: versionTag(version2), commit: release.commit, ahead: release.ahead };
|
|
45051
45125
|
}
|
|
45052
45126
|
function projectOf10(context) {
|
|
45053
45127
|
if (context.project === null)
|
|
@@ -45070,23 +45144,34 @@ function tagConfig(project, warn3) {
|
|
|
45070
45144
|
}
|
|
45071
45145
|
}
|
|
45072
45146
|
function readTagInputs(root, git, config) {
|
|
45147
|
+
const branch = readBranch3(git);
|
|
45148
|
+
const version2 = readVersion(root, config.versionFile);
|
|
45149
|
+
const walkable = version2.version !== null && branch.branch === config.releaseBranch;
|
|
45073
45150
|
return {
|
|
45074
45151
|
releaseBranch: config.releaseBranch,
|
|
45075
|
-
branch
|
|
45076
|
-
version:
|
|
45152
|
+
branch,
|
|
45153
|
+
version: version2,
|
|
45077
45154
|
changelog: readNewestRelease(root, config.changelog),
|
|
45078
|
-
tags: readTags(git)
|
|
45155
|
+
tags: readTags(git),
|
|
45156
|
+
release: walkable && version2.version !== null ? readReleaseCommit(git, config.versionFile, version2.version) : null
|
|
45079
45157
|
};
|
|
45080
45158
|
}
|
|
45081
|
-
function writeTag(git, tag) {
|
|
45082
|
-
const result = git(["tag", tag,
|
|
45159
|
+
function writeTag(git, tag, commit) {
|
|
45160
|
+
const result = git(["tag", tag, commit]);
|
|
45083
45161
|
if (result.ok)
|
|
45084
45162
|
return;
|
|
45085
45163
|
throw new CommandExit(1, `\u274C ${tag} could not be written: ${gitSaid(result)}`);
|
|
45086
45164
|
}
|
|
45165
|
+
function pastReleaseWarning(written, branch) {
|
|
45166
|
+
if (written.ahead === 0)
|
|
45167
|
+
return null;
|
|
45168
|
+
const commits = written.ahead === 1 ? "1 commit" : `${String(written.ahead)} commits`;
|
|
45169
|
+
return `HEAD of ${branch} is ${commits} past ${written.commit.slice(0, SHORT_COMMIT)}, where ${written.version}` + ` was set; they are not in ${written.tag}.`;
|
|
45170
|
+
}
|
|
45087
45171
|
function renderTagged(written, branch, followUps) {
|
|
45172
|
+
const where = written.ahead === 0 ? `the HEAD of ${branch}` : `${written.commit.slice(0, SHORT_COMMIT)}, the commit of ${branch} that set ${written.version}`;
|
|
45088
45173
|
return [
|
|
45089
|
-
`\u2705 Tagged ${written.tag} at
|
|
45174
|
+
`\u2705 Tagged ${written.tag} at ${where}.`,
|
|
45090
45175
|
"Next:",
|
|
45091
45176
|
...followUps.map((followUp2) => `${INDENT14}${followUp2.command} \u2014 ${followUp2.why}`)
|
|
45092
45177
|
];
|
|
@@ -45104,8 +45189,9 @@ function runTag(context, seams = DEFAULT_RELEASE_SEAMS) {
|
|
|
45104
45189
|
throw new CommandExit(1, `\u274C ${decision.message}
|
|
45105
45190
|
Usage: ${RELEASE_TAG_USAGE}`);
|
|
45106
45191
|
}
|
|
45107
|
-
writeTag(git, decision.tag);
|
|
45108
|
-
const
|
|
45192
|
+
writeTag(git, decision.tag, decision.commit);
|
|
45193
|
+
const place2 = { ahead: decision.ahead, branch: config.releaseBranch };
|
|
45194
|
+
const followUps = followUpsFor2(decision.tag, decision.version, readPublishTarget(inputs.version.text), place2);
|
|
45109
45195
|
return { inputs, written: decision, followUps };
|
|
45110
45196
|
}
|
|
45111
45197
|
function createReleaseTagCommand(seams = DEFAULT_RELEASE_SEAMS) {
|
|
@@ -45113,8 +45199,8 @@ function createReleaseTagCommand(seams = DEFAULT_RELEASE_SEAMS) {
|
|
|
45113
45199
|
name: "release tag",
|
|
45114
45200
|
subject: "release",
|
|
45115
45201
|
action: "tag",
|
|
45116
|
-
summary: "tag the
|
|
45117
|
-
description: "Writes `v<version>` on the
|
|
45202
|
+
summary: "tag the commit that set the version both release files agree on",
|
|
45203
|
+
description: "Writes `v<version>` on the release branch \u2014 `pr.base`, or `main` \u2014 when the" + " version `release.versionFile` declares is the one the newest section of `release.changelog` names." + " The tag goes on the commit that set that version: HEAD, or, where later commits landed on the branch," + " the earlier commit, with a warning naming how many commits HEAD is past it." + " It refuses, and writes nothing, when another branch is checked out, when a tag already names that" + " version, when the two files disagree, when no commit holds the version yet, and when the version" + " file, the tag list or the history could not be read. After the tag it prints what to run next: the" + " push that puts the tag on the remote, and the publish line for the registry the version file" + " configures, spelled to publish from the tag when HEAD is past it, which it does not run. With" + " `--output=json` the readings, the decision and the follow-ups are the data of the terminal result" + " event.",
|
|
45118
45204
|
args: [],
|
|
45119
45205
|
flags: [],
|
|
45120
45206
|
examples: [
|
|
@@ -45130,6 +45216,9 @@ function createReleaseTagCommand(seams = DEFAULT_RELEASE_SEAMS) {
|
|
|
45130
45216
|
outputs: ["text", "json"],
|
|
45131
45217
|
run: async (context) => {
|
|
45132
45218
|
const result = runTag(context, seams);
|
|
45219
|
+
const past = pastReleaseWarning(result.written, result.inputs.releaseBranch);
|
|
45220
|
+
if (past !== null)
|
|
45221
|
+
context.output.warn(past);
|
|
45133
45222
|
if (context.outputMode === "json") {
|
|
45134
45223
|
context.output.result(result);
|
|
45135
45224
|
return;
|
|
@@ -45141,7 +45230,7 @@ function createReleaseTagCommand(seams = DEFAULT_RELEASE_SEAMS) {
|
|
|
45141
45230
|
};
|
|
45142
45231
|
return Object.freeze(command);
|
|
45143
45232
|
}
|
|
45144
|
-
var RELEASE_TAG_USAGE = "rafa release tag", DEFAULT_RELEASE_BRANCH = "main", DEFAULT_REGISTRY = "https://registry.npmjs.org", RELEASE_REMOTE2 = "origin", INDENT14 = " ", NO_PACKAGE2, tag_default;
|
|
45233
|
+
var RELEASE_TAG_USAGE = "rafa release tag", DEFAULT_RELEASE_BRANCH = "main", DEFAULT_REGISTRY = "https://registry.npmjs.org", RELEASE_REMOTE2 = "origin", INDENT14 = " ", SHORT_COMMIT = 7, NO_PACKAGE2, ON_HEAD, tag_default;
|
|
45145
45234
|
var init_tag = __esm(() => {
|
|
45146
45235
|
init_command();
|
|
45147
45236
|
init_config_load();
|
|
@@ -45150,6 +45239,7 @@ var init_tag = __esm(() => {
|
|
|
45150
45239
|
init_version2();
|
|
45151
45240
|
init_plan_files();
|
|
45152
45241
|
init_merge_followups();
|
|
45242
|
+
init_release_commit();
|
|
45153
45243
|
init_status();
|
|
45154
45244
|
NO_PACKAGE2 = Object.freeze({
|
|
45155
45245
|
manager: "npm",
|
|
@@ -45157,6 +45247,7 @@ var init_tag = __esm(() => {
|
|
|
45157
45247
|
name: null,
|
|
45158
45248
|
isPrivate: false
|
|
45159
45249
|
});
|
|
45250
|
+
ON_HEAD = Object.freeze({ ahead: 0, branch: DEFAULT_RELEASE_BRANCH });
|
|
45160
45251
|
tag_default = createReleaseTagCommand();
|
|
45161
45252
|
});
|
|
45162
45253
|
|
|
@@ -47477,7 +47568,7 @@ import { existsSync as existsSync47 } from "fs";
|
|
|
47477
47568
|
function isIdleWorktree(row3) {
|
|
47478
47569
|
return !row3.blockers.some((blocker) => blocker.kind === "recent");
|
|
47479
47570
|
}
|
|
47480
|
-
function
|
|
47571
|
+
function unread3(problem2) {
|
|
47481
47572
|
return { read: false, problem: problem2 };
|
|
47482
47573
|
}
|
|
47483
47574
|
function read2(reading2) {
|
|
@@ -47488,7 +47579,7 @@ function localSection(work) {
|
|
|
47488
47579
|
const reading2 = work();
|
|
47489
47580
|
return isUnread(reading2) ? reading2 : read2(reading2);
|
|
47490
47581
|
} catch (error) {
|
|
47491
|
-
return
|
|
47582
|
+
return unread3(messageOf(error));
|
|
47492
47583
|
}
|
|
47493
47584
|
}
|
|
47494
47585
|
function isUnread(value) {
|
|
@@ -47521,13 +47612,13 @@ async function networkSection(what, deadline, work) {
|
|
|
47521
47612
|
let timer;
|
|
47522
47613
|
const expired = new Promise((resolve30) => {
|
|
47523
47614
|
timer = setTimeout(() => {
|
|
47524
|
-
resolve30(
|
|
47615
|
+
resolve30(unread3(`the ${what} was not read within the ${String(deadline.ms)}ms network deadline`));
|
|
47525
47616
|
}, Math.max(0, deadline.left()));
|
|
47526
47617
|
});
|
|
47527
47618
|
try {
|
|
47528
47619
|
return await Promise.race([work().then((reading2) => read2(reading2)), expired]);
|
|
47529
47620
|
} catch (error) {
|
|
47530
|
-
return
|
|
47621
|
+
return unread3(messageOf(error));
|
|
47531
47622
|
} finally {
|
|
47532
47623
|
clearTimeout(timer);
|
|
47533
47624
|
}
|
|
@@ -47543,7 +47634,7 @@ function readBranchSection(sources) {
|
|
|
47543
47634
|
};
|
|
47544
47635
|
const branch = readBranch2(sources, note);
|
|
47545
47636
|
if (branch === "") {
|
|
47546
|
-
return
|
|
47637
|
+
return unread3(notes.join("; ") || "the branch at the project root could not be read");
|
|
47547
47638
|
}
|
|
47548
47639
|
const plans = readPlans(sources, note);
|
|
47549
47640
|
return { branch, plan: readBranchPlan(branch, plans), notes };
|
|
@@ -47570,9 +47661,9 @@ function readLoopsSection(root, sources) {
|
|
|
47570
47661
|
}
|
|
47571
47662
|
function pullSection(sources, branch, provider, deadline) {
|
|
47572
47663
|
if (provider.provider !== "gh")
|
|
47573
|
-
return Promise.resolve(
|
|
47664
|
+
return Promise.resolve(unread3(notGhProblem("pull request", provider)));
|
|
47574
47665
|
if (!branch.read) {
|
|
47575
|
-
return Promise.resolve(
|
|
47666
|
+
return Promise.resolve(unread3(`no pull request was looked for, as the branch was not read: ${branch.problem}`));
|
|
47576
47667
|
}
|
|
47577
47668
|
return networkSection("pull request", deadline, () => readPull(sources, branch.branch));
|
|
47578
47669
|
}
|
|
@@ -47656,11 +47747,11 @@ async function readHousekeeping(input, cleanup, now) {
|
|
|
47656
47747
|
const settings = doctorCleanupSettings({ root: input.root, home: input.home, config: input.config, gh: null }, now);
|
|
47657
47748
|
const reading2 = await readCleanup(cleanup, settings);
|
|
47658
47749
|
if (!reading2.ok)
|
|
47659
|
-
return
|
|
47750
|
+
return unread3(reading2.detail);
|
|
47660
47751
|
const idle = reading2.worktrees.filter((row3) => isIdleWorktree(row3));
|
|
47661
47752
|
return read2({ counts: cleanupCounts(reading2), idleWorktrees: idle.length, notes: reading2.notes });
|
|
47662
47753
|
} catch (error) {
|
|
47663
|
-
return
|
|
47754
|
+
return unread3(messageOf(error));
|
|
47664
47755
|
}
|
|
47665
47756
|
}
|
|
47666
47757
|
async function readStatusSections(input, seams = {}) {
|
|
@@ -47689,7 +47780,7 @@ async function readStatusSections(input, seams = {}) {
|
|
|
47689
47780
|
const blockedIssues = seams.blockedIssues ?? ((runner) => readBlockedIssues({ gh: runner }));
|
|
47690
47781
|
deadline.start();
|
|
47691
47782
|
const pull = pullSection(sources, branch, provider, deadline);
|
|
47692
|
-
const boardSection = isGh ? networkSection("board", deadline, () => readBoard(root, board, listing3, blockedIssues(gh))) : Promise.resolve(
|
|
47783
|
+
const boardSection = isGh ? networkSection("board", deadline, () => readBoard(root, board, listing3, blockedIssues(gh))) : Promise.resolve(unread3(notGhProblem("board", provider)));
|
|
47693
47784
|
const housekeeping = readHousekeeping(input, cleanup, now);
|
|
47694
47785
|
return {
|
|
47695
47786
|
branch,
|
|
@@ -47917,7 +48008,7 @@ var init_commands2 = __esm(() => {
|
|
|
47917
48008
|
{ name: "agent", summary: "copy an agent definition into the project; list what a session sees" },
|
|
47918
48009
|
{ name: "skill", summary: "check a skills directory; list each tier; demote and backfill it" },
|
|
47919
48010
|
{ name: "instinct", summary: "check an instincts directory; list, show, flag and promote its records" },
|
|
47920
|
-
{ name: "release", summary: "read the release state of the project; tag the
|
|
48011
|
+
{ name: "release", summary: "read the release state of the project; tag the commit that set the version" },
|
|
47921
48012
|
{ name: "board", summary: "list the boards with their owner, epic count, and which is current and home" },
|
|
47922
48013
|
{ name: "epic", summary: "show one epic's issues as the Roadmap table; create an epic; defer or promote it; move an issue to it; close it through the gate or cancel it" }
|
|
47923
48014
|
]);
|
|
@@ -283,7 +283,7 @@ import {
|
|
|
283
283
|
writePositionFile,
|
|
284
284
|
writeSession,
|
|
285
285
|
writeShippedFile
|
|
286
|
-
} from "./index-
|
|
286
|
+
} from "./index-h369efkh.js";
|
|
287
287
|
import {
|
|
288
288
|
PROBE_TIMEOUT_MS,
|
|
289
289
|
findNextTask,
|
|
@@ -15149,6 +15149,16 @@ function remoteHoldsBranch(git, branch, warn3) {
|
|
|
15149
15149
|
warn3(`${REMOTE3} could not be asked whether it still holds ${branch}, so it is left alone: ${gitSaid(probe2)}`);
|
|
15150
15150
|
return false;
|
|
15151
15151
|
}
|
|
15152
|
+
function localHoldsBranch(git, branch, warn3) {
|
|
15153
|
+
const probe2 = git(["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
|
|
15154
|
+
if (probe2.ok)
|
|
15155
|
+
return true;
|
|
15156
|
+
const said = gitSaid(probe2);
|
|
15157
|
+
if (said === "")
|
|
15158
|
+
return false;
|
|
15159
|
+
warn3(`could not read whether this checkout holds a local branch ${branch}, so its delete runs: ${said}`);
|
|
15160
|
+
return true;
|
|
15161
|
+
}
|
|
15152
15162
|
function textOf(path) {
|
|
15153
15163
|
try {
|
|
15154
15164
|
return readFileSync19(path, "utf8");
|
|
@@ -15226,25 +15236,34 @@ async function reportTick(context, pr, seams, detail) {
|
|
|
15226
15236
|
}
|
|
15227
15237
|
return tick;
|
|
15228
15238
|
}
|
|
15229
|
-
function readyLine(base, branch,
|
|
15230
|
-
const
|
|
15231
|
-
|
|
15239
|
+
function readyLine(base, branch, present) {
|
|
15240
|
+
const pulled = `${base} is checked out and pulled`;
|
|
15241
|
+
if (present.local) {
|
|
15242
|
+
return present.remote ? `${pulled}, and ${branch} is gone locally and on ${REMOTE3}.` : `${pulled}, and ${branch} is gone locally; ${REMOTE3} had already deleted it.`;
|
|
15243
|
+
}
|
|
15244
|
+
return present.remote ? `${pulled}, and ${branch} is gone on ${REMOTE3}; there was no local branch to delete.` : `${pulled}; ${branch} had no local branch, and ${REMOTE3} had already deleted it.`;
|
|
15232
15245
|
}
|
|
15233
15246
|
function quotedLines2(said) {
|
|
15234
15247
|
return said === "" ? [] : said.split(`
|
|
15235
15248
|
`).map((line) => `${INDENT4}${line}`);
|
|
15236
15249
|
}
|
|
15237
|
-
function runCleanUp(context, git, detail,
|
|
15250
|
+
function runCleanUp(context, git, detail, present) {
|
|
15238
15251
|
const steps = cleanUpSteps({
|
|
15239
15252
|
branch: detail.headRefName,
|
|
15240
15253
|
base: detail.baseRefName,
|
|
15241
15254
|
remote: REMOTE3,
|
|
15242
|
-
|
|
15255
|
+
localBranchPresent: present.local,
|
|
15256
|
+
remoteBranchPresent: present.remote
|
|
15243
15257
|
});
|
|
15244
15258
|
const reports = [];
|
|
15245
15259
|
for (const step of steps) {
|
|
15260
|
+
if (step.skip !== undefined) {
|
|
15261
|
+
reports.push({ id: step.id, label: step.label, command: commandLine(step), ok: true, skipped: true });
|
|
15262
|
+
context.output.info(`${step.label}: skipped \u2014 ${step.skip}`);
|
|
15263
|
+
continue;
|
|
15264
|
+
}
|
|
15246
15265
|
const result = git(step.argv.slice(1));
|
|
15247
|
-
reports.push({ id: step.id, label: step.label, command: commandLine(step), ok: result.ok });
|
|
15266
|
+
reports.push({ id: step.id, label: step.label, command: commandLine(step), ok: result.ok, skipped: false });
|
|
15248
15267
|
if (result.ok) {
|
|
15249
15268
|
context.output.info(`${step.label}: done`);
|
|
15250
15269
|
continue;
|
|
@@ -15340,11 +15359,15 @@ async function runMerge(context, seams) {
|
|
|
15340
15359
|
context.output.info(`Merged #${detail.number} into ${detail.baseRefName} (${method}).`);
|
|
15341
15360
|
const commentUrl = await commentIfUnchecked(context, pr, detail.number, answer2.unchecked);
|
|
15342
15361
|
const roadmapTicks = await reportTick(context, pr, seams, detail);
|
|
15343
|
-
const
|
|
15362
|
+
const warn3 = (message) => {
|
|
15344
15363
|
context.output.warn(message);
|
|
15345
|
-
}
|
|
15346
|
-
const
|
|
15347
|
-
|
|
15364
|
+
};
|
|
15365
|
+
const present = {
|
|
15366
|
+
remote: remoteHoldsBranch(git, detail.headRefName, warn3),
|
|
15367
|
+
local: localHoldsBranch(git, detail.headRefName, warn3)
|
|
15368
|
+
};
|
|
15369
|
+
const steps = runCleanUp(context, git, detail, present);
|
|
15370
|
+
context.output.info(readyLine(detail.baseRefName, detail.headRefName, present));
|
|
15348
15371
|
const followUps = followUpsFor(pr, git);
|
|
15349
15372
|
if (followUps.length > 0) {
|
|
15350
15373
|
context.output.info("Follow-ups:");
|
|
@@ -15371,7 +15394,7 @@ function createPrMergeCommand(seams = DEFAULT_MERGE_SEAMS) {
|
|
|
15371
15394
|
subject: "pr",
|
|
15372
15395
|
action: "merge",
|
|
15373
15396
|
summary: "merge a pull request and clean up both branches",
|
|
15374
|
-
description: "Merges one pull request through the GitHub CLI and then, in code, switches to the base branch," + " pulls it fast-forward only, deletes the head branch locally and on the remote where it is still there," + " and prunes, reporting each step. Refuses before it asks anything on a dirty working tree, on a pull" + " request that is not green or does not merge, and on a head branch checked out in another worktree. It" + " shows the pull request, its branches and the method and asks `Merge? [y/N]`; `--yes` skips the question," + " and without a terminal and without `--yes` it refuses. A pull request that reports no checks at all is" + " refused unless `--skip-checks` is given, which is refused on any pull request that does report checks;" + " with it the command reads how many workflows the repository defines, prints a warning for that case, asks" + " `Merge #<n> with no checks? [y/N]` (which `--yes` answers only where the repository defines no workflow)," + " and after the merge posts one comment on the pull request saying so. A step that fails never undoes the merge: it" + " prints what is left as commands to paste and exits 1. After the merge it ticks the `Closes #<n>` line of" + " every issue the pull request closes on every open board whose checklist lists it, or on the roadmap issue while no issue carries `type:roadmap`, warning rather than failing when that write" + ' does not land. It ends by reading every open issue whose "Blocked by:" line names an issue this pull' + " request closes, asking whether to remove `spec:blocked` from each one whose blockers have all closed;" + " `--yes` does not answer that question, and every failure of that reading is a warning. With" + " `--output=json` the pull request, the method, the steps that ran, the follow-ups, the roadmap tick and" + " the unblock reading are the data of the terminal result event. Refuses with exit code 2 where" + " `pr.provider` is not `gh`.",
|
|
15397
|
+
description: "Merges one pull request through the GitHub CLI and then, in code, switches to the base branch," + " pulls it fast-forward only, deletes the head branch locally and on the remote where it is still there," + " and prunes, reporting each step; a head branch this checkout has no local branch for is reported as a" + " skipped local delete, and the rest still run. Refuses before it asks anything on a dirty working tree, on a pull" + " request that is not green or does not merge, and on a head branch checked out in another worktree. It" + " shows the pull request, its branches and the method and asks `Merge? [y/N]`; `--yes` skips the question," + " and without a terminal and without `--yes` it refuses. A pull request that reports no checks at all is" + " refused unless `--skip-checks` is given, which is refused on any pull request that does report checks;" + " with it the command reads how many workflows the repository defines, prints a warning for that case, asks" + " `Merge #<n> with no checks? [y/N]` (which `--yes` answers only where the repository defines no workflow)," + " and after the merge posts one comment on the pull request saying so. A step that fails never undoes the merge: it" + " prints what is left as commands to paste and exits 1. After the merge it ticks the `Closes #<n>` line of" + " every issue the pull request closes on every open board whose checklist lists it, or on the roadmap issue while no issue carries `type:roadmap`, warning rather than failing when that write" + ' does not land. It ends by reading every open issue whose "Blocked by:" line names an issue this pull' + " request closes, asking whether to remove `spec:blocked` from each one whose blockers have all closed;" + " `--yes` does not answer that question, and every failure of that reading is a warning. With" + " `--output=json` the pull request, the method, the steps that ran, the follow-ups, the roadmap tick and" + " the unblock reading are the data of the terminal result event. Refuses with exit code 2 where" + " `pr.provider` is not `gh`.",
|
|
15375
15398
|
args: [
|
|
15376
15399
|
{
|
|
15377
15400
|
name: "n",
|
|
@@ -17858,11 +17881,50 @@ var wait_default = createPrWaitCommand();
|
|
|
17858
17881
|
// src/commands/release/tag.ts
|
|
17859
17882
|
import { readFileSync as readFileSync21 } from "fs";
|
|
17860
17883
|
import { join as join32 } from "path";
|
|
17884
|
+
|
|
17885
|
+
// src/commands/release/release-commit.ts
|
|
17886
|
+
function unread2(reason, message) {
|
|
17887
|
+
return { commit: null, ahead: 0, problem: { reason, message } };
|
|
17888
|
+
}
|
|
17889
|
+
function versionAt(git, commit, path) {
|
|
17890
|
+
const shown = git(["show", `${commit}:./${path}`]);
|
|
17891
|
+
return shown.ok ? readManifestVersion(shown.stdout) : null;
|
|
17892
|
+
}
|
|
17893
|
+
function readReleaseCommit(git, path, version2) {
|
|
17894
|
+
const log = git(["log", "--first-parent", "--format=%H", "HEAD", "--", `./${path}`]);
|
|
17895
|
+
if (!log.ok)
|
|
17896
|
+
return unread2("git", `the history of ${path} could not be read: ${gitSaid(log)}`);
|
|
17897
|
+
const changed = log.stdout.split(`
|
|
17898
|
+
`).map((line) => line.trim()).filter((line) => line !== "");
|
|
17899
|
+
if (changed.length === 0) {
|
|
17900
|
+
return unread2("version", `no commit on this branch holds ${path}; commit it before tagging`);
|
|
17901
|
+
}
|
|
17902
|
+
let release = null;
|
|
17903
|
+
let newest;
|
|
17904
|
+
for (const commit of changed) {
|
|
17905
|
+
const declared = versionAt(git, commit, path);
|
|
17906
|
+
if (newest === undefined)
|
|
17907
|
+
newest = declared;
|
|
17908
|
+
if (declared !== version2)
|
|
17909
|
+
break;
|
|
17910
|
+
release = commit;
|
|
17911
|
+
}
|
|
17912
|
+
if (release === null) {
|
|
17913
|
+
return unread2("version", `${path} says ${version2}, and the last commit on this branch that changed it` + ` says ${newest ?? "no version"}; commit the version before tagging it`);
|
|
17914
|
+
}
|
|
17915
|
+
const count2 = git(["rev-list", "--count", "--first-parent", `${release}..HEAD`]);
|
|
17916
|
+
if (!count2.ok)
|
|
17917
|
+
return unread2("git", `the commits past ${release} could not be counted: ${gitSaid(count2)}`);
|
|
17918
|
+
return { commit: release, ahead: Number.parseInt(count2.stdout.trim(), 10), problem: null };
|
|
17919
|
+
}
|
|
17920
|
+
|
|
17921
|
+
// src/commands/release/tag.ts
|
|
17861
17922
|
var RELEASE_TAG_USAGE = "rafa release tag";
|
|
17862
17923
|
var DEFAULT_RELEASE_BRANCH = "main";
|
|
17863
17924
|
var DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
|
17864
17925
|
var RELEASE_REMOTE = "origin";
|
|
17865
17926
|
var INDENT8 = " ";
|
|
17927
|
+
var SHORT_COMMIT = 7;
|
|
17866
17928
|
function readBranch2(git) {
|
|
17867
17929
|
const result = git(["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
17868
17930
|
if (!result.ok) {
|
|
@@ -17939,18 +18001,22 @@ function readPublishTarget(text) {
|
|
|
17939
18001
|
isPrivate: fields["private"] === true
|
|
17940
18002
|
};
|
|
17941
18003
|
}
|
|
17942
|
-
|
|
18004
|
+
var ON_HEAD = Object.freeze({ ahead: 0, branch: DEFAULT_RELEASE_BRANCH });
|
|
18005
|
+
function followUpsFor2(tag, version2, target, place2 = ON_HEAD) {
|
|
17943
18006
|
const push = {
|
|
17944
18007
|
command: `git push ${RELEASE_REMOTE} ${tag}`,
|
|
17945
18008
|
why: `the tag is local until ${RELEASE_REMOTE} has it`
|
|
17946
18009
|
};
|
|
17947
18010
|
if (target.name === null || target.isPrivate)
|
|
17948
18011
|
return [push];
|
|
18012
|
+
const publishes = `publishes ${target.name}@${version2} to ${target.registry}`;
|
|
18013
|
+
if (place2.ahead === 0)
|
|
18014
|
+
return [push, { command: `${target.manager} publish`, why: publishes }];
|
|
17949
18015
|
return [
|
|
17950
18016
|
push,
|
|
17951
18017
|
{
|
|
17952
|
-
command:
|
|
17953
|
-
why:
|
|
18018
|
+
command: `git switch --detach ${tag} && ${target.manager} publish && git switch ${place2.branch}`,
|
|
18019
|
+
why: `${publishes} from the tagged commit, not HEAD; skip it if ${target.registry} has that version already`
|
|
17954
18020
|
}
|
|
17955
18021
|
];
|
|
17956
18022
|
}
|
|
@@ -17990,7 +18056,14 @@ function decideTag(inputs) {
|
|
|
17990
18056
|
const disagrees = changelogRefusal(inputs, version2);
|
|
17991
18057
|
if (disagrees !== null)
|
|
17992
18058
|
return disagrees;
|
|
17993
|
-
|
|
18059
|
+
const release = inputs.release;
|
|
18060
|
+
if (release === null)
|
|
18061
|
+
return refuse2("version", `${inputs.version.path} was not looked up in the history`);
|
|
18062
|
+
if (release.problem !== null)
|
|
18063
|
+
return refuse2(release.problem.reason, release.problem.message);
|
|
18064
|
+
if (release.commit === null)
|
|
18065
|
+
return refuse2("git", `no commit could be named for ${version2}`);
|
|
18066
|
+
return { kind: "ready", version: version2, tag: versionTag(version2), commit: release.commit, ahead: release.ahead };
|
|
17994
18067
|
}
|
|
17995
18068
|
function projectOf9(context) {
|
|
17996
18069
|
if (context.project === null)
|
|
@@ -18013,23 +18086,34 @@ function tagConfig(project, warn3) {
|
|
|
18013
18086
|
}
|
|
18014
18087
|
}
|
|
18015
18088
|
function readTagInputs(root, git, config) {
|
|
18089
|
+
const branch = readBranch2(git);
|
|
18090
|
+
const version2 = readVersion(root, config.versionFile);
|
|
18091
|
+
const walkable = version2.version !== null && branch.branch === config.releaseBranch;
|
|
18016
18092
|
return {
|
|
18017
18093
|
releaseBranch: config.releaseBranch,
|
|
18018
|
-
branch
|
|
18019
|
-
version:
|
|
18094
|
+
branch,
|
|
18095
|
+
version: version2,
|
|
18020
18096
|
changelog: readNewestRelease(root, config.changelog),
|
|
18021
|
-
tags: readTags(git)
|
|
18097
|
+
tags: readTags(git),
|
|
18098
|
+
release: walkable && version2.version !== null ? readReleaseCommit(git, config.versionFile, version2.version) : null
|
|
18022
18099
|
};
|
|
18023
18100
|
}
|
|
18024
|
-
function writeTag(git, tag) {
|
|
18025
|
-
const result = git(["tag", tag,
|
|
18101
|
+
function writeTag(git, tag, commit) {
|
|
18102
|
+
const result = git(["tag", tag, commit]);
|
|
18026
18103
|
if (result.ok)
|
|
18027
18104
|
return;
|
|
18028
18105
|
throw new CommandExit(1, `\u274C ${tag} could not be written: ${gitSaid(result)}`);
|
|
18029
18106
|
}
|
|
18107
|
+
function pastReleaseWarning(written, branch) {
|
|
18108
|
+
if (written.ahead === 0)
|
|
18109
|
+
return null;
|
|
18110
|
+
const commits = written.ahead === 1 ? "1 commit" : `${String(written.ahead)} commits`;
|
|
18111
|
+
return `HEAD of ${branch} is ${commits} past ${written.commit.slice(0, SHORT_COMMIT)}, where ${written.version}` + ` was set; they are not in ${written.tag}.`;
|
|
18112
|
+
}
|
|
18030
18113
|
function renderTagged(written, branch, followUps) {
|
|
18114
|
+
const where = written.ahead === 0 ? `the HEAD of ${branch}` : `${written.commit.slice(0, SHORT_COMMIT)}, the commit of ${branch} that set ${written.version}`;
|
|
18031
18115
|
return [
|
|
18032
|
-
`\u2705 Tagged ${written.tag} at
|
|
18116
|
+
`\u2705 Tagged ${written.tag} at ${where}.`,
|
|
18033
18117
|
"Next:",
|
|
18034
18118
|
...followUps.map((followUp2) => `${INDENT8}${followUp2.command} \u2014 ${followUp2.why}`)
|
|
18035
18119
|
];
|
|
@@ -18047,8 +18131,9 @@ function runTag(context, seams = DEFAULT_RELEASE_SEAMS) {
|
|
|
18047
18131
|
throw new CommandExit(1, `\u274C ${decision.message}
|
|
18048
18132
|
Usage: ${RELEASE_TAG_USAGE}`);
|
|
18049
18133
|
}
|
|
18050
|
-
writeTag(git, decision.tag);
|
|
18051
|
-
const
|
|
18134
|
+
writeTag(git, decision.tag, decision.commit);
|
|
18135
|
+
const place2 = { ahead: decision.ahead, branch: config.releaseBranch };
|
|
18136
|
+
const followUps = followUpsFor2(decision.tag, decision.version, readPublishTarget(inputs.version.text), place2);
|
|
18052
18137
|
return { inputs, written: decision, followUps };
|
|
18053
18138
|
}
|
|
18054
18139
|
function createReleaseTagCommand(seams = DEFAULT_RELEASE_SEAMS) {
|
|
@@ -18056,8 +18141,8 @@ function createReleaseTagCommand(seams = DEFAULT_RELEASE_SEAMS) {
|
|
|
18056
18141
|
name: "release tag",
|
|
18057
18142
|
subject: "release",
|
|
18058
18143
|
action: "tag",
|
|
18059
|
-
summary: "tag the
|
|
18060
|
-
description: "Writes `v<version>` on the
|
|
18144
|
+
summary: "tag the commit that set the version both release files agree on",
|
|
18145
|
+
description: "Writes `v<version>` on the release branch \u2014 `pr.base`, or `main` \u2014 when the" + " version `release.versionFile` declares is the one the newest section of `release.changelog` names." + " The tag goes on the commit that set that version: HEAD, or, where later commits landed on the branch," + " the earlier commit, with a warning naming how many commits HEAD is past it." + " It refuses, and writes nothing, when another branch is checked out, when a tag already names that" + " version, when the two files disagree, when no commit holds the version yet, and when the version" + " file, the tag list or the history could not be read. After the tag it prints what to run next: the" + " push that puts the tag on the remote, and the publish line for the registry the version file" + " configures, spelled to publish from the tag when HEAD is past it, which it does not run. With" + " `--output=json` the readings, the decision and the follow-ups are the data of the terminal result" + " event.",
|
|
18061
18146
|
args: [],
|
|
18062
18147
|
flags: [],
|
|
18063
18148
|
examples: [
|
|
@@ -18073,6 +18158,9 @@ function createReleaseTagCommand(seams = DEFAULT_RELEASE_SEAMS) {
|
|
|
18073
18158
|
outputs: ["text", "json"],
|
|
18074
18159
|
run: async (context) => {
|
|
18075
18160
|
const result = runTag(context, seams);
|
|
18161
|
+
const past = pastReleaseWarning(result.written, result.inputs.releaseBranch);
|
|
18162
|
+
if (past !== null)
|
|
18163
|
+
context.output.warn(past);
|
|
18076
18164
|
if (context.outputMode === "json") {
|
|
18077
18165
|
context.output.result(result);
|
|
18078
18166
|
return;
|
|
@@ -20328,7 +20416,7 @@ var STATUS_NETWORK_TIMEOUT_MS = 5000;
|
|
|
20328
20416
|
function isIdleWorktree(row2) {
|
|
20329
20417
|
return !row2.blockers.some((blocker) => blocker.kind === "recent");
|
|
20330
20418
|
}
|
|
20331
|
-
function
|
|
20419
|
+
function unread3(problem2) {
|
|
20332
20420
|
return { read: false, problem: problem2 };
|
|
20333
20421
|
}
|
|
20334
20422
|
function read2(reading) {
|
|
@@ -20339,7 +20427,7 @@ function localSection(work) {
|
|
|
20339
20427
|
const reading = work();
|
|
20340
20428
|
return isUnread(reading) ? reading : read2(reading);
|
|
20341
20429
|
} catch (error) {
|
|
20342
|
-
return
|
|
20430
|
+
return unread3(messageOf(error));
|
|
20343
20431
|
}
|
|
20344
20432
|
}
|
|
20345
20433
|
function isUnread(value) {
|
|
@@ -20372,13 +20460,13 @@ async function networkSection(what, deadline, work) {
|
|
|
20372
20460
|
let timer;
|
|
20373
20461
|
const expired = new Promise((resolve16) => {
|
|
20374
20462
|
timer = setTimeout(() => {
|
|
20375
|
-
resolve16(
|
|
20463
|
+
resolve16(unread3(`the ${what} was not read within the ${String(deadline.ms)}ms network deadline`));
|
|
20376
20464
|
}, Math.max(0, deadline.left()));
|
|
20377
20465
|
});
|
|
20378
20466
|
try {
|
|
20379
20467
|
return await Promise.race([work().then((reading) => read2(reading)), expired]);
|
|
20380
20468
|
} catch (error) {
|
|
20381
|
-
return
|
|
20469
|
+
return unread3(messageOf(error));
|
|
20382
20470
|
} finally {
|
|
20383
20471
|
clearTimeout(timer);
|
|
20384
20472
|
}
|
|
@@ -20394,7 +20482,7 @@ function readBranchSection(sources) {
|
|
|
20394
20482
|
};
|
|
20395
20483
|
const branch = readBranch(sources, note);
|
|
20396
20484
|
if (branch === "") {
|
|
20397
|
-
return
|
|
20485
|
+
return unread3(notes.join("; ") || "the branch at the project root could not be read");
|
|
20398
20486
|
}
|
|
20399
20487
|
const plans = readPlans(sources, note);
|
|
20400
20488
|
return { branch, plan: readBranchPlan(branch, plans), notes };
|
|
@@ -20421,9 +20509,9 @@ function readLoopsSection(root, sources) {
|
|
|
20421
20509
|
}
|
|
20422
20510
|
function pullSection(sources, branch, provider, deadline) {
|
|
20423
20511
|
if (provider.provider !== "gh")
|
|
20424
|
-
return Promise.resolve(
|
|
20512
|
+
return Promise.resolve(unread3(notGhProblem("pull request", provider)));
|
|
20425
20513
|
if (!branch.read) {
|
|
20426
|
-
return Promise.resolve(
|
|
20514
|
+
return Promise.resolve(unread3(`no pull request was looked for, as the branch was not read: ${branch.problem}`));
|
|
20427
20515
|
}
|
|
20428
20516
|
return networkSection("pull request", deadline, () => readPull(sources, branch.branch));
|
|
20429
20517
|
}
|
|
@@ -20507,11 +20595,11 @@ async function readHousekeeping(input, cleanup, now) {
|
|
|
20507
20595
|
const settings = doctorCleanupSettings({ root: input.root, home: input.home, config: input.config, gh: null }, now);
|
|
20508
20596
|
const reading = await readCleanup(cleanup, settings);
|
|
20509
20597
|
if (!reading.ok)
|
|
20510
|
-
return
|
|
20598
|
+
return unread3(reading.detail);
|
|
20511
20599
|
const idle = reading.worktrees.filter((row2) => isIdleWorktree(row2));
|
|
20512
20600
|
return read2({ counts: cleanupCounts(reading), idleWorktrees: idle.length, notes: reading.notes });
|
|
20513
20601
|
} catch (error) {
|
|
20514
|
-
return
|
|
20602
|
+
return unread3(messageOf(error));
|
|
20515
20603
|
}
|
|
20516
20604
|
}
|
|
20517
20605
|
async function readStatusSections(input, seams = {}) {
|
|
@@ -20540,7 +20628,7 @@ async function readStatusSections(input, seams = {}) {
|
|
|
20540
20628
|
const blockedIssues = seams.blockedIssues ?? ((runner) => readBlockedIssues({ gh: runner }));
|
|
20541
20629
|
deadline.start();
|
|
20542
20630
|
const pull = pullSection(sources, branch, provider, deadline);
|
|
20543
|
-
const boardSection = isGh ? networkSection("board", deadline, () => readBoard(root, board, listing2, blockedIssues(gh))) : Promise.resolve(
|
|
20631
|
+
const boardSection = isGh ? networkSection("board", deadline, () => readBoard(root, board, listing2, blockedIssues(gh))) : Promise.resolve(unread3(notGhProblem("board", provider)));
|
|
20544
20632
|
const housekeeping = readHousekeeping(input, cleanup, now);
|
|
20545
20633
|
return {
|
|
20546
20634
|
branch,
|
|
@@ -20641,7 +20729,7 @@ var CORE_SUBJECTS = Object.freeze([
|
|
|
20641
20729
|
{ name: "agent", summary: "copy an agent definition into the project; list what a session sees" },
|
|
20642
20730
|
{ name: "skill", summary: "check a skills directory; list each tier; demote and backfill it" },
|
|
20643
20731
|
{ name: "instinct", summary: "check an instincts directory; list, show, flag and promote its records" },
|
|
20644
|
-
{ name: "release", summary: "read the release state of the project; tag the
|
|
20732
|
+
{ name: "release", summary: "read the release state of the project; tag the commit that set the version" },
|
|
20645
20733
|
{ name: "board", summary: "list the boards with their owner, epic count, and which is current and home" },
|
|
20646
20734
|
{ name: "epic", summary: "show one epic's issues as the Roadmap table; create an epic; defer or promote it; move an issue to it; close it through the gate or cancel it" }
|
|
20647
20735
|
]);
|
|
@@ -5132,7 +5132,7 @@ async function report(args, repoRoot) {
|
|
|
5132
5132
|
|
|
5133
5133
|
// package.json
|
|
5134
5134
|
var name = "@open-tomato/rafa";
|
|
5135
|
-
var version = "0.24.
|
|
5135
|
+
var version = "0.24.1";
|
|
5136
5136
|
|
|
5137
5137
|
// src/modules/manifest.ts
|
|
5138
5138
|
var MANIFEST_VERSION = 1;
|
|
@@ -9930,7 +9930,7 @@ async function enforceRefsGate(options) {
|
|
|
9930
9930
|
import path2 from "path";
|
|
9931
9931
|
async function coreRoster() {
|
|
9932
9932
|
const [{ CORE_REGISTRY }, { describeRegistry }] = await Promise.all([
|
|
9933
|
-
import("./index-
|
|
9933
|
+
import("./index-amyd4dse.js"),
|
|
9934
9934
|
import("./describe-66gth329.js")
|
|
9935
9935
|
]);
|
|
9936
9936
|
return describeRegistry(CORE_REGISTRY, version);
|
|
@@ -11496,7 +11496,7 @@ function readMergeRefusal(reading2) {
|
|
|
11496
11496
|
return held.length === 0 ? null : worktreeRefusal(reading2.branch, held);
|
|
11497
11497
|
}
|
|
11498
11498
|
function cleanUpSteps(plan) {
|
|
11499
|
-
const { base, branch, remote = DEFAULT_REMOTE2, remoteBranchPresent } = plan;
|
|
11499
|
+
const { base, branch, remote = DEFAULT_REMOTE2, localBranchPresent, remoteBranchPresent } = plan;
|
|
11500
11500
|
const steps = [
|
|
11501
11501
|
{ id: "switch-base", label: `switch to ${base}`, argv: ["git", "switch", base] },
|
|
11502
11502
|
{
|
|
@@ -11507,7 +11507,8 @@ function cleanUpSteps(plan) {
|
|
|
11507
11507
|
{
|
|
11508
11508
|
id: "delete-local",
|
|
11509
11509
|
label: `delete the local branch ${branch}`,
|
|
11510
|
-
argv: ["git", "branch", "-D", branch]
|
|
11510
|
+
argv: ["git", "branch", "-D", branch],
|
|
11511
|
+
...localBranchPresent ? {} : { skip: `no local branch ${branch}; nothing to delete` }
|
|
11511
11512
|
}
|
|
11512
11513
|
];
|
|
11513
11514
|
if (remoteBranchPresent) {
|
|
@@ -11532,7 +11533,7 @@ function commandLine(step) {
|
|
|
11532
11533
|
}
|
|
11533
11534
|
function remainingFrom(steps, failed2) {
|
|
11534
11535
|
const at = steps.findIndex((step) => step.id === failed2);
|
|
11535
|
-
return at === -1 ? Object.freeze([]) : Object.freeze(steps.slice(at));
|
|
11536
|
+
return at === -1 ? Object.freeze([]) : Object.freeze(steps.slice(at).filter((step) => step.skip === undefined));
|
|
11536
11537
|
}
|
|
11537
11538
|
// src/pr/none.ts
|
|
11538
11539
|
import { spawnSync as spawnSync2 } from "child_process";
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-tomato/rafa",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.1",
|
|
4
4
|
"description": "Alpha. Runs a plan through the ralph loop: one Claude Code session per task, one commit per task, then a pull request and a CI wait.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|