@dbx-tools/projen 0.9.154 → 0.9.158
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 +36 -47
- package/index.ts +42 -20
- package/package.json +8 -8
- package/src/_task-command.ts +7 -7
- package/src/appkit-workspace.ts +278 -104
- package/src/barrels.ts +147 -259
- package/src/bun-app.ts +54 -10
- package/src/clean.ts +6 -6
- package/src/engine-root.ts +4 -4
- package/src/mixin.ts +0 -2
- package/src/module-exports.ts +4 -5
- package/src/npm-packaging.ts +128 -0
- package/src/npm-release.ts +200 -0
- package/src/packages.ts +11 -11
- package/src/project-js.ts +209 -103
- package/src/project-predicate.ts +5 -12
- package/src/project-py.ts +6 -6
- package/src/project.ts +7 -14
- package/src/publish.ts +3 -3
- package/src/python-node-bindings.ts +16 -12
- package/src/python-packaging.ts +177 -0
- package/src/release-options.ts +2 -2
- package/src/release.ts +3 -3
- package/src/shared-core-usage.ts +17 -4
- package/src/tags.ts +10 -9
- package/src/watch.ts +7 -9
- package/src/workspace-lock.ts +2 -2
- package/src/workspace-manifest.ts +2 -2
- package/tasks/appkit-deploy.ts +35 -15
- package/tasks/barrels.ts +6 -9
- package/tasks/bump.ts +1 -1
- package/tasks/clean.ts +3 -3
- package/tasks/cli.ts +3 -3
- package/tasks/compile-workspace.ts +8 -8
- package/tasks/dev-watch.ts +11 -11
- package/tasks/local-publish.ts +6 -6
- package/tasks/publish-npm.ts +11 -319
- package/tasks/publish-python.ts +2 -180
- package/tasks/publish.ts +6 -11
- package/tasks/python-node-bindings.ts +2 -2
- package/tasks/python-registry.ts +6 -6
- package/tasks/python-sync.ts +2 -3
- package/tasks/release-version.ts +1 -1
- package/tasks/release.ts +11 -11
- package/tasks/sync.ts +2 -2
- package/tasks/test-workspace.ts +9 -9
- package/tasks/verify-publications.ts +9 -5
- package/tasks/version-check.ts +5 -5
- /package/{tasks → src}/python-release.ts +0 -0
package/tasks/release-version.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env -S bun
|
|
2
2
|
/** Validate one stable release version against the canonical workspace policy. */
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
|
-
import
|
|
4
|
+
import { projectUtils } from "@dbx-tools/core";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { runTaskMain, taskCommand, taskOptions } from "./cli.ts";
|
|
7
7
|
import { TaskRootOptionSchema } from "./options.ts";
|
package/tasks/release.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
/** Run the configured release transaction. */
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
5
|
+
import { projectUtils, type ProjectGhAccount, resolveProjectGhAccount } from "@dbx-tools/core";
|
|
6
|
+
import { log, toError, parse } from "@dbx-tools/shared-core";
|
|
7
7
|
import type { Command } from "commander";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
import { parsedTaskOptions, runTaskMain, taskCommand } from "./cli.ts";
|
|
@@ -67,7 +67,7 @@ const GithubReleaseRunViewSchema = z
|
|
|
67
67
|
|
|
68
68
|
/** Inputs required to locate and watch one tag-triggered release workflow. */
|
|
69
69
|
export interface WatchReleaseGithubActionsOptions {
|
|
70
|
-
readonly account:
|
|
70
|
+
readonly account: ProjectGhAccount;
|
|
71
71
|
readonly head: string;
|
|
72
72
|
readonly root: string;
|
|
73
73
|
readonly tag: string;
|
|
@@ -80,7 +80,7 @@ export type ReleaseGithubActionsWatcher = (
|
|
|
80
80
|
options: WatchReleaseGithubActionsOptions,
|
|
81
81
|
) => Promise<void>;
|
|
82
82
|
|
|
83
|
-
function githubRepository(account:
|
|
83
|
+
function githubRepository(account: ProjectGhAccount): string {
|
|
84
84
|
return account.host === "github.com"
|
|
85
85
|
? account.remote.repository
|
|
86
86
|
: `${account.host}/${account.remote.repository}`;
|
|
@@ -194,7 +194,7 @@ export async function watchReleaseGithubActions(
|
|
|
194
194
|
],
|
|
195
195
|
{ check: true, env: account.env, stderr: "inherit" },
|
|
196
196
|
);
|
|
197
|
-
const parsed = z.array(GithubReleaseRunSchema).safeParse(
|
|
197
|
+
const parsed = z.array(GithubReleaseRunSchema).safeParse(parse(output, []));
|
|
198
198
|
if (!parsed.success) throw new Error("GitHub returned invalid release workflow metadata");
|
|
199
199
|
run = parsed.data.find(
|
|
200
200
|
(candidate) => candidate.headSha === head && candidate.headBranch === tag,
|
|
@@ -234,7 +234,7 @@ export async function watchReleaseGithubActions(
|
|
|
234
234
|
],
|
|
235
235
|
{ check: true, env: account.env, stderr: "inherit" },
|
|
236
236
|
);
|
|
237
|
-
const parsed = GithubReleaseRunViewSchema.safeParse(
|
|
237
|
+
const parsed = GithubReleaseRunViewSchema.safeParse(parse(output));
|
|
238
238
|
if (!parsed.success) throw new Error("GitHub returned invalid release progress metadata");
|
|
239
239
|
reportGithubProgress(parsed.data, progress);
|
|
240
240
|
completed = parsed.data.status === "completed";
|
|
@@ -251,7 +251,7 @@ export async function watchReleaseGithubActions(
|
|
|
251
251
|
}
|
|
252
252
|
} catch (error) {
|
|
253
253
|
logger.warn("GitHub Actions release watch stopped; the remote run was not cancelled", {
|
|
254
|
-
error:
|
|
254
|
+
error: toError(error),
|
|
255
255
|
runId: run.databaseId,
|
|
256
256
|
url: run.url,
|
|
257
257
|
});
|
|
@@ -305,7 +305,7 @@ function pushAnnotatedReleaseTag(options: {
|
|
|
305
305
|
}): void {
|
|
306
306
|
const { annotation, branch, head, remote, root, tag } = options;
|
|
307
307
|
runTaskCommand(root, "git", ["tag", "--annotate", tag, "--message", annotation]);
|
|
308
|
-
const githubAccount =
|
|
308
|
+
const githubAccount = resolveProjectGhAccount(root, { remote });
|
|
309
309
|
if (!githubAccount) {
|
|
310
310
|
logger.warn(
|
|
311
311
|
"no authenticated GitHub account can access the release repository; using git push",
|
|
@@ -382,7 +382,7 @@ function pushAnnotatedReleaseTag(options: {
|
|
|
382
382
|
} catch (error) {
|
|
383
383
|
if (remoteRefCreated) throw error;
|
|
384
384
|
logger.warn("GitHub API tag creation failed; using git push", {
|
|
385
|
-
error:
|
|
385
|
+
error: toError(error),
|
|
386
386
|
repository: githubAccount.remote.repository,
|
|
387
387
|
});
|
|
388
388
|
runTaskCommand(root, "git", ["push", remote, `refs/tags/${tag}`]);
|
|
@@ -480,7 +480,7 @@ export async function runRelease(
|
|
|
480
480
|
/** After local release actions, wait for and stream the matching GitHub Actions run. */
|
|
481
481
|
readonly watchGithubActions?: boolean;
|
|
482
482
|
readonly githubActionsWatcher?: ReleaseGithubActionsWatcher;
|
|
483
|
-
readonly resolveGithubAccount?: typeof
|
|
483
|
+
readonly resolveGithubAccount?: typeof resolveProjectGhAccount;
|
|
484
484
|
},
|
|
485
485
|
): Promise<string> {
|
|
486
486
|
const { branch, prefix, remote, root } = options;
|
|
@@ -606,7 +606,7 @@ export async function runRelease(
|
|
|
606
606
|
}
|
|
607
607
|
|
|
608
608
|
if (shouldWatchReleaseGithubActions(options, selection)) {
|
|
609
|
-
const account = (options.resolveGithubAccount ??
|
|
609
|
+
const account = (options.resolveGithubAccount ?? resolveProjectGhAccount)(root, {
|
|
610
610
|
remote,
|
|
611
611
|
});
|
|
612
612
|
if (account) {
|
package/tasks/sync.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env -S bun
|
|
2
2
|
/** Synthesize once or supervise Projen, barrels, and registered focused watchers. */
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import {
|
|
4
|
+
import { log, toError } from "@dbx-tools/shared-core";
|
|
5
5
|
import concurrently from "concurrently";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { runTaskMain, taskCommand, taskOptions } from "./cli.ts";
|
|
@@ -84,7 +84,7 @@ export async function main(args: string[] = process.argv.slice(2)): Promise<void
|
|
|
84
84
|
} catch (err) {
|
|
85
85
|
// A tree that doesn't synth is precisely when the watcher is most useful: the edit
|
|
86
86
|
// that repairs it is the one the projenrc watcher is sitting there waiting for.
|
|
87
|
-
logger.error("initial sync failed - watching anyway", { error:
|
|
87
|
+
logger.error("initial sync failed - watching anyway", { error: toError(err) });
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
const watchers = [
|
package/tasks/test-workspace.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { basename, join, relative, resolve, sep } from "node:path";
|
|
3
|
-
import
|
|
4
|
-
import { findFilesSync } from "@dbx-tools/path
|
|
5
|
-
import { log,
|
|
3
|
+
import { spawnSync, spawn } from "@dbx-tools/core";
|
|
4
|
+
import { findFilesSync } from "@dbx-tools/path";
|
|
5
|
+
import { log, sequence } from "@dbx-tools/shared-core";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { runTaskMain, taskCommand, taskOptions, taskPositionals, taskRoot } from "./cli.ts";
|
|
8
8
|
import { TaskRootOptionSchema } from "./options.ts";
|
|
@@ -137,7 +137,7 @@ function changedFiles(root: string, base?: string): string[] {
|
|
|
137
137
|
const candidates = base ? [base] : ["origin/main", "main", "HEAD~1"];
|
|
138
138
|
let committed: string[] = [];
|
|
139
139
|
for (const candidate of candidates) {
|
|
140
|
-
const result =
|
|
140
|
+
const result = spawnSync("git", ["diff", "--name-only", `${candidate}...HEAD`], {
|
|
141
141
|
cwd: root,
|
|
142
142
|
stdin: "ignore",
|
|
143
143
|
stdout: "capture",
|
|
@@ -148,14 +148,14 @@ function changedFiles(root: string, base?: string): string[] {
|
|
|
148
148
|
break;
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
|
-
const working =
|
|
151
|
+
const working = spawnSync("git", ["diff", "--name-only", "HEAD"], {
|
|
152
152
|
cwd: root,
|
|
153
153
|
stdin: "ignore",
|
|
154
154
|
stdout: "capture",
|
|
155
155
|
stderr: "ignore",
|
|
156
156
|
check: true,
|
|
157
157
|
}).stdoutLines;
|
|
158
|
-
return [...
|
|
158
|
+
return [...sequence(committed, working).filter(Boolean).distinct()].sort();
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
function selectedTests(
|
|
@@ -203,13 +203,13 @@ function runnerGroup(root: string, path: string): string {
|
|
|
203
203
|
if (relativePath.startsWith("packages/js/shared/")) return "browser-shared";
|
|
204
204
|
if (
|
|
205
205
|
relativePath.startsWith("packages/js/ui/") ||
|
|
206
|
-
relativePath.startsWith("packages/
|
|
206
|
+
relativePath.startsWith("packages/demo/client/")
|
|
207
207
|
) {
|
|
208
208
|
return "react-ui";
|
|
209
209
|
}
|
|
210
210
|
if (relativePath.startsWith("projen/")) return "projen";
|
|
211
211
|
if (relativePath.startsWith("docs/scripts/")) return "docs";
|
|
212
|
-
if (relativePath.startsWith("packages/
|
|
212
|
+
if (relativePath.startsWith("packages/demo/")) return "demo";
|
|
213
213
|
return "node";
|
|
214
214
|
}
|
|
215
215
|
|
|
@@ -228,7 +228,7 @@ async function runTests(root: string, files: readonly string[]): Promise<void> {
|
|
|
228
228
|
const started = performance.now();
|
|
229
229
|
const jobs = [...groups].map(async ([name, paths]) => {
|
|
230
230
|
const groupStarted = performance.now();
|
|
231
|
-
const result = await
|
|
231
|
+
const result = await spawn("bun", ["test", ...paths], {
|
|
232
232
|
cwd: root,
|
|
233
233
|
stdin: "ignore",
|
|
234
234
|
stdout: "inherit",
|
|
@@ -3,10 +3,14 @@
|
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import { readFileSync, readdirSync } from "node:fs";
|
|
5
5
|
import { basename, join, resolve } from "node:path";
|
|
6
|
-
import {
|
|
6
|
+
import { log, poll, mapConcurrent, toError } from "@dbx-tools/shared-core";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { runTaskMain, taskCommand, taskOptions } from "./cli.ts";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
npmReleaseMatches,
|
|
11
|
+
publishedNpmRelease,
|
|
12
|
+
readNpmArchiveIdentity,
|
|
13
|
+
} from "../src/npm-release.ts";
|
|
10
14
|
import { PUBLIC_NPM_REGISTRY_URL, PUBLIC_PYPI_REGISTRY_URL } from "../src/release-context.ts";
|
|
11
15
|
|
|
12
16
|
const DEFAULT_CONCURRENCY = 8;
|
|
@@ -65,9 +69,9 @@ export async function waitForPublications(
|
|
|
65
69
|
let pending = [...probes];
|
|
66
70
|
let previousCount: number | undefined;
|
|
67
71
|
try {
|
|
68
|
-
for await (const unavailable of
|
|
72
|
+
for await (const unavailable of poll<PublicationProbe[]>(
|
|
69
73
|
async ({ signal }) => {
|
|
70
|
-
const results = await
|
|
74
|
+
const results = await mapConcurrent(
|
|
71
75
|
pending,
|
|
72
76
|
async (probe) => {
|
|
73
77
|
try {
|
|
@@ -75,7 +79,7 @@ export async function waitForPublications(
|
|
|
75
79
|
if (available) errors.delete(probe.label);
|
|
76
80
|
return { available, probe };
|
|
77
81
|
} catch (error) {
|
|
78
|
-
errors.set(probe.label,
|
|
82
|
+
errors.set(probe.label, toError(error));
|
|
79
83
|
return { available: false, probe };
|
|
80
84
|
}
|
|
81
85
|
},
|
package/tasks/version-check.ts
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/** Verify that every committed package version matches the root VERSION file. */
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { projectUtils } from "@dbx-tools/core";
|
|
6
|
+
import { findFiles } from "@dbx-tools/path";
|
|
7
|
+
import { log, parseRecord } from "@dbx-tools/shared-core";
|
|
8
8
|
import { parse } from "smol-toml";
|
|
9
9
|
import { runTaskMain } from "./cli.ts";
|
|
10
10
|
import { recordedPackages } from "../src/packages.ts";
|
|
@@ -13,7 +13,7 @@ import { readWorkspaceVersion } from "../src/workspace-version.ts";
|
|
|
13
13
|
const logger = log.logger("projen:version-check");
|
|
14
14
|
|
|
15
15
|
function manifestVersion(path: string): string | undefined {
|
|
16
|
-
const manifest =
|
|
16
|
+
const manifest = parseRecord(readFileSync(path, "utf8"));
|
|
17
17
|
return typeof manifest?.version === "string" ? manifest.version : undefined;
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -37,7 +37,7 @@ export async function main(): Promise<void> {
|
|
|
37
37
|
check(`${pkg.path}/package.json`, manifestVersion(join(pkg.dir, "package.json")));
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
for await (const path of
|
|
40
|
+
for await (const path of findFiles("**/pyproject.toml", { cwd: root })) {
|
|
41
41
|
check(path, pythonVersion(join(root, path)));
|
|
42
42
|
}
|
|
43
43
|
if (mismatches.length > 0) {
|
|
File without changes
|