@dbx-tools/projen 0.6.229 → 0.7.0
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 +59 -85
- package/index.ts +9 -1
- package/package.json +8 -5
- package/src/openapi.ts +9 -1
- package/src/project-js.ts +68 -10
- package/src/project-py.ts +133 -4
- package/src/project-rs.ts +392 -25
- package/src/release-catalog.ts +832 -0
- package/src/release-dispatch.ts +3 -2
- package/src/release-plan.ts +236 -0
- package/src/release-please.ts +242 -0
- package/src/release.ts +428 -0
- package/tasks/publish-npm.ts +4 -4
- package/tasks/publish-python.ts +56 -14
- package/tasks/publish.ts +60 -30
- package/tasks/release-bootstrap.ts +59 -0
- package/tasks/release-plan.ts +89 -0
- package/tasks/release-please.ts +163 -0
- package/tasks/release-summary-units.ts +44 -0
- package/tasks/release-summary.ts +33 -7
- package/tasks/uniffi-python.d.ts +5 -0
- package/tasks/uniffi-python.js +21 -2
- package/tasks/uniffi-release.mjs +8 -3
- package/tasks/version-check.ts +43 -15
package/tasks/uniffi-python.js
CHANGED
|
@@ -54,16 +54,27 @@ export const pythonProjectInfo = (source, toml) => {
|
|
|
54
54
|
if (typeof project.name !== "string" || !project.name) {
|
|
55
55
|
throw new Error("Missing Python project name");
|
|
56
56
|
}
|
|
57
|
+
if (typeof project.version !== "string" || !project.version) {
|
|
58
|
+
throw new Error("Missing Python project version");
|
|
59
|
+
}
|
|
57
60
|
const config = document?.tool?.["dbx-tools"];
|
|
58
61
|
return {
|
|
59
62
|
name: project.name,
|
|
63
|
+
version: project.version,
|
|
60
64
|
private: Boolean(config && typeof config === "object" && config.private === true),
|
|
65
|
+
uniffi: Boolean(config && typeof config === "object" && config.uniffi === true),
|
|
61
66
|
};
|
|
62
67
|
};
|
|
63
68
|
|
|
69
|
+
const compatibleRequirement = (version) => {
|
|
70
|
+
const [major, minor] = version.split(".").map(Number);
|
|
71
|
+
const upper = major === 0 ? `0.${minor + 1}.0` : `${major + 1}.0.0`;
|
|
72
|
+
return `>=${version},<${upper}`;
|
|
73
|
+
};
|
|
74
|
+
|
|
64
75
|
export const stampPythonProject = (
|
|
65
76
|
source,
|
|
66
|
-
{ packages, rewriteDependencies = true, toml, version },
|
|
77
|
+
{ packages, rewriteDependencies = true, usePackageVersions = false, toml, version },
|
|
67
78
|
) => {
|
|
68
79
|
const marker = source.startsWith("# ") ? source.slice(0, source.indexOf("\n")) : undefined;
|
|
69
80
|
const document = toml.parse(source);
|
|
@@ -83,7 +94,15 @@ export const stampPythonProject = (
|
|
|
83
94
|
throw new Error("Python project dependencies must be strings");
|
|
84
95
|
}
|
|
85
96
|
const sibling = packages.find((candidate) => directSibling(dependency, candidate));
|
|
86
|
-
return sibling
|
|
97
|
+
return sibling
|
|
98
|
+
? `${sibling.name}${
|
|
99
|
+
usePackageVersions
|
|
100
|
+
? sibling.uniffi
|
|
101
|
+
? `==${sibling.version}`
|
|
102
|
+
: compatibleRequirement(sibling.version)
|
|
103
|
+
: `==${version}`
|
|
104
|
+
}`
|
|
105
|
+
: dependency;
|
|
87
106
|
});
|
|
88
107
|
}
|
|
89
108
|
}
|
package/tasks/uniffi-release.mjs
CHANGED
|
@@ -222,9 +222,13 @@ const testNodeFacade = ({
|
|
|
222
222
|
};
|
|
223
223
|
|
|
224
224
|
/** Resolve workspace and generated catalog protocols for a publishable facade. */
|
|
225
|
-
const facadeDependency = (name, dependency,
|
|
225
|
+
const facadeDependency = (name, dependency, catalog, workspaceVersions) => {
|
|
226
226
|
if (typeof dependency !== "string") return dependency;
|
|
227
|
-
if (dependency.startsWith("workspace:"))
|
|
227
|
+
if (dependency.startsWith("workspace:")) {
|
|
228
|
+
const version = workspaceVersions.get(name);
|
|
229
|
+
if (!version) throw new Error(`Missing workspace version for ${name}`);
|
|
230
|
+
return dependency === "workspace:*" ? version : `${dependency.slice("workspace:".length)}${version}`;
|
|
231
|
+
}
|
|
228
232
|
if (!dependency.startsWith("catalog:")) return dependency;
|
|
229
233
|
const resolved = catalog[name];
|
|
230
234
|
if (!resolved) throw new Error(`Missing root catalog entry for ${name}`);
|
|
@@ -344,6 +348,7 @@ const packageNodeFacade = ({ output, nodeDirectory, nodePackage, version, native
|
|
|
344
348
|
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
345
349
|
const workspaceManifest = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
|
|
346
350
|
const catalog = workspaceManifest.catalog ?? {};
|
|
351
|
+
const workspaceVersions = localWorkspacePackages();
|
|
347
352
|
manifest.version = version;
|
|
348
353
|
manifest.private = false;
|
|
349
354
|
manifest.license = manifest.license === "UNLICENSED" ? "Apache-2.0" : manifest.license;
|
|
@@ -353,7 +358,7 @@ const packageNodeFacade = ({ output, nodeDirectory, nodePackage, version, native
|
|
|
353
358
|
manifest.dependencies = Object.fromEntries(
|
|
354
359
|
Object.entries(manifest.dependencies ?? {}).map(([name, dependency]) => [
|
|
355
360
|
name,
|
|
356
|
-
facadeDependency(name, dependency,
|
|
361
|
+
facadeDependency(name, dependency, catalog, workspaceVersions),
|
|
357
362
|
]),
|
|
358
363
|
);
|
|
359
364
|
writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
package/tasks/version-check.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env -S bun
|
|
2
|
-
/** Verify that every committed package version matches
|
|
2
|
+
/** Verify that every committed package version matches its owning release unit. */
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
-
import { join } from "node:path";
|
|
4
|
+
import { dirname, join, relative } from "node:path";
|
|
5
5
|
import { exec, project } from "@dbx-tools/core";
|
|
6
6
|
import { find } from "@dbx-tools/path";
|
|
7
7
|
import { json, log, object } from "@dbx-tools/shared-core";
|
|
8
8
|
import { parse } from "smol-toml";
|
|
9
9
|
import { recordedPackages } from "../src/packages.ts";
|
|
10
|
+
import type { ReleaseUnitGraph } from "../src/release-catalog.ts";
|
|
10
11
|
import { readWorkspaceVersion } from "../src/workspace-version.ts";
|
|
11
12
|
|
|
12
13
|
const logger = log.logger("projen:version-check");
|
|
@@ -23,7 +24,7 @@ function pythonVersion(path: string): string | undefined {
|
|
|
23
24
|
return typeof manifest.project?.version === "string" ? manifest.project.version : undefined;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
function cargoVersions(root: string): Array<{ name: string; version: string }> {
|
|
27
|
+
function cargoVersions(root: string): Array<{ name: string; version: string; path: string }> {
|
|
27
28
|
if (!existsSync(join(root, "Cargo.toml"))) return [];
|
|
28
29
|
const locked = existsSync(join(root, "Cargo.lock"));
|
|
29
30
|
const result = exec.spawnSync(
|
|
@@ -43,43 +44,70 @@ function cargoVersions(root: string): Array<{ name: string; version: string }> {
|
|
|
43
44
|
if (
|
|
44
45
|
!object.isRecord(candidate) ||
|
|
45
46
|
typeof candidate.name !== "string" ||
|
|
46
|
-
typeof candidate.version !== "string"
|
|
47
|
+
typeof candidate.version !== "string" ||
|
|
48
|
+
typeof candidate.manifest_path !== "string"
|
|
47
49
|
) {
|
|
48
50
|
return [];
|
|
49
51
|
}
|
|
50
|
-
return [
|
|
52
|
+
return [
|
|
53
|
+
{
|
|
54
|
+
name: candidate.name,
|
|
55
|
+
version: candidate.version,
|
|
56
|
+
path: relative(root, dirname(candidate.manifest_path)).replaceAll("\\", "/") || ".",
|
|
57
|
+
},
|
|
58
|
+
];
|
|
51
59
|
});
|
|
52
60
|
}
|
|
53
61
|
|
|
54
62
|
function main(): void {
|
|
55
63
|
const root = project.root() ?? process.cwd();
|
|
56
|
-
const
|
|
64
|
+
const fixedVersion = readWorkspaceVersion(root);
|
|
65
|
+
const graphPath = join(root, ".projen/release-units.json");
|
|
66
|
+
const graph = existsSync(graphPath)
|
|
67
|
+
? (JSON.parse(readFileSync(graphPath, "utf8")) as ReleaseUnitGraph)
|
|
68
|
+
: undefined;
|
|
69
|
+
const units = new Map(graph?.units.map((unit) => [unit.id, unit.version]) ?? []);
|
|
70
|
+
const projects = new Map(graph?.projects.map((entry) => [entry.path, entry]) ?? []);
|
|
57
71
|
const mismatches: string[] = [];
|
|
58
|
-
const
|
|
59
|
-
|
|
72
|
+
const expected = (path: string): string | undefined => {
|
|
73
|
+
const releaseProject = projects.get(path);
|
|
74
|
+
if (releaseProject?.unit) return units.get(releaseProject.unit);
|
|
75
|
+
return graph?.mode === "independent" ? undefined : fixedVersion;
|
|
76
|
+
};
|
|
77
|
+
const check = (name: string, path: string, actual: string | undefined): void => {
|
|
78
|
+
const version = expected(path);
|
|
79
|
+
if (version !== undefined && actual !== version) {
|
|
80
|
+
mismatches.push(`${name}: ${actual ?? "missing"} != ${version}`);
|
|
81
|
+
}
|
|
60
82
|
};
|
|
61
83
|
|
|
62
|
-
check("package.json", manifestVersion(join(root, "package.json")));
|
|
84
|
+
check("package.json", ".", manifestVersion(join(root, "package.json")));
|
|
63
85
|
for (const pkg of recordedPackages(root)) {
|
|
64
|
-
check(`${pkg.path}/package.json`, manifestVersion(join(pkg.dir, "package.json")));
|
|
86
|
+
check(`${pkg.path}/package.json`, pkg.path, manifestVersion(join(pkg.dir, "package.json")));
|
|
65
87
|
const barrel = join(pkg.dir, "index.ts");
|
|
66
88
|
if (existsSync(barrel)) {
|
|
67
89
|
const actual = /export const PACKAGE_VERSION = "([^"]+)";/.exec(
|
|
68
90
|
readFileSync(barrel, "utf8"),
|
|
69
91
|
)?.[1];
|
|
70
|
-
check(`${pkg.path}/index.ts`, actual);
|
|
92
|
+
check(`${pkg.path}/index.ts`, pkg.path, actual);
|
|
71
93
|
}
|
|
72
94
|
}
|
|
73
95
|
|
|
74
96
|
for (const path of find.findFiles("**/pyproject.toml", { cwd: root })) {
|
|
75
|
-
check(path, pythonVersion(join(root, path)));
|
|
97
|
+
check(path, dirname(path).replaceAll("\\", "/"), pythonVersion(join(root, path)));
|
|
98
|
+
}
|
|
99
|
+
for (const pkg of cargoVersions(root)) {
|
|
100
|
+
check(`Cargo package ${pkg.name}`, pkg.path, pkg.version);
|
|
76
101
|
}
|
|
77
|
-
for (const pkg of cargoVersions(root)) check(`Cargo package ${pkg.name}`, pkg.version);
|
|
78
102
|
|
|
79
103
|
if (mismatches.length > 0) {
|
|
80
|
-
throw new Error(`
|
|
104
|
+
throw new Error(`Release-unit version mismatch:\n${mismatches.join("\n")}`);
|
|
81
105
|
}
|
|
82
|
-
logger.success(
|
|
106
|
+
logger.success(
|
|
107
|
+
graph
|
|
108
|
+
? `all package versions match ${graph.units.length} release units`
|
|
109
|
+
: `all workspace versions match ${fixedVersion}`,
|
|
110
|
+
);
|
|
83
111
|
}
|
|
84
112
|
|
|
85
113
|
main();
|