@dbx-tools/projen 0.9.19 → 0.9.21
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/._LICENSE +0 -0
- package/._README.md +0 -0
- package/._index.ts +0 -0
- package/._package.json +0 -0
- package/README.md +67 -83
- package/index.ts +2 -7
- package/package.json +9 -5
- package/src/.__lazy-require.ts +0 -0
- package/src/.__release-platform.ts +0 -0
- package/src/.__rust-project.ts +0 -0
- package/src/.__rust-release-workflow.ts +0 -0
- package/src/.__task-command.ts +0 -0
- package/src/._barrels.ts +0 -0
- package/src/._bun-app.ts +0 -0
- package/src/._bun-workflow.ts +0 -0
- package/src/._clean.ts +0 -0
- package/src/._codegen.ts +0 -0
- package/src/._dbx-tools-config.ts +0 -0
- package/src/._engine-root.ts +0 -0
- package/src/._generated.ts +0 -0
- package/src/._mixin.ts +0 -0
- package/src/._module-exports.ts +0 -0
- package/src/._openapi.ts +0 -0
- package/src/._packages.ts +0 -0
- package/src/._pnpm-workspace.ts +0 -0
- package/src/._project-js.ts +0 -0
- package/src/._project-predicate.ts +0 -0
- package/src/._project-py.ts +0 -0
- package/src/._project-rs.ts +0 -0
- package/src/._project.ts +0 -0
- package/src/._projen-version.ts +0 -0
- package/src/._publish.ts +0 -0
- package/src/._release-catalog.ts +0 -0
- package/src/._release-dispatch.ts +0 -0
- package/src/._release-github.ts +0 -0
- package/src/._release.ts +0 -0
- package/src/._scaffold.ts +0 -0
- package/src/._tags.ts +0 -0
- package/src/._tsconfig.ts +0 -0
- package/src/._uniffi.ts +0 -0
- package/src/._vscode.ts +0 -0
- package/src/._watch.ts +0 -0
- package/src/._workspace-lock.ts +0 -0
- package/src/._workspace-version.ts +0 -0
- package/src/_rust-release-workflow.ts +4 -391
- package/src/_task-command.ts +75 -0
- package/src/project-js.ts +2 -42
- package/src/project-py.ts +5 -96
- package/src/project-rs.ts +3 -76
- package/src/release-catalog.ts +37 -203
- package/src/release.ts +12 -634
- package/src/scaffold.ts +2 -6
- package/src/workspace-version.ts +9 -121
- package/tasks/._barrels.ts +0 -0
- package/tasks/._bump.ts +0 -0
- package/tasks/._clean.ts +0 -0
- package/tasks/._compile-workspace.ts +0 -0
- package/tasks/._local-publish.ts +0 -0
- package/tasks/._openapi.ts +0 -0
- package/tasks/._projenrc.ts +0 -0
- package/tasks/._publish-npm.ts +0 -0
- package/tasks/._publish-python.ts +0 -0
- package/tasks/._publish-uniffi-local.ts +0 -0
- package/tasks/._publish.ts +0 -0
- package/tasks/._python-registry.ts +0 -0
- package/tasks/._release-assets.ts +0 -0
- package/tasks/._release-candidate.ts +0 -0
- package/tasks/._release-manifest.ts +0 -0
- package/tasks/._release-pr.ts +0 -0
- package/tasks/._release-summary.ts +0 -0
- package/tasks/._release-version.ts +0 -0
- package/tasks/._rust.ts +0 -0
- package/tasks/._sync.ts +0 -0
- package/tasks/._uniffi-python.d.ts +0 -0
- package/tasks/._uniffi-python.js +0 -0
- package/tasks/._uniffi-release.mjs +0 -0
- package/tasks/._uniffi.ts +0 -0
- package/tasks/._version-check.ts +0 -0
- package/tasks/bump.ts +17 -34
- package/tasks/local-publish.ts +124 -117
- package/tasks/publish-npm.ts +62 -30
- package/tasks/publish-python.ts +38 -140
- package/tasks/publish-uniffi-local.ts +129 -84
- package/tasks/publish.ts +25 -139
- package/tasks/python-registry.ts +2 -9
- package/tasks/release-assets.ts +56 -65
- package/tasks/release-candidate.ts +123 -90
- package/tasks/release-pr.ts +266 -240
- package/tasks/release-summary.ts +8 -10
- package/tasks/release-version.ts +23 -2
- package/tasks/rust.ts +8 -13
- package/tasks/uniffi-python.d.ts +2 -3
- package/tasks/uniffi-python.js +7 -20
- package/tasks/uniffi-release.mjs +19 -13
- package/tasks/uniffi.ts +15 -24
- package/tasks/version-check.ts +24 -56
- package/src/release-plan.ts +0 -269
- package/src/release-please.ts +0 -242
- package/tasks/release-bootstrap.ts +0 -59
- package/tasks/release-plan.ts +0 -89
- package/tasks/release-please.ts +0 -162
- package/tasks/release-request.ts +0 -166
- package/tasks/release-summary-units.ts +0 -75
- package/tasks/stamp-python.ts +0 -13
package/tasks/release-pr.ts
CHANGED
|
@@ -10,11 +10,9 @@
|
|
|
10
10
|
import { existsSync } from "node:fs";
|
|
11
11
|
import { join } from "node:path";
|
|
12
12
|
import { fileURLToPath } from "node:url";
|
|
13
|
-
import * as exec from "@dbx-tools/core/exec";
|
|
14
13
|
import * as projectUtils from "@dbx-tools/core/project-utils";
|
|
15
14
|
import { asyncUtils, json, log, object } from "@dbx-tools/shared-core";
|
|
16
15
|
import { Command } from "commander";
|
|
17
|
-
import { publishLocalRelease } from "./local-publish.ts";
|
|
18
16
|
import { hasLocalReleaseTargets, missingLocalReleaseTools } from "./release-assets.ts";
|
|
19
17
|
import { generateReleaseSummary } from "./release-summary.ts";
|
|
20
18
|
import {
|
|
@@ -26,7 +24,10 @@ import {
|
|
|
26
24
|
type VersionLevel,
|
|
27
25
|
} from "../src/_release-platform.ts";
|
|
28
26
|
import {
|
|
27
|
+
captureGitTaskCommand,
|
|
29
28
|
captureTaskCommand,
|
|
29
|
+
gitTaskCommandSucceeds,
|
|
30
|
+
runGitTaskCommand,
|
|
30
31
|
runTaskCommand,
|
|
31
32
|
runTaskCommandAsync,
|
|
32
33
|
taskCommandSucceeds,
|
|
@@ -55,22 +56,8 @@ import {
|
|
|
55
56
|
|
|
56
57
|
const logger = log.logger("projen:release");
|
|
57
58
|
|
|
58
|
-
function git(
|
|
59
|
-
root: string,
|
|
60
|
-
args: string[],
|
|
61
|
-
{ capture = false, check = true }: { capture?: boolean; check?: boolean } = {},
|
|
62
|
-
): string {
|
|
63
|
-
if (capture) return captureTaskCommand(root, "git", args, { check });
|
|
64
|
-
runTaskCommand(root, "git", args);
|
|
65
|
-
return "";
|
|
66
|
-
}
|
|
67
|
-
|
|
68
59
|
function pushCurrentBranch(root: string, branch: string): void {
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function gitSucceeds(root: string, args: string[]): boolean {
|
|
73
|
-
return taskCommandSucceeds(root, "git", args);
|
|
60
|
+
runGitTaskCommand(root, ["push", "--set-upstream", "origin", `HEAD:${branch}`]);
|
|
74
61
|
}
|
|
75
62
|
|
|
76
63
|
/** Wait for required checks and return the merged pull request commit. */
|
|
@@ -149,27 +136,22 @@ function githubAccount(root: string): {
|
|
|
149
136
|
const repository = projectUtils.repositoryUrl(root);
|
|
150
137
|
if (!repository) throw new Error("Release preparation requires a GitHub repository");
|
|
151
138
|
const identity = githubRepositoryIdentity(repository);
|
|
152
|
-
const status =
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const accounts = githubAuthenticatedAccounts(status ?? "", identity.hostname);
|
|
139
|
+
const status = captureTaskCommand(root, "gh", [
|
|
140
|
+
"auth",
|
|
141
|
+
"status",
|
|
142
|
+
"--hostname",
|
|
143
|
+
identity.hostname,
|
|
144
|
+
"--json",
|
|
145
|
+
"hosts",
|
|
146
|
+
]);
|
|
147
|
+
const accounts = githubAuthenticatedAccounts(status, identity.hostname);
|
|
162
148
|
for (const account of accounts) {
|
|
163
149
|
if (!githubAccountSupportsWorkflowChanges(account)) continue;
|
|
164
|
-
const token =
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
stdin: "ignore",
|
|
170
|
-
check: false,
|
|
171
|
-
})
|
|
172
|
-
.stdout?.trim();
|
|
150
|
+
const token = captureTaskCommand(
|
|
151
|
+
root,
|
|
152
|
+
"gh",
|
|
153
|
+
githubTokenArguments(identity.hostname, account.login),
|
|
154
|
+
);
|
|
173
155
|
if (!token) continue;
|
|
174
156
|
const tokenEnvironment = {
|
|
175
157
|
...process.env,
|
|
@@ -177,16 +159,11 @@ function githubAccount(root: string): {
|
|
|
177
159
|
GH_REPO: githubRepositorySpecifier(identity),
|
|
178
160
|
[githubTokenEnvironmentName(identity.hostname)]: token,
|
|
179
161
|
};
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
stdin: "ignore",
|
|
186
|
-
check: false,
|
|
187
|
-
});
|
|
188
|
-
const repositoryData =
|
|
189
|
-
repositoryResult.exitCode === 0 ? json.parseRecord(repositoryResult.stdout ?? "") : undefined;
|
|
162
|
+
const repositoryData = json.parseRecord(
|
|
163
|
+
captureTaskCommand(root, "gh", ["api", githubRepositoryApiPath(identity)], {
|
|
164
|
+
env: tokenEnvironment,
|
|
165
|
+
}),
|
|
166
|
+
);
|
|
190
167
|
const permissions = githubRepositoryPermissions(repositoryData);
|
|
191
168
|
if (!permissions.push && !permissions.maintain && !permissions.admin) {
|
|
192
169
|
continue;
|
|
@@ -238,12 +215,12 @@ program
|
|
|
238
215
|
.addOption(releaseLevelOption())
|
|
239
216
|
.option("--prefix <prefix>", "release tag prefix", "v")
|
|
240
217
|
.option("--base <branch>", "release pull request base branch", "main")
|
|
218
|
+
.option("--python-root <path>", "Python package root", "packages/py")
|
|
241
219
|
.option("--message <message>", "commit message for pending source work", "chore: prepare release")
|
|
242
220
|
.addOption(releaseOperatingSystemOption())
|
|
243
221
|
.addOption(releaseArchitectureOption())
|
|
244
222
|
.option("--local-registry <value>", "local npm registry: auto, false, or an explicit URL", "auto")
|
|
245
223
|
.option("--local-pypi <value>", "local PyPI index: auto, false, or an explicit URL", "auto")
|
|
246
|
-
.option("--python-root <path>", "Python workspace package root")
|
|
247
224
|
.option(
|
|
248
225
|
"--validate-task <task>",
|
|
249
226
|
"repository task to run before release validation; repeatable",
|
|
@@ -270,12 +247,12 @@ program
|
|
|
270
247
|
level: VersionLevel;
|
|
271
248
|
prefix: string;
|
|
272
249
|
base: string;
|
|
250
|
+
pythonRoot: string;
|
|
273
251
|
message: string;
|
|
274
252
|
os: ReleaseOs[];
|
|
275
253
|
arch: ReleaseArch[];
|
|
276
254
|
localRegistry: string;
|
|
277
255
|
localPypi: string;
|
|
278
|
-
pythonRoot?: string;
|
|
279
256
|
validateTask: string[];
|
|
280
257
|
releaseSummary: boolean;
|
|
281
258
|
releaseSummaryProviders?: string;
|
|
@@ -303,7 +280,9 @@ program
|
|
|
303
280
|
if (opts.approve && !opts.wait) {
|
|
304
281
|
throw new Error("automatic merge requires waiting so the draft candidate can be built");
|
|
305
282
|
}
|
|
306
|
-
const currentBranch =
|
|
283
|
+
const currentBranch = captureGitTaskCommand(root, ["branch", "--show-current"], {
|
|
284
|
+
check: true,
|
|
285
|
+
});
|
|
307
286
|
if (!currentBranch) throw new Error("Release preparation requires a local branch");
|
|
308
287
|
const account = githubAccount(root);
|
|
309
288
|
if (!account.canManage) {
|
|
@@ -315,12 +294,9 @@ program
|
|
|
315
294
|
throw new Error(`Local release candidate build requires: ${localTools.join(", ")}`);
|
|
316
295
|
}
|
|
317
296
|
}
|
|
318
|
-
|
|
319
|
-
const comparisonBase = resolveBaseVersion(root
|
|
320
|
-
|
|
321
|
-
includeComponentTags: false,
|
|
322
|
-
}).version;
|
|
323
|
-
const next = resolveNextVersion(root, [opts.prefix], opts.level, { fetch: false });
|
|
297
|
+
runGitTaskCommand(root, ["fetch", "--tags", "origin", opts.base]);
|
|
298
|
+
const comparisonBase = resolveBaseVersion(root);
|
|
299
|
+
const next = resolveNextVersion(root, opts.level);
|
|
324
300
|
const releaseVersionScript = fileURLToPath(
|
|
325
301
|
new URL("./release-version.ts", import.meta.url),
|
|
326
302
|
);
|
|
@@ -334,228 +310,278 @@ program
|
|
|
334
310
|
]);
|
|
335
311
|
const releaseTag = `${opts.prefix}${next.version}`;
|
|
336
312
|
const releaseBranch = `release/${releaseTag}`;
|
|
337
|
-
const releaseRoot = join(root, ".worktrees", releaseTag);
|
|
338
313
|
if (currentBranch.startsWith("release/")) {
|
|
339
314
|
throw new Error("Release preparation must start from a source branch");
|
|
340
315
|
}
|
|
341
316
|
if (
|
|
342
|
-
|
|
343
|
-
capture: true,
|
|
344
|
-
check: false,
|
|
345
|
-
})
|
|
317
|
+
captureGitTaskCommand(root, ["ls-remote", "--tags", "origin", `refs/tags/${releaseTag}`])
|
|
346
318
|
) {
|
|
347
319
|
throw new Error(`Release tag already exists: ${releaseTag}`);
|
|
348
320
|
}
|
|
349
321
|
|
|
350
|
-
const status =
|
|
351
|
-
|
|
352
|
-
|
|
322
|
+
const status = captureGitTaskCommand(
|
|
323
|
+
root,
|
|
324
|
+
["status", "--porcelain=v1", "--untracked-files=all"],
|
|
325
|
+
{ check: true },
|
|
326
|
+
);
|
|
353
327
|
if (status) {
|
|
354
|
-
|
|
355
|
-
|
|
328
|
+
runGitTaskCommand(root, ["add", "-A"]);
|
|
329
|
+
runGitTaskCommand(root, ["commit", "-m", opts.message]);
|
|
356
330
|
}
|
|
357
|
-
if (
|
|
358
|
-
|
|
331
|
+
if (
|
|
332
|
+
!gitTaskCommandSucceeds(root, [
|
|
333
|
+
"merge-base",
|
|
334
|
+
"--is-ancestor",
|
|
335
|
+
`origin/${opts.base}`,
|
|
336
|
+
"HEAD",
|
|
337
|
+
])
|
|
338
|
+
) {
|
|
339
|
+
runGitTaskCommand(root, ["merge", "--no-edit", `origin/${opts.base}`]);
|
|
359
340
|
}
|
|
360
341
|
pushCurrentBranch(root, currentBranch);
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
{
|
|
370
|
-
)
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
"stash",
|
|
384
|
-
"push",
|
|
385
|
-
"--include-untracked",
|
|
386
|
-
"--message",
|
|
387
|
-
"release-resume",
|
|
342
|
+
const localBranch = Boolean(
|
|
343
|
+
captureGitTaskCommand(root, ["branch", "--list", releaseBranch]),
|
|
344
|
+
);
|
|
345
|
+
const remoteBranch = Boolean(
|
|
346
|
+
captureGitTaskCommand(root, [
|
|
347
|
+
"ls-remote",
|
|
348
|
+
"--heads",
|
|
349
|
+
"origin",
|
|
350
|
+
`refs/heads/${releaseBranch}`,
|
|
351
|
+
]),
|
|
352
|
+
);
|
|
353
|
+
let releaseCompleted = false;
|
|
354
|
+
try {
|
|
355
|
+
if (localBranch) {
|
|
356
|
+
runGitTaskCommand(root, ["switch", releaseBranch]);
|
|
357
|
+
} else if (remoteBranch) {
|
|
358
|
+
runGitTaskCommand(root, [
|
|
359
|
+
"switch",
|
|
360
|
+
"--track",
|
|
361
|
+
"-c",
|
|
362
|
+
releaseBranch,
|
|
363
|
+
`origin/${releaseBranch}`,
|
|
388
364
|
]);
|
|
365
|
+
} else {
|
|
366
|
+
runGitTaskCommand(root, ["switch", "-c", releaseBranch]);
|
|
389
367
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
368
|
+
const resumableStash = captureGitTaskCommand(root, [
|
|
369
|
+
"stash",
|
|
370
|
+
"list",
|
|
371
|
+
"--format=%gd%x09%s",
|
|
372
|
+
])
|
|
373
|
+
.split("\n")
|
|
374
|
+
.find((line) => line.includes(`release-resume:${releaseBranch}`))
|
|
375
|
+
?.split("\t")[0];
|
|
376
|
+
if (resumableStash) runGitTaskCommand(root, ["stash", "pop", resumableStash]);
|
|
377
|
+
if (
|
|
378
|
+
!gitTaskCommandSucceeds(root, ["merge-base", "--is-ancestor", currentBranch, "HEAD"])
|
|
379
|
+
) {
|
|
380
|
+
runGitTaskCommand(root, ["merge", "--no-edit", currentBranch]);
|
|
395
381
|
}
|
|
396
|
-
|
|
397
|
-
}
|
|
398
|
-
runTaskCommand(releaseRoot, process.execPath, ["install"]);
|
|
382
|
+
runTaskCommand(root, process.execPath, ["install"]);
|
|
399
383
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
runTaskCommand(releaseRoot, process.execPath, [versionCheckScript]);
|
|
416
|
-
if (opts.validate) {
|
|
417
|
-
for (const task of opts.validateTask) {
|
|
418
|
-
runTaskCommand(releaseRoot, process.execPath, ["run", task]);
|
|
419
|
-
}
|
|
420
|
-
if (existsSync(join(releaseRoot, "Cargo.toml"))) {
|
|
421
|
-
runTaskCommand(releaseRoot, "cargo", [
|
|
422
|
-
"test",
|
|
423
|
-
"--workspace",
|
|
424
|
-
...(existsSync(join(releaseRoot, "Cargo.lock")) ? ["--locked"] : []),
|
|
384
|
+
const bumpScript = fileURLToPath(new URL("./bump.ts", import.meta.url));
|
|
385
|
+
const versionCheckScript = fileURLToPath(new URL("./version-check.ts", import.meta.url));
|
|
386
|
+
const preparedVersion = readWorkspaceVersion(root);
|
|
387
|
+
if (preparedVersion !== next.version) {
|
|
388
|
+
if (preparedVersion !== comparisonBase) {
|
|
389
|
+
throw new Error(
|
|
390
|
+
`${releaseBranch} carries ${preparedVersion}; expected ${comparisonBase} or ${next.version}`,
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
runTaskCommand(root, process.execPath, [
|
|
394
|
+
bumpScript,
|
|
395
|
+
"--level",
|
|
396
|
+
opts.level,
|
|
397
|
+
...opts.os.flatMap((value) => ["--os", value]),
|
|
398
|
+
...opts.arch.flatMap((value) => ["--arch", value]),
|
|
425
399
|
]);
|
|
400
|
+
} else {
|
|
401
|
+
logger.info(`resuming prepared ${releaseTag}`);
|
|
402
|
+
}
|
|
403
|
+
if (readWorkspaceVersion(root) !== next.version) {
|
|
404
|
+
throw new Error(`Release preparation did not produce ${next.version}`);
|
|
426
405
|
}
|
|
427
|
-
runTaskCommand(releaseRoot, process.execPath, ["run", "compile"]);
|
|
428
|
-
} else {
|
|
429
|
-
logger.warn("release validation skipped by --no-validate");
|
|
430
|
-
}
|
|
431
|
-
if (opts.localPublish) {
|
|
432
|
-
await publishLocalRelease({
|
|
433
|
-
root: releaseRoot,
|
|
434
|
-
version: next.version,
|
|
435
|
-
localRegistry: opts.localRegistry,
|
|
436
|
-
localPypi: opts.localPypi,
|
|
437
|
-
pythonRoot: opts.pythonRoot,
|
|
438
|
-
localCargo: opts.localCargo,
|
|
439
|
-
reuseValidatedNodeCompile: opts.validate,
|
|
440
|
-
});
|
|
441
|
-
} else {
|
|
442
|
-
logger.info("local publication skipped by --no-local-publish");
|
|
443
|
-
}
|
|
444
|
-
runTaskCommand(releaseRoot, process.execPath, [versionCheckScript]);
|
|
445
|
-
const releaseSummary = opts.releaseSummary
|
|
446
|
-
? await generateReleaseSummary({
|
|
447
|
-
root: releaseRoot,
|
|
448
|
-
version: next.version,
|
|
449
|
-
fromRef: `${opts.prefix}${comparisonBase}`,
|
|
450
|
-
providers: releaseSummaryProviders(opts.releaseSummaryProviders),
|
|
451
|
-
})
|
|
452
|
-
: undefined;
|
|
453
406
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
407
|
+
runTaskCommand(root, process.execPath, [versionCheckScript]);
|
|
408
|
+
if (opts.validate) {
|
|
409
|
+
for (const task of opts.validateTask) {
|
|
410
|
+
runTaskCommand(root, process.execPath, ["run", task]);
|
|
411
|
+
}
|
|
412
|
+
if (existsSync(join(root, "Cargo.toml"))) {
|
|
413
|
+
runTaskCommand(root, "cargo", [
|
|
414
|
+
"test",
|
|
415
|
+
"--workspace",
|
|
416
|
+
...(existsSync(join(root, "Cargo.lock")) ? ["--locked"] : []),
|
|
417
|
+
]);
|
|
418
|
+
}
|
|
419
|
+
runTaskCommand(root, process.execPath, ["run", "compile"]);
|
|
420
|
+
} else {
|
|
421
|
+
logger.warn("release validation skipped by --no-validate");
|
|
422
|
+
}
|
|
423
|
+
runTaskCommand(root, process.execPath, [versionCheckScript]);
|
|
424
|
+
const releaseSummary = opts.releaseSummary
|
|
425
|
+
? await generateReleaseSummary({
|
|
426
|
+
root,
|
|
427
|
+
version: next.version,
|
|
428
|
+
fromRef: `${opts.prefix}${comparisonBase}`,
|
|
429
|
+
providers: releaseSummaryProviders(opts.releaseSummaryProviders),
|
|
430
|
+
})
|
|
431
|
+
: undefined;
|
|
432
|
+
|
|
433
|
+
runGitTaskCommand(root, ["add", "-A"]);
|
|
434
|
+
const staged = captureGitTaskCommand(root, ["diff", "--cached", "--name-only"], {
|
|
435
|
+
check: true,
|
|
436
|
+
});
|
|
437
|
+
if (staged) {
|
|
438
|
+
runGitTaskCommand(root, ["commit", "-m", `chore(release): ${next.version}`]);
|
|
439
|
+
} else if (!localBranch && !remoteBranch) {
|
|
440
|
+
throw new Error("Release preparation produced no changes");
|
|
441
|
+
}
|
|
442
|
+
runGitTaskCommand(root, ["push", "--set-upstream", "origin", releaseBranch]);
|
|
465
443
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
const ensurePullRequest = (): void => {
|
|
444
|
+
const title = `chore(release): ${next.version}`;
|
|
445
|
+
const body = [
|
|
446
|
+
`Release ${releaseTag}.`,
|
|
447
|
+
"",
|
|
448
|
+
`Source commit: ${captureGitTaskCommand(root, ["rev-parse", `${releaseBranch}^`], { check: true })}`,
|
|
449
|
+
"",
|
|
450
|
+
"Merging this PR updates VERSION on main and prepares a draft GitHub Release.",
|
|
451
|
+
...(releaseSummary ? ["", releaseSummary] : []),
|
|
452
|
+
].join("\n");
|
|
453
|
+
const githubEnvironment = {
|
|
454
|
+
...process.env,
|
|
455
|
+
GH_HOST: account.hostname,
|
|
456
|
+
GH_REPO: githubRepositorySpecifier(account),
|
|
457
|
+
[githubTokenEnvironmentName(account.hostname)]: account.token,
|
|
458
|
+
};
|
|
482
459
|
if (
|
|
483
|
-
taskCommandSucceeds(root, "gh", ["pr", "view", releaseBranch], {
|
|
460
|
+
!taskCommandSucceeds(root, "gh", ["pr", "view", releaseBranch], {
|
|
484
461
|
env: githubEnvironment,
|
|
485
462
|
})
|
|
486
463
|
) {
|
|
487
|
-
|
|
464
|
+
runTaskCommand(
|
|
465
|
+
root,
|
|
466
|
+
"gh",
|
|
467
|
+
[
|
|
468
|
+
"pr",
|
|
469
|
+
"create",
|
|
470
|
+
"--base",
|
|
471
|
+
opts.base,
|
|
472
|
+
"--head",
|
|
473
|
+
releaseBranch,
|
|
474
|
+
"--title",
|
|
475
|
+
title,
|
|
476
|
+
"--body",
|
|
477
|
+
body,
|
|
478
|
+
],
|
|
479
|
+
{ env: githubEnvironment },
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
if (opts.approve) {
|
|
483
|
+
runTaskCommand(root, "gh", ["pr", "merge", releaseBranch, "--auto", "--merge"], {
|
|
484
|
+
env: githubEnvironment,
|
|
485
|
+
});
|
|
488
486
|
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
[
|
|
493
|
-
"pr",
|
|
494
|
-
"create",
|
|
495
|
-
"--base",
|
|
496
|
-
opts.base,
|
|
497
|
-
"--head",
|
|
487
|
+
if (opts.approve && opts.wait) {
|
|
488
|
+
const mergeSha = await waitForPullRequestMerge(
|
|
489
|
+
root,
|
|
498
490
|
releaseBranch,
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
]
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
});
|
|
512
|
-
}
|
|
513
|
-
if (opts.approve && opts.wait) {
|
|
514
|
-
const mergeSha = await waitForPullRequestMerge(
|
|
515
|
-
root,
|
|
516
|
-
releaseBranch,
|
|
517
|
-
githubEnvironment,
|
|
518
|
-
waitTimeoutMs,
|
|
519
|
-
);
|
|
520
|
-
logger.info("release pull request merged", { releaseBranch, mergeSha });
|
|
521
|
-
git(root, ["fetch", "origin", opts.base]);
|
|
522
|
-
git(releaseRoot, ["switch", "--detach", mergeSha]);
|
|
523
|
-
runTaskCommand(releaseRoot, process.execPath, ["install"]);
|
|
524
|
-
const releaseCandidateScript = join(
|
|
525
|
-
releaseRoot,
|
|
526
|
-
"node_modules/@dbx-tools/projen/tasks/release-candidate.ts",
|
|
527
|
-
);
|
|
528
|
-
runTaskCommand(
|
|
529
|
-
releaseRoot,
|
|
530
|
-
process.execPath,
|
|
531
|
-
[
|
|
491
|
+
githubEnvironment,
|
|
492
|
+
waitTimeoutMs,
|
|
493
|
+
);
|
|
494
|
+
logger.info("release pull request merged", { releaseBranch, mergeSha });
|
|
495
|
+
runGitTaskCommand(root, ["fetch", "origin", opts.base]);
|
|
496
|
+
runGitTaskCommand(root, ["switch", "--detach", mergeSha]);
|
|
497
|
+
runTaskCommand(root, process.execPath, ["install"]);
|
|
498
|
+
const releaseCandidateScript = join(
|
|
499
|
+
root,
|
|
500
|
+
"node_modules/@dbx-tools/projen/tasks/release-candidate.ts",
|
|
501
|
+
);
|
|
502
|
+
const candidateArguments = [
|
|
532
503
|
releaseCandidateScript,
|
|
533
504
|
"--root",
|
|
534
|
-
|
|
505
|
+
root,
|
|
535
506
|
"--version",
|
|
536
507
|
next.version,
|
|
537
508
|
"--tag",
|
|
538
509
|
releaseTag,
|
|
539
510
|
"--sha",
|
|
540
511
|
mergeSha,
|
|
512
|
+
"--python-root",
|
|
513
|
+
opts.pythonRoot,
|
|
541
514
|
"--notes-file",
|
|
542
515
|
`docs/releases/v${next.version}.md`,
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
516
|
+
];
|
|
517
|
+
runTaskCommand(root, process.execPath, candidateArguments, {
|
|
518
|
+
env: githubEnvironment,
|
|
519
|
+
});
|
|
520
|
+
if (opts.localPublish) {
|
|
521
|
+
const localPublishScript = join(
|
|
522
|
+
root,
|
|
523
|
+
"node_modules/@dbx-tools/projen/tasks/local-publish.ts",
|
|
524
|
+
);
|
|
525
|
+
runTaskCommand(
|
|
526
|
+
root,
|
|
527
|
+
process.execPath,
|
|
528
|
+
[
|
|
529
|
+
localPublishScript,
|
|
530
|
+
"--root",
|
|
531
|
+
root,
|
|
532
|
+
"--candidate-directory",
|
|
533
|
+
"dist/release/upload",
|
|
534
|
+
"--version",
|
|
535
|
+
next.version,
|
|
536
|
+
"--tag",
|
|
537
|
+
releaseTag,
|
|
538
|
+
"--sha",
|
|
539
|
+
mergeSha,
|
|
540
|
+
"--local-registry",
|
|
541
|
+
opts.localRegistry,
|
|
542
|
+
"--local-pypi",
|
|
543
|
+
opts.localPypi,
|
|
544
|
+
...(opts.localCargo ? ["--local-cargo"] : []),
|
|
545
|
+
],
|
|
546
|
+
{ env: githubEnvironment },
|
|
547
|
+
);
|
|
548
|
+
} else {
|
|
549
|
+
logger.info("local publication skipped by --no-local-publish");
|
|
550
|
+
}
|
|
551
|
+
runTaskCommand(root, process.execPath, [...candidateArguments, "--upload-existing"], {
|
|
552
|
+
env: githubEnvironment,
|
|
553
|
+
});
|
|
554
|
+
logger.success(`prepared draft ${releaseTag} from ${mergeSha}`);
|
|
555
|
+
} else {
|
|
556
|
+
logger.success(`opened ${releaseBranch} for ${releaseTag}`);
|
|
557
|
+
}
|
|
558
|
+
releaseCompleted = true;
|
|
559
|
+
} finally {
|
|
560
|
+
const activeBranch = captureGitTaskCommand(root, ["branch", "--show-current"]);
|
|
561
|
+
if (activeBranch !== currentBranch) {
|
|
562
|
+
const releaseStatus = captureGitTaskCommand(
|
|
563
|
+
root,
|
|
564
|
+
["status", "--porcelain=v1", "--untracked-files=all"],
|
|
565
|
+
{ check: true },
|
|
566
|
+
);
|
|
567
|
+
if (releaseStatus) {
|
|
568
|
+
runGitTaskCommand(root, [
|
|
569
|
+
"stash",
|
|
570
|
+
"push",
|
|
571
|
+
"--include-untracked",
|
|
572
|
+
"--message",
|
|
573
|
+
`release-resume:${releaseBranch}`,
|
|
574
|
+
]);
|
|
575
|
+
}
|
|
576
|
+
runGitTaskCommand(root, ["switch", currentBranch]);
|
|
577
|
+
}
|
|
578
|
+
if (
|
|
579
|
+
releaseCompleted &&
|
|
580
|
+
captureGitTaskCommand(root, ["branch", "--list", releaseBranch])
|
|
581
|
+
) {
|
|
582
|
+
runGitTaskCommand(root, ["branch", "--delete", "--force", releaseBranch]);
|
|
583
|
+
}
|
|
551
584
|
}
|
|
552
|
-
git(root, ["worktree", "remove", "--force", releaseRoot]);
|
|
553
|
-
git(root, ["branch", "--delete", "--force", releaseBranch]);
|
|
554
|
-
logger.success(
|
|
555
|
-
`${
|
|
556
|
-
opts.approve ? "enabled automatic merge for" : "opened"
|
|
557
|
-
} ${releaseBranch} for ${releaseTag}${opts.approve && !opts.wait ? " without waiting" : ""}`,
|
|
558
|
-
);
|
|
559
585
|
});
|
|
560
586
|
},
|
|
561
587
|
);
|