agentplane 0.3.11 → 0.3.12
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/assets/AGENTS.md +2 -2
- package/assets/agents/CODER.json +4 -0
- package/assets/agents/CREATOR.json +1 -0
- package/assets/agents/DOCS.json +2 -1
- package/assets/agents/INTEGRATOR.json +2 -1
- package/assets/agents/ORCHESTRATOR.json +2 -0
- package/assets/agents/PLANNER.json +3 -1
- package/assets/agents/REVIEWER.json +1 -0
- package/assets/agents/TESTER.json +2 -2
- package/assets/agents/UPDATER.json +1 -0
- package/assets/agents/UPGRADER.json +1 -1
- package/assets/policy/incidents.md +1 -0
- package/bin/agentplane.js +58 -3
- package/bin/stale-dist-policy.js +6 -1
- package/dist/.build-manifest.json +88 -68
- package/dist/cli/run-cli/command-catalog/core.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog/core.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog/core.js +6 -1
- package/dist/cli/run-cli/command-catalog.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
- package/dist/cli/run-cli.test-helpers.d.ts +1 -0
- package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
- package/dist/cli/run-cli.test-helpers.js +14 -0
- package/dist/commands/branch/cleanup-merged.d.ts +1 -0
- package/dist/commands/branch/cleanup-merged.d.ts.map +1 -1
- package/dist/commands/branch/cleanup-merged.js +18 -9
- package/dist/commands/branch/work-start.d.ts.map +1 -1
- package/dist/commands/branch/work-start.js +82 -5
- package/dist/commands/doctor/branch-pr.js +2 -2
- package/dist/commands/guard/impl/commands.d.ts +1 -0
- package/dist/commands/guard/impl/commands.d.ts.map +1 -1
- package/dist/commands/guard/impl/commands.js +78 -8
- package/dist/commands/hooks/index.d.ts +1 -1
- package/dist/commands/hooks/index.d.ts.map +1 -1
- package/dist/commands/hooks/index.js +48 -12
- package/dist/commands/pr/check.d.ts.map +1 -1
- package/dist/commands/pr/check.js +3 -0
- package/dist/commands/pr/integrate/cmd.d.ts.map +1 -1
- package/dist/commands/pr/integrate/cmd.js +27 -2
- package/dist/commands/pr/integrate/internal/cleanup.d.ts +1 -11
- package/dist/commands/pr/integrate/internal/cleanup.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/cleanup.js +1 -46
- package/dist/commands/pr/integrate/internal/finalize.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/finalize.js +3 -0
- package/dist/commands/pr/integrate/internal/github-protection.d.ts +5 -0
- package/dist/commands/pr/integrate/internal/github-protection.d.ts.map +1 -0
- package/dist/commands/pr/integrate/internal/github-protection.js +13 -0
- package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.d.ts +15 -0
- package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.d.ts.map +1 -0
- package/dist/commands/pr/integrate/internal/pre-integrate-bootstrap.js +35 -0
- package/dist/commands/pr/integrate/internal/prepare.d.ts +1 -0
- package/dist/commands/pr/integrate/internal/prepare.d.ts.map +1 -1
- package/dist/commands/pr/integrate/internal/prepare.js +8 -0
- package/dist/commands/pr/internal/auto-commit.d.ts +7 -0
- package/dist/commands/pr/internal/auto-commit.d.ts.map +1 -0
- package/dist/commands/pr/internal/auto-commit.js +64 -0
- package/dist/commands/pr/internal/freshness.d.ts +1 -0
- package/dist/commands/pr/internal/freshness.d.ts.map +1 -1
- package/dist/commands/pr/internal/freshness.js +2 -0
- package/dist/commands/pr/internal/sync.d.ts.map +1 -1
- package/dist/commands/pr/internal/sync.js +93 -26
- package/dist/commands/pr/open.d.ts.map +1 -1
- package/dist/commands/pr/open.js +11 -0
- package/dist/commands/pr/update.d.ts.map +1 -1
- package/dist/commands/pr/update.js +13 -2
- package/dist/commands/release/apply.command.d.ts +3 -1
- package/dist/commands/release/apply.command.d.ts.map +1 -1
- package/dist/commands/release/apply.command.js +354 -18
- package/dist/commands/release/apply.mutation.d.ts.map +1 -1
- package/dist/commands/release/apply.mutation.js +1 -0
- package/dist/commands/release/apply.reporting.d.ts +1 -0
- package/dist/commands/release/apply.reporting.d.ts.map +1 -1
- package/dist/commands/release/apply.reporting.js +12 -8
- package/dist/commands/release/apply.types.d.ts +13 -0
- package/dist/commands/release/apply.types.d.ts.map +1 -1
- package/dist/commands/release/plan.command.d.ts.map +1 -1
- package/dist/commands/release/plan.command.js +48 -0
- package/dist/commands/shared/merged-branch-cleanup.d.ts +12 -0
- package/dist/commands/shared/merged-branch-cleanup.d.ts.map +1 -0
- package/dist/commands/shared/merged-branch-cleanup.js +46 -0
- package/dist/commands/shared/post-commit-pr-artifacts.d.ts.map +1 -1
- package/dist/commands/shared/post-commit-pr-artifacts.js +35 -0
- package/dist/commands/shared/task-backend.d.ts.map +1 -1
- package/dist/commands/shared/task-backend.js +37 -5
- package/dist/commands/shared/task-local-freshness.d.ts +2 -0
- package/dist/commands/shared/task-local-freshness.d.ts.map +1 -1
- package/dist/commands/shared/task-local-freshness.js +7 -1
- package/dist/commands/task/finish-shared.d.ts +1 -0
- package/dist/commands/task/finish-shared.d.ts.map +1 -1
- package/dist/commands/task/finish-shared.js +1 -0
- package/dist/commands/task/hosted-close-pr.command.d.ts.map +1 -1
- package/dist/commands/task/hosted-close-pr.command.js +35 -0
- package/dist/commands/task/hosted-close.command.d.ts.map +1 -1
- package/dist/commands/task/hosted-close.command.js +185 -18
- package/dist/commands/task/hosted-merge-sync.d.ts +4 -1
- package/dist/commands/task/hosted-merge-sync.d.ts.map +1 -1
- package/dist/commands/task/hosted-merge-sync.js +52 -10
- package/dist/commands/task/start-ready.d.ts.map +1 -1
- package/dist/commands/task/start-ready.js +0 -86
- package/package.json +2 -2
package/dist/commands/pr/open.js
CHANGED
|
@@ -3,6 +3,8 @@ import { mapBackendError } from "../../cli/error-map.js";
|
|
|
3
3
|
import { exitCodeForError } from "../../cli/exit-codes.js";
|
|
4
4
|
import { createCliEmitter } from "../../cli/output.js";
|
|
5
5
|
import { CliError } from "../../shared/errors.js";
|
|
6
|
+
import { loadCommandContext } from "../shared/task-backend.js";
|
|
7
|
+
import { maybeAutoCommitTaskPrArtifacts } from "./internal/auto-commit.js";
|
|
6
8
|
import { syncPrArtifacts } from "./internal/sync.js";
|
|
7
9
|
function prOpenOutcomeDetails(meta, openOutcome) {
|
|
8
10
|
if (openOutcome)
|
|
@@ -35,6 +37,15 @@ export async function cmdPrOpen(opts) {
|
|
|
35
37
|
branch: opts.branch,
|
|
36
38
|
remoteMode: opts.syncOnly ? "sync-only" : "auto",
|
|
37
39
|
});
|
|
40
|
+
const commandCtx = opts.ctx ??
|
|
41
|
+
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
42
|
+
if (meta.branch) {
|
|
43
|
+
await maybeAutoCommitTaskPrArtifacts({
|
|
44
|
+
ctx: commandCtx,
|
|
45
|
+
taskId: opts.taskId,
|
|
46
|
+
branch: meta.branch,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
38
49
|
output.success("pr open", path.relative(resolved.gitRoot, prDir), prOpenOutcomeDetails(meta, openOutcome ?? null));
|
|
39
50
|
return 0;
|
|
40
51
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/update.ts"],"names":[],"mappings":"AAOA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/pr/update.ts"],"names":[],"mappings":"AAOA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAqEnC,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsClB"}
|
|
@@ -5,6 +5,7 @@ import { createCliEmitter } from "../../cli/output.js";
|
|
|
5
5
|
import { CliError } from "../../shared/errors.js";
|
|
6
6
|
import { gitRevParse } from "../shared/git-ops.js";
|
|
7
7
|
import { loadBackendTask, loadCommandContext, } from "../shared/task-backend.js";
|
|
8
|
+
import { maybeAutoCommitTaskPrArtifacts } from "./internal/auto-commit.js";
|
|
8
9
|
import { assessPrArtifactFreshness } from "./internal/freshness.js";
|
|
9
10
|
import { syncPrArtifacts } from "./internal/sync.js";
|
|
10
11
|
async function readTextIfExists(filePath) {
|
|
@@ -38,6 +39,7 @@ async function warnOnStaleVerifyAfterUpdate(opts) {
|
|
|
38
39
|
const freshness = await assessPrArtifactFreshness({
|
|
39
40
|
gitRoot: opts.resolved.gitRoot,
|
|
40
41
|
workflowDir: path.join(opts.resolved.gitRoot, config.paths.workflow_dir),
|
|
42
|
+
tasksPath: config.paths.tasks_path,
|
|
41
43
|
taskId: opts.taskId,
|
|
42
44
|
branchHeadSha,
|
|
43
45
|
metaHeadSha: opts.meta.head_sha ?? null,
|
|
@@ -54,16 +56,25 @@ async function warnOnStaleVerifyAfterUpdate(opts) {
|
|
|
54
56
|
export async function cmdPrUpdate(opts) {
|
|
55
57
|
try {
|
|
56
58
|
const output = createCliEmitter();
|
|
59
|
+
const commandCtx = opts.ctx ??
|
|
60
|
+
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
57
61
|
const { meta, prDir, resolved } = await syncPrArtifacts({
|
|
58
|
-
ctx:
|
|
62
|
+
ctx: commandCtx,
|
|
59
63
|
cwd: opts.cwd,
|
|
60
64
|
rootOverride: opts.rootOverride,
|
|
61
65
|
taskId: opts.taskId,
|
|
62
66
|
mode: "update",
|
|
63
67
|
});
|
|
68
|
+
if (meta.branch) {
|
|
69
|
+
await maybeAutoCommitTaskPrArtifacts({
|
|
70
|
+
ctx: commandCtx,
|
|
71
|
+
taskId: opts.taskId,
|
|
72
|
+
branch: meta.branch,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
64
75
|
await warnOnStaleVerifyAfterUpdate({
|
|
65
76
|
output,
|
|
66
|
-
ctx:
|
|
77
|
+
ctx: commandCtx,
|
|
67
78
|
cwd: opts.cwd,
|
|
68
79
|
rootOverride: opts.rootOverride,
|
|
69
80
|
taskId: opts.taskId,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { CommandHandler, CommandSpec } from "../../cli/spec/spec.js";
|
|
2
2
|
import type { ReleaseApplyParsed } from "./apply.types.js";
|
|
3
3
|
export declare const releaseApplySpec: CommandSpec<ReleaseApplyParsed>;
|
|
4
|
+
export declare const releaseCandidateSpec: CommandSpec<ReleaseApplyParsed>;
|
|
4
5
|
export declare const runReleaseApply: CommandHandler<ReleaseApplyParsed>;
|
|
5
|
-
export
|
|
6
|
+
export declare const runReleaseCandidate: CommandHandler<ReleaseApplyParsed>;
|
|
7
|
+
export { pushReleaseCandidateBranch, pushReleaseRefs } from "./apply.reporting.js";
|
|
6
8
|
//# sourceMappingURL=apply.command.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.command.d.ts","sourceRoot":"","sources":["../../../src/commands/release/apply.command.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"apply.command.d.ts","sourceRoot":"","sources":["../../../src/commands/release/apply.command.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAoC1E,OAAO,KAAK,EACV,kBAAkB,EAInB,MAAM,kBAAkB,CAAC;AA8c1B,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,kBAAkB,CA0E5D,CAAC;AAgCF,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,kBAAkB,CAuChE,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,kBAAkB,CAwF9D,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,cAAc,CAAC,kBAAkB,CAwFlE,CAAC;AAEF,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { loadConfig, resolveProject } from "@agentplaneorg/core";
|
|
2
|
+
import { extractTaskSuffix, loadConfig, resolveBaseBranch, resolveProject, } from "@agentplaneorg/core";
|
|
3
3
|
import { createCliEmitter } from "../../cli/output.js";
|
|
4
4
|
import { exitCodeForError } from "../../cli/exit-codes.js";
|
|
5
5
|
import { usageError } from "../../cli/spec/errors.js";
|
|
@@ -7,12 +7,14 @@ import { withDiagnosticContext } from "../../shared/diagnostics.js";
|
|
|
7
7
|
import { CliError } from "../../shared/errors.js";
|
|
8
8
|
import { execFileAsync, gitEnv } from "../shared/git.js";
|
|
9
9
|
import { GitContext } from "../shared/git-context.js";
|
|
10
|
+
import { gitCurrentBranch } from "../shared/git-ops.js";
|
|
11
|
+
import { parseTaskIdFromBranch } from "../shared/git-worktree.js";
|
|
10
12
|
import { ensureActionApproved } from "../shared/approval-requirements.js";
|
|
11
13
|
import { ensureNetworkApproved } from "../shared/network-approval.js";
|
|
12
14
|
import { runOperatorPipeline } from "../shared/operator-pipeline.js";
|
|
13
15
|
import { cleanHookEnv, maybePersistExpectedCliVersion, maybeRefreshGeneratedReference, maybeUpdateBunLockfile, replaceAgentplanePackageMetadata, replacePackageVersionInFile, } from "./apply.mutation.js";
|
|
14
16
|
import { ensureCleanTrackedTree, ensureNpmVersionsAvailable, ensureRemoteExists, ensureRemoteTagDoesNotExist, ensureTagDoesNotExist, fileExists, loadReleasePlan, readCoreDependencyVersion, readPackageVersion, runReleasePrepublishGate, validateReleaseNotes, } from "./apply.preflight.js";
|
|
15
|
-
import { pushReleaseRefs, writeReleaseApplyReport } from "./apply.reporting.js";
|
|
17
|
+
import { pushReleaseCandidateBranch, pushReleaseRefs, writeReleaseApplyReport, } from "./apply.reporting.js";
|
|
16
18
|
const output = createCliEmitter();
|
|
17
19
|
async function resolveReleasePlanInputs(opts) {
|
|
18
20
|
const { planDir, plan, minBullets } = await loadReleasePlan({
|
|
@@ -84,18 +86,21 @@ async function ensureReleasePlanMatchesRepoState(opts) {
|
|
|
84
86
|
}
|
|
85
87
|
async function runPushPreflight(opts) {
|
|
86
88
|
const loaded = await loadConfig(opts.agentplaneDir);
|
|
89
|
+
const pushReason = opts.route.kind === "release_candidate"
|
|
90
|
+
? `${opts.commandLabel} will push current branch ${opts.route.current_branch} to ${opts.remote} as a release candidate for ${opts.nextTag}; final publication remains gated on merge to ${opts.route.base_branch}`
|
|
91
|
+
: `${opts.commandLabel} will push HEAD and ${opts.nextTag} to ${opts.remote}`;
|
|
87
92
|
await ensureNetworkApproved({
|
|
88
|
-
action: "release_apply",
|
|
93
|
+
action: opts.route.kind === "release_candidate" ? "release_candidate" : "release_apply",
|
|
89
94
|
config: loaded.config,
|
|
90
95
|
yes: opts.yes,
|
|
91
|
-
reason:
|
|
96
|
+
reason: `${opts.commandLabel} validates npm version availability and pushes over network`,
|
|
92
97
|
interactive: Boolean(process.stdin.isTTY),
|
|
93
98
|
});
|
|
94
99
|
await ensureActionApproved({
|
|
95
100
|
action: "git_push",
|
|
96
101
|
config: loaded.config,
|
|
97
102
|
yes: opts.yes,
|
|
98
|
-
reason:
|
|
103
|
+
reason: pushReason,
|
|
99
104
|
interactive: Boolean(process.stdin.isTTY),
|
|
100
105
|
});
|
|
101
106
|
await ensureRemoteExists(opts.gitRoot, opts.remote);
|
|
@@ -104,6 +109,140 @@ async function runPushPreflight(opts) {
|
|
|
104
109
|
await runReleasePrepublishGate(opts.gitRoot);
|
|
105
110
|
return true;
|
|
106
111
|
}
|
|
112
|
+
async function resolveDirectReleaseRoute(opts) {
|
|
113
|
+
const loaded = await loadConfig(opts.agentplaneDir);
|
|
114
|
+
const workflowMode = loaded.config.workflow_mode;
|
|
115
|
+
const currentBranch = await gitCurrentBranch(opts.gitRoot);
|
|
116
|
+
if (workflowMode !== "branch_pr") {
|
|
117
|
+
return {
|
|
118
|
+
kind: "direct_release",
|
|
119
|
+
workflow_mode: workflowMode,
|
|
120
|
+
current_branch: currentBranch,
|
|
121
|
+
base_branch: null,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const baseBranch = await resolveBaseBranch({
|
|
125
|
+
cwd: opts.cwd,
|
|
126
|
+
rootOverride: opts.rootOverride ?? null,
|
|
127
|
+
mode: workflowMode,
|
|
128
|
+
});
|
|
129
|
+
if (!baseBranch) {
|
|
130
|
+
throw new CliError({
|
|
131
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
132
|
+
code: "E_VALIDATION",
|
|
133
|
+
message: "Release apply in branch_pr mode requires a resolved base branch.\n" +
|
|
134
|
+
"Pin it with `agentplane branch base set <branch>` or configure origin/HEAD before rerunning.",
|
|
135
|
+
context: withDiagnosticContext({ command: "release apply" }, {
|
|
136
|
+
state: "branch_pr release routing could not resolve the protected base branch",
|
|
137
|
+
likelyCause: "the release flow needs to know whether this checkout is the protected base branch or a task branch before deciding if it should create or push a release tag",
|
|
138
|
+
nextAction: {
|
|
139
|
+
command: "agentplane branch base set <branch>",
|
|
140
|
+
reason: "pin the protected base branch so release commands can choose between the direct route and the release-candidate route",
|
|
141
|
+
reasonCode: "release_branch_pr_base_unresolved",
|
|
142
|
+
},
|
|
143
|
+
}),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
if (currentBranch !== baseBranch) {
|
|
147
|
+
throw new CliError({
|
|
148
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
149
|
+
code: "E_VALIDATION",
|
|
150
|
+
message: "release apply is not available on branch_pr task branches.\n" +
|
|
151
|
+
"Use `agentplane release candidate` to prepare and optionally push the release candidate branch.",
|
|
152
|
+
context: withDiagnosticContext({ command: "release apply" }, {
|
|
153
|
+
state: "release apply was invoked from a branch_pr candidate branch",
|
|
154
|
+
likelyCause: "branch_pr repositories must prepare release candidates on dedicated non-base branches and publish only after merge into the protected base branch",
|
|
155
|
+
nextAction: {
|
|
156
|
+
command: "agentplane release candidate",
|
|
157
|
+
reason: "prepare the release candidate on the current branch instead of treating it as a direct publish route",
|
|
158
|
+
reasonCode: "release_apply_branch_pr_candidate_requires_explicit_route",
|
|
159
|
+
},
|
|
160
|
+
}),
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
throw new CliError({
|
|
164
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
165
|
+
code: "E_VALIDATION",
|
|
166
|
+
message: "release apply is not available in branch_pr mode.\n" +
|
|
167
|
+
"Prepare the release candidate on a dedicated branch, merge it into the protected base branch, then let hosted publish run from main.",
|
|
168
|
+
context: withDiagnosticContext({ command: "release apply" }, {
|
|
169
|
+
state: "release apply was invoked from a branch_pr base checkout",
|
|
170
|
+
likelyCause: "branch_pr repositories publish from the merged base branch, so local direct release apply should not act as the publication route",
|
|
171
|
+
nextAction: {
|
|
172
|
+
command: "agentplane release candidate",
|
|
173
|
+
reason: "run the explicit release-candidate route from a dedicated non-base branch/worktree before merging to the protected base branch",
|
|
174
|
+
reasonCode: "release_apply_branch_pr_base_requires_candidate_route",
|
|
175
|
+
},
|
|
176
|
+
}),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
async function resolveReleaseCandidateRoute(opts) {
|
|
180
|
+
const loaded = await loadConfig(opts.agentplaneDir);
|
|
181
|
+
const workflowMode = loaded.config.workflow_mode;
|
|
182
|
+
const currentBranch = await gitCurrentBranch(opts.gitRoot);
|
|
183
|
+
if (workflowMode !== "branch_pr") {
|
|
184
|
+
throw new CliError({
|
|
185
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
186
|
+
code: "E_VALIDATION",
|
|
187
|
+
message: "release candidate is only available when workflow_mode=branch_pr.\n" +
|
|
188
|
+
"Use `agentplane release apply` for direct-mode releases.",
|
|
189
|
+
context: withDiagnosticContext({ command: "release candidate" }, {
|
|
190
|
+
state: "release candidate was invoked outside branch_pr mode",
|
|
191
|
+
likelyCause: "direct-mode repositories have no protected-base candidate route, so release preparation and publication stay on the direct release path",
|
|
192
|
+
nextAction: {
|
|
193
|
+
command: "agentplane release apply",
|
|
194
|
+
reason: "use the direct release route when the repository workflow mode is not branch_pr",
|
|
195
|
+
reasonCode: "release_candidate_requires_branch_pr_mode",
|
|
196
|
+
},
|
|
197
|
+
}),
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
const baseBranch = await resolveBaseBranch({
|
|
201
|
+
cwd: opts.cwd,
|
|
202
|
+
rootOverride: opts.rootOverride ?? null,
|
|
203
|
+
mode: workflowMode,
|
|
204
|
+
});
|
|
205
|
+
if (!baseBranch) {
|
|
206
|
+
throw new CliError({
|
|
207
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
208
|
+
code: "E_VALIDATION",
|
|
209
|
+
message: "Release candidate routing in branch_pr mode requires a resolved base branch.\n" +
|
|
210
|
+
"Pin it with `agentplane branch base set <branch>` or configure origin/HEAD before rerunning.",
|
|
211
|
+
context: withDiagnosticContext({ command: "release candidate" }, {
|
|
212
|
+
state: "branch_pr release-candidate routing could not resolve the protected base branch",
|
|
213
|
+
likelyCause: "the candidate route must know which protected branch will eventually receive and publish the release candidate",
|
|
214
|
+
nextAction: {
|
|
215
|
+
command: "agentplane branch base set <branch>",
|
|
216
|
+
reason: "pin the protected base branch so release candidate routing can target the correct merge branch",
|
|
217
|
+
reasonCode: "release_candidate_base_unresolved",
|
|
218
|
+
},
|
|
219
|
+
}),
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (currentBranch === baseBranch) {
|
|
223
|
+
throw new CliError({
|
|
224
|
+
exitCode: exitCodeForError("E_VALIDATION"),
|
|
225
|
+
code: "E_VALIDATION",
|
|
226
|
+
message: "release candidate must run from a dedicated non-base branch/worktree in branch_pr mode.\n" +
|
|
227
|
+
`Current branch ${currentBranch} is the protected base branch ${baseBranch}.`,
|
|
228
|
+
context: withDiagnosticContext({ command: "release candidate" }, {
|
|
229
|
+
state: "release candidate was invoked from the protected base branch",
|
|
230
|
+
likelyCause: "branch_pr release candidates must be prepared on a dedicated branch so the hosted PR becomes the promotion boundary into the protected base branch",
|
|
231
|
+
nextAction: {
|
|
232
|
+
command: "agentplane work start <task-id> --agent CODER --slug <slug> --worktree",
|
|
233
|
+
reason: "create or switch to a dedicated release-candidate branch/worktree before preparing the candidate",
|
|
234
|
+
reasonCode: "release_candidate_requires_non_base_branch",
|
|
235
|
+
},
|
|
236
|
+
}),
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
kind: "release_candidate",
|
|
241
|
+
workflow_mode: workflowMode,
|
|
242
|
+
current_branch: currentBranch,
|
|
243
|
+
base_branch: baseBranch,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
107
246
|
async function applyReleaseMutation(opts) {
|
|
108
247
|
let releaseCommit = null;
|
|
109
248
|
await Promise.all([
|
|
@@ -133,7 +272,12 @@ async function applyReleaseMutation(opts) {
|
|
|
133
272
|
output.line("No changes to commit.");
|
|
134
273
|
return { releaseCommit };
|
|
135
274
|
}
|
|
136
|
-
const
|
|
275
|
+
const taskId = opts.route.kind === "release_candidate"
|
|
276
|
+
? parseTaskIdFromBranch(opts.taskBranchPrefix, opts.route.current_branch)
|
|
277
|
+
: null;
|
|
278
|
+
const subject = taskId
|
|
279
|
+
? `✨ ${extractTaskSuffix(taskId)} release: publish ${opts.nextTag}`
|
|
280
|
+
: `✨ release: publish ${opts.nextTag}`;
|
|
137
281
|
await opts.git.commit({ message: subject, env: cleanHookEnv() });
|
|
138
282
|
const { stdout: headHash } = await execFileAsync("git", ["rev-parse", "HEAD"], {
|
|
139
283
|
cwd: opts.gitRoot,
|
|
@@ -143,14 +287,32 @@ async function applyReleaseMutation(opts) {
|
|
|
143
287
|
return { releaseCommit };
|
|
144
288
|
}
|
|
145
289
|
async function finalizeReleaseApply(opts) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
290
|
+
const tagCreated = opts.route.kind === "direct_release";
|
|
291
|
+
const pushedRefs = [];
|
|
292
|
+
if (tagCreated) {
|
|
293
|
+
await execFileAsync("git", ["tag", opts.plan.nextTag], {
|
|
294
|
+
cwd: opts.gitRoot,
|
|
295
|
+
env: gitEnv(),
|
|
296
|
+
});
|
|
297
|
+
output.line(`Release tag created: ${opts.plan.nextTag}`);
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
output.line(`Release candidate prepared on ${opts.route.current_branch}; skipped local tag creation for ${opts.plan.nextTag} because final publication is deferred until merge to ${opts.route.base_branch}.`);
|
|
301
|
+
}
|
|
151
302
|
if (opts.push) {
|
|
152
|
-
|
|
153
|
-
|
|
303
|
+
if (opts.route.kind === "release_candidate") {
|
|
304
|
+
await pushReleaseCandidateBranch(opts.gitRoot, opts.remote);
|
|
305
|
+
pushedRefs.push("HEAD");
|
|
306
|
+
output.line(`Pushed: ${opts.remote} ${opts.route.current_branch} (release candidate branch only; no tag pushed)`);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
await pushReleaseRefs(opts.gitRoot, opts.remote, opts.plan.nextTag);
|
|
310
|
+
pushedRefs.push("HEAD", opts.plan.nextTag);
|
|
311
|
+
output.line(`Pushed: ${opts.remote} HEAD + ${opts.plan.nextTag}`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
else if (opts.route.kind === "release_candidate") {
|
|
315
|
+
output.line(`Next: git push <remote> HEAD # merge ${opts.route.current_branch} into ${opts.route.base_branch} before publishing ${opts.plan.nextTag}`);
|
|
154
316
|
}
|
|
155
317
|
else {
|
|
156
318
|
output.line(`Next: git push <remote> HEAD && git push <remote> ${opts.plan.nextTag}`);
|
|
@@ -171,7 +333,18 @@ async function finalizeReleaseApply(opts) {
|
|
|
171
333
|
npm_version_available_checked: opts.npmVersionChecked,
|
|
172
334
|
},
|
|
173
335
|
commit: opts.releaseCommit,
|
|
174
|
-
|
|
336
|
+
route: opts.route,
|
|
337
|
+
tag: {
|
|
338
|
+
name: opts.plan.nextTag,
|
|
339
|
+
created: tagCreated,
|
|
340
|
+
pushed: tagCreated && opts.push,
|
|
341
|
+
},
|
|
342
|
+
push: {
|
|
343
|
+
requested: opts.push,
|
|
344
|
+
remote: opts.remote,
|
|
345
|
+
performed: pushedRefs.length > 0,
|
|
346
|
+
refs: pushedRefs,
|
|
347
|
+
},
|
|
175
348
|
});
|
|
176
349
|
output.line(`Release report: ${path.relative(opts.gitRoot, reportPath)}`);
|
|
177
350
|
return 0;
|
|
@@ -179,8 +352,8 @@ async function finalizeReleaseApply(opts) {
|
|
|
179
352
|
export const releaseApplySpec = {
|
|
180
353
|
id: ["release", "apply"],
|
|
181
354
|
group: "Release",
|
|
182
|
-
summary: "Apply a prepared release: bump versions, validate notes, commit, and tag.",
|
|
183
|
-
description: "Applies a release plan generated by `agentplane release plan
|
|
355
|
+
summary: "Apply a prepared direct-mode release: bump versions, validate notes, commit, and tag.",
|
|
356
|
+
description: "Applies a release plan generated by `agentplane release plan` on the direct release route. This command does not author release notes; it expects a DOCS agent to have written docs/releases/vX.Y.Z.md. In branch_pr repositories, use `agentplane release candidate` on a dedicated non-base branch instead.",
|
|
184
357
|
options: [
|
|
185
358
|
{
|
|
186
359
|
kind: "string",
|
|
@@ -193,7 +366,7 @@ export const releaseApplySpec = {
|
|
|
193
366
|
name: "push",
|
|
194
367
|
default: false,
|
|
195
368
|
description: "Optional direct-push mode: push the release commit and tag immediately " +
|
|
196
|
-
"(requires --yes).
|
|
369
|
+
"(requires --yes). This is for the direct release route only.",
|
|
197
370
|
},
|
|
198
371
|
{
|
|
199
372
|
kind: "string",
|
|
@@ -247,6 +420,70 @@ export const releaseApplySpec = {
|
|
|
247
420
|
},
|
|
248
421
|
],
|
|
249
422
|
};
|
|
423
|
+
const releaseCandidateOptions = [
|
|
424
|
+
{
|
|
425
|
+
kind: "string",
|
|
426
|
+
name: "plan",
|
|
427
|
+
valueHint: "<path>",
|
|
428
|
+
description: "Path to a release plan directory (defaults to the latest under .agentplane/.release/plan/).",
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
kind: "boolean",
|
|
432
|
+
name: "push",
|
|
433
|
+
default: false,
|
|
434
|
+
description: "Optional candidate-push mode: push only the release candidate branch for hosted review and merge (requires --yes). The release tag is not created or pushed here.",
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
kind: "string",
|
|
438
|
+
name: "remote",
|
|
439
|
+
valueHint: "<name>",
|
|
440
|
+
description: "Git remote to push to (default: origin).",
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
kind: "boolean",
|
|
444
|
+
name: "yes",
|
|
445
|
+
default: false,
|
|
446
|
+
description: "Approve minor/major bumps and allow pushing. Patch bumps can be applied without this flag.",
|
|
447
|
+
},
|
|
448
|
+
];
|
|
449
|
+
export const releaseCandidateSpec = {
|
|
450
|
+
id: ["release", "candidate"],
|
|
451
|
+
group: "Release",
|
|
452
|
+
summary: "Prepare a branch_pr release candidate: bump versions, validate notes, commit, and optionally push the candidate branch.",
|
|
453
|
+
description: "Prepares a release candidate from a generated release plan on a dedicated non-base branch in branch_pr mode. This command creates the candidate commit but intentionally does not create or push the release tag; final publication remains gated on merge to the protected base branch and hosted publish from main.",
|
|
454
|
+
options: releaseCandidateOptions,
|
|
455
|
+
parse: releaseApplySpec.parse,
|
|
456
|
+
validate: (p) => {
|
|
457
|
+
if (p.push && p.yes !== true) {
|
|
458
|
+
throw usageError({
|
|
459
|
+
spec: releaseCandidateSpec,
|
|
460
|
+
command: "release candidate",
|
|
461
|
+
message: "Option --push requires explicit approval. Re-run with --yes.",
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
if (!p.remote.trim()) {
|
|
465
|
+
throw usageError({
|
|
466
|
+
spec: releaseCandidateSpec,
|
|
467
|
+
command: "release candidate",
|
|
468
|
+
message: "Option --remote must be non-empty.",
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
},
|
|
472
|
+
examples: [
|
|
473
|
+
{
|
|
474
|
+
cmd: "agentplane release candidate",
|
|
475
|
+
why: "Prepare the latest release plan on the current branch_pr candidate branch.",
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
cmd: "agentplane release candidate --plan .agentplane/.release/plan/<runId>",
|
|
479
|
+
why: "Prepare a specific release plan on the current candidate branch.",
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
cmd: "agentplane release candidate --push --yes",
|
|
483
|
+
why: "Prepare and push only the release candidate branch for hosted review and merge.",
|
|
484
|
+
},
|
|
485
|
+
],
|
|
486
|
+
};
|
|
250
487
|
export const runReleaseApply = async (ctx, flags) => {
|
|
251
488
|
return await runOperatorPipeline({
|
|
252
489
|
init: async () => {
|
|
@@ -259,12 +496,20 @@ export const runReleaseApply = async (ctx, flags) => {
|
|
|
259
496
|
gitRoot,
|
|
260
497
|
planOverride: flags.plan,
|
|
261
498
|
});
|
|
499
|
+
const loaded = await loadConfig(resolved.agentplaneDir);
|
|
262
500
|
return {
|
|
263
501
|
resolved,
|
|
264
502
|
gitRoot,
|
|
265
503
|
planDir,
|
|
266
504
|
plan,
|
|
267
505
|
notesPath,
|
|
506
|
+
taskBranchPrefix: loaded.config.branch.task_prefix,
|
|
507
|
+
route: await resolveDirectReleaseRoute({
|
|
508
|
+
cwd: ctx.cwd,
|
|
509
|
+
rootOverride: ctx.rootOverride ?? null,
|
|
510
|
+
gitRoot,
|
|
511
|
+
agentplaneDir: resolved.agentplaneDir,
|
|
512
|
+
}),
|
|
268
513
|
corePkgPath: path.join(gitRoot, "packages", "core", "package.json"),
|
|
269
514
|
agentplanePkgPath: path.join(gitRoot, "packages", "agentplane", "package.json"),
|
|
270
515
|
npmVersionChecked: false,
|
|
@@ -291,7 +536,95 @@ export const runReleaseApply = async (ctx, flags) => {
|
|
|
291
536
|
remote: flags.remote,
|
|
292
537
|
nextTag: state.plan.nextTag,
|
|
293
538
|
nextVersion: state.plan.nextVersion,
|
|
539
|
+
route: state.route,
|
|
540
|
+
yes: flags.yes,
|
|
541
|
+
commandLabel: "release apply --push",
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
},
|
|
545
|
+
execute: async (state) => {
|
|
546
|
+
const git = new GitContext({ gitRoot: state.gitRoot });
|
|
547
|
+
return await applyReleaseMutation({
|
|
548
|
+
agentplaneDir: state.resolved.agentplaneDir,
|
|
549
|
+
gitRoot: state.gitRoot,
|
|
550
|
+
git,
|
|
551
|
+
notesPath: state.notesPath,
|
|
552
|
+
corePkgPath: state.corePkgPath,
|
|
553
|
+
agentplanePkgPath: state.agentplanePkgPath,
|
|
554
|
+
nextTag: state.plan.nextTag,
|
|
555
|
+
nextVersion: state.plan.nextVersion,
|
|
556
|
+
route: state.route,
|
|
557
|
+
taskBranchPrefix: state.taskBranchPrefix,
|
|
558
|
+
});
|
|
559
|
+
},
|
|
560
|
+
finalize: async (state, mutation) => await finalizeReleaseApply({
|
|
561
|
+
gitRoot: state.gitRoot,
|
|
562
|
+
planDir: state.planDir,
|
|
563
|
+
notesPath: state.notesPath,
|
|
564
|
+
plan: state.plan,
|
|
565
|
+
npmVersionChecked: state.npmVersionChecked,
|
|
566
|
+
releaseCommit: mutation.releaseCommit,
|
|
567
|
+
route: state.route,
|
|
568
|
+
push: flags.push,
|
|
569
|
+
remote: flags.remote,
|
|
570
|
+
}),
|
|
571
|
+
});
|
|
572
|
+
};
|
|
573
|
+
export const runReleaseCandidate = async (ctx, flags) => {
|
|
574
|
+
return await runOperatorPipeline({
|
|
575
|
+
init: async () => {
|
|
576
|
+
const resolved = await resolveProject({
|
|
577
|
+
cwd: ctx.cwd,
|
|
578
|
+
rootOverride: ctx.rootOverride ?? null,
|
|
579
|
+
});
|
|
580
|
+
const gitRoot = resolved.gitRoot;
|
|
581
|
+
const { planDir, plan, notesPath } = await resolveReleasePlanInputs({
|
|
582
|
+
gitRoot,
|
|
583
|
+
planOverride: flags.plan,
|
|
584
|
+
});
|
|
585
|
+
const loaded = await loadConfig(resolved.agentplaneDir);
|
|
586
|
+
return {
|
|
587
|
+
resolved,
|
|
588
|
+
gitRoot,
|
|
589
|
+
planDir,
|
|
590
|
+
plan,
|
|
591
|
+
notesPath,
|
|
592
|
+
taskBranchPrefix: loaded.config.branch.task_prefix,
|
|
593
|
+
route: await resolveReleaseCandidateRoute({
|
|
594
|
+
cwd: ctx.cwd,
|
|
595
|
+
rootOverride: ctx.rootOverride ?? null,
|
|
596
|
+
gitRoot,
|
|
597
|
+
agentplaneDir: resolved.agentplaneDir,
|
|
598
|
+
}),
|
|
599
|
+
corePkgPath: path.join(gitRoot, "packages", "core", "package.json"),
|
|
600
|
+
agentplanePkgPath: path.join(gitRoot, "packages", "agentplane", "package.json"),
|
|
601
|
+
npmVersionChecked: false,
|
|
602
|
+
};
|
|
603
|
+
},
|
|
604
|
+
preflight: async (state) => {
|
|
605
|
+
if ((state.plan.bump === "minor" || state.plan.bump === "major") && flags.yes !== true) {
|
|
606
|
+
throw usageError({
|
|
607
|
+
spec: releaseCandidateSpec,
|
|
608
|
+
command: "release candidate",
|
|
609
|
+
message: `Bump '${state.plan.bump}' requires explicit approval. Re-run with --yes.`,
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
await ensureReleasePlanMatchesRepoState({
|
|
613
|
+
gitRoot: state.gitRoot,
|
|
614
|
+
plan: state.plan,
|
|
615
|
+
corePkgPath: state.corePkgPath,
|
|
616
|
+
agentplanePkgPath: state.agentplanePkgPath,
|
|
617
|
+
});
|
|
618
|
+
if (flags.push) {
|
|
619
|
+
state.npmVersionChecked = await runPushPreflight({
|
|
620
|
+
agentplaneDir: state.resolved.agentplaneDir,
|
|
621
|
+
gitRoot: state.gitRoot,
|
|
622
|
+
remote: flags.remote,
|
|
623
|
+
nextTag: state.plan.nextTag,
|
|
624
|
+
nextVersion: state.plan.nextVersion,
|
|
625
|
+
route: state.route,
|
|
294
626
|
yes: flags.yes,
|
|
627
|
+
commandLabel: "release candidate --push",
|
|
295
628
|
});
|
|
296
629
|
}
|
|
297
630
|
},
|
|
@@ -306,6 +639,8 @@ export const runReleaseApply = async (ctx, flags) => {
|
|
|
306
639
|
agentplanePkgPath: state.agentplanePkgPath,
|
|
307
640
|
nextTag: state.plan.nextTag,
|
|
308
641
|
nextVersion: state.plan.nextVersion,
|
|
642
|
+
route: state.route,
|
|
643
|
+
taskBranchPrefix: state.taskBranchPrefix,
|
|
309
644
|
});
|
|
310
645
|
},
|
|
311
646
|
finalize: async (state, mutation) => await finalizeReleaseApply({
|
|
@@ -315,9 +650,10 @@ export const runReleaseApply = async (ctx, flags) => {
|
|
|
315
650
|
plan: state.plan,
|
|
316
651
|
npmVersionChecked: state.npmVersionChecked,
|
|
317
652
|
releaseCommit: mutation.releaseCommit,
|
|
653
|
+
route: state.route,
|
|
318
654
|
push: flags.push,
|
|
319
655
|
remote: flags.remote,
|
|
320
656
|
}),
|
|
321
657
|
});
|
|
322
658
|
};
|
|
323
|
-
export { pushReleaseRefs } from "./apply.reporting.js";
|
|
659
|
+
export { pushReleaseCandidateBranch, pushReleaseRefs } from "./apply.reporting.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.mutation.d.ts","sourceRoot":"","sources":["../../../src/commands/release/apply.mutation.ts"],"names":[],"mappings":"AASA,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,wBAAsB,gCAAgC,CACpD,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAC1C,OAAO,CAAC,IAAI,CAAC,CAyBf;AAED,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAC1C,OAAO,CAAC,OAAO,CAAC,CAyBlB;AAED,wBAAsB,8BAA8B,CAClD,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED,wBAAgB,YAAY,IAAI,MAAM,CAAC,UAAU,
|
|
1
|
+
{"version":3,"file":"apply.mutation.d.ts","sourceRoot":"","sources":["../../../src/commands/release/apply.mutation.ts"],"names":[],"mappings":"AASA,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,wBAAsB,gCAAgC,CACpD,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAC1C,OAAO,CAAC,IAAI,CAAC,CAyBf;AAED,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAC1C,OAAO,CAAC,OAAO,CAAC,CAyBlB;AAED,wBAAsB,8BAA8B,CAClD,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED,wBAAgB,YAAY,IAAI,MAAM,CAAC,UAAU,CAOhD"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ReleaseApplyReport } from "./apply.types.js";
|
|
2
2
|
export declare function writeReleaseApplyReport(gitRoot: string, report: ReleaseApplyReport): Promise<string>;
|
|
3
3
|
export declare function pushReleaseRefs(gitRoot: string, remote: string, tag: string): Promise<void>;
|
|
4
|
+
export declare function pushReleaseCandidateBranch(gitRoot: string, remote: string): Promise<void>;
|
|
4
5
|
//# sourceMappingURL=apply.reporting.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.reporting.d.ts","sourceRoot":"","sources":["../../../src/commands/release/apply.reporting.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"apply.reporting.d.ts","sourceRoot":"","sources":["../../../src/commands/release/apply.reporting.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAe3D,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjG;AAED,wBAAsB,0BAA0B,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/F"}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { execFileAsync, gitEnv } from "../shared/git.js";
|
|
4
|
+
async function pushRefspecsNoVerify(gitRoot, remote, refspecs) {
|
|
5
|
+
for (const refspec of refspecs) {
|
|
6
|
+
await execFileAsync("git", ["push", "--no-verify", remote, refspec], {
|
|
7
|
+
cwd: gitRoot,
|
|
8
|
+
env: gitEnv(),
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
}
|
|
4
12
|
export async function writeReleaseApplyReport(gitRoot, report) {
|
|
5
13
|
const runId = new Date().toISOString().replaceAll(":", "-").replaceAll(".", "-");
|
|
6
14
|
const dir = path.join(gitRoot, ".agentplane", ".release", "apply");
|
|
@@ -13,12 +21,8 @@ export async function writeReleaseApplyReport(gitRoot, report) {
|
|
|
13
21
|
return reportPath;
|
|
14
22
|
}
|
|
15
23
|
export async function pushReleaseRefs(gitRoot, remote, tag) {
|
|
16
|
-
await
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
await execFileAsync("git", ["push", "--no-verify", remote, tag], {
|
|
21
|
-
cwd: gitRoot,
|
|
22
|
-
env: gitEnv(),
|
|
23
|
-
});
|
|
24
|
+
await pushRefspecsNoVerify(gitRoot, remote, ["HEAD", tag]);
|
|
25
|
+
}
|
|
26
|
+
export async function pushReleaseCandidateBranch(gitRoot, remote) {
|
|
27
|
+
await pushRefspecsNoVerify(gitRoot, remote, ["HEAD"]);
|
|
24
28
|
}
|