@dbx-tools/projen 0.9.21 → 0.9.29
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 +77 -207
- package/index.ts +10 -14
- package/package.json +4 -4
- package/src/barrels.ts +1 -74
- package/src/module-exports.ts +175 -1
- package/src/openapi.ts +5 -72
- package/src/packages.ts +45 -0
- package/src/project-js.ts +3 -6
- package/src/project-predicate.ts +1 -2
- package/src/project-py.ts +82 -103
- package/src/project.ts +2 -2
- package/src/python-node-bindings.ts +138 -0
- package/src/python-node-bundle.ts +92 -0
- package/src/release-catalog.ts +3 -5
- package/src/{release-dispatch.ts → release-context.ts} +0 -11
- package/src/release.ts +70 -152
- package/tasks/bump.ts +12 -21
- package/tasks/databricks-cli-assets.ts +129 -0
- package/tasks/local-publish.ts +23 -107
- package/tasks/publish-npm.ts +10 -1
- package/tasks/publish-python.ts +26 -11
- package/tasks/publish.ts +12 -48
- package/tasks/python-node-bindings-watch.ts +47 -0
- package/tasks/python-node-bindings.ts +1017 -0
- package/tasks/python-release.ts +74 -0
- package/tasks/release.ts +99 -0
- package/tasks/sync.ts +13 -18
- package/tasks/version-check.ts +1 -28
- package/._LICENSE +0 -0
- package/._README.md +0 -0
- package/._index.ts +0 -0
- package/._package.json +0 -0
- 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/_release-platform.ts +0 -78
- package/src/_rust-project.ts +0 -429
- package/src/_rust-release-workflow.ts +0 -311
- package/src/project-rs.ts +0 -1054
- package/src/release-github.ts +0 -109
- package/src/uniffi.ts +0 -65
- 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/publish-uniffi-local.ts +0 -359
- package/tasks/release-assets.ts +0 -467
- package/tasks/release-candidate.ts +0 -416
- package/tasks/release-manifest.ts +0 -273
- package/tasks/release-pr.ts +0 -589
- package/tasks/release-summary.ts +0 -379
- package/tasks/rust.ts +0 -173
- package/tasks/uniffi-python.d.ts +0 -60
- package/tasks/uniffi-python.js +0 -178
- package/tasks/uniffi-release.mjs +0 -579
- package/tasks/uniffi.ts +0 -262
package/src/release.ts
CHANGED
|
@@ -6,14 +6,7 @@ import { JobPermission, type Job, type JobStep } from "projen/lib/github/workflo
|
|
|
6
6
|
import { BUN_VERSION, bunCacheRestoreSteps, bunCacheSaveStep } from "./bun-workflow.ts";
|
|
7
7
|
import { projectReleaseBranch, type DBXToolsJavaScriptProject } from "./project-js.ts";
|
|
8
8
|
import { applyTasks, taskScript } from "./project.ts";
|
|
9
|
-
import {
|
|
10
|
-
RELEASE_SHA,
|
|
11
|
-
RELEASE_TAG,
|
|
12
|
-
RELEASE_VERSION,
|
|
13
|
-
releaseSourceSteps,
|
|
14
|
-
type ReleaseSummaryProviderName,
|
|
15
|
-
} from "./release-dispatch.ts";
|
|
16
|
-
import { readWorkspaceVersion } from "./workspace-version.ts";
|
|
9
|
+
import { RELEASE_VERSION, releaseSourceSteps } from "./release-context.ts";
|
|
17
10
|
|
|
18
11
|
const NODE_VERSION = "24";
|
|
19
12
|
const NPM_VERSION = "11.4.2";
|
|
@@ -23,7 +16,7 @@ const releaseTagPrefixes = new WeakMap<DBXToolsJavaScriptProject, string>();
|
|
|
23
16
|
const releaseWorkflows = new WeakMap<DBXToolsJavaScriptProject, GithubWorkflow>();
|
|
24
17
|
|
|
25
18
|
/** Independently recoverable portions of the release workflow. */
|
|
26
|
-
export type ReleaseStage = "all" | "node" | "python" | "
|
|
19
|
+
export type ReleaseStage = "all" | "node" | "python" | "docs";
|
|
27
20
|
|
|
28
21
|
/** GitHub Pages configuration included in the unified release workflow. */
|
|
29
22
|
export interface ReleaseDocsOptions {
|
|
@@ -37,16 +30,6 @@ export interface ReleaseDocsOptions {
|
|
|
37
30
|
readonly artifactPath: string;
|
|
38
31
|
}
|
|
39
32
|
|
|
40
|
-
/** Optional local AI summary generation during reviewed release preparation. */
|
|
41
|
-
export interface ReleaseSummaryOptions {
|
|
42
|
-
/**
|
|
43
|
-
* Provider fallback order.
|
|
44
|
-
*
|
|
45
|
-
* @default ["cursor", "codex", "claude"]
|
|
46
|
-
*/
|
|
47
|
-
readonly providers?: readonly ReleaseSummaryProviderName[];
|
|
48
|
-
}
|
|
49
|
-
|
|
50
33
|
/** Options for {@link DBXToolsRelease}. */
|
|
51
34
|
export interface DBXToolsReleaseOptions {
|
|
52
35
|
/** Git tag prefix. Defaults to `v`. */
|
|
@@ -55,15 +38,10 @@ export interface DBXToolsReleaseOptions {
|
|
|
55
38
|
readonly nodeRelease?: boolean;
|
|
56
39
|
/** Build and deploy generated documentation through GitHub Pages. */
|
|
57
40
|
readonly docs?: ReleaseDocsOptions;
|
|
58
|
-
/** Python package root
|
|
41
|
+
/** Python package root used by attached Python publication jobs. */
|
|
59
42
|
readonly pythonRoot?: string;
|
|
60
|
-
/** Repository task names run after VERSION
|
|
43
|
+
/** Repository task names run after VERSION verification and before publication. */
|
|
61
44
|
readonly validationTasks?: readonly string[];
|
|
62
|
-
/**
|
|
63
|
-
* Generate a versioned release summary locally. Defaults to enabled with the
|
|
64
|
-
* standard Cursor, Codex, Claude fallback order.
|
|
65
|
-
*/
|
|
66
|
-
readonly summary?: boolean | ReleaseSummaryOptions;
|
|
67
45
|
}
|
|
68
46
|
|
|
69
47
|
/** Locate the unified workflow so attached language workspaces can add jobs. */
|
|
@@ -90,32 +68,22 @@ export function releaseTagPattern(project: DBXToolsJavaScriptProject): string {
|
|
|
90
68
|
return `${prefix}*`;
|
|
91
69
|
}
|
|
92
70
|
|
|
93
|
-
/** Run a release stage
|
|
71
|
+
/** Run a release stage after its prerequisite tag-build jobs succeed. */
|
|
94
72
|
export function releaseStageCondition(
|
|
95
|
-
|
|
73
|
+
_stage: Exclude<ReleaseStage, "all">,
|
|
96
74
|
prerequisites: readonly string[] = [],
|
|
97
75
|
): string {
|
|
98
|
-
if (prerequisites.length === 0) {
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
const prefix = prerequisites.length
|
|
102
|
-
? `always() && ${prerequisites.map((condition) => `(${condition})`).join(" && ")} && `
|
|
103
|
-
: "";
|
|
104
|
-
return `\${{ ${prefix}(github.event_name == 'release' || inputs.stage == 'all' || inputs.stage == '${stage}') }}`;
|
|
76
|
+
if (prerequisites.length === 0) return "${{ success() }}";
|
|
77
|
+
return `\${{ always() && ${prerequisites.map((condition) => `(${condition})`).join(" && ")} }}`;
|
|
105
78
|
}
|
|
106
79
|
|
|
107
|
-
/** Publish a
|
|
80
|
+
/** Publish a release stage after its prerequisite tag-build jobs succeed. */
|
|
108
81
|
export function releasePublishCondition(
|
|
109
|
-
|
|
82
|
+
_stage: Exclude<ReleaseStage, "all">,
|
|
110
83
|
prerequisites: readonly string[] = [],
|
|
111
84
|
): string {
|
|
112
|
-
if (prerequisites.length === 0) {
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
const prefix = prerequisites.length
|
|
116
|
-
? `always() && ${prerequisites.map((condition) => `(${condition})`).join(" && ")} && `
|
|
117
|
-
: "";
|
|
118
|
-
return `\${{ ${prefix}(github.event_name == 'release' || (inputs.dry_run != true && (inputs.stage == 'all' || inputs.stage == '${stage}'))) }}`;
|
|
85
|
+
if (prerequisites.length === 0) return "${{ success() }}";
|
|
86
|
+
return `\${{ always() && ${prerequisites.map((condition) => `(${condition})`).join(" && ")} }}`;
|
|
119
87
|
}
|
|
120
88
|
|
|
121
89
|
/** Shared Bun, Node, cache, and install setup for Node release jobs. */
|
|
@@ -142,17 +110,49 @@ export function nodeReleaseSetupSteps(project: DBXToolsJavaScriptProject): reado
|
|
|
142
110
|
export function npmPublishEnvironment(): Record<string, string> {
|
|
143
111
|
return {
|
|
144
112
|
NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}",
|
|
145
|
-
NPM_CONFIG_PROVENANCE:
|
|
146
|
-
|
|
147
|
-
DRY_RUN:
|
|
148
|
-
"${{ github.event_name == 'workflow_dispatch' && inputs.dry_run && '--dry-run' || '' }}",
|
|
113
|
+
NPM_CONFIG_PROVENANCE: "true",
|
|
114
|
+
DRY_RUN: "",
|
|
149
115
|
};
|
|
150
116
|
}
|
|
151
117
|
|
|
152
|
-
|
|
118
|
+
/** Install uv and restore its download/build cache using Python manifests. */
|
|
119
|
+
export function uvSetupStep(): JobStep {
|
|
120
|
+
return {
|
|
121
|
+
name: "Setup uv",
|
|
122
|
+
uses: "astral-sh/setup-uv@v7",
|
|
123
|
+
with: {
|
|
124
|
+
"enable-cache": true,
|
|
125
|
+
"cache-dependency-glob": "**/pyproject.toml",
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function refreshDocsRegistryDependencies(workflow: GithubWorkflow): void {
|
|
131
|
+
const docs = workflow.getJob("build-docs") as Job | undefined;
|
|
132
|
+
if (!docs) return;
|
|
133
|
+
const registryJobs = Object.keys(workflow.jobs).filter(
|
|
134
|
+
(name) => name === "publish-node" || name.startsWith("publish-pypi-"),
|
|
135
|
+
);
|
|
136
|
+
if (registryJobs.length > 0) workflow.updateJob("build-docs", { ...docs, needs: registryJobs });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Keep documentation publication behind every configured package registry. */
|
|
140
|
+
export function refreshReleaseDocsDependencies(project: DBXToolsJavaScriptProject): void {
|
|
141
|
+
const workflow = releaseWorkflows.get(project);
|
|
142
|
+
if (workflow) refreshDocsRegistryDependencies(workflow);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function verifyContextJob(
|
|
146
|
+
project: DBXToolsJavaScriptProject,
|
|
147
|
+
tagPrefix: string,
|
|
148
|
+
releaseBranch: string,
|
|
149
|
+
options: DBXToolsReleaseOptions,
|
|
150
|
+
): Job {
|
|
153
151
|
return {
|
|
154
152
|
runsOn: ["ubuntu-latest"],
|
|
155
153
|
permissions: { contents: JobPermission.READ },
|
|
154
|
+
timeoutMinutes: 30,
|
|
155
|
+
env: { BUN_VERSION, CI: "true" },
|
|
156
156
|
outputs: {
|
|
157
157
|
release_tag: { stepId: "release", outputName: "release_tag" },
|
|
158
158
|
expected_sha: { stepId: "release", outputName: "expected_sha" },
|
|
@@ -163,24 +163,19 @@ function verifyContextJob(tagPrefix: string, releaseBranch: string): Job {
|
|
|
163
163
|
name: "Checkout release source",
|
|
164
164
|
uses: "actions/checkout@v6",
|
|
165
165
|
with: {
|
|
166
|
-
ref: "${{ github.
|
|
166
|
+
ref: "${{ github.ref_name }}",
|
|
167
167
|
"fetch-depth": 0,
|
|
168
168
|
},
|
|
169
169
|
},
|
|
170
|
-
{
|
|
171
|
-
name: "Setup Bun",
|
|
172
|
-
uses: "oven-sh/setup-bun@v2",
|
|
173
|
-
with: { "bun-version": BUN_VERSION },
|
|
174
|
-
},
|
|
170
|
+
...bunCacheRestoreSteps(project, { ignorePaths: project.workflowCacheIgnorePaths }),
|
|
175
171
|
{ name: "Install release validation dependencies", run: "bun install --frozen-lockfile" },
|
|
172
|
+
bunCacheSaveStep(),
|
|
176
173
|
{
|
|
177
174
|
name: "Verify release context",
|
|
178
175
|
id: "release",
|
|
179
176
|
shell: "bash",
|
|
180
177
|
env: {
|
|
181
|
-
RELEASE_TAG:
|
|
182
|
-
"${{ github.event_name == 'release' && github.event.release.tag_name || inputs.release_tag }}",
|
|
183
|
-
GH_TOKEN: "${{ github.token }}",
|
|
178
|
+
RELEASE_TAG: "${{ github.ref_name }}",
|
|
184
179
|
},
|
|
185
180
|
// prettier-ignore
|
|
186
181
|
run: stringUtils.dedent(
|
|
@@ -194,17 +189,8 @@ function verifyContextJob(tagPrefix: string, releaseBranch: string): Job {
|
|
|
194
189
|
test "$(git cat-file -t "$RELEASE_TAG")" = "tag"
|
|
195
190
|
RELEASE_SHA="$(git rev-parse "$RELEASE_TAG^{commit}")"
|
|
196
191
|
test "$(git rev-parse HEAD)" = "$RELEASE_SHA"
|
|
197
|
-
git
|
|
192
|
+
test "$(git rev-parse "origin/${releaseBranch}")" = "$RELEASE_SHA"
|
|
198
193
|
test "$(tr -d '\\r\\n' < VERSION)" = "$RELEASE_VERSION"
|
|
199
|
-
test "$(gh release view "$RELEASE_TAG" --json isDraft --jq .isDraft)" = "false"
|
|
200
|
-
rm -rf dist/release-candidate
|
|
201
|
-
mkdir -p dist/release-candidate
|
|
202
|
-
gh release download "$RELEASE_TAG" --dir dist/release-candidate
|
|
203
|
-
bun node_modules/@dbx-tools/projen/tasks/release-manifest.ts verify \
|
|
204
|
-
--directory dist/release-candidate \
|
|
205
|
-
--tag "$RELEASE_TAG" \
|
|
206
|
-
--sha "$RELEASE_SHA" \
|
|
207
|
-
--version "$RELEASE_VERSION"
|
|
208
194
|
echo "release_tag=$RELEASE_TAG" >> "$GITHUB_OUTPUT"
|
|
209
195
|
echo "expected_sha=$RELEASE_SHA" >> "$GITHUB_OUTPUT"
|
|
210
196
|
echo "release_version=$RELEASE_VERSION" >> "$GITHUB_OUTPUT"
|
|
@@ -212,6 +198,10 @@ function verifyContextJob(tagPrefix: string, releaseBranch: string): Job {
|
|
|
212
198
|
// ============================================================================
|
|
213
199
|
),
|
|
214
200
|
},
|
|
201
|
+
...(options.validationTasks ?? []).map((task) => ({
|
|
202
|
+
name: `Validate ${task}`,
|
|
203
|
+
run: `bun run ${task}`,
|
|
204
|
+
})),
|
|
215
205
|
],
|
|
216
206
|
};
|
|
217
207
|
}
|
|
@@ -227,26 +217,9 @@ function nodePublishJob(project: DBXToolsJavaScriptProject): Job {
|
|
|
227
217
|
steps: [
|
|
228
218
|
...nodeReleaseSetupSteps(project),
|
|
229
219
|
{
|
|
230
|
-
name: "
|
|
231
|
-
env: { GH_TOKEN: "${{ github.token }}", RELEASE_SHA, RELEASE_TAG, RELEASE_VERSION },
|
|
232
|
-
shell: "bash",
|
|
233
|
-
run: [
|
|
234
|
-
"rm -rf dist/release-download dist/npm-release",
|
|
235
|
-
"mkdir -p dist/release-download",
|
|
236
|
-
'gh release download "$RELEASE_TAG" --pattern release-manifest.json --pattern SHA256SUMS --pattern "*.tgz" --dir dist/release-download',
|
|
237
|
-
"bun node_modules/@dbx-tools/projen/tasks/release-manifest.ts verify \\",
|
|
238
|
-
" --directory dist/release-download \\",
|
|
239
|
-
' --tag "$RELEASE_TAG" \\',
|
|
240
|
-
' --sha "$RELEASE_SHA" \\',
|
|
241
|
-
' --version "$RELEASE_VERSION" \\',
|
|
242
|
-
" --kind npm \\",
|
|
243
|
-
" --output dist/npm-release",
|
|
244
|
-
].join("\n"),
|
|
245
|
-
},
|
|
246
|
-
{
|
|
247
|
-
name: "Publish approved npm archives",
|
|
220
|
+
name: "Publish npm workspace",
|
|
248
221
|
env: { RELEASE_VERSION, ...npmPublishEnvironment() },
|
|
249
|
-
run: 'bun node_modules/@dbx-tools/projen/tasks/publish
|
|
222
|
+
run: 'bun node_modules/@dbx-tools/projen/tasks/publish.ts "$RELEASE_VERSION" $DRY_RUN',
|
|
250
223
|
},
|
|
251
224
|
],
|
|
252
225
|
};
|
|
@@ -303,6 +276,7 @@ function addDocsJobs(
|
|
|
303
276
|
},
|
|
304
277
|
],
|
|
305
278
|
});
|
|
279
|
+
refreshDocsRegistryDependencies(workflow);
|
|
306
280
|
}
|
|
307
281
|
|
|
308
282
|
/** Owns the single release workflow and local release preparation tasks. */
|
|
@@ -311,18 +285,11 @@ export class DBXToolsRelease extends Component {
|
|
|
311
285
|
super(project);
|
|
312
286
|
const tagPrefix = options.tagPrefix ?? "v";
|
|
313
287
|
const releaseBranch = projectReleaseBranch(project);
|
|
314
|
-
const summary = options.summary ?? true;
|
|
315
|
-
const summaryArgs =
|
|
316
|
-
summary === false || (typeof summary === "object" && summary.providers?.length === 0)
|
|
317
|
-
? ["--no-release-summary"]
|
|
318
|
-
: typeof summary === "object" && summary.providers
|
|
319
|
-
? [`--release-summary-providers ${summary.providers.join(",")}`]
|
|
320
|
-
: [];
|
|
321
288
|
releaseTagPrefixes.set(project, tagPrefix);
|
|
322
289
|
if (options.nodeRelease !== false) nodeReleaseProjects.add(project);
|
|
323
290
|
applyTasks(project, {
|
|
324
291
|
bump: {
|
|
325
|
-
exec: taskScript(project, "bump.ts"
|
|
292
|
+
exec: taskScript(project, "bump.ts"),
|
|
326
293
|
receiveArgs: true,
|
|
327
294
|
description: "Increment VERSION and synchronize generated workspace versions",
|
|
328
295
|
},
|
|
@@ -335,33 +302,11 @@ export class DBXToolsRelease extends Component {
|
|
|
335
302
|
release: {
|
|
336
303
|
exec: taskScript(
|
|
337
304
|
project,
|
|
338
|
-
"release
|
|
339
|
-
|
|
340
|
-
`--prefix ${tagPrefix}`,
|
|
341
|
-
`--base ${releaseBranch}`,
|
|
342
|
-
...(options.pythonRoot
|
|
343
|
-
? [`--python-root ${JSON.stringify(options.pythonRoot)}`]
|
|
344
|
-
: []),
|
|
345
|
-
...(options.validationTasks ?? []).map(
|
|
346
|
-
(task) => `--validate-task ${JSON.stringify(task)}`,
|
|
347
|
-
),
|
|
348
|
-
...summaryArgs,
|
|
349
|
-
].join(" "),
|
|
350
|
-
),
|
|
351
|
-
receiveArgs: true,
|
|
352
|
-
description:
|
|
353
|
-
"Prepare, validate, locally publish, and upload a draft release candidate",
|
|
354
|
-
},
|
|
355
|
-
"release:assets": {
|
|
356
|
-
exec: taskScript(
|
|
357
|
-
project,
|
|
358
|
-
"release-candidate.ts",
|
|
359
|
-
options.pythonRoot
|
|
360
|
-
? `--python-root ${JSON.stringify(options.pythonRoot)}`
|
|
361
|
-
: undefined,
|
|
305
|
+
"release.ts",
|
|
306
|
+
`--prefix ${tagPrefix} --branch ${releaseBranch}`,
|
|
362
307
|
),
|
|
363
308
|
receiveArgs: true,
|
|
364
|
-
description: "
|
|
309
|
+
description: "Run bump, commit it, and push an annotated release tag",
|
|
365
310
|
},
|
|
366
311
|
}
|
|
367
312
|
: {}),
|
|
@@ -372,49 +317,22 @@ export class DBXToolsRelease extends Component {
|
|
|
372
317
|
fileName: "release.yml",
|
|
373
318
|
limitConcurrency: true,
|
|
374
319
|
concurrencyOptions: {
|
|
375
|
-
group:
|
|
376
|
-
"release-${{ github.event_name == 'release' && github.event.release.tag_name || inputs.release_tag }}",
|
|
320
|
+
group: "release-${{ github.ref_name }}",
|
|
377
321
|
cancelInProgress: false,
|
|
378
322
|
},
|
|
379
323
|
});
|
|
380
|
-
|
|
381
|
-
workflow.runName =
|
|
382
|
-
`release ${version} ` +
|
|
383
|
-
"${{ github.event_name == 'release' && github.event.release.tag_name || inputs.release_tag }}";
|
|
324
|
+
releaseWorkflows.set(project, workflow);
|
|
325
|
+
workflow.runName = "release ${{ github.ref_name }}";
|
|
384
326
|
workflow.on({
|
|
385
|
-
|
|
386
|
-
workflowDispatch: {
|
|
387
|
-
inputs: {
|
|
388
|
-
release_tag: {
|
|
389
|
-
description: "Annotated release tag to validate",
|
|
390
|
-
type: "string",
|
|
391
|
-
required: true,
|
|
392
|
-
},
|
|
393
|
-
stage: {
|
|
394
|
-
description: "Published release stage to validate or recover",
|
|
395
|
-
type: "choice",
|
|
396
|
-
options: ["all", "node", "python", "cargo", "docs"],
|
|
397
|
-
default: "all",
|
|
398
|
-
required: true,
|
|
399
|
-
},
|
|
400
|
-
dry_run: {
|
|
401
|
-
description: "Build and validate without publishing",
|
|
402
|
-
type: "boolean",
|
|
403
|
-
default: "true",
|
|
404
|
-
required: true,
|
|
405
|
-
},
|
|
406
|
-
},
|
|
407
|
-
},
|
|
327
|
+
push: { tags: [`${tagPrefix}*`] },
|
|
408
328
|
});
|
|
409
329
|
workflow.file?.addOverride("permissions.contents", "read");
|
|
410
|
-
workflow.
|
|
411
|
-
workflow.addJob("verify-context", verifyContextJob(tagPrefix, releaseBranch));
|
|
330
|
+
workflow.addJob("verify-context", verifyContextJob(project, tagPrefix, releaseBranch, options));
|
|
412
331
|
if (options.nodeRelease !== false) {
|
|
413
332
|
workflow.addJob("publish-node", nodePublishJob(project));
|
|
414
333
|
}
|
|
415
334
|
if (options.docs) {
|
|
416
335
|
addDocsJobs(workflow, project, options.docs);
|
|
417
336
|
}
|
|
418
|
-
releaseWorkflows.set(project, workflow);
|
|
419
337
|
}
|
|
420
338
|
}
|
package/tasks/bump.ts
CHANGED
|
@@ -6,43 +6,34 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as projectUtils from "@dbx-tools/core/project-utils";
|
|
8
8
|
import { log } from "@dbx-tools/shared-core";
|
|
9
|
-
import { Command } from "commander";
|
|
9
|
+
import { Command, Option } from "commander";
|
|
10
|
+
import { runTaskCommand } from "../src/_task-command.ts";
|
|
10
11
|
import {
|
|
11
|
-
|
|
12
|
-
releaseLevelOption,
|
|
13
|
-
releaseOperatingSystemOption,
|
|
14
|
-
releasePlatformFilter,
|
|
15
|
-
type ReleaseArch,
|
|
16
|
-
type ReleaseOs,
|
|
12
|
+
resolveNextVersion,
|
|
17
13
|
type VersionLevel,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
import { resolveNextVersion, writeWorkspaceVersion } from "../src/workspace-version.ts";
|
|
14
|
+
writeWorkspaceVersion,
|
|
15
|
+
} from "../src/workspace-version.ts";
|
|
21
16
|
|
|
22
17
|
const logger = log.logger("projen:bump");
|
|
23
18
|
|
|
24
19
|
const program = new Command();
|
|
25
20
|
program
|
|
26
21
|
.description("Increment VERSION and synchronize generated workspace versions")
|
|
27
|
-
.addOption(
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
.addOption(
|
|
23
|
+
new Option("-l, --level <level>", "semver increment")
|
|
24
|
+
.choices(["patch", "minor", "major"])
|
|
25
|
+
.default("patch"),
|
|
26
|
+
)
|
|
30
27
|
.option("--no-synth", "write VERSION without synchronizing generated files")
|
|
31
|
-
.action((opts: { level: VersionLevel;
|
|
28
|
+
.action((opts: { level: VersionLevel; synth: boolean }) => {
|
|
32
29
|
const root = projectUtils.root() ?? process.cwd();
|
|
33
30
|
const next = resolveNextVersion(root, opts.level);
|
|
34
|
-
const releasePlatforms = releasePlatformFilter(opts.os, opts.arch);
|
|
35
31
|
|
|
36
32
|
logger.info(`bump ${next.base} -> ${next.version} (${opts.level})`);
|
|
37
33
|
writeWorkspaceVersion(root, next.version);
|
|
38
34
|
|
|
39
35
|
if (opts.synth) {
|
|
40
|
-
runTaskCommand(root, process.execPath, [".projenrc.ts"]
|
|
41
|
-
env: {
|
|
42
|
-
...process.env,
|
|
43
|
-
...(releasePlatforms ? { DBX_TOOLS_RELEASE_PLATFORMS: releasePlatforms } : {}),
|
|
44
|
-
},
|
|
45
|
-
});
|
|
36
|
+
runTaskCommand(root, process.execPath, [".projenrc.ts"]);
|
|
46
37
|
}
|
|
47
38
|
logger.success(`workspace version synchronized at ${next.version}`);
|
|
48
39
|
});
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env -S bun
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
import { parseArgs } from "node:util";
|
|
5
|
+
|
|
6
|
+
import * as projectUtils from "@dbx-tools/core/project-utils";
|
|
7
|
+
|
|
8
|
+
import { makeReadonly, makeWritable } from "../src/generated.ts";
|
|
9
|
+
|
|
10
|
+
const MINIMUM_VERSION = "0.296.0";
|
|
11
|
+
const REPOSITORY = "databricks/cli";
|
|
12
|
+
const PLATFORM_ASSETS = {
|
|
13
|
+
"darwin-arm64": "darwin_arm64",
|
|
14
|
+
"darwin-x64": "darwin_amd64",
|
|
15
|
+
"linux-arm64": "linux_arm64",
|
|
16
|
+
"linux-x64": "linux_amd64",
|
|
17
|
+
"win32-arm64": "windows_arm64",
|
|
18
|
+
"win32-x64": "windows_amd64",
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
21
|
+
interface GitHubAsset {
|
|
22
|
+
readonly browser_download_url: string;
|
|
23
|
+
readonly digest?: string;
|
|
24
|
+
readonly name: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface GitHubRelease {
|
|
28
|
+
readonly assets: GitHubAsset[];
|
|
29
|
+
readonly published_at: string;
|
|
30
|
+
readonly tag_name: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface CliAsset {
|
|
34
|
+
readonly sha256: string;
|
|
35
|
+
readonly url: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface CliAssetManifest {
|
|
39
|
+
readonly schemaVersion: 1;
|
|
40
|
+
readonly dbxToolsVersion: string;
|
|
41
|
+
readonly minimumVersion: string;
|
|
42
|
+
readonly version: string;
|
|
43
|
+
readonly publishedAt: string;
|
|
44
|
+
readonly assets: Record<keyof typeof PLATFORM_ASSETS, CliAsset>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function validManifest(value: unknown, dbxToolsVersion: string): value is CliAssetManifest {
|
|
48
|
+
if (!value || typeof value !== "object") return false;
|
|
49
|
+
const manifest = value as Partial<CliAssetManifest>;
|
|
50
|
+
return (
|
|
51
|
+
manifest.schemaVersion === 1 &&
|
|
52
|
+
manifest.dbxToolsVersion === dbxToolsVersion &&
|
|
53
|
+
manifest.minimumVersion === MINIMUM_VERSION &&
|
|
54
|
+
typeof manifest.version === "string" &&
|
|
55
|
+
typeof manifest.publishedAt === "string" &&
|
|
56
|
+
Boolean(manifest.assets) &&
|
|
57
|
+
Object.keys(PLATFORM_ASSETS).every((key) => {
|
|
58
|
+
const asset = manifest.assets?.[key as keyof typeof PLATFORM_ASSETS];
|
|
59
|
+
return (
|
|
60
|
+
typeof asset?.url === "string" &&
|
|
61
|
+
typeof asset.sha256 === "string" &&
|
|
62
|
+
/^[0-9a-f]{64}$/.test(asset.sha256)
|
|
63
|
+
);
|
|
64
|
+
})
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function latestManifest(dbxToolsVersion: string): Promise<CliAssetManifest> {
|
|
69
|
+
const response = await fetch(`https://api.github.com/repos/${REPOSITORY}/releases/latest`, {
|
|
70
|
+
headers: {
|
|
71
|
+
accept: "application/vnd.github+json",
|
|
72
|
+
"user-agent": `dbx-tools/${dbxToolsVersion}`,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
throw new Error(`Could not resolve the latest Databricks CLI release (${response.status})`);
|
|
77
|
+
}
|
|
78
|
+
const release = (await response.json()) as GitHubRelease;
|
|
79
|
+
const version = release.tag_name.replace(/^v/, "");
|
|
80
|
+
const assets = Object.fromEntries(
|
|
81
|
+
Object.entries(PLATFORM_ASSETS).map(([platform, suffix]) => {
|
|
82
|
+
const name = `databricks_cli_${version}_${suffix}.tar.gz`;
|
|
83
|
+
const asset = release.assets.find((candidate) => candidate.name === name);
|
|
84
|
+
const sha256 = asset?.digest?.match(/^sha256:([0-9a-f]{64})$/i)?.[1]?.toLowerCase();
|
|
85
|
+
if (!asset || !sha256)
|
|
86
|
+
throw new Error(`Release ${release.tag_name} has no digest for ${name}`);
|
|
87
|
+
return [platform, { url: asset.browser_download_url, sha256 }];
|
|
88
|
+
}),
|
|
89
|
+
) as CliAssetManifest["assets"];
|
|
90
|
+
return {
|
|
91
|
+
schemaVersion: 1,
|
|
92
|
+
dbxToolsVersion,
|
|
93
|
+
minimumVersion: MINIMUM_VERSION,
|
|
94
|
+
version,
|
|
95
|
+
publishedAt: release.published_at,
|
|
96
|
+
assets,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const { values } = parseArgs({
|
|
101
|
+
options: {
|
|
102
|
+
check: { type: "boolean", default: false },
|
|
103
|
+
root: { type: "string" },
|
|
104
|
+
},
|
|
105
|
+
strict: true,
|
|
106
|
+
});
|
|
107
|
+
const root = resolve(values.root ?? projectUtils.root() ?? process.cwd());
|
|
108
|
+
const output = join(root, "packages/js/node/auth/src/generated/databricks-cli-assets.json");
|
|
109
|
+
const dbxToolsVersion = readFileSync(join(root, "VERSION"), "utf8").trim();
|
|
110
|
+
let current: unknown;
|
|
111
|
+
if (existsSync(output)) {
|
|
112
|
+
try {
|
|
113
|
+
current = JSON.parse(readFileSync(output, "utf8"));
|
|
114
|
+
} catch {
|
|
115
|
+
current = undefined;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (validManifest(current, dbxToolsVersion)) {
|
|
119
|
+
console.log(`verified ${output.slice(root.length + 1)}`);
|
|
120
|
+
} else if (values.check) {
|
|
121
|
+
throw new Error("Databricks CLI asset manifest is missing or stale");
|
|
122
|
+
} else {
|
|
123
|
+
const manifest = await latestManifest(dbxToolsVersion);
|
|
124
|
+
mkdirSync(dirname(output), { recursive: true });
|
|
125
|
+
makeWritable(output);
|
|
126
|
+
writeFileSync(output, `${JSON.stringify(manifest, undefined, 2)}\n`);
|
|
127
|
+
makeReadonly(output);
|
|
128
|
+
console.log(`generated ${output.slice(root.length + 1)}`);
|
|
129
|
+
}
|