@dbx-tools/projen 0.9.146 → 0.9.149
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -12
- package/index.ts +1 -1
- package/package.json +5 -5
- package/src/_task-command.ts +36 -1
- package/tasks/local-publish.ts +24 -5
- package/tasks/release.ts +39 -23
package/README.md
CHANGED
|
@@ -316,14 +316,14 @@ scripts, and generated files on top.
|
|
|
316
316
|
Every workspace root exposes a generic development watcher:
|
|
317
317
|
|
|
318
318
|
```bash
|
|
319
|
-
bun run dev:watch
|
|
319
|
+
bun run dev:watch <command> [args...]
|
|
320
320
|
```
|
|
321
321
|
|
|
322
|
-
It restarts after watched writes have been quiet for 15 seconds. Command paths
|
|
323
|
-
|
|
322
|
+
It restarts after watched writes have been quiet for 15 seconds. Command paths
|
|
323
|
+
and task selectors identify the owning package. Its transitive workspace
|
|
324
324
|
dependencies are watched with the shared generated/dependency/test/temp ignores.
|
|
325
|
-
|
|
326
|
-
run its concrete server entrypoint. The `server` tag does not assume one.
|
|
325
|
+
The configured restart key triggers an immediate restart. The demo uses this
|
|
326
|
+
task to run its concrete server entrypoint. The `server` tag does not assume one.
|
|
327
327
|
|
|
328
328
|
AppKit 0.81's `appkitServerConfig()` is the preferred tsdown preset for a
|
|
329
329
|
consumer app using conventional compiled `server/agents/*/agent.ts` entries. It
|
|
@@ -541,10 +541,11 @@ diverged. From `main`, it calls the existing `bump` task, commits the generated
|
|
|
541
541
|
version changes, pushes `main`, and pushes the matching annotated `vX.Y.Z` tag.
|
|
542
542
|
Pass `--no-bump` only to release an existing synchronized local bump. The tag
|
|
543
543
|
workflow verifies that the tag points at the exact `origin/main` commit. The
|
|
544
|
-
local task
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
544
|
+
local task completes local publication and demo deployment first, then waits for
|
|
545
|
+
this workflow by default. It preserves the live checklist through a scroll-safe
|
|
546
|
+
non-TTY stream and prints the final logs. Local-only releases and repositories
|
|
547
|
+
without a resolved authenticated GitHub account skip the watcher. Stopping the
|
|
548
|
+
local watcher does not cancel the remote run.
|
|
548
549
|
|
|
549
550
|
One `build-release` job installs workspace dependencies, runs validation, packs
|
|
550
551
|
the npm archives, builds all Python distributions, and builds the documentation
|
|
@@ -556,7 +557,9 @@ workspace. Each Python package retains its own publishing environment and waits
|
|
|
556
557
|
for its package dependencies to publish. The npm job uses the bundled archive
|
|
557
558
|
publisher without a checkout or workspace install. Pages deploys the already
|
|
558
559
|
built site after registry publication succeeds. Local npm and Python registry publication remains available
|
|
559
|
-
through the direct local publication tooling.
|
|
560
|
+
through the direct local publication tooling. Those local publishers run
|
|
561
|
+
concurrently; a failure or release termination stops every live publisher before
|
|
562
|
+
the command returns.
|
|
560
563
|
|
|
561
564
|
The default release publishes npm, Python, and docs, then publishes to
|
|
562
565
|
configured local registries. Use `bun run release --help` or the generated
|
|
@@ -658,8 +661,8 @@ release [options]
|
|
|
658
661
|
| `--no-docs` | Disable build and deploy documentation |
|
|
659
662
|
| `--validation` | Run optional release validation tasks before publishing (default: true, env: PROJEN_RELEASE_VALIDATION) |
|
|
660
663
|
| `--no-validation` | Disable run optional release validation tasks before publishing |
|
|
661
|
-
| `-w, --watch-github-actions` | Wait for and
|
|
662
|
-
| `--no-watch-github-actions` | Disable wait for and
|
|
664
|
+
| `-w, --watch-github-actions` | Wait for and log the tag-triggered GitHub Actions release (default: true, env: PROJEN_RELEASE_WATCH_GITHUB_ACTIONS) |
|
|
665
|
+
| `--no-watch-github-actions` | Disable wait for and log the tag-triggered github actions release |
|
|
663
666
|
| `--release-notes` | Generate and commit release notes for a new version bump (default: true, env: PROJEN_RELEASE_RELEASE_NOTES) |
|
|
664
667
|
| `--no-release-notes` | Disable generate and commit release notes for a new version bump |
|
|
665
668
|
| `--release-notes-text <value>` | Write supplied release-note Markdown without invoking Genie (env: PROJEN_RELEASE_RELEASE_NOTES_TEXT) |
|
package/index.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
|
|
5
5
|
export const PACKAGE_IDENTIFIER = "@dbx-tools/projen";
|
|
6
|
-
export const PACKAGE_VERSION = "0.9.
|
|
6
|
+
export const PACKAGE_VERSION = "0.9.149";
|
|
7
7
|
export * as barrels from "./src/barrels.ts";
|
|
8
8
|
export * as bunApp from "./src/bun-app.ts";
|
|
9
9
|
export * as bunWorkflow from "./src/bun-workflow.ts";
|
package/package.json
CHANGED
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@clack/prompts": "^1.7.0",
|
|
33
|
-
"@dbx-tools/cli-args": "^0.9.
|
|
34
|
-
"@dbx-tools/core": "^0.9.
|
|
35
|
-
"@dbx-tools/path": "^0.9.
|
|
36
|
-
"@dbx-tools/shared-core": "^0.9.
|
|
33
|
+
"@dbx-tools/cli-args": "^0.9.149",
|
|
34
|
+
"@dbx-tools/core": "^0.9.149",
|
|
35
|
+
"@dbx-tools/path": "^0.9.149",
|
|
36
|
+
"@dbx-tools/shared-core": "^0.9.149",
|
|
37
37
|
"commander": "^15.0.0",
|
|
38
38
|
"concurrently": "^10.0.3",
|
|
39
39
|
"constructs": "^10.6.0",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
"main": "index.ts",
|
|
57
57
|
"license": "Apache-2.0",
|
|
58
|
-
"version": "0.9.
|
|
58
|
+
"version": "0.9.149",
|
|
59
59
|
"types": "index.ts",
|
|
60
60
|
"type": "module",
|
|
61
61
|
"exports": {
|
package/src/_task-command.ts
CHANGED
|
@@ -40,7 +40,17 @@ export async function runTaskCommandAsync(
|
|
|
40
40
|
args: readonly string[],
|
|
41
41
|
options: TaskCommandOptions & { readonly signal?: AbortSignal } = {},
|
|
42
42
|
): Promise<void> {
|
|
43
|
-
await
|
|
43
|
+
await spawnTaskCommand(cwd, command, args, options);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Start one supervised task command and return its live process handle. */
|
|
47
|
+
export function spawnTaskCommand(
|
|
48
|
+
cwd: string,
|
|
49
|
+
command: string,
|
|
50
|
+
args: readonly string[],
|
|
51
|
+
options: TaskCommandOptions & { readonly signal?: AbortSignal } = {},
|
|
52
|
+
): exec.ChildProcessResult {
|
|
53
|
+
return exec.spawn(executable(command), [...args], {
|
|
44
54
|
cwd,
|
|
45
55
|
env: options.env,
|
|
46
56
|
stdout: "inherit",
|
|
@@ -51,6 +61,31 @@ export async function runTaskCommandAsync(
|
|
|
51
61
|
});
|
|
52
62
|
}
|
|
53
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Run a command with piped stdout forwarded line-by-line.
|
|
66
|
+
*
|
|
67
|
+
* The child sees a non-TTY output stream, so interactive redraw commands fall
|
|
68
|
+
* back to append-only output while the parent still receives live progress.
|
|
69
|
+
*/
|
|
70
|
+
export async function streamTaskCommand(
|
|
71
|
+
cwd: string,
|
|
72
|
+
command: string,
|
|
73
|
+
args: readonly string[],
|
|
74
|
+
options: TaskCommandOptions = {},
|
|
75
|
+
): Promise<void> {
|
|
76
|
+
await exec.spawn(executable(command), [...args], {
|
|
77
|
+
cwd,
|
|
78
|
+
env: options.env,
|
|
79
|
+
stdout: {
|
|
80
|
+
capture: false,
|
|
81
|
+
onLine: (line) => console.log(line),
|
|
82
|
+
},
|
|
83
|
+
stderr: options.stderr ?? "inherit",
|
|
84
|
+
stdin: "ignore",
|
|
85
|
+
check: true,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
54
89
|
/** Capture trimmed stdout, optionally throwing when the command fails. */
|
|
55
90
|
export function captureTaskCommand(
|
|
56
91
|
cwd: string,
|
package/tasks/local-publish.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/** Build and publish the current workspace to configured loopback registries. */
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
import type { ChildProcessResult } from "@dbx-tools/core/exec";
|
|
4
5
|
import * as projectUtils from "@dbx-tools/core/project-utils";
|
|
5
6
|
import { log, net } from "@dbx-tools/shared-core";
|
|
6
7
|
import { activePythonIndexes, resolveLocalPypi } from "./python-registry.ts";
|
|
7
|
-
import {
|
|
8
|
+
import { spawnTaskCommand } from "../src/_task-command.ts";
|
|
8
9
|
|
|
9
10
|
const logger = log.logger("projen:local-publish");
|
|
10
11
|
|
|
@@ -38,6 +39,24 @@ export function localPublishTaskPath(task: "publish.ts" | "publish-python.ts"):
|
|
|
38
39
|
return fileURLToPath(new URL(task, import.meta.url));
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
/** Await concurrent publishers and terminate every live sibling after one fails. */
|
|
43
|
+
export async function awaitLocalPublishers(
|
|
44
|
+
publishes: readonly ChildProcessResult[],
|
|
45
|
+
): Promise<void> {
|
|
46
|
+
try {
|
|
47
|
+
await Promise.all(publishes);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
await Promise.all(
|
|
50
|
+
publishes.map((publish) =>
|
|
51
|
+
publish.exitCode === null && publish.signalCode === null
|
|
52
|
+
? publish.shutdown()
|
|
53
|
+
: Promise.resolve(),
|
|
54
|
+
),
|
|
55
|
+
);
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
41
60
|
/** Build and publish the current workspace directly to local registries. */
|
|
42
61
|
export async function publishLocalRelease(
|
|
43
62
|
options: LocalPublishOptions,
|
|
@@ -46,7 +65,7 @@ export async function publishLocalRelease(
|
|
|
46
65
|
const localRegistry = resolveLocalRegistry(options.localRegistry);
|
|
47
66
|
const activeIndexes = activePythonIndexes();
|
|
48
67
|
const localPypi = resolveLocalPypi(options.localPypi, activeIndexes);
|
|
49
|
-
const publishes:
|
|
68
|
+
const publishes: ChildProcessResult[] = [];
|
|
50
69
|
|
|
51
70
|
if (
|
|
52
71
|
options.localPypi.toLowerCase() === "auto" &&
|
|
@@ -62,7 +81,7 @@ export async function publishLocalRelease(
|
|
|
62
81
|
const publishNpmScript = localPublishTaskPath("publish.ts");
|
|
63
82
|
logger.info(`building and publishing npm workspace to ${localRegistry}`);
|
|
64
83
|
publishes.push(
|
|
65
|
-
|
|
84
|
+
spawnTaskCommand(root, process.execPath, [
|
|
66
85
|
publishNpmScript,
|
|
67
86
|
options.version,
|
|
68
87
|
"--registry",
|
|
@@ -75,7 +94,7 @@ export async function publishLocalRelease(
|
|
|
75
94
|
const publishPythonScript = localPublishTaskPath("publish-python.ts");
|
|
76
95
|
logger.info(`building and publishing Python workspace to ${localPypi.publishUrl}`);
|
|
77
96
|
publishes.push(
|
|
78
|
-
|
|
97
|
+
spawnTaskCommand(root, process.execPath, [
|
|
79
98
|
publishPythonScript,
|
|
80
99
|
options.version,
|
|
81
100
|
"--root",
|
|
@@ -93,7 +112,7 @@ export async function publishLocalRelease(
|
|
|
93
112
|
return { npm: false, python: false };
|
|
94
113
|
}
|
|
95
114
|
|
|
96
|
-
await
|
|
115
|
+
await awaitLocalPublishers(publishes);
|
|
97
116
|
logger.success(`published local workspace ${options.version}`);
|
|
98
117
|
return { npm: Boolean(localRegistry), python: Boolean(localPypi) };
|
|
99
118
|
}
|
package/tasks/release.ts
CHANGED
|
@@ -11,7 +11,12 @@ import { publishLocalRelease } from "./local-publish.ts";
|
|
|
11
11
|
import { TaskDirectoriesOptionSchema, TaskRootOptionSchema } from "./options.ts";
|
|
12
12
|
import { writeReleaseNotes } from "./release-notes.ts";
|
|
13
13
|
import { assertReleaseVersion } from "./release-version.ts";
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
captureTaskCommand,
|
|
16
|
+
runTaskCommand,
|
|
17
|
+
streamTaskCommand,
|
|
18
|
+
taskCommandSucceeds,
|
|
19
|
+
} from "../src/_task-command.ts";
|
|
15
20
|
import { RELEASE_WORKFLOW_FILE } from "../src/release-context.ts";
|
|
16
21
|
import {
|
|
17
22
|
RELEASE_INSTALL_MODES,
|
|
@@ -134,11 +139,19 @@ export async function watchReleaseGithubActions(
|
|
|
134
139
|
url: run.url,
|
|
135
140
|
});
|
|
136
141
|
try {
|
|
137
|
-
|
|
142
|
+
await streamTaskCommand(
|
|
138
143
|
root,
|
|
139
144
|
"gh",
|
|
140
|
-
[
|
|
141
|
-
|
|
145
|
+
[
|
|
146
|
+
"run",
|
|
147
|
+
"watch",
|
|
148
|
+
String(run.databaseId),
|
|
149
|
+
"--repo",
|
|
150
|
+
repository,
|
|
151
|
+
"--interval",
|
|
152
|
+
String(Math.max(1, Math.round(pollIntervalMs / 1_000))),
|
|
153
|
+
],
|
|
154
|
+
{ env: { ...account.env, NO_COLOR: "1" } },
|
|
142
155
|
);
|
|
143
156
|
runTaskCommand(
|
|
144
157
|
root,
|
|
@@ -374,9 +387,10 @@ export async function runRelease(
|
|
|
374
387
|
/** Path to complete release notes supplied instead of invoking Genie. */
|
|
375
388
|
readonly releaseNotesFile?: string;
|
|
376
389
|
readonly writeReleaseNotes?: typeof writeReleaseNotes;
|
|
377
|
-
/**
|
|
390
|
+
/** After local release actions, wait for and stream the matching GitHub Actions run. */
|
|
378
391
|
readonly watchGithubActions?: boolean;
|
|
379
392
|
readonly githubActionsWatcher?: ReleaseGithubActionsWatcher;
|
|
393
|
+
readonly resolveGithubAccount?: typeof projectUtils.resolveProjectGhAccount;
|
|
380
394
|
},
|
|
381
395
|
): Promise<string> {
|
|
382
396
|
const { branch, prefix, remote, root } = options;
|
|
@@ -480,23 +494,6 @@ export async function runRelease(
|
|
|
480
494
|
}
|
|
481
495
|
logger.success(`released ${tag}`, { sha: head });
|
|
482
496
|
|
|
483
|
-
if (shouldWatchReleaseGithubActions(options, selection)) {
|
|
484
|
-
const account = projectUtils.resolveProjectGhAccount(root, { remote });
|
|
485
|
-
if (account) {
|
|
486
|
-
await (options.githubActionsWatcher ?? watchReleaseGithubActions)({
|
|
487
|
-
account,
|
|
488
|
-
head,
|
|
489
|
-
root,
|
|
490
|
-
tag,
|
|
491
|
-
});
|
|
492
|
-
} else {
|
|
493
|
-
logger.info("skipping GitHub Actions release watch: no authenticated account", {
|
|
494
|
-
remote,
|
|
495
|
-
tag,
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
|
|
500
497
|
// Restore local deploys: when a non-standard (loopback) npm or uv registry is
|
|
501
498
|
// configured, publish the freshly tagged version to it directly. Detection and
|
|
502
499
|
// publishing are owned by local-publish.ts; this no-ops on standard registries.
|
|
@@ -518,6 +515,25 @@ export async function runRelease(
|
|
|
518
515
|
]);
|
|
519
516
|
}
|
|
520
517
|
|
|
518
|
+
if (shouldWatchReleaseGithubActions(options, selection)) {
|
|
519
|
+
const account = (options.resolveGithubAccount ?? projectUtils.resolveProjectGhAccount)(root, {
|
|
520
|
+
remote,
|
|
521
|
+
});
|
|
522
|
+
if (account) {
|
|
523
|
+
await (options.githubActionsWatcher ?? watchReleaseGithubActions)({
|
|
524
|
+
account,
|
|
525
|
+
head,
|
|
526
|
+
root,
|
|
527
|
+
tag,
|
|
528
|
+
});
|
|
529
|
+
} else {
|
|
530
|
+
logger.info("skipping GitHub Actions release watch: no authenticated account", {
|
|
531
|
+
remote,
|
|
532
|
+
tag,
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
521
537
|
return tag;
|
|
522
538
|
}
|
|
523
539
|
|
|
@@ -552,7 +568,7 @@ export const ReleaseOptionsSchema = z.object({
|
|
|
552
568
|
watchGithubActions: z
|
|
553
569
|
.boolean()
|
|
554
570
|
.default(true)
|
|
555
|
-
.describe("Wait for and
|
|
571
|
+
.describe("Wait for and log the tag-triggered GitHub Actions release"),
|
|
556
572
|
releaseNotes: z
|
|
557
573
|
.boolean()
|
|
558
574
|
.default(true)
|