@dbx-tools/projen 0.9.17 → 0.9.19
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 +39 -36
- package/index.ts +2 -2
- package/package.json +4 -5
- package/src/_release-platform.ts +10 -0
- package/src/_rust-project.ts +3 -0
- package/src/_rust-release-workflow.ts +117 -528
- package/src/project-js.ts +8 -13
- package/src/project-py.ts +62 -54
- package/src/project-rs.ts +7 -37
- package/src/release-github.ts +23 -0
- package/src/release-plan.ts +32 -40
- package/src/release.ts +91 -135
- package/tasks/compile-workspace.ts +121 -0
- package/tasks/publish-npm.ts +63 -11
- package/tasks/publish-python.ts +101 -26
- package/tasks/publish.ts +22 -3
- package/tasks/release-assets.ts +476 -0
- package/tasks/release-candidate.ts +383 -0
- package/tasks/release-manifest.ts +273 -0
- package/tasks/release-plan.ts +1 -2
- package/tasks/release-pr.ts +86 -60
- package/tasks/uniffi-python.js +24 -12
- package/tasks/uniffi-release.mjs +35 -2
- package/src/_rust-release.ts +0 -633
- package/tasks/build-rust-release.ts +0 -68
- package/tasks/rust-release.d.ts +0 -45
- package/tasks/rust-release.mjs +0 -1726
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/** Rust release planning and generated GitHub workflow jobs. */
|
|
2
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
|
-
import { dirname, join,
|
|
4
|
+
import { dirname, join, resolve } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { stringUtils } from "@dbx-tools/shared-core";
|
|
7
7
|
import { TextFile, javascript } from "projen";
|
|
8
8
|
import { JobPermission, type Job, type JobStep } from "projen/lib/github/workflows-model";
|
|
9
|
+
import { releaseBinaryAssetName } from "./_release-platform.ts";
|
|
9
10
|
import { UNIFFI_BINDGEN_FEATURE, type RustProject } from "./_rust-project.ts";
|
|
10
11
|
import { BUN_VERSION } from "./bun-workflow.ts";
|
|
11
12
|
import type { DBXToolsJavaScriptProject } from "./project-js.ts";
|
|
@@ -16,48 +17,22 @@ import type {
|
|
|
16
17
|
UniFFIReleaseTarget,
|
|
17
18
|
} from "./project-rs.ts";
|
|
18
19
|
import { defaultReleaseUnitId } from "./release-catalog.ts";
|
|
19
|
-
import {
|
|
20
|
-
RELEASE_SHA,
|
|
21
|
-
RELEASE_SUMMARY_FILE,
|
|
22
|
-
RELEASE_TAG,
|
|
23
|
-
RELEASE_VERSION,
|
|
24
|
-
releaseSourceSteps,
|
|
25
|
-
} from "./release-dispatch.ts";
|
|
20
|
+
import { RELEASE_VERSION, releaseSourceSteps } from "./release-dispatch.ts";
|
|
26
21
|
import {
|
|
27
22
|
independentReleaseSetupSteps,
|
|
28
23
|
npmPublishEnvironment,
|
|
29
|
-
|
|
30
|
-
releaseArtifactSteps,
|
|
31
|
-
releaseStageCondition,
|
|
24
|
+
releasePublishCondition,
|
|
32
25
|
} from "./release.ts";
|
|
33
26
|
|
|
34
27
|
const require = createRequire(import.meta.url);
|
|
35
28
|
|
|
36
29
|
type RustPackageDependencyResolver = (pkg: RustProject) => RustProject[];
|
|
37
30
|
|
|
38
|
-
const
|
|
31
|
+
const RUST_BUILD_ENV = {
|
|
39
32
|
CARGO_INCREMENTAL: "0",
|
|
40
33
|
CARGO_TERM_COLOR: "always",
|
|
41
34
|
} as const;
|
|
42
35
|
|
|
43
|
-
function rustCacheSteps(sharedKey: string): readonly JobStep[] {
|
|
44
|
-
return [
|
|
45
|
-
{
|
|
46
|
-
name: "Cache Cargo registry and dependencies",
|
|
47
|
-
id: "cargo_cache",
|
|
48
|
-
uses: "Swatinem/rust-cache@v2.9.2",
|
|
49
|
-
with: {
|
|
50
|
-
"cache-targets": true,
|
|
51
|
-
"cache-workspace-crates": true,
|
|
52
|
-
"add-job-id-key": false,
|
|
53
|
-
"add-rust-environment-hash-key": true,
|
|
54
|
-
"shared-key": sharedKey,
|
|
55
|
-
"save-if": "${{ github.event_name == 'push' }}",
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
];
|
|
59
|
-
}
|
|
60
|
-
|
|
61
36
|
function timedBash(phase: string, command: string): string {
|
|
62
37
|
return [
|
|
63
38
|
"SECONDS=0",
|
|
@@ -66,15 +41,6 @@ function timedBash(phase: string, command: string): string {
|
|
|
66
41
|
].join("\n");
|
|
67
42
|
}
|
|
68
43
|
|
|
69
|
-
export function releaseBinaryAssetName(
|
|
70
|
-
binaryName: string,
|
|
71
|
-
nodeTarget: string,
|
|
72
|
-
os: RustReleaseOs | "darwin" | "linux" | "win32",
|
|
73
|
-
): string {
|
|
74
|
-
const extension = os === "win32" ? "zip" : "tar.gz";
|
|
75
|
-
return `${binaryName}-${nodeTarget}.${extension}`;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
44
|
function taskSource(name: string): string {
|
|
79
45
|
const sourceDirectory = dirname(fileURLToPath(import.meta.url));
|
|
80
46
|
const candidates = [
|
|
@@ -117,21 +83,21 @@ export function orderRustBindings(bindings: readonly RustBindingMapping[]): Rust
|
|
|
117
83
|
return ordered;
|
|
118
84
|
}
|
|
119
85
|
|
|
120
|
-
interface RustReleaseBinding extends RustBindingMapping {
|
|
86
|
+
export interface RustReleaseBinding extends RustBindingMapping {
|
|
121
87
|
readonly node: string;
|
|
122
88
|
readonly python: string;
|
|
123
89
|
readonly nodePackage: string;
|
|
124
90
|
readonly pythonPackage: string;
|
|
125
91
|
}
|
|
126
92
|
|
|
127
|
-
interface RustReleaseBinaryPlan {
|
|
93
|
+
export interface RustReleaseBinaryPlan {
|
|
128
94
|
readonly crate: string;
|
|
129
95
|
readonly binary: string;
|
|
130
96
|
readonly excludedOs: readonly RustReleaseOs[];
|
|
131
97
|
readonly requiredFeatures: readonly string[];
|
|
132
98
|
}
|
|
133
99
|
|
|
134
|
-
interface RustReleaseTargetPlan {
|
|
100
|
+
export interface RustReleaseTargetPlan {
|
|
135
101
|
readonly runner: string;
|
|
136
102
|
readonly cargo: string;
|
|
137
103
|
readonly node: string;
|
|
@@ -139,56 +105,42 @@ interface RustReleaseTargetPlan {
|
|
|
139
105
|
readonly os: RustReleaseOs;
|
|
140
106
|
readonly cpu: string;
|
|
141
107
|
readonly libc: string;
|
|
108
|
+
readonly glibcVersion: string;
|
|
142
109
|
readonly packages: readonly string[];
|
|
143
|
-
readonly sources: readonly string[];
|
|
144
110
|
readonly binaries: readonly string[];
|
|
145
111
|
readonly features: readonly string[];
|
|
146
|
-
readonly
|
|
112
|
+
readonly localFeatures: readonly string[];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Generated release inputs shared by GitHub-hosted and local target builds. */
|
|
116
|
+
export interface RustReleaseConfiguration {
|
|
117
|
+
readonly releaseRustVersion: string;
|
|
118
|
+
readonly usesCargoLock: boolean;
|
|
119
|
+
readonly bindings: readonly RustReleaseBinding[];
|
|
120
|
+
readonly binaries: readonly RustReleaseBinaryPlan[];
|
|
121
|
+
readonly targets: readonly RustReleaseTargetPlan[];
|
|
147
122
|
}
|
|
148
123
|
|
|
149
124
|
export interface RustReleasePlan {
|
|
150
125
|
readonly releaseRustVersion: string;
|
|
151
126
|
readonly releaseTask: string;
|
|
152
|
-
readonly releaseHelper: string;
|
|
153
127
|
readonly bindings: readonly RustReleaseBinding[];
|
|
154
128
|
readonly nodeBindings: readonly RustReleaseBinding[];
|
|
155
129
|
readonly releaseBinaries: readonly RustReleaseBinaryPlan[];
|
|
156
130
|
readonly publicCrates: readonly string[];
|
|
157
|
-
readonly
|
|
158
|
-
readonly binaryTargets: readonly RustReleaseTargetPlan[];
|
|
131
|
+
readonly targets: readonly RustReleaseTargetPlan[];
|
|
159
132
|
readonly hasPythonBindings: boolean;
|
|
160
133
|
readonly usesCargoLock: boolean;
|
|
161
134
|
readonly usePreinstalledWindowsRust: boolean;
|
|
162
135
|
readonly hasTargetOutputs: boolean;
|
|
163
136
|
}
|
|
164
137
|
|
|
165
|
-
function packageClosure(
|
|
166
|
-
roots: readonly RustProject[],
|
|
167
|
-
packageDependencies: RustPackageDependencyResolver,
|
|
168
|
-
): RustProject[] {
|
|
169
|
-
const found = new Set<RustProject>();
|
|
170
|
-
const visit = (pkg: RustProject): void => {
|
|
171
|
-
if (found.has(pkg)) return;
|
|
172
|
-
found.add(pkg);
|
|
173
|
-
for (const dependency of packageDependencies(pkg)) visit(dependency);
|
|
174
|
-
};
|
|
175
|
-
for (const pkg of roots) visit(pkg);
|
|
176
|
-
return [...found].sort((left, right) => left.crateName.localeCompare(right.crateName));
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function packageSources(
|
|
180
|
-
project: javascript.NodeProject,
|
|
181
|
-
packages: readonly RustProject[],
|
|
182
|
-
): string[] {
|
|
183
|
-
return packages.map((pkg) => relative(project.outdir, pkg.outdir).replaceAll("\\", "/")).sort();
|
|
184
|
-
}
|
|
185
|
-
|
|
186
138
|
function releaseTargetPlan(
|
|
187
139
|
target: UniFFIReleaseTarget,
|
|
188
140
|
packages: readonly RustProject[],
|
|
189
|
-
sources: readonly string[],
|
|
190
141
|
binaries: readonly string[],
|
|
191
142
|
features: readonly string[],
|
|
143
|
+
localFeatures: readonly string[],
|
|
192
144
|
): RustReleaseTargetPlan {
|
|
193
145
|
const packageNames = packages.map((pkg) => pkg.crateName).sort();
|
|
194
146
|
const sortedBinaries = [...new Set(binaries)].sort();
|
|
@@ -201,15 +153,11 @@ function releaseTargetPlan(
|
|
|
201
153
|
os: target.os,
|
|
202
154
|
cpu: target.cpu,
|
|
203
155
|
libc: target.libc ?? "",
|
|
156
|
+
glibcVersion: target.glibcVersion ?? "",
|
|
204
157
|
packages: packageNames,
|
|
205
|
-
sources,
|
|
206
158
|
binaries: sortedBinaries,
|
|
207
159
|
features: sortedFeatures,
|
|
208
|
-
|
|
209
|
-
packages: packageNames,
|
|
210
|
-
binaries: sortedBinaries,
|
|
211
|
-
features: sortedFeatures,
|
|
212
|
-
}),
|
|
160
|
+
localFeatures: [...new Set(localFeatures)].sort(),
|
|
213
161
|
};
|
|
214
162
|
}
|
|
215
163
|
|
|
@@ -261,55 +209,48 @@ export function planRustRelease(
|
|
|
261
209
|
const bindingPackages = packages.filter((pkg) =>
|
|
262
210
|
bindings.some((binding) => binding.crate === pkg.crateName),
|
|
263
211
|
);
|
|
264
|
-
const
|
|
265
|
-
const bindingSources = packageSources(project, bindingClosure);
|
|
266
|
-
const uniffiTargets = bindings.length
|
|
267
|
-
? targets.map((target) =>
|
|
268
|
-
releaseTargetPlan(
|
|
269
|
-
target,
|
|
270
|
-
bindingPackages,
|
|
271
|
-
bindingSources,
|
|
272
|
-
[],
|
|
273
|
-
bindingPackages.map((pkg) => `${pkg.crateName}/${UNIFFI_BINDGEN_FEATURE}`),
|
|
274
|
-
),
|
|
275
|
-
)
|
|
276
|
-
: [];
|
|
277
|
-
const binaryTargets = targets.flatMap((target) => {
|
|
212
|
+
const releaseTargets = targets.flatMap((target) => {
|
|
278
213
|
const selectedBinaries = releaseBinaries.filter(
|
|
279
214
|
(binary) => !binary.excludedOs.includes(target.os),
|
|
280
215
|
);
|
|
281
216
|
const binaryPackages = packages.filter((pkg) =>
|
|
282
217
|
selectedBinaries.some((binary) => binary.crate === pkg.crateName),
|
|
283
218
|
);
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
const features =
|
|
287
|
-
|
|
219
|
+
const selectedPackages = [...new Set([...bindingPackages, ...binaryPackages])];
|
|
220
|
+
if (!selectedPackages.length) return [];
|
|
221
|
+
const features = [
|
|
222
|
+
...bindingPackages.map((pkg) => `${pkg.crateName}/${UNIFFI_BINDGEN_FEATURE}`),
|
|
223
|
+
...selectedBinaries.flatMap((binary) =>
|
|
224
|
+
binary.requiredFeatures.map((feature) => `${binary.crate}/${feature}`),
|
|
225
|
+
),
|
|
226
|
+
];
|
|
227
|
+
const localFeatures = selectedPackages.flatMap((pkg) =>
|
|
228
|
+
(pkg.packageOptions.releaseLocalFeatures ?? []).map(
|
|
229
|
+
(feature) => `${pkg.crateName}/${feature}`,
|
|
230
|
+
),
|
|
288
231
|
);
|
|
289
232
|
return [
|
|
290
233
|
releaseTargetPlan(
|
|
291
234
|
target,
|
|
292
|
-
|
|
293
|
-
packageSources(project, binaryClosure),
|
|
235
|
+
selectedPackages,
|
|
294
236
|
selectedBinaries.map((binary) => binary.binary),
|
|
295
237
|
features,
|
|
238
|
+
localFeatures,
|
|
296
239
|
),
|
|
297
240
|
];
|
|
298
241
|
});
|
|
299
|
-
const hasTargetOutputs =
|
|
242
|
+
const hasTargetOutputs = releaseTargets.length > 0;
|
|
300
243
|
if (hasTargetOutputs && targets.length === 0) {
|
|
301
244
|
throw new Error("Rust release requires at least one target");
|
|
302
245
|
}
|
|
303
246
|
return {
|
|
304
247
|
releaseRustVersion,
|
|
305
248
|
releaseTask: ".projen/uniffi-release.mjs",
|
|
306
|
-
releaseHelper: ".projen/rust-release.mjs",
|
|
307
249
|
bindings,
|
|
308
250
|
nodeBindings: bindings.filter((binding) => Boolean(binding.node && binding.nodePackage)),
|
|
309
251
|
releaseBinaries,
|
|
310
252
|
publicCrates,
|
|
311
|
-
|
|
312
|
-
binaryTargets,
|
|
253
|
+
targets: releaseTargets,
|
|
313
254
|
hasPythonBindings: bindings.some((binding) => binding.python),
|
|
314
255
|
usesCargoLock: existsSync(join(project.outdir, "Cargo.lock")),
|
|
315
256
|
usePreinstalledWindowsRust: releaseRustVersion === "stable",
|
|
@@ -318,10 +259,7 @@ export function planRustRelease(
|
|
|
318
259
|
}
|
|
319
260
|
|
|
320
261
|
function rustBuildJobIds(plan: RustReleasePlan): string[] {
|
|
321
|
-
return [
|
|
322
|
-
...(plan.uniffiTargets.length ? ["rust-uniffi"] : []),
|
|
323
|
-
...(plan.binaryTargets.length ? ["rust-binaries"] : []),
|
|
324
|
-
];
|
|
262
|
+
return plan.targets.length ? ["rust-build"] : [];
|
|
325
263
|
}
|
|
326
264
|
|
|
327
265
|
function rustBuildResultCondition(plan: RustReleasePlan): string {
|
|
@@ -334,15 +272,25 @@ export function configureRustReleaseTask(
|
|
|
334
272
|
project: javascript.NodeProject,
|
|
335
273
|
plan: RustReleasePlan,
|
|
336
274
|
): void {
|
|
275
|
+
new TextFile(project, ".projen/rust-release.json", {
|
|
276
|
+
lines: JSON.stringify(
|
|
277
|
+
{
|
|
278
|
+
releaseRustVersion: plan.releaseRustVersion,
|
|
279
|
+
usesCargoLock: plan.usesCargoLock,
|
|
280
|
+
bindings: plan.bindings,
|
|
281
|
+
binaries: plan.releaseBinaries,
|
|
282
|
+
targets: plan.targets,
|
|
283
|
+
} satisfies RustReleaseConfiguration,
|
|
284
|
+
null,
|
|
285
|
+
2,
|
|
286
|
+
).split("\n"),
|
|
287
|
+
});
|
|
337
288
|
const bindingSupportFiles = [
|
|
338
289
|
plan.releaseTask,
|
|
339
290
|
".projen/uniffi-python.js",
|
|
340
291
|
".projen/smol-toml.cjs",
|
|
341
292
|
".projen/smol-toml.LICENSE",
|
|
342
293
|
] as const;
|
|
343
|
-
new TextFile(project, plan.releaseHelper, {
|
|
344
|
-
lines: taskSource("rust-release.mjs").trimEnd().split("\n"),
|
|
345
|
-
});
|
|
346
294
|
if (plan.bindings.length) {
|
|
347
295
|
new TextFile(project, plan.releaseTask, {
|
|
348
296
|
lines: taskSource("uniffi-release.mjs").trimEnd().split("\n"),
|
|
@@ -359,31 +307,7 @@ export function configureRustReleaseTask(
|
|
|
359
307
|
} else {
|
|
360
308
|
for (const path of bindingSupportFiles) project.tryRemoveFile(path);
|
|
361
309
|
}
|
|
362
|
-
|
|
363
|
-
description: "Write the version-independent Rust release build manifest",
|
|
364
|
-
});
|
|
365
|
-
for (const [namespace, targets] of [
|
|
366
|
-
["uniffi", plan.uniffiTargets],
|
|
367
|
-
["binaries", plan.binaryTargets],
|
|
368
|
-
] as const) {
|
|
369
|
-
if (!targets.length) continue;
|
|
370
|
-
const sources = [...new Set(targets.flatMap((target) => target.sources))].sort();
|
|
371
|
-
fingerprintTask.exec(
|
|
372
|
-
[
|
|
373
|
-
`node ${plan.releaseHelper} fingerprint`,
|
|
374
|
-
"--root .",
|
|
375
|
-
`--output ${JSON.stringify(`.release/rust-${namespace}.json`)}`,
|
|
376
|
-
`--namespace ${JSON.stringify(namespace)}`,
|
|
377
|
-
...targets.map(
|
|
378
|
-
(target) => `--target ${JSON.stringify(`${target.cargo}|${target.fingerprintConfig}`)}`,
|
|
379
|
-
),
|
|
380
|
-
`--toolchain ${JSON.stringify(plan.releaseRustVersion)}`,
|
|
381
|
-
...sources.map((source) => `--source ${JSON.stringify(source)}`),
|
|
382
|
-
"--source-only",
|
|
383
|
-
"--portable",
|
|
384
|
-
].join(" "),
|
|
385
|
-
);
|
|
386
|
-
}
|
|
310
|
+
project.tryRemoveFile(".projen/rust-release.mjs");
|
|
387
311
|
}
|
|
388
312
|
|
|
389
313
|
function rustBindingCommands(plan: RustReleasePlan, independent: boolean): string[] {
|
|
@@ -458,42 +382,38 @@ function rustBinaryCommands(plan: RustReleasePlan, independent: boolean): string
|
|
|
458
382
|
});
|
|
459
383
|
}
|
|
460
384
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
function rustArtifactSteps(plan: RustReleasePlan, kind: RustBuildKind): JobStep[] {
|
|
385
|
+
function rustArtifactSteps(plan: RustReleasePlan): JobStep[] {
|
|
464
386
|
const binaryCrates = [...new Set(plan.releaseBinaries.map((binary) => binary.crate))];
|
|
465
387
|
return [
|
|
466
|
-
...(
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
: []),
|
|
496
|
-
...(kind === "binaries" ? binaryCrates : []).map((crate) => {
|
|
388
|
+
...plan.bindings.flatMap((binding) => [
|
|
389
|
+
...(binding.node
|
|
390
|
+
? [
|
|
391
|
+
{
|
|
392
|
+
name: `Upload ${binding.crate} native npm package`,
|
|
393
|
+
uses: "actions/upload-artifact@v7",
|
|
394
|
+
with: {
|
|
395
|
+
name: `${binding.crate}-\${{ matrix.node }}-npm`,
|
|
396
|
+
path: `dist/release/${binding.crate}/\${{ matrix.node }}/npm/*.tgz`,
|
|
397
|
+
"retention-days": 7,
|
|
398
|
+
},
|
|
399
|
+
},
|
|
400
|
+
]
|
|
401
|
+
: []),
|
|
402
|
+
...(binding.python
|
|
403
|
+
? [
|
|
404
|
+
{
|
|
405
|
+
name: `Upload ${binding.crate} Python wheel`,
|
|
406
|
+
uses: "actions/upload-artifact@v7",
|
|
407
|
+
with: {
|
|
408
|
+
name: `${binding.pythonPackage}--\${{ matrix.python }}--python-wheel`,
|
|
409
|
+
path: `dist/release/${binding.crate}/\${{ matrix.node }}/python/*.whl`,
|
|
410
|
+
"retention-days": 7,
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
]
|
|
414
|
+
: []),
|
|
415
|
+
]),
|
|
416
|
+
...binaryCrates.map((crate) => {
|
|
497
417
|
const binaries = plan.releaseBinaries.filter((binary) => binary.crate === crate);
|
|
498
418
|
const excludedOs =
|
|
499
419
|
binaries[0]?.excludedOs.filter((os) =>
|
|
@@ -520,85 +440,42 @@ function matrixArgumentLoop(variable: string, field: string, flag: string): stri
|
|
|
520
440
|
return `while IFS= read -r ${variable}; do ${variable}="\${${variable}%$'\\r'}"; ${variable}_ARGS+=(${flag} "$${variable}"); done < <(jq -r '.[]' <<<'\${{ toJSON(matrix.${field}) }}')`;
|
|
521
441
|
}
|
|
522
442
|
|
|
523
|
-
function rustCargoBuildCommand(plan: RustReleasePlan
|
|
443
|
+
function rustCargoBuildCommand(plan: RustReleasePlan): string {
|
|
524
444
|
return [
|
|
525
445
|
"PACKAGE_ARGS=()",
|
|
526
446
|
"FEATURE_ARGS=()",
|
|
527
447
|
matrixArgumentLoop("PACKAGE", "packages", "--package"),
|
|
528
448
|
matrixArgumentLoop("FEATURE", "features", "--features"),
|
|
529
|
-
|
|
530
|
-
? ["BINARY_ARGS=()", matrixArgumentLoop("BINARY", "binaries", "--bin")]
|
|
531
|
-
: ["BINARY_ARGS=()"]),
|
|
532
|
-
`cargo build --release --timings "\${PACKAGE_ARGS[@]}" "\${BINARY_ARGS[@]}" "\${FEATURE_ARGS[@]}"${
|
|
449
|
+
`cargo build --release --timings "\${PACKAGE_ARGS[@]}" "\${FEATURE_ARGS[@]}"${
|
|
533
450
|
plan.usesCargoLock ? " --locked" : ""
|
|
534
451
|
} --target "\${{ matrix.cargo }}"`,
|
|
535
452
|
].join("\n");
|
|
536
453
|
}
|
|
537
454
|
|
|
538
|
-
export function rustBuildJob(
|
|
539
|
-
plan
|
|
540
|
-
|
|
541
|
-
independentSetup?: readonly JobStep[],
|
|
542
|
-
): Job {
|
|
543
|
-
const independent = Boolean(independentSetup);
|
|
544
|
-
const targets = kind === "uniffi" ? plan.uniffiTargets : plan.binaryTargets;
|
|
545
|
-
const outputName = kind === "uniffi" ? "rust_uniffi_targets" : "rust_binary_targets";
|
|
546
|
-
const title = kind === "uniffi" ? "UniFFI" : "binaries";
|
|
547
|
-
const bindingCommands = kind === "uniffi" ? rustBindingCommands(plan, independent) : [];
|
|
548
|
-
const binaryCommands = kind === "binaries" ? rustBinaryCommands(plan, independent) : [];
|
|
549
|
-
const fingerprintSources = [...new Set(targets.flatMap((target) => target.sources))].sort();
|
|
455
|
+
export function rustBuildJob(plan: RustReleasePlan, setup: readonly JobStep[]): Job {
|
|
456
|
+
const bindingCommands = rustBindingCommands(plan, true);
|
|
457
|
+
const binaryCommands = rustBinaryCommands(plan, true);
|
|
550
458
|
return {
|
|
551
|
-
if:
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
name: `${title} / \${{ matrix.node }}`,
|
|
555
|
-
needs: [independentSetup ? "release-plan" : "verify-context"],
|
|
459
|
+
if: "${{ needs.release-plan.outputs.rust_targets != '[]' && (github.event_name == 'push' || inputs.stage != 'docs') }}",
|
|
460
|
+
name: "Rust / ${{ matrix.node }}",
|
|
461
|
+
needs: ["release-plan"],
|
|
556
462
|
runsOn: ["${{ matrix.runner }}"],
|
|
557
463
|
permissions: { contents: JobPermission.READ },
|
|
558
|
-
env: {
|
|
559
|
-
...RUST_CACHE_ENV,
|
|
560
|
-
...(independentSetup ? { BUN_VERSION } : {}),
|
|
561
|
-
},
|
|
464
|
+
env: { ...RUST_BUILD_ENV, BUN_VERSION },
|
|
562
465
|
strategy: {
|
|
563
466
|
failFast: false,
|
|
564
467
|
matrix: {
|
|
565
|
-
include:
|
|
566
|
-
? (`\${{ fromJSON(needs.release-plan.outputs.${outputName}) }}` as never)
|
|
567
|
-
: ([...targets] as never),
|
|
468
|
+
include: "${{ fromJSON(needs.release-plan.outputs.rust_targets) }}" as never,
|
|
568
469
|
},
|
|
569
470
|
},
|
|
570
471
|
steps: [
|
|
571
|
-
...
|
|
572
|
-
...(
|
|
573
|
-
? [{ name: "Setup uv", uses: "astral-sh/setup-uv@v7" }]
|
|
574
|
-
: []),
|
|
472
|
+
...setup,
|
|
473
|
+
...(plan.hasPythonBindings ? [{ name: "Setup uv", uses: "astral-sh/setup-uv@v7" }] : []),
|
|
575
474
|
{
|
|
576
475
|
name: "Setup Rust",
|
|
577
|
-
...(plan.usePreinstalledWindowsRust ? { if: "${{ matrix.os != 'win32' }}" } : {}),
|
|
578
476
|
uses: `dtolnay/rust-toolchain@${plan.releaseRustVersion}`,
|
|
579
477
|
with: { targets: "${{ matrix.cargo }}" },
|
|
580
478
|
},
|
|
581
|
-
...(plan.usePreinstalledWindowsRust
|
|
582
|
-
? [
|
|
583
|
-
{
|
|
584
|
-
name: "Verify preinstalled Windows Rust",
|
|
585
|
-
if: "${{ matrix.os == 'win32' }}",
|
|
586
|
-
shell: "bash",
|
|
587
|
-
run: [
|
|
588
|
-
"rustc --version --verbose",
|
|
589
|
-
"cargo --version",
|
|
590
|
-
'rustup target list --installed | grep -Fx "${{ matrix.cargo }}"',
|
|
591
|
-
'test -f "$(rustc --print sysroot)/lib/rustlib/${{ matrix.cargo }}/bin/rust-lld.exe"',
|
|
592
|
-
].join("\n"),
|
|
593
|
-
},
|
|
594
|
-
]
|
|
595
|
-
: []),
|
|
596
|
-
{
|
|
597
|
-
name: "Install LLVM release tools",
|
|
598
|
-
shell: "bash",
|
|
599
|
-
run: "rustup component add llvm-tools-preview",
|
|
600
|
-
},
|
|
601
|
-
...rustCacheSteps(`release-${kind}-\${{ matrix.cargo }}-rust-${plan.releaseRustVersion}`),
|
|
602
479
|
{
|
|
603
480
|
name: "Install Linux native dependencies",
|
|
604
481
|
if: "${{ matrix.os == 'linux' }}",
|
|
@@ -614,120 +491,15 @@ export function rustBuildJob(
|
|
|
614
491
|
),
|
|
615
492
|
},
|
|
616
493
|
{
|
|
617
|
-
name: "
|
|
618
|
-
if: independentSetup
|
|
619
|
-
? undefined
|
|
620
|
-
: "${{ github.event_name == 'push' || inputs.stage == 'all' }}",
|
|
621
|
-
...(!independentSetup ? { id: "rust-fingerprint" } : {}),
|
|
494
|
+
name: "Build Rust release outputs",
|
|
622
495
|
shell: "bash",
|
|
623
|
-
run:
|
|
624
|
-
`RUNTIME_MANIFEST="dist/rust-raw/rust-${kind}-build-\${{ matrix.node }}.json"`,
|
|
625
|
-
'mkdir -p "$(dirname "$RUNTIME_MANIFEST")"',
|
|
626
|
-
[
|
|
627
|
-
`node ${plan.releaseHelper} fingerprint --root .`,
|
|
628
|
-
'--output "$RUNTIME_MANIFEST"',
|
|
629
|
-
`--namespace ${JSON.stringify(kind)}`,
|
|
630
|
-
'--target "${{ matrix.cargo }}|${{ matrix.fingerprintConfig }}"',
|
|
631
|
-
`--toolchain ${JSON.stringify(plan.releaseRustVersion)}`,
|
|
632
|
-
...fingerprintSources.map((source) => `--source ${JSON.stringify(source)}`),
|
|
633
|
-
"--source-only",
|
|
634
|
-
...(independentSetup ? ["--portable"] : []),
|
|
635
|
-
].join(" "),
|
|
636
|
-
`test "$(jq -r .namespace "$RUNTIME_MANIFEST")" = "$(jq -r .namespace .release/rust-${kind}.json)"`,
|
|
637
|
-
`test "$(jq -r .rustSourceHash "$RUNTIME_MANIFEST")" = "$(jq -r .rustSourceHash .release/rust-${kind}.json)"`,
|
|
638
|
-
'KEY="$(jq -r --arg target "${{ matrix.cargo }}" \'.targets[$target] // empty\' "$RUNTIME_MANIFEST")"',
|
|
639
|
-
'test -n "$KEY"',
|
|
640
|
-
'echo "key=$KEY" >> "$GITHUB_OUTPUT"',
|
|
641
|
-
].join("\n"),
|
|
496
|
+
run: timedBash("rust", rustCargoBuildCommand(plan)),
|
|
642
497
|
},
|
|
643
|
-
...(!independentSetup
|
|
644
|
-
? [
|
|
645
|
-
{
|
|
646
|
-
name: "Reuse matching raw Rust outputs",
|
|
647
|
-
id: "raw-native",
|
|
648
|
-
shell: "bash",
|
|
649
|
-
env: { GH_TOKEN: "${{ github.token }}" },
|
|
650
|
-
// prettier-ignore
|
|
651
|
-
run: stringUtils.dedent(
|
|
652
|
-
// ============================================================================
|
|
653
|
-
/*bash*/`
|
|
654
|
-
KEY="\${{ steps.rust-fingerprint.outputs.key }}"
|
|
655
|
-
test -n "$KEY"
|
|
656
|
-
ASSET="rust-${kind}-raw-\${{ matrix.node }}-$KEY.tar.gz"
|
|
657
|
-
mkdir -p dist/rust-raw
|
|
658
|
-
MATCH="$(gh api --paginate "repos/\${{ github.repository }}/releases?per_page=100" --jq '.[] | select(.draft == false) | . as $release | .assets[] | select(.name == "'"$ASSET"'") | [$release.tag_name, .url] | @tsv' | head -n 1)"
|
|
659
|
-
if [ -n "$MATCH" ]; then
|
|
660
|
-
TAG="\${MATCH%%$'\\t'*}"
|
|
661
|
-
URL="\${MATCH#*$'\\t'}"
|
|
662
|
-
CHECKSUM_URL="$(gh api "repos/\${{ github.repository }}/releases/tags/$TAG" --jq '.assets[] | select(.name == "'"$ASSET.sha256"'") | .url')"
|
|
663
|
-
rm -rf "target/\${{ matrix.cargo }}/release"
|
|
664
|
-
if test -n "$CHECKSUM_URL" && gh api "$URL" -H "Accept: application/octet-stream" > "dist/rust-raw/$ASSET" && gh api "$CHECKSUM_URL" -H "Accept: application/octet-stream" > "dist/rust-raw/$ASSET.sha256" && (cd dist/rust-raw && if command -v sha256sum >/dev/null 2>&1; then sha256sum --check "$ASSET.sha256"; else shasum -a 256 --check "$ASSET.sha256"; fi) && tar -xzf "dist/rust-raw/$ASSET"; then
|
|
665
|
-
echo "hit=true" >> "$GITHUB_OUTPUT"
|
|
666
|
-
else
|
|
667
|
-
rm -rf "target/\${{ matrix.cargo }}/release" "dist/rust-raw/$ASSET" "dist/rust-raw/$ASSET.sha256"
|
|
668
|
-
echo "::warning::matching raw Rust bundle failed validation; rebuilding"
|
|
669
|
-
echo "hit=false" >> "$GITHUB_OUTPUT"
|
|
670
|
-
fi
|
|
671
|
-
else
|
|
672
|
-
echo "hit=false" >> "$GITHUB_OUTPUT"
|
|
673
|
-
fi
|
|
674
|
-
echo "asset=$ASSET" >> "$GITHUB_OUTPUT"
|
|
675
|
-
`
|
|
676
|
-
// ============================================================================
|
|
677
|
-
),
|
|
678
|
-
},
|
|
679
|
-
]
|
|
680
|
-
: []),
|
|
681
|
-
{
|
|
682
|
-
name: `Build Rust ${title} outputs`,
|
|
683
|
-
...(independentSetup ? {} : { if: "${{ steps.raw-native.outputs.hit != 'true' }}" }),
|
|
684
|
-
shell: "bash",
|
|
685
|
-
env: {
|
|
686
|
-
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER:
|
|
687
|
-
"${{ matrix.os == 'win32' && 'rust-lld' || '' }}",
|
|
688
|
-
},
|
|
689
|
-
run: timedBash(`rust_${kind}`, rustCargoBuildCommand(plan, kind)),
|
|
690
|
-
},
|
|
691
|
-
...(!independentSetup
|
|
692
|
-
? [
|
|
693
|
-
{
|
|
694
|
-
name: "Upload Cargo timings",
|
|
695
|
-
if: "${{ steps.raw-native.outputs.hit != 'true' }}",
|
|
696
|
-
uses: "actions/upload-artifact@v7",
|
|
697
|
-
with: {
|
|
698
|
-
name: `rust-${kind}-\${{ matrix.node }}-cargo-timings`,
|
|
699
|
-
path: "target/cargo-timings/*",
|
|
700
|
-
"retention-days": 14,
|
|
701
|
-
},
|
|
702
|
-
},
|
|
703
|
-
]
|
|
704
|
-
: []),
|
|
705
|
-
...(!independentSetup
|
|
706
|
-
? [
|
|
707
|
-
{
|
|
708
|
-
name: "Archive raw Rust outputs",
|
|
709
|
-
if: "${{ steps.raw-native.outputs.hit != 'true' }}",
|
|
710
|
-
shell: "bash",
|
|
711
|
-
run: [
|
|
712
|
-
"mkdir -p dist/rust-raw",
|
|
713
|
-
'tar -czf "dist/rust-raw/${{ steps.raw-native.outputs.asset }}" "target/${{ matrix.cargo }}/release"',
|
|
714
|
-
'(cd dist/rust-raw && if command -v sha256sum >/dev/null 2>&1; then sha256sum "${{ steps.raw-native.outputs.asset }}"; else shasum -a 256 "${{ steps.raw-native.outputs.asset }}"; fi > "${{ steps.raw-native.outputs.asset }}.sha256")',
|
|
715
|
-
].join("\n"),
|
|
716
|
-
},
|
|
717
|
-
{
|
|
718
|
-
name: "Stamp native release version",
|
|
719
|
-
shell: "bash",
|
|
720
|
-
env: { VERSION: RELEASE_VERSION },
|
|
721
|
-
run: `node ${plan.releaseHelper} stamp-tree --root "target/\${{ matrix.cargo }}/release" --version "$VERSION"`,
|
|
722
|
-
},
|
|
723
|
-
]
|
|
724
|
-
: []),
|
|
725
498
|
...(bindingCommands.length
|
|
726
499
|
? [
|
|
727
500
|
{
|
|
728
501
|
name: "Package UniFFI outputs",
|
|
729
502
|
shell: "bash",
|
|
730
|
-
...(independentSetup ? {} : { env: { VERSION: RELEASE_VERSION } }),
|
|
731
503
|
run: timedBash("uniffi_packaging", bindingCommands.join("\n")),
|
|
732
504
|
},
|
|
733
505
|
]
|
|
@@ -741,32 +513,16 @@ export function rustBuildJob(
|
|
|
741
513
|
},
|
|
742
514
|
]
|
|
743
515
|
: []),
|
|
744
|
-
...(
|
|
745
|
-
? [
|
|
746
|
-
{
|
|
747
|
-
name: "Upload reusable raw Rust outputs",
|
|
748
|
-
uses: "actions/upload-artifact@v7",
|
|
749
|
-
with: {
|
|
750
|
-
name: `rust-${kind}-\${{ matrix.node }}-raw`,
|
|
751
|
-
path: "dist/rust-raw/*",
|
|
752
|
-
"retention-days": 7,
|
|
753
|
-
},
|
|
754
|
-
},
|
|
755
|
-
]
|
|
756
|
-
: []),
|
|
757
|
-
...rustArtifactSteps(plan, kind),
|
|
516
|
+
...rustArtifactSteps(plan),
|
|
758
517
|
],
|
|
759
518
|
};
|
|
760
519
|
}
|
|
761
520
|
|
|
762
|
-
export function rustCargoPublishJob(plan: RustReleasePlan
|
|
763
|
-
const registry = local ? '"${{ vars.LOCAL_CARGO_REGISTRY }}"' : "crates-io";
|
|
521
|
+
export function rustCargoPublishJob(plan: RustReleasePlan): Job {
|
|
764
522
|
return {
|
|
765
|
-
if:
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
needs: ["verify-context", ...rustBuildJobIds(plan)],
|
|
769
|
-
runsOn: [local ? "self-hosted" : "ubuntu-latest"],
|
|
523
|
+
if: releasePublishCondition("cargo", ["needs.verify-context.result == 'success'"]),
|
|
524
|
+
needs: ["verify-context"],
|
|
525
|
+
runsOn: ["ubuntu-latest"],
|
|
770
526
|
permissions: { contents: JobPermission.READ },
|
|
771
527
|
steps: [
|
|
772
528
|
...releaseSourceSteps(),
|
|
@@ -775,14 +531,21 @@ export function rustCargoPublishJob(plan: RustReleasePlan, local: boolean): Job
|
|
|
775
531
|
uses: `dtolnay/rust-toolchain@${plan.releaseRustVersion}`,
|
|
776
532
|
},
|
|
777
533
|
{
|
|
778
|
-
name:
|
|
534
|
+
name: "Publish public crates",
|
|
779
535
|
env: {
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
: "${{ secrets.CARGO_REGISTRY_TOKEN }}",
|
|
536
|
+
RELEASE_VERSION,
|
|
537
|
+
CARGO_REGISTRY_TOKEN: "${{ secrets.CARGO_REGISTRY_TOKEN }}",
|
|
783
538
|
},
|
|
784
539
|
run: plan.publicCrates
|
|
785
|
-
.map((crate) =>
|
|
540
|
+
.map((crate) =>
|
|
541
|
+
[
|
|
542
|
+
`if cargo info "${crate}@$RELEASE_VERSION" >/dev/null 2>&1; then`,
|
|
543
|
+
` echo "skip published ${crate}@$RELEASE_VERSION"`,
|
|
544
|
+
"else",
|
|
545
|
+
` cargo publish --package "${crate}" --registry crates-io --no-verify`,
|
|
546
|
+
"fi",
|
|
547
|
+
].join("\n"),
|
|
548
|
+
)
|
|
786
549
|
.join("\n"),
|
|
787
550
|
},
|
|
788
551
|
],
|
|
@@ -850,15 +613,6 @@ export function independentRustGitHubReleaseJob(
|
|
|
850
613
|
"merge-multiple": true,
|
|
851
614
|
},
|
|
852
615
|
},
|
|
853
|
-
{
|
|
854
|
-
name: "Download reusable raw Rust outputs",
|
|
855
|
-
uses: "actions/download-artifact@v8",
|
|
856
|
-
with: {
|
|
857
|
-
pattern: "*-raw",
|
|
858
|
-
path: "dist/rust-raw",
|
|
859
|
-
"merge-multiple": true,
|
|
860
|
-
},
|
|
861
|
-
},
|
|
862
616
|
{
|
|
863
617
|
name: "Upload affected GitHub release assets",
|
|
864
618
|
env: { GH_TOKEN: "${{ github.token }}" },
|
|
@@ -879,100 +633,10 @@ export function independentRustGitHubReleaseJob(
|
|
|
879
633
|
};
|
|
880
634
|
}
|
|
881
635
|
|
|
882
|
-
export function rustGitHubReleaseJob(plan: RustReleasePlan): Job {
|
|
883
|
-
return {
|
|
884
|
-
if: "${{ github.event_name == 'push' }}",
|
|
885
|
-
needs: ["verify-context", ...rustBuildJobIds(plan)],
|
|
886
|
-
runsOn: ["ubuntu-latest"],
|
|
887
|
-
permissions: { contents: JobPermission.WRITE },
|
|
888
|
-
steps: [
|
|
889
|
-
...releaseSourceSteps(),
|
|
890
|
-
{
|
|
891
|
-
name: "Download release binaries",
|
|
892
|
-
uses: "actions/download-artifact@v8",
|
|
893
|
-
with: {
|
|
894
|
-
pattern: "*-binary",
|
|
895
|
-
path: "dist/rust-release",
|
|
896
|
-
"merge-multiple": true,
|
|
897
|
-
},
|
|
898
|
-
},
|
|
899
|
-
{
|
|
900
|
-
name: "Download reusable raw Rust outputs",
|
|
901
|
-
uses: "actions/download-artifact@v8",
|
|
902
|
-
with: {
|
|
903
|
-
pattern: "*-raw",
|
|
904
|
-
path: "dist/rust-raw",
|
|
905
|
-
"merge-multiple": true,
|
|
906
|
-
},
|
|
907
|
-
},
|
|
908
|
-
{
|
|
909
|
-
name: "Publish GitHub release assets",
|
|
910
|
-
uses: "softprops/action-gh-release@v2",
|
|
911
|
-
with: {
|
|
912
|
-
files: ["dist/rust-release/*", "dist/rust-raw/*"].join("\n"),
|
|
913
|
-
body_path: RELEASE_SUMMARY_FILE,
|
|
914
|
-
generate_release_notes: true,
|
|
915
|
-
tag_name: RELEASE_TAG,
|
|
916
|
-
target_commitish: RELEASE_SHA,
|
|
917
|
-
},
|
|
918
|
-
},
|
|
919
|
-
{
|
|
920
|
-
name: "Delete superseded raw Rust release assets",
|
|
921
|
-
uses: "actions/github-script@v8",
|
|
922
|
-
env: { CURRENT_RELEASE_TAG: RELEASE_TAG },
|
|
923
|
-
with: {
|
|
924
|
-
// prettier-ignore
|
|
925
|
-
script: stringUtils.dedent(
|
|
926
|
-
// ============================================================================
|
|
927
|
-
/*js*/`
|
|
928
|
-
const currentTag = process.env.CURRENT_RELEASE_TAG;
|
|
929
|
-
if (!currentTag) throw new Error("CURRENT_RELEASE_TAG is required");
|
|
930
|
-
const parseVersion = (tag) => {
|
|
931
|
-
const match = /^v(\\d+)\\.(\\d+)\\.(\\d+)$/.exec(tag);
|
|
932
|
-
return match ? match.slice(1).map(Number) : undefined;
|
|
933
|
-
};
|
|
934
|
-
const compareVersions = (left, right) => {
|
|
935
|
-
for (let index = 0; index < 3; index += 1) {
|
|
936
|
-
if (left[index] !== right[index]) return left[index] - right[index];
|
|
937
|
-
}
|
|
938
|
-
return 0;
|
|
939
|
-
};
|
|
940
|
-
const currentVersion = parseVersion(currentTag);
|
|
941
|
-
if (!currentVersion) throw new Error(\`Unsupported release tag: \${currentTag}\`);
|
|
942
|
-
const releases = await github.paginate(github.rest.repos.listReleases, {
|
|
943
|
-
...context.repo,
|
|
944
|
-
per_page: 100,
|
|
945
|
-
});
|
|
946
|
-
const assets = releases.flatMap((release) => {
|
|
947
|
-
const version = parseVersion(release.tag_name);
|
|
948
|
-
if (release.draft || !version || compareVersions(version, currentVersion) >= 0) {
|
|
949
|
-
return [];
|
|
950
|
-
}
|
|
951
|
-
return release.assets.filter((asset) =>
|
|
952
|
-
/^rust-(?:(?:uniffi|binaries)-(?:raw|build)|(?:raw|build))-/.test(asset.name)
|
|
953
|
-
);
|
|
954
|
-
});
|
|
955
|
-
for (const asset of assets) {
|
|
956
|
-
core.info(\`Deleting \${asset.name} (\${asset.id})\`);
|
|
957
|
-
await github.rest.repos.deleteReleaseAsset({
|
|
958
|
-
...context.repo,
|
|
959
|
-
asset_id: asset.id,
|
|
960
|
-
});
|
|
961
|
-
}
|
|
962
|
-
core.info(\`Deleted \${assets.length} superseded raw Rust release assets\`);
|
|
963
|
-
`
|
|
964
|
-
// ============================================================================
|
|
965
|
-
),
|
|
966
|
-
},
|
|
967
|
-
},
|
|
968
|
-
],
|
|
969
|
-
};
|
|
970
|
-
}
|
|
971
|
-
|
|
972
636
|
export function independentRustNativeNpmPublishJob(project: DBXToolsJavaScriptProject): Job {
|
|
973
637
|
return {
|
|
974
638
|
if: "${{ needs.release-plan.outputs.node == 'true' && (github.event_name == 'push' || inputs.stage == 'all' || inputs.stage == 'node') }}",
|
|
975
|
-
needs: ["release-plan", "rust-
|
|
639
|
+
needs: ["release-plan", "rust-build"],
|
|
976
640
|
runsOn: ["ubuntu-latest"],
|
|
977
641
|
permissions: { contents: JobPermission.READ, idToken: JobPermission.WRITE },
|
|
978
642
|
timeoutMinutes: 15,
|
|
@@ -1032,78 +696,3 @@ export function independentRustNodeFacadePublishJob(
|
|
|
1032
696
|
],
|
|
1033
697
|
};
|
|
1034
698
|
}
|
|
1035
|
-
|
|
1036
|
-
export function rustNativeNpmPublishJob(project: DBXToolsJavaScriptProject): Job {
|
|
1037
|
-
return {
|
|
1038
|
-
if: "${{ always() && needs.verify-context.result == 'success' && needs.rust-uniffi.result != 'failure' && needs.rust-uniffi.result != 'cancelled' && (github.event_name == 'push' || inputs.stage == 'all' || inputs.stage == 'node') }}",
|
|
1039
|
-
needs: ["verify-context", "rust-uniffi"],
|
|
1040
|
-
runsOn: ["ubuntu-latest"],
|
|
1041
|
-
permissions: {
|
|
1042
|
-
actions: JobPermission.READ,
|
|
1043
|
-
contents: JobPermission.READ,
|
|
1044
|
-
idToken: JobPermission.WRITE,
|
|
1045
|
-
},
|
|
1046
|
-
timeoutMinutes: 15,
|
|
1047
|
-
env: { BUN_VERSION, CI: "true" },
|
|
1048
|
-
steps: [
|
|
1049
|
-
...nodeReleaseSetupSteps(project),
|
|
1050
|
-
...releaseArtifactSteps({
|
|
1051
|
-
currentName: "Download native npm packages",
|
|
1052
|
-
recoveredName: "Download recovered native npm packages",
|
|
1053
|
-
pattern: "*-npm",
|
|
1054
|
-
path: "dist/uniffi/native",
|
|
1055
|
-
}),
|
|
1056
|
-
{
|
|
1057
|
-
name: "Publish native npm packages",
|
|
1058
|
-
env: { RELEASE_VERSION, ...npmPublishEnvironment() },
|
|
1059
|
-
run: 'bun node_modules/@dbx-tools/projen/tasks/publish-npm.ts --directory dist/uniffi/native --version "$RELEASE_VERSION" $DRY_RUN',
|
|
1060
|
-
},
|
|
1061
|
-
],
|
|
1062
|
-
};
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1065
|
-
export function rustNodeFacadePublishJob(
|
|
1066
|
-
project: DBXToolsJavaScriptProject,
|
|
1067
|
-
bindings: readonly RustReleaseBinding[],
|
|
1068
|
-
): Job {
|
|
1069
|
-
return {
|
|
1070
|
-
if: releaseStageCondition("node"),
|
|
1071
|
-
needs: ["verify-context", "publish-node"],
|
|
1072
|
-
runsOn: ["ubuntu-latest"],
|
|
1073
|
-
permissions: { contents: JobPermission.READ, idToken: JobPermission.WRITE },
|
|
1074
|
-
timeoutMinutes: 30,
|
|
1075
|
-
env: { BUN_VERSION, CI: "true" },
|
|
1076
|
-
steps: [
|
|
1077
|
-
...nodeReleaseSetupSteps(project),
|
|
1078
|
-
{
|
|
1079
|
-
name: "Build and publish UniFFI npm facades",
|
|
1080
|
-
env: { RELEASE_VERSION, ...npmPublishEnvironment() },
|
|
1081
|
-
run: bindings
|
|
1082
|
-
.flatMap((binding) => {
|
|
1083
|
-
const output = `dist/uniffi/facades/${binding.crate}`;
|
|
1084
|
-
return [
|
|
1085
|
-
`node .projen/uniffi-release.mjs facade --node "${binding.node}" --node-package "${binding.nodePackage}" --node-triple "linux-x64-gnu" --version "$RELEASE_VERSION" --output "${output}"`,
|
|
1086
|
-
`bun node_modules/@dbx-tools/projen/tasks/publish-npm.ts --directory "${output}/npm-facade" --version "$RELEASE_VERSION" $DRY_RUN`,
|
|
1087
|
-
];
|
|
1088
|
-
})
|
|
1089
|
-
.join("\n"),
|
|
1090
|
-
},
|
|
1091
|
-
{
|
|
1092
|
-
name: "Smoke test published UniFFI npm facades",
|
|
1093
|
-
if: "${{ github.event_name == 'push' && vars.UNIFFI_FACADE_SMOKE == 'true' }}",
|
|
1094
|
-
continueOnError: true,
|
|
1095
|
-
env: { RELEASE_VERSION },
|
|
1096
|
-
run: [
|
|
1097
|
-
'SMOKE_DIR="$(mktemp -d)"',
|
|
1098
|
-
"trap 'rm -rf \"$SMOKE_DIR\"' EXIT",
|
|
1099
|
-
'cd "$SMOKE_DIR"',
|
|
1100
|
-
"npm init --yes >/dev/null",
|
|
1101
|
-
...bindings.flatMap((binding) => [
|
|
1102
|
-
`npm install --ignore-scripts --no-audit --no-fund --package-lock=false "${binding.nodePackage}@$RELEASE_VERSION"`,
|
|
1103
|
-
`node -e 'import("${binding.nodePackage}")'`,
|
|
1104
|
-
]),
|
|
1105
|
-
].join("\n"),
|
|
1106
|
-
},
|
|
1107
|
-
],
|
|
1108
|
-
};
|
|
1109
|
-
}
|