@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/src/project-py.ts
CHANGED
|
@@ -14,8 +14,6 @@ import {
|
|
|
14
14
|
releaseSourceSteps,
|
|
15
15
|
} from "./release-dispatch.ts";
|
|
16
16
|
import {
|
|
17
|
-
independentReleaseSetupSteps,
|
|
18
|
-
registerIndependentPublicationJob,
|
|
19
17
|
releaseTagPattern,
|
|
20
18
|
releasePublishCondition,
|
|
21
19
|
releaseStageCondition,
|
|
@@ -114,8 +112,6 @@ const DEFAULT_DEV_DEPENDENCIES = [
|
|
|
114
112
|
"ruff>=0.12,<1",
|
|
115
113
|
] as const;
|
|
116
114
|
|
|
117
|
-
const quote = (value: string): string => JSON.stringify(value);
|
|
118
|
-
|
|
119
115
|
/** Repository-relative path for a Python package directory. */
|
|
120
116
|
export function pythonPackagePath(repository: PythonRepositoryOptions, directory: string): string {
|
|
121
117
|
return `${repository.root ?? "packages/py"}/${directory}`;
|
|
@@ -279,10 +275,7 @@ export class DBXToolsPythonWorkspace extends Component {
|
|
|
279
275
|
}));
|
|
280
276
|
const resolvedOptions = { ...options, packages };
|
|
281
277
|
this.requiresPython = options.requiresPython ?? ">=3.10";
|
|
282
|
-
this.version =
|
|
283
|
-
isDBXToolsJavaScriptProject()(project) && project.releaseCatalog.mode === "independent"
|
|
284
|
-
? "0.0.0"
|
|
285
|
-
: readWorkspaceVersion(project.outdir);
|
|
278
|
+
this.version = readWorkspaceVersion(project.outdir);
|
|
286
279
|
this.file = this.emitWorkspace(project, resolvedOptions, scope);
|
|
287
280
|
this.packages = packages.map(
|
|
288
281
|
(pkg) =>
|
|
@@ -462,93 +455,10 @@ export class DBXToolsPythonWorkspace extends Component {
|
|
|
462
455
|
const uniffiPublications = this.uniffiPublications(options);
|
|
463
456
|
const allPublications = [...publications, ...uniffiPublications];
|
|
464
457
|
if (allPublications.length === 0) return;
|
|
465
|
-
const usesRustArtifacts = uniffiPublications.length > 0;
|
|
466
458
|
const workflow = tryReleaseWorkflow(project);
|
|
467
459
|
if (!workflow) {
|
|
468
460
|
throw new Error("Python release requires the root dbx-tools release mode");
|
|
469
461
|
}
|
|
470
|
-
if (project.releaseCatalog.mode === "independent") {
|
|
471
|
-
workflow.addJob("build-python", {
|
|
472
|
-
if: usesRustArtifacts
|
|
473
|
-
? "${{ always() && needs.release-plan.outputs.python == 'true' && needs.rust-build.result != 'failure' && needs.rust-build.result != 'cancelled' && (github.event_name == 'push' || inputs.stage == 'all' || inputs.stage == 'python') }}"
|
|
474
|
-
: "${{ needs.release-plan.outputs.python == 'true' && (github.event_name == 'push' || inputs.stage == 'all' || inputs.stage == 'python') }}",
|
|
475
|
-
needs: ["release-plan", ...(usesRustArtifacts ? ["rust-build"] : [])],
|
|
476
|
-
runsOn: ["ubuntu-latest"],
|
|
477
|
-
permissions: { actions: JobPermission.READ, contents: JobPermission.READ },
|
|
478
|
-
timeoutMinutes: 20,
|
|
479
|
-
env: { BUN_VERSION },
|
|
480
|
-
steps: [
|
|
481
|
-
...independentReleaseSetupSteps(project),
|
|
482
|
-
{ name: "Setup uv", uses: "astral-sh/setup-uv@v7" },
|
|
483
|
-
...uniffiPublications.map((publication) => ({
|
|
484
|
-
name: `Download ${publication.distribution} native wheels`,
|
|
485
|
-
uses: "actions/download-artifact@v8",
|
|
486
|
-
with: {
|
|
487
|
-
pattern: `${publication.distribution}--*--python-wheel`,
|
|
488
|
-
path: `dist/${publication.directory}`,
|
|
489
|
-
"merge-multiple": true,
|
|
490
|
-
},
|
|
491
|
-
})),
|
|
492
|
-
{
|
|
493
|
-
name: "Build affected distributions",
|
|
494
|
-
shell: "bash",
|
|
495
|
-
run: publications
|
|
496
|
-
.map(
|
|
497
|
-
(publication) =>
|
|
498
|
-
`if jq -e --arg package ${quote(publication.distribution)} '.pythonPackages[] | select(.identity == $package)' dist/release-plan.json >/dev/null; then uv build --package ${quote(publication.distribution)} --out-dir dist/${publication.directory}; fi`,
|
|
499
|
-
)
|
|
500
|
-
.join("\n"),
|
|
501
|
-
},
|
|
502
|
-
{
|
|
503
|
-
name: "Validate affected distributions",
|
|
504
|
-
run: "find dist -type f \\( -name '*.whl' -o -name '*.tar.gz' \\) -print0 | xargs -0 uvx twine check",
|
|
505
|
-
},
|
|
506
|
-
{
|
|
507
|
-
name: "Upload distributions",
|
|
508
|
-
uses: "actions/upload-artifact@v7",
|
|
509
|
-
with: { name: "python-distributions", path: "dist", "retention-days": 7 },
|
|
510
|
-
},
|
|
511
|
-
],
|
|
512
|
-
});
|
|
513
|
-
for (const publication of allPublications) {
|
|
514
|
-
const dependencyJobs = (publication.dependencies ?? []).map(
|
|
515
|
-
(dependency) => `publish-pypi-${dependency}`,
|
|
516
|
-
);
|
|
517
|
-
const dependencyCondition = dependencyJobs
|
|
518
|
-
.map((job) => `needs.${job}.result != 'failure' && needs.${job}.result != 'cancelled'`)
|
|
519
|
-
.join(" && ");
|
|
520
|
-
workflow.addJob(`publish-pypi-${publication.directory}`, {
|
|
521
|
-
if: `\${{ always() && needs.build-python.result == 'success' && contains(needs.release-plan.outputs.python_packages, '"identity":"${publication.distribution}"') && (github.event_name == 'push' || inputs.stage == 'all' || inputs.stage == 'python')${dependencyCondition ? ` && ${dependencyCondition}` : ""} }}`,
|
|
522
|
-
needs: ["release-plan", "build-python", ...dependencyJobs],
|
|
523
|
-
environment: {
|
|
524
|
-
name: publication.environment,
|
|
525
|
-
url:
|
|
526
|
-
options.environmentUrl ??
|
|
527
|
-
`https://pypi.org/project/${publication.distribution.replaceAll("_", "-")}/`,
|
|
528
|
-
},
|
|
529
|
-
runsOn: ["ubuntu-latest"],
|
|
530
|
-
permissions: { idToken: JobPermission.WRITE },
|
|
531
|
-
timeoutMinutes: 10,
|
|
532
|
-
steps: [
|
|
533
|
-
{
|
|
534
|
-
name: "Download distributions",
|
|
535
|
-
uses: "actions/download-artifact@v8",
|
|
536
|
-
with: { name: "python-distributions", path: "dist" },
|
|
537
|
-
},
|
|
538
|
-
{
|
|
539
|
-
name: `Publish ${publication.distribution} to PyPI`,
|
|
540
|
-
uses: "pypa/gh-action-pypi-publish@release/v1",
|
|
541
|
-
with: {
|
|
542
|
-
"packages-dir": `dist/${publication.directory}`,
|
|
543
|
-
"skip-existing": true,
|
|
544
|
-
},
|
|
545
|
-
},
|
|
546
|
-
],
|
|
547
|
-
});
|
|
548
|
-
registerIndependentPublicationJob(workflow, `publish-pypi-${publication.directory}`);
|
|
549
|
-
}
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
462
|
workflow.addJob("build-python", {
|
|
553
463
|
if: releaseStageCondition("python", ["needs.verify-context.result == 'success'"]),
|
|
554
464
|
needs: ["verify-context"],
|
|
@@ -697,11 +607,10 @@ export class DBXToolsPythonWorkspace extends Component {
|
|
|
697
607
|
): void {
|
|
698
608
|
const repository = this.githubRepository();
|
|
699
609
|
const publications = this.trustedPublisherPublications(options);
|
|
700
|
-
const releaseTag =
|
|
701
|
-
|
|
702
|
-
?
|
|
703
|
-
:
|
|
704
|
-
: "v*";
|
|
610
|
+
const releaseTag =
|
|
611
|
+
isDBXToolsJavaScriptProject()(project) && tryReleaseWorkflow(project)
|
|
612
|
+
? releaseTagPattern(project)
|
|
613
|
+
: "v*";
|
|
705
614
|
const linesBeforeAuthentication = [
|
|
706
615
|
"# PyPI Trusted Publisher Setup Instructions",
|
|
707
616
|
"",
|
package/src/project-rs.ts
CHANGED
|
@@ -20,13 +20,8 @@ import {
|
|
|
20
20
|
} from "./_rust-project.ts";
|
|
21
21
|
import {
|
|
22
22
|
configureRustReleaseTask,
|
|
23
|
-
independentRustCargoPublishJob,
|
|
24
|
-
independentRustGitHubReleaseJob,
|
|
25
|
-
independentRustNativeNpmPublishJob,
|
|
26
|
-
independentRustNodeFacadePublishJob,
|
|
27
23
|
orderRustBindings,
|
|
28
24
|
planRustRelease,
|
|
29
|
-
rustBuildJob,
|
|
30
25
|
rustCargoPublishJob,
|
|
31
26
|
} from "./_rust-release-workflow.ts";
|
|
32
27
|
import { toPosix } from "./packages.ts";
|
|
@@ -39,12 +34,7 @@ import {
|
|
|
39
34
|
import { isDBXToolsJavaScriptProject } from "./project-predicate.ts";
|
|
40
35
|
import { pythonModuleName, type PythonPackageOptions } from "./project-py.ts";
|
|
41
36
|
import { defaultReleaseUnitId, type ReleaseDependencyInput } from "./release-catalog.ts";
|
|
42
|
-
import {
|
|
43
|
-
hasNodeRelease,
|
|
44
|
-
independentReleaseSetupSteps,
|
|
45
|
-
registerIndependentPublicationJob,
|
|
46
|
-
tryReleaseWorkflow,
|
|
47
|
-
} from "./release.ts";
|
|
37
|
+
import { tryReleaseWorkflow } from "./release.ts";
|
|
48
38
|
import { readWorkspaceVersion } from "./workspace-version.ts";
|
|
49
39
|
export { discoverRustCrates, hasUniFFIBindings } from "./_rust-project.ts";
|
|
50
40
|
export { orderRustBindings } from "./_rust-release-workflow.ts";
|
|
@@ -454,10 +444,7 @@ function planRustReleaseBinaries(
|
|
|
454
444
|
component: defaultReleaseUnitId("rust", pkg.crateName),
|
|
455
445
|
version: readWorkspaceVersion(project.outdir),
|
|
456
446
|
};
|
|
457
|
-
const tagPrefix =
|
|
458
|
-
isDBXToolsJavaScriptProject()(project) && project.releaseCatalog.mode === "independent"
|
|
459
|
-
? `${identity.component}-v`
|
|
460
|
-
: "v";
|
|
447
|
+
const tagPrefix = "v";
|
|
461
448
|
return {
|
|
462
449
|
command,
|
|
463
450
|
description,
|
|
@@ -666,14 +653,6 @@ function createRustPackages(
|
|
|
666
653
|
...resolved.packageOptions[directory],
|
|
667
654
|
};
|
|
668
655
|
const name = `${resolved.scope}-${directory.toLowerCase().replace(/[^a-z0-9-]+/g, "-")}`;
|
|
669
|
-
const version =
|
|
670
|
-
isDBXToolsJavaScriptProject()(project) && project.releaseCatalog.mode === "independent"
|
|
671
|
-
? project.releaseCatalog.versionForRegistration(
|
|
672
|
-
"rust",
|
|
673
|
-
name,
|
|
674
|
-
`${resolved.root}/${directory}`,
|
|
675
|
-
)
|
|
676
|
-
: undefined;
|
|
677
656
|
return new DBXToolsRustProject({
|
|
678
657
|
parent: project,
|
|
679
658
|
outdir: `${resolved.root}/${directory}`,
|
|
@@ -682,7 +661,6 @@ function createRustPackages(
|
|
|
682
661
|
workspaceRoot: resolved.root,
|
|
683
662
|
workspace: true,
|
|
684
663
|
scope: resolved.scope,
|
|
685
|
-
...(version ? { version } : {}),
|
|
686
664
|
...configured,
|
|
687
665
|
});
|
|
688
666
|
});
|
|
@@ -828,9 +806,7 @@ function configureRustWorkspaceFiles(
|
|
|
828
806
|
.map((pkg) => `${resolved.root}/${pkg.packageOptions.directory}`),
|
|
829
807
|
resolver: "2",
|
|
830
808
|
package: {
|
|
831
|
-
|
|
832
|
-
? { version: readWorkspaceVersion(project.outdir) }
|
|
833
|
-
: {}),
|
|
809
|
+
version: readWorkspaceVersion(project.outdir),
|
|
834
810
|
edition: options.edition ?? "2021",
|
|
835
811
|
"rust-version": options.rustVersion ?? "1.82",
|
|
836
812
|
license: options.license ?? DBX_TOOLS_LICENSE,
|
|
@@ -915,29 +891,6 @@ function rustReleaseDependencies(
|
|
|
915
891
|
});
|
|
916
892
|
}
|
|
917
893
|
|
|
918
|
-
function configureIndependentRustVersions(
|
|
919
|
-
project: DBXToolsJavaScriptProject,
|
|
920
|
-
packages: readonly DBXToolsRustProject[],
|
|
921
|
-
): void {
|
|
922
|
-
for (const pkg of packages) {
|
|
923
|
-
for (const [section, dependencies] of [
|
|
924
|
-
["dependencies", pkg.packageOptions.dependencies],
|
|
925
|
-
["dev-dependencies", pkg.packageOptions.devDependencies],
|
|
926
|
-
] as const) {
|
|
927
|
-
for (const [name, dependency] of Object.entries(dependencies ?? {})) {
|
|
928
|
-
if (typeof dependency === "string" || !dependency.path) continue;
|
|
929
|
-
const dependencyPath = resolve(pkg.outdir, dependency.path);
|
|
930
|
-
const target = packages.find((candidate) => resolve(candidate.outdir) === dependencyPath);
|
|
931
|
-
if (!target) continue;
|
|
932
|
-
pkg.manifestFile.addOverride(
|
|
933
|
-
`${section}.${name}.version`,
|
|
934
|
-
project.releaseCatalog.versionFor(target),
|
|
935
|
-
);
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
|
|
941
894
|
/** Generated Rust workspace plus convention-derived UniFFI binding packages. */
|
|
942
895
|
export class DBXToolsRustWorkspace extends Component {
|
|
943
896
|
readonly packages: readonly DBXToolsRustProject[];
|
|
@@ -985,9 +938,6 @@ export class DBXToolsRustWorkspace extends Component {
|
|
|
985
938
|
],
|
|
986
939
|
});
|
|
987
940
|
}
|
|
988
|
-
if (project.releaseCatalog.mode === "independent") {
|
|
989
|
-
configureIndependentRustVersions(project, this.packages);
|
|
990
|
-
}
|
|
991
941
|
}
|
|
992
942
|
this.releaseBinaries = planRustReleaseBinaries(project, this.packages, resolved);
|
|
993
943
|
configureRustCliRegistry(project, options.cliRegistryPath, this.releaseBinaries);
|
|
@@ -1097,29 +1047,6 @@ export class DBXToolsRustWorkspace extends Component {
|
|
|
1097
1047
|
throw new Error("Rust release requires the root dbx-tools release mode");
|
|
1098
1048
|
}
|
|
1099
1049
|
configureRustReleaseTask(project, plan);
|
|
1100
|
-
if (project.releaseCatalog.mode === "independent") {
|
|
1101
|
-
if (plan.targets.length) {
|
|
1102
|
-
workflow.addJob("rust-build", rustBuildJob(plan, independentReleaseSetupSteps(project)));
|
|
1103
|
-
}
|
|
1104
|
-
if (plan.publicCrates.length) {
|
|
1105
|
-
workflow.addJob("publish-cargo", independentRustCargoPublishJob(project, plan));
|
|
1106
|
-
registerIndependentPublicationJob(workflow, "publish-cargo");
|
|
1107
|
-
}
|
|
1108
|
-
if (plan.releaseBinaries.length) {
|
|
1109
|
-
workflow.addJob("publish-github-release", independentRustGitHubReleaseJob(project, plan));
|
|
1110
|
-
registerIndependentPublicationJob(workflow, "publish-github-release");
|
|
1111
|
-
}
|
|
1112
|
-
if (plan.nodeBindings.length && hasNodeRelease(project)) {
|
|
1113
|
-
workflow.addJob("publish-native-npm", independentRustNativeNpmPublishJob(project));
|
|
1114
|
-
registerIndependentPublicationJob(workflow, "publish-native-npm");
|
|
1115
|
-
workflow.addJob(
|
|
1116
|
-
"publish-node-facades",
|
|
1117
|
-
independentRustNodeFacadePublishJob(project, plan.nodeBindings),
|
|
1118
|
-
);
|
|
1119
|
-
registerIndependentPublicationJob(workflow, "publish-node-facades");
|
|
1120
|
-
}
|
|
1121
|
-
return;
|
|
1122
|
-
}
|
|
1123
1050
|
if (plan.publicCrates.length) {
|
|
1124
1051
|
workflow.addJob("publish-cargo", rustCargoPublishJob(plan));
|
|
1125
1052
|
}
|
package/src/release-catalog.ts
CHANGED
|
@@ -1,25 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cross-language release-unit ownership and dependency graph.
|
|
3
3
|
*
|
|
4
|
-
* The catalog
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* enabled.
|
|
4
|
+
* The catalog owns cross-language package identity, release grouping, and
|
|
5
|
+
* publication order. Every registered project reads its version from the root
|
|
6
|
+
* VERSION file.
|
|
8
7
|
*
|
|
9
8
|
* @module
|
|
10
9
|
*/
|
|
11
10
|
|
|
12
|
-
import { execFileSync } from "node:child_process";
|
|
13
11
|
import { createHash } from "node:crypto";
|
|
14
12
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
15
13
|
import { basename, join, relative, resolve } from "node:path";
|
|
16
|
-
import { Component,
|
|
14
|
+
import { Component, type Project } from "projen";
|
|
15
|
+
import { probeTaskCommand } from "./_task-command.ts";
|
|
17
16
|
import { toPosix } from "./packages.ts";
|
|
18
17
|
import { readWorkspaceVersion } from "./workspace-version.ts";
|
|
19
18
|
|
|
20
|
-
/** Version source used by the generated workspace. */
|
|
21
|
-
export type DBXToolsVersioningMode = "fixed" | "independent";
|
|
22
|
-
|
|
23
19
|
/** Runtime family represented by a release project. */
|
|
24
20
|
export type ReleaseProjectLanguage = "javascript" | "python" | "rust";
|
|
25
21
|
|
|
@@ -51,11 +47,6 @@ export interface ReleaseUnitRule {
|
|
|
51
47
|
|
|
52
48
|
/** Root catalog configuration. */
|
|
53
49
|
export interface DBXToolsReleaseCatalogOptions {
|
|
54
|
-
readonly mode?: DBXToolsVersioningMode;
|
|
55
|
-
readonly manifestFile?: string;
|
|
56
|
-
readonly graphFile?: string;
|
|
57
|
-
readonly releasePleaseConfigFile?: string;
|
|
58
|
-
readonly bootstrapSha?: string;
|
|
59
50
|
readonly units?: readonly ReleaseUnitRule[];
|
|
60
51
|
readonly externalProjects?: readonly ExternalReleaseProjectRegistration[];
|
|
61
52
|
}
|
|
@@ -151,7 +142,6 @@ export interface ReleaseUnit {
|
|
|
151
142
|
/** Generated execution graph consumed by validation and release tasks. */
|
|
152
143
|
export interface ReleaseUnitGraph {
|
|
153
144
|
readonly schemaVersion: 1;
|
|
154
|
-
readonly mode: DBXToolsVersioningMode;
|
|
155
145
|
readonly units: readonly ReleaseUnit[];
|
|
156
146
|
readonly projects: readonly ReleaseProjectNode[];
|
|
157
147
|
readonly artifacts: readonly ReleaseArtifact[];
|
|
@@ -219,22 +209,6 @@ export function defaultPublishOrder(kind: ReleaseEdgeKind): boolean {
|
|
|
219
209
|
return !["test", "development"].includes(kind);
|
|
220
210
|
}
|
|
221
211
|
|
|
222
|
-
/** Read one component version, falling back to fixed workspace compatibility. */
|
|
223
|
-
export function readReleaseUnitVersion(
|
|
224
|
-
root: string,
|
|
225
|
-
component: string,
|
|
226
|
-
manifestFile = ".release-please-manifest.json",
|
|
227
|
-
): string {
|
|
228
|
-
const path = resolve(root, manifestFile);
|
|
229
|
-
if (!existsSync(path)) return readWorkspaceVersion(root);
|
|
230
|
-
const parsed = JSON.parse(readFileSync(path, "utf8")) as Record<string, unknown>;
|
|
231
|
-
const version = parsed[`.release-units/${component}`];
|
|
232
|
-
if (typeof version !== "string") {
|
|
233
|
-
throw new Error(`Release Please manifest is missing .release-units/${component}`);
|
|
234
|
-
}
|
|
235
|
-
return version;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
212
|
/**
|
|
239
213
|
* Root release catalog shared by every generated language project.
|
|
240
214
|
*
|
|
@@ -243,12 +217,6 @@ export function readReleaseUnitVersion(
|
|
|
243
217
|
* after project construction.
|
|
244
218
|
*/
|
|
245
219
|
export class DBXToolsReleaseCatalog extends Component {
|
|
246
|
-
readonly mode: DBXToolsVersioningMode;
|
|
247
|
-
readonly manifestFile: string;
|
|
248
|
-
readonly graphFile: string;
|
|
249
|
-
readonly releasePleaseConfigFile: string;
|
|
250
|
-
readonly bootstrapSha?: string;
|
|
251
|
-
|
|
252
220
|
private readonly projects = new Map<Project, RegisteredProject>();
|
|
253
221
|
private readonly externalProjects = new Map<string, ExternalReleaseProjectRegistration>();
|
|
254
222
|
private readonly artifacts = new Map<string, RegisteredArtifact>();
|
|
@@ -257,37 +225,11 @@ export class DBXToolsReleaseCatalog extends Component {
|
|
|
257
225
|
dependency: ReleaseDependencyInput;
|
|
258
226
|
}> = [];
|
|
259
227
|
private readonly rules: ReleaseUnitRule[];
|
|
260
|
-
private readonly markerFiles = new Set<string>();
|
|
261
228
|
|
|
262
229
|
constructor(project: Project, options: DBXToolsReleaseCatalogOptions = {}) {
|
|
263
230
|
super(project);
|
|
264
|
-
this.mode = options.mode ?? "fixed";
|
|
265
|
-
this.manifestFile = options.manifestFile ?? ".release-please-manifest.json";
|
|
266
|
-
this.graphFile = options.graphFile ?? ".projen/release-units.json";
|
|
267
|
-
this.releasePleaseConfigFile = options.releasePleaseConfigFile ?? "release-please-config.json";
|
|
268
|
-
this.bootstrapSha = options.bootstrapSha;
|
|
269
231
|
this.rules = [...(options.units ?? [])];
|
|
270
232
|
for (const external of options.externalProjects ?? []) this.registerExternalProject(external);
|
|
271
|
-
if (this.mode === "independent") {
|
|
272
|
-
new JsonFile(project, this.graphFile, {
|
|
273
|
-
marker: false,
|
|
274
|
-
readonly: true,
|
|
275
|
-
obj: () => this.graph(),
|
|
276
|
-
});
|
|
277
|
-
new JsonFile(project, this.releasePleaseConfigFile, {
|
|
278
|
-
marker: false,
|
|
279
|
-
readonly: true,
|
|
280
|
-
obj: () => this.releasePleaseConfig(),
|
|
281
|
-
});
|
|
282
|
-
project
|
|
283
|
-
.addTask("release:bootstrap", {
|
|
284
|
-
description: "Bootstrap Release Please state from release units",
|
|
285
|
-
})
|
|
286
|
-
.exec("bun node_modules/@dbx-tools/projen/tasks/release-bootstrap.ts");
|
|
287
|
-
} else {
|
|
288
|
-
project.tryRemoveFile(this.graphFile);
|
|
289
|
-
project.tryRemoveFile(this.releasePleaseConfigFile);
|
|
290
|
-
}
|
|
291
233
|
}
|
|
292
234
|
|
|
293
235
|
/** Register one attached Projen project. */
|
|
@@ -349,10 +291,7 @@ export class DBXToolsReleaseCatalog extends Component {
|
|
|
349
291
|
versionFor(project: Project): string {
|
|
350
292
|
const registered = this.projects.get(project);
|
|
351
293
|
if (!registered) throw new Error(`Release project is not registered: ${project.outdir}`);
|
|
352
|
-
|
|
353
|
-
return this.mode === "independent" ? "0.0.0" : readWorkspaceVersion(this.project.outdir);
|
|
354
|
-
}
|
|
355
|
-
return this.versionForUnit(this.unitFor(registered));
|
|
294
|
+
return this.workspaceVersion();
|
|
356
295
|
}
|
|
357
296
|
|
|
358
297
|
/** Stable unit, component, and version identity for a registered project. */
|
|
@@ -372,58 +311,23 @@ export class DBXToolsReleaseCatalog extends Component {
|
|
|
372
311
|
}
|
|
373
312
|
|
|
374
313
|
/** Current version for a project selected by its repository-relative path. */
|
|
375
|
-
versionForPath(
|
|
376
|
-
|
|
377
|
-
const attached = [...this.projects.values()].find(
|
|
378
|
-
(registered) => this.projectId(registered.project) === normalized,
|
|
379
|
-
);
|
|
380
|
-
if (attached) return this.versionFor(attached.project);
|
|
381
|
-
const external = this.externalProjects.get(normalized);
|
|
382
|
-
if (!external) {
|
|
383
|
-
if (this.mode === "fixed") return readWorkspaceVersion(this.project.outdir);
|
|
384
|
-
throw new Error(`Release project path is not registered: ${normalized}`);
|
|
385
|
-
}
|
|
386
|
-
if (external.publish === false) {
|
|
387
|
-
return this.mode === "independent" ? "0.0.0" : readWorkspaceVersion(this.project.outdir);
|
|
388
|
-
}
|
|
389
|
-
const unit =
|
|
390
|
-
external.unit ??
|
|
391
|
-
this.rules.find(
|
|
392
|
-
(rule) =>
|
|
393
|
-
rule.projectPaths?.includes(normalized) ||
|
|
394
|
-
rule.projectIdentities?.includes(external.identity),
|
|
395
|
-
)?.id ??
|
|
396
|
-
defaultReleaseUnitId(external.language, external.identity);
|
|
397
|
-
return this.versionForUnit(unit);
|
|
314
|
+
versionForPath(_path: string): string {
|
|
315
|
+
return this.workspaceVersion();
|
|
398
316
|
}
|
|
399
317
|
|
|
400
318
|
/** Resolve a version before the corresponding Projen project is constructed. */
|
|
401
319
|
versionForRegistration(
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
320
|
+
_language: ReleaseProjectLanguage,
|
|
321
|
+
_identity: string,
|
|
322
|
+
_path: string,
|
|
323
|
+
_unit?: string,
|
|
406
324
|
): string {
|
|
407
|
-
|
|
408
|
-
const resolvedUnit =
|
|
409
|
-
unit ??
|
|
410
|
-
this.rules.find(
|
|
411
|
-
(rule) =>
|
|
412
|
-
rule.projectPaths?.includes(normalized) || rule.projectIdentities?.includes(identity),
|
|
413
|
-
)?.id ??
|
|
414
|
-
defaultReleaseUnitId(language, identity);
|
|
415
|
-
return this.versionForUnit(resolvedUnit);
|
|
325
|
+
return this.workspaceVersion();
|
|
416
326
|
}
|
|
417
327
|
|
|
418
328
|
/** Current version for a release unit. */
|
|
419
|
-
versionForUnit(
|
|
420
|
-
|
|
421
|
-
const component = this.rules.find((rule) => rule.id === unit)?.component ?? unit;
|
|
422
|
-
const versions = this.readIndependentVersions();
|
|
423
|
-
const key = `.release-units/${component}`;
|
|
424
|
-
const version = versions[key];
|
|
425
|
-
if (!version) throw new Error(`Release Please manifest is missing ${key}`);
|
|
426
|
-
return version;
|
|
329
|
+
versionForUnit(_unit: string): string {
|
|
330
|
+
return this.workspaceVersion();
|
|
427
331
|
}
|
|
428
332
|
|
|
429
333
|
/** Build and validate the normalized release graph. */
|
|
@@ -510,7 +414,7 @@ export class DBXToolsReleaseCatalog extends Component {
|
|
|
510
414
|
return {
|
|
511
415
|
id,
|
|
512
416
|
component: unit.component,
|
|
513
|
-
version: this.
|
|
417
|
+
version: this.workspaceVersion(),
|
|
514
418
|
projects: [...unit.projects].sort(),
|
|
515
419
|
artifacts: [...unit.artifacts].sort(),
|
|
516
420
|
sourceHash: hashStrings(hashes),
|
|
@@ -520,7 +424,6 @@ export class DBXToolsReleaseCatalog extends Component {
|
|
|
520
424
|
|
|
521
425
|
return {
|
|
522
426
|
schemaVersion: 1,
|
|
523
|
-
mode: this.mode,
|
|
524
427
|
units: serializedUnits,
|
|
525
428
|
projects,
|
|
526
429
|
artifacts,
|
|
@@ -529,55 +432,6 @@ export class DBXToolsReleaseCatalog extends Component {
|
|
|
529
432
|
};
|
|
530
433
|
}
|
|
531
434
|
|
|
532
|
-
/** Generated Release Please manifest-mode configuration. */
|
|
533
|
-
releasePleaseConfig(): Record<string, unknown> {
|
|
534
|
-
return {
|
|
535
|
-
$schema:
|
|
536
|
-
"https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
|
|
537
|
-
"release-type": "simple",
|
|
538
|
-
"separate-pull-requests": false,
|
|
539
|
-
"include-component-in-tag": true,
|
|
540
|
-
"include-v-in-tag": true,
|
|
541
|
-
...(this.bootstrapSha ? { "bootstrap-sha": this.bootstrapSha } : {}),
|
|
542
|
-
packages: Object.fromEntries(
|
|
543
|
-
this.graph().units.map((unit) => [
|
|
544
|
-
`.release-units/${unit.component}`,
|
|
545
|
-
{
|
|
546
|
-
"release-type": "simple",
|
|
547
|
-
"package-name": unit.id,
|
|
548
|
-
component: unit.component,
|
|
549
|
-
"changelog-path": "CHANGELOG.md",
|
|
550
|
-
"version-file": "version.txt",
|
|
551
|
-
},
|
|
552
|
-
]),
|
|
553
|
-
),
|
|
554
|
-
};
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
public override preSynthesize(): void {
|
|
558
|
-
const graph = this.graph();
|
|
559
|
-
if (this.mode === "fixed") return;
|
|
560
|
-
for (const unit of graph.units) {
|
|
561
|
-
const path = `.release-units/${unit.component}/source.json`;
|
|
562
|
-
if (this.markerFiles.has(path)) continue;
|
|
563
|
-
this.markerFiles.add(path);
|
|
564
|
-
new JsonFile(this.project, path, {
|
|
565
|
-
marker: false,
|
|
566
|
-
readonly: true,
|
|
567
|
-
obj: () => {
|
|
568
|
-
const current = this.graph().units.find((candidate) => candidate.id === unit.id);
|
|
569
|
-
if (!current) throw new Error(`Release unit disappeared during synthesis: ${unit.id}`);
|
|
570
|
-
return {
|
|
571
|
-
schemaVersion: 1,
|
|
572
|
-
unit: current.id,
|
|
573
|
-
component: current.component,
|
|
574
|
-
sourceHash: current.sourceHash,
|
|
575
|
-
};
|
|
576
|
-
},
|
|
577
|
-
});
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
|
|
581
435
|
private projectNode(registered: RegisteredProject): ReleaseProjectNode {
|
|
582
436
|
const identity = resolveValue(registered.registration.identity);
|
|
583
437
|
const publish = resolveValue(registered.registration.publish ?? true);
|
|
@@ -651,6 +505,10 @@ export class DBXToolsReleaseCatalog extends Component {
|
|
|
651
505
|
return toPosix(relative(this.project.outdir, project.outdir)) || ".";
|
|
652
506
|
}
|
|
653
507
|
|
|
508
|
+
private workspaceVersion(): string {
|
|
509
|
+
return readWorkspaceVersion(this.project.outdir);
|
|
510
|
+
}
|
|
511
|
+
|
|
654
512
|
private dependencies(
|
|
655
513
|
byIdentity: ReadonlyMap<string, readonly ReleaseProjectNode[]>,
|
|
656
514
|
byId: ReadonlyMap<string, ReleaseProjectNode>,
|
|
@@ -719,31 +577,6 @@ export class DBXToolsReleaseCatalog extends Component {
|
|
|
719
577
|
[a.from, a.to, a.kind].join("\0").localeCompare([b.from, b.to, b.kind].join("\0")),
|
|
720
578
|
);
|
|
721
579
|
}
|
|
722
|
-
|
|
723
|
-
private versionForResolvedUnit(unit: string, component: string): string {
|
|
724
|
-
if (this.mode === "fixed") return readWorkspaceVersion(this.project.outdir);
|
|
725
|
-
const key = `.release-units/${component}`;
|
|
726
|
-
const version = this.readIndependentVersions()[key];
|
|
727
|
-
if (!version) throw new Error(`Release Please manifest is missing ${key} for ${unit}`);
|
|
728
|
-
return version;
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
private readIndependentVersions(): Record<string, string> {
|
|
732
|
-
const path = resolve(this.project.outdir, this.manifestFile);
|
|
733
|
-
if (!existsSync(path)) throw new Error(`Independent version manifest not found: ${path}`);
|
|
734
|
-
const parsed = JSON.parse(readFileSync(path, "utf8")) as unknown;
|
|
735
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
736
|
-
throw new Error(`Independent version manifest must contain an object: ${path}`);
|
|
737
|
-
}
|
|
738
|
-
return Object.fromEntries(
|
|
739
|
-
Object.entries(parsed).map(([key, value]) => {
|
|
740
|
-
if (typeof value !== "string" || !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(value)) {
|
|
741
|
-
throw new Error(`Invalid independent version for ${key}: ${String(value)}`);
|
|
742
|
-
}
|
|
743
|
-
return [key, value];
|
|
744
|
-
}),
|
|
745
|
-
);
|
|
746
|
-
}
|
|
747
580
|
}
|
|
748
581
|
|
|
749
582
|
/** Publish dependency batches ordered with dependencies before dependents. */
|
|
@@ -795,22 +628,23 @@ function hashPaths(root: string, paths: readonly string[]): string {
|
|
|
795
628
|
|
|
796
629
|
function gitReleaseFiles(root: string, paths: readonly string[]): string[] | undefined {
|
|
797
630
|
const relativePaths = paths.map((path) => toPosix(relative(root, path)));
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
631
|
+
const output = probeTaskCommand(root, "git", [
|
|
632
|
+
"ls-files",
|
|
633
|
+
"--cached",
|
|
634
|
+
"--others",
|
|
635
|
+
"--exclude-standard",
|
|
636
|
+
"-z",
|
|
637
|
+
"--",
|
|
638
|
+
...relativePaths,
|
|
639
|
+
]);
|
|
640
|
+
if (output === undefined) return undefined;
|
|
641
|
+
return output
|
|
642
|
+
.split("\0")
|
|
643
|
+
.filter(Boolean)
|
|
644
|
+
.map((path) => resolve(root, path))
|
|
645
|
+
.filter((path) => existsSync(path))
|
|
646
|
+
.filter((path) => paths.some((sourcePath) => trackedReleaseFile(sourcePath, path)))
|
|
647
|
+
.sort();
|
|
814
648
|
}
|
|
815
649
|
|
|
816
650
|
function trackedReleaseFile(sourcePath: string, path: string): boolean {
|