@dbx-tools/projen 0.9.18 → 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 +72 -88
- 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 +18 -582
- package/src/_task-command.ts +75 -0
- package/src/project-js.ts +2 -42
- package/src/project-py.ts +60 -162
- package/src/project-rs.ts +4 -100
- package/src/release-catalog.ts +37 -203
- package/src/release.ts +96 -775
- 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 +125 -41
- package/tasks/publish-python.ts +79 -106
- package/tasks/publish-uniffi-local.ts +129 -84
- package/tasks/publish.ts +44 -139
- package/tasks/python-registry.ts +2 -9
- package/tasks/release-assets.ts +56 -65
- package/tasks/release-candidate.ts +416 -0
- package/tasks/release-manifest.ts +273 -0
- package/tasks/release-pr.ts +312 -369
- 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
|
@@ -1,54 +1,23 @@
|
|
|
1
|
-
/** Rust release planning
|
|
1
|
+
/** Rust release planning, candidate configuration, and Cargo promotion. */
|
|
2
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { dirname, join, resolve } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
-
import { stringUtils } from "@dbx-tools/shared-core";
|
|
7
6
|
import { TextFile, javascript } from "projen";
|
|
8
|
-
import { JobPermission, type Job
|
|
9
|
-
import { releaseBinaryAssetName } from "./_release-platform.ts";
|
|
7
|
+
import { JobPermission, type Job } from "projen/lib/github/workflows-model";
|
|
10
8
|
import { UNIFFI_BINDGEN_FEATURE, type RustProject } from "./_rust-project.ts";
|
|
11
|
-
import { BUN_VERSION } from "./bun-workflow.ts";
|
|
12
|
-
import type { DBXToolsJavaScriptProject } from "./project-js.ts";
|
|
13
9
|
import type {
|
|
14
10
|
DBXToolsRustWorkspaceOptions,
|
|
15
11
|
RustBindingMapping,
|
|
16
12
|
RustReleaseOs,
|
|
17
13
|
UniFFIReleaseTarget,
|
|
18
14
|
} from "./project-rs.ts";
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
RELEASE_SHA,
|
|
22
|
-
RELEASE_SUMMARY_FILE,
|
|
23
|
-
RELEASE_TAG,
|
|
24
|
-
RELEASE_VERSION,
|
|
25
|
-
releaseSourceSteps,
|
|
26
|
-
} from "./release-dispatch.ts";
|
|
27
|
-
import {
|
|
28
|
-
independentReleaseSetupSteps,
|
|
29
|
-
npmPublishEnvironment,
|
|
30
|
-
nodeReleaseSetupSteps,
|
|
31
|
-
releaseArtifactSteps,
|
|
32
|
-
releaseStageCondition,
|
|
33
|
-
} from "./release.ts";
|
|
15
|
+
import { RELEASE_VERSION, releaseSourceSteps } from "./release-dispatch.ts";
|
|
16
|
+
import { releasePublishCondition } from "./release.ts";
|
|
34
17
|
|
|
35
18
|
const require = createRequire(import.meta.url);
|
|
36
|
-
|
|
37
19
|
type RustPackageDependencyResolver = (pkg: RustProject) => RustProject[];
|
|
38
20
|
|
|
39
|
-
const RUST_BUILD_ENV = {
|
|
40
|
-
CARGO_INCREMENTAL: "0",
|
|
41
|
-
CARGO_TERM_COLOR: "always",
|
|
42
|
-
} as const;
|
|
43
|
-
|
|
44
|
-
function timedBash(phase: string, command: string): string {
|
|
45
|
-
return [
|
|
46
|
-
"SECONDS=0",
|
|
47
|
-
`trap 'status=$?; echo "phase=${phase} duration_seconds=$SECONDS status=$status"; exit "$status"' EXIT`,
|
|
48
|
-
command,
|
|
49
|
-
].join("\n");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
21
|
function taskSource(name: string): string {
|
|
53
22
|
const sourceDirectory = dirname(fileURLToPath(import.meta.url));
|
|
54
23
|
const candidates = [
|
|
@@ -265,17 +234,6 @@ export function planRustRelease(
|
|
|
265
234
|
hasTargetOutputs,
|
|
266
235
|
};
|
|
267
236
|
}
|
|
268
|
-
|
|
269
|
-
function rustBuildJobIds(plan: RustReleasePlan): string[] {
|
|
270
|
-
return plan.targets.length ? ["rust-build"] : [];
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
function rustBuildResultCondition(plan: RustReleasePlan): string {
|
|
274
|
-
return rustBuildJobIds(plan)
|
|
275
|
-
.map((job) => `needs.${job}.result != 'failure' && needs.${job}.result != 'cancelled'`)
|
|
276
|
-
.join(" && ");
|
|
277
|
-
}
|
|
278
|
-
|
|
279
237
|
export function configureRustReleaseTask(
|
|
280
238
|
project: javascript.NodeProject,
|
|
281
239
|
plan: RustReleasePlan,
|
|
@@ -318,267 +276,12 @@ export function configureRustReleaseTask(
|
|
|
318
276
|
project.tryRemoveFile(".projen/rust-release.mjs");
|
|
319
277
|
}
|
|
320
278
|
|
|
321
|
-
function
|
|
322
|
-
return plan.bindings.map((binding) => {
|
|
323
|
-
const unit = defaultReleaseUnitId("rust", binding.crate);
|
|
324
|
-
const command = [
|
|
325
|
-
`node ${plan.releaseTask} build`,
|
|
326
|
-
`--crate "${binding.crate}"`,
|
|
327
|
-
`--node "${binding.node}"`,
|
|
328
|
-
`--python "${binding.python}"`,
|
|
329
|
-
`--node-package "${binding.nodePackage}"`,
|
|
330
|
-
`--python-package "${binding.pythonPackage}"`,
|
|
331
|
-
`--python-module "${binding.pythonModule}"`,
|
|
332
|
-
'--cargo-target "${{ matrix.cargo }}"',
|
|
333
|
-
'--node-triple "${{ matrix.node }}"',
|
|
334
|
-
'--python-tag "${{ matrix.python }}"',
|
|
335
|
-
'--os "${{ matrix.os }}"',
|
|
336
|
-
'--cpu "${{ matrix.cpu }}"',
|
|
337
|
-
'--libc "${{ matrix.libc }}"',
|
|
338
|
-
independent
|
|
339
|
-
? `--version "$(jq -r --arg unit "${unit}" '.units[] | select(.id == $unit) | .newVersion' dist/release-plan.json)"`
|
|
340
|
-
: '--version "$VERSION"',
|
|
341
|
-
`--output "dist/release/${binding.crate}/\${{ matrix.node }}"`,
|
|
342
|
-
"--skip-build",
|
|
343
|
-
].join(" \\\n ");
|
|
344
|
-
return independent
|
|
345
|
-
? [
|
|
346
|
-
`if jq -e --arg unit "${unit}" '.units[] | select(.id == $unit)' dist/release-plan.json >/dev/null; then`,
|
|
347
|
-
` ${command.replaceAll("\n", "\n ")}`,
|
|
348
|
-
"fi",
|
|
349
|
-
].join("\n")
|
|
350
|
-
: command;
|
|
351
|
-
});
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
function rustReleaseBinaryCondition(excludedOs: readonly RustReleaseOs[]): string | undefined {
|
|
355
|
-
return excludedOs.length
|
|
356
|
-
? `\${{ ${excludedOs.map((os) => `matrix.os != '${os}'`).join(" && ")} }}`
|
|
357
|
-
: undefined;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
function rustBinaryCommands(plan: RustReleasePlan, independent: boolean): string[] {
|
|
361
|
-
return plan.releaseBinaries.flatMap((pkg) => {
|
|
362
|
-
const unit = defaultReleaseUnitId("rust", pkg.crate);
|
|
363
|
-
const windowsAsset = releaseBinaryAssetName(pkg.binary, "${{ matrix.node }}", "win32");
|
|
364
|
-
const unixAsset = releaseBinaryAssetName(pkg.binary, "${{ matrix.node }}", "linux");
|
|
365
|
-
const commands = [
|
|
366
|
-
`mkdir -p "dist/release/${pkg.crate}/\${{ matrix.node }}/binary/stage"`,
|
|
367
|
-
`SOURCE="target/\${{ matrix.cargo }}/release/${pkg.binary}\${{ matrix.os == 'win32' && '.exe' || '' }}"`,
|
|
368
|
-
`DESTINATION="dist/release/${pkg.crate}/\${{ matrix.node }}/binary/stage/${pkg.binary}\${{ matrix.os == 'win32' && '.exe' || '' }}"`,
|
|
369
|
-
'cp "$SOURCE" "$DESTINATION"',
|
|
370
|
-
'if [ "${{ matrix.os }}" = "win32" ]; then',
|
|
371
|
-
` 7z a "dist/release/${pkg.crate}/\${{ matrix.node }}/binary/${windowsAsset}" "$DESTINATION"`,
|
|
372
|
-
"else",
|
|
373
|
-
` tar -C "dist/release/${pkg.crate}/\${{ matrix.node }}/binary/stage" -czf "dist/release/${pkg.crate}/\${{ matrix.node }}/binary/${unixAsset}" "${pkg.binary}"`,
|
|
374
|
-
"fi",
|
|
375
|
-
`rm -rf "dist/release/${pkg.crate}/\${{ matrix.node }}/binary/stage"`,
|
|
376
|
-
];
|
|
377
|
-
const excludedCondition = pkg.excludedOs
|
|
378
|
-
.map((os) => `[ "\${{ matrix.os }}" != "${os}" ]`)
|
|
379
|
-
.join(" && ");
|
|
380
|
-
const platformCommands = excludedCondition
|
|
381
|
-
? [`if ${excludedCondition}; then`, ...commands.map((command) => ` ${command}`), "fi"]
|
|
382
|
-
: commands;
|
|
383
|
-
return independent
|
|
384
|
-
? [
|
|
385
|
-
`if jq -e --arg unit "${unit}" '.units[] | select(.id == $unit)' dist/release-plan.json >/dev/null; then`,
|
|
386
|
-
...platformCommands.map((command) => ` ${command}`),
|
|
387
|
-
"fi",
|
|
388
|
-
]
|
|
389
|
-
: platformCommands;
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
function rustArtifactSteps(plan: RustReleasePlan): JobStep[] {
|
|
394
|
-
const binaryCrates = [...new Set(plan.releaseBinaries.map((binary) => binary.crate))];
|
|
395
|
-
return [
|
|
396
|
-
...plan.bindings.flatMap((binding) => [
|
|
397
|
-
...(binding.node
|
|
398
|
-
? [
|
|
399
|
-
{
|
|
400
|
-
name: `Upload ${binding.crate} native npm package`,
|
|
401
|
-
uses: "actions/upload-artifact@v7",
|
|
402
|
-
with: {
|
|
403
|
-
name: `${binding.crate}-\${{ matrix.node }}-npm`,
|
|
404
|
-
path: `dist/release/${binding.crate}/\${{ matrix.node }}/npm/*.tgz`,
|
|
405
|
-
"retention-days": 7,
|
|
406
|
-
},
|
|
407
|
-
},
|
|
408
|
-
]
|
|
409
|
-
: []),
|
|
410
|
-
...(binding.python
|
|
411
|
-
? [
|
|
412
|
-
{
|
|
413
|
-
name: `Upload ${binding.crate} Python wheel`,
|
|
414
|
-
uses: "actions/upload-artifact@v7",
|
|
415
|
-
with: {
|
|
416
|
-
name: `${binding.pythonPackage}--\${{ matrix.python }}--python-wheel`,
|
|
417
|
-
path: `dist/release/${binding.crate}/\${{ matrix.node }}/python/*.whl`,
|
|
418
|
-
"retention-days": 7,
|
|
419
|
-
},
|
|
420
|
-
},
|
|
421
|
-
]
|
|
422
|
-
: []),
|
|
423
|
-
]),
|
|
424
|
-
...binaryCrates.map((crate) => {
|
|
425
|
-
const binaries = plan.releaseBinaries.filter((binary) => binary.crate === crate);
|
|
426
|
-
const excludedOs =
|
|
427
|
-
binaries[0]?.excludedOs.filter((os) =>
|
|
428
|
-
binaries.every((binary) => binary.excludedOs.includes(os)),
|
|
429
|
-
) ?? [];
|
|
430
|
-
return {
|
|
431
|
-
name: `Upload ${crate} release binary`,
|
|
432
|
-
uses: "actions/upload-artifact@v7",
|
|
433
|
-
...(rustReleaseBinaryCondition(excludedOs)
|
|
434
|
-
? { if: rustReleaseBinaryCondition(excludedOs) }
|
|
435
|
-
: {}),
|
|
436
|
-
with: {
|
|
437
|
-
name: `${crate}-\${{ matrix.node }}-binary`,
|
|
438
|
-
path: `dist/release/${crate}/\${{ matrix.node }}/binary/*`,
|
|
439
|
-
"retention-days": 7,
|
|
440
|
-
},
|
|
441
|
-
};
|
|
442
|
-
}),
|
|
443
|
-
];
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
/** Build a Bash loop that preserves matrix values across LF and CRLF runners. */
|
|
447
|
-
function matrixArgumentLoop(variable: string, field: string, flag: string): string {
|
|
448
|
-
return `while IFS= read -r ${variable}; do ${variable}="\${${variable}%$'\\r'}"; ${variable}_ARGS+=(${flag} "$${variable}"); done < <(jq -r '.[]' <<<'\${{ toJSON(matrix.${field}) }}')`;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
function rustCargoBuildCommand(plan: RustReleasePlan): string {
|
|
452
|
-
return [
|
|
453
|
-
"PACKAGE_ARGS=()",
|
|
454
|
-
"FEATURE_ARGS=()",
|
|
455
|
-
matrixArgumentLoop("PACKAGE", "packages", "--package"),
|
|
456
|
-
matrixArgumentLoop("FEATURE", "features", "--features"),
|
|
457
|
-
`cargo build --release --timings "\${PACKAGE_ARGS[@]}" "\${FEATURE_ARGS[@]}"${
|
|
458
|
-
plan.usesCargoLock ? " --locked" : ""
|
|
459
|
-
} --target "\${{ matrix.cargo }}"`,
|
|
460
|
-
].join("\n");
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
export function rustBuildJob(plan: RustReleasePlan, independentSetup?: readonly JobStep[]): Job {
|
|
464
|
-
const independent = Boolean(independentSetup);
|
|
465
|
-
const bindingCommands = rustBindingCommands(plan, independent);
|
|
466
|
-
const binaryCommands = rustBinaryCommands(plan, independent);
|
|
467
|
-
return {
|
|
468
|
-
if: independentSetup
|
|
469
|
-
? "${{ needs.release-plan.outputs.rust_targets != '[]' && (github.event_name == 'push' || inputs.stage != 'docs') }}"
|
|
470
|
-
: "${{ needs.verify-context.outputs.build_mode == 'remote' && (github.event_name == 'push' || inputs.stage == 'all') }}",
|
|
471
|
-
name: "Rust / ${{ matrix.node }}",
|
|
472
|
-
needs: [independentSetup ? "release-plan" : "verify-context"],
|
|
473
|
-
runsOn: ["${{ matrix.runner }}"],
|
|
474
|
-
permissions: { contents: JobPermission.READ },
|
|
475
|
-
env: {
|
|
476
|
-
...RUST_BUILD_ENV,
|
|
477
|
-
...(independentSetup ? { BUN_VERSION } : {}),
|
|
478
|
-
},
|
|
479
|
-
strategy: {
|
|
480
|
-
failFast: false,
|
|
481
|
-
matrix: {
|
|
482
|
-
include: independentSetup
|
|
483
|
-
? ("${{ fromJSON(needs.release-plan.outputs.rust_targets) }}" as never)
|
|
484
|
-
: ([...plan.targets] as never),
|
|
485
|
-
},
|
|
486
|
-
},
|
|
487
|
-
steps: [
|
|
488
|
-
...(independentSetup ?? releaseSourceSteps()),
|
|
489
|
-
...(plan.hasPythonBindings ? [{ name: "Setup uv", uses: "astral-sh/setup-uv@v7" }] : []),
|
|
490
|
-
{
|
|
491
|
-
name: "Setup Rust",
|
|
492
|
-
uses: `dtolnay/rust-toolchain@${plan.releaseRustVersion}`,
|
|
493
|
-
with: { targets: "${{ matrix.cargo }}" },
|
|
494
|
-
},
|
|
495
|
-
{
|
|
496
|
-
name: "Install Linux native dependencies",
|
|
497
|
-
if: "${{ matrix.os == 'linux' }}",
|
|
498
|
-
// prettier-ignore
|
|
499
|
-
run: stringUtils.dedent(
|
|
500
|
-
// ============================================================================
|
|
501
|
-
/*bash*/`
|
|
502
|
-
sudo rm -f /etc/apt/sources.list.d/google-chrome.list
|
|
503
|
-
sudo apt-get update
|
|
504
|
-
sudo apt-get install --yes libdbus-1-dev pkg-config
|
|
505
|
-
`
|
|
506
|
-
// ============================================================================
|
|
507
|
-
),
|
|
508
|
-
},
|
|
509
|
-
{
|
|
510
|
-
name: "Build Rust release outputs",
|
|
511
|
-
shell: "bash",
|
|
512
|
-
run: timedBash("rust", rustCargoBuildCommand(plan)),
|
|
513
|
-
},
|
|
514
|
-
...(bindingCommands.length
|
|
515
|
-
? [
|
|
516
|
-
{
|
|
517
|
-
name: "Package UniFFI outputs",
|
|
518
|
-
shell: "bash",
|
|
519
|
-
...(independentSetup ? {} : { env: { VERSION: RELEASE_VERSION } }),
|
|
520
|
-
run: timedBash("uniffi_packaging", bindingCommands.join("\n")),
|
|
521
|
-
},
|
|
522
|
-
]
|
|
523
|
-
: []),
|
|
524
|
-
...(binaryCommands.length
|
|
525
|
-
? [
|
|
526
|
-
{
|
|
527
|
-
name: "Package release binaries",
|
|
528
|
-
shell: "bash",
|
|
529
|
-
run: timedBash("binary_packaging", binaryCommands.join("\n")),
|
|
530
|
-
},
|
|
531
|
-
]
|
|
532
|
-
: []),
|
|
533
|
-
...rustArtifactSteps(plan),
|
|
534
|
-
],
|
|
535
|
-
};
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
/** Wait for the selected local or GitHub-hosted native build source. */
|
|
539
|
-
export function rustAssetsJob(): Job {
|
|
279
|
+
export function rustCargoPublishJob(plan: RustReleasePlan): Job {
|
|
540
280
|
return {
|
|
541
|
-
if: "
|
|
542
|
-
needs: ["verify-context"
|
|
281
|
+
if: releasePublishCondition("cargo", ["needs.verify-context.result == 'success'"]),
|
|
282
|
+
needs: ["verify-context"],
|
|
543
283
|
runsOn: ["ubuntu-latest"],
|
|
544
284
|
permissions: { contents: JobPermission.READ },
|
|
545
|
-
steps: [
|
|
546
|
-
{
|
|
547
|
-
name: "Wait for locally uploaded release assets",
|
|
548
|
-
if: "${{ needs.verify-context.outputs.build_mode == 'local' }}",
|
|
549
|
-
env: {
|
|
550
|
-
GH_TOKEN: "${{ github.token }}",
|
|
551
|
-
RELEASE_TAG: RELEASE_TAG,
|
|
552
|
-
},
|
|
553
|
-
shell: "bash",
|
|
554
|
-
run: [
|
|
555
|
-
"mkdir -p dist/local-release",
|
|
556
|
-
"for ATTEMPT in $(seq 1 360); do",
|
|
557
|
-
' if gh release download "$RELEASE_TAG" --pattern rust-assets.json --dir dist/local-release --clobber; then exit 0; fi',
|
|
558
|
-
' echo "waiting for local release assets ($ATTEMPT/360)"',
|
|
559
|
-
" sleep 5",
|
|
560
|
-
"done",
|
|
561
|
-
'echo "::error::local release assets were not uploaded"',
|
|
562
|
-
"exit 1",
|
|
563
|
-
].join("\n"),
|
|
564
|
-
},
|
|
565
|
-
{
|
|
566
|
-
name: "Confirm native release assets",
|
|
567
|
-
run: "true",
|
|
568
|
-
},
|
|
569
|
-
],
|
|
570
|
-
};
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
export function rustCargoPublishJob(plan: RustReleasePlan, local: boolean): Job {
|
|
574
|
-
const registry = local ? '"${{ vars.LOCAL_CARGO_REGISTRY }}"' : "crates-io";
|
|
575
|
-
return {
|
|
576
|
-
if: local
|
|
577
|
-
? "${{ github.event_name == 'push' && vars.LOCAL_REPOSITORIES == 'true' }}"
|
|
578
|
-
: "${{ github.event_name == 'push' }}",
|
|
579
|
-
needs: ["verify-context", ...(plan.hasTargetOutputs ? ["rust-assets"] : [])],
|
|
580
|
-
runsOn: [local ? "self-hosted" : "ubuntu-latest"],
|
|
581
|
-
permissions: { contents: JobPermission.READ },
|
|
582
285
|
steps: [
|
|
583
286
|
...releaseSourceSteps(),
|
|
584
287
|
{
|
|
@@ -586,290 +289,23 @@ export function rustCargoPublishJob(plan: RustReleasePlan, local: boolean): Job
|
|
|
586
289
|
uses: `dtolnay/rust-toolchain@${plan.releaseRustVersion}`,
|
|
587
290
|
},
|
|
588
291
|
{
|
|
589
|
-
name:
|
|
292
|
+
name: "Publish public crates",
|
|
590
293
|
env: {
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
: "${{ secrets.CARGO_REGISTRY_TOKEN }}",
|
|
294
|
+
RELEASE_VERSION,
|
|
295
|
+
CARGO_REGISTRY_TOKEN: "${{ secrets.CARGO_REGISTRY_TOKEN }}",
|
|
594
296
|
},
|
|
595
297
|
run: plan.publicCrates
|
|
596
|
-
.map((crate) =>
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
export function independentRustCargoPublishJob(
|
|
604
|
-
project: DBXToolsJavaScriptProject,
|
|
605
|
-
plan: RustReleasePlan,
|
|
606
|
-
): Job {
|
|
607
|
-
const commands = plan.publicCrates.map((crate) =>
|
|
608
|
-
[
|
|
609
|
-
`VERSION="$(jq -r --arg package "${crate}" '.rustPackages[] | select(.identity == $package) | .version' dist/release-plan.json)"`,
|
|
610
|
-
'if [ -n "$VERSION" ]; then',
|
|
611
|
-
` if cargo info "${crate}@$VERSION" >/dev/null 2>&1; then`,
|
|
612
|
-
` echo "skip published ${crate}@$VERSION"`,
|
|
613
|
-
" else",
|
|
614
|
-
` cargo publish --package "${crate}" --registry crates-io --no-verify`,
|
|
615
|
-
" fi",
|
|
616
|
-
"fi",
|
|
617
|
-
].join("\n"),
|
|
618
|
-
);
|
|
619
|
-
const buildCondition = rustBuildResultCondition(plan);
|
|
620
|
-
return {
|
|
621
|
-
if: plan.hasTargetOutputs
|
|
622
|
-
? `\${{ always() && needs.release-plan.outputs.rust == 'true' && ${buildCondition} && (github.event_name == 'push' || inputs.stage == 'all' || inputs.stage == 'rust') }}`
|
|
623
|
-
: "${{ needs.release-plan.outputs.rust == 'true' && (github.event_name == 'push' || inputs.stage == 'all' || inputs.stage == 'rust') }}",
|
|
624
|
-
needs: ["release-plan", ...rustBuildJobIds(plan)],
|
|
625
|
-
runsOn: ["ubuntu-latest"],
|
|
626
|
-
permissions: { contents: JobPermission.READ },
|
|
627
|
-
env: { BUN_VERSION },
|
|
628
|
-
steps: [
|
|
629
|
-
...independentReleaseSetupSteps(project),
|
|
630
|
-
{
|
|
631
|
-
name: "Setup Rust",
|
|
632
|
-
uses: `dtolnay/rust-toolchain@${plan.releaseRustVersion}`,
|
|
633
|
-
},
|
|
634
|
-
{
|
|
635
|
-
name: "Publish affected Cargo crates",
|
|
636
|
-
env: { CARGO_REGISTRY_TOKEN: "${{ secrets.CARGO_REGISTRY_TOKEN }}" },
|
|
637
|
-
run: commands.join("\n"),
|
|
638
|
-
},
|
|
639
|
-
],
|
|
640
|
-
};
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
export function independentRustGitHubReleaseJob(
|
|
644
|
-
project: DBXToolsJavaScriptProject,
|
|
645
|
-
plan: RustReleasePlan,
|
|
646
|
-
): Job {
|
|
647
|
-
return {
|
|
648
|
-
if: "${{ needs.release-plan.outputs.github == 'true' && (github.event_name == 'push' || inputs.stage == 'all' || inputs.stage == 'github') }}",
|
|
649
|
-
needs: ["release-plan", ...rustBuildJobIds(plan)],
|
|
650
|
-
runsOn: ["ubuntu-latest"],
|
|
651
|
-
permissions: { contents: JobPermission.WRITE },
|
|
652
|
-
env: { BUN_VERSION },
|
|
653
|
-
steps: [
|
|
654
|
-
...independentReleaseSetupSteps(project),
|
|
655
|
-
{
|
|
656
|
-
name: "Download release binaries",
|
|
657
|
-
uses: "actions/download-artifact@v8",
|
|
658
|
-
with: {
|
|
659
|
-
pattern: "*-binary",
|
|
660
|
-
path: "dist/rust-release",
|
|
661
|
-
"merge-multiple": true,
|
|
662
|
-
},
|
|
663
|
-
},
|
|
664
|
-
{
|
|
665
|
-
name: "Upload affected GitHub release assets",
|
|
666
|
-
env: { GH_TOKEN: "${{ github.token }}" },
|
|
667
|
-
shell: "bash",
|
|
668
|
-
run: plan.releaseBinaries
|
|
669
|
-
.map((binary) => {
|
|
670
|
-
const unit = defaultReleaseUnitId("rust", binary.crate);
|
|
671
|
-
return [
|
|
672
|
-
`VERSION="$(jq -r --arg unit "${unit}" '.units[] | select(.id == $unit) | .newVersion' dist/release-plan.json)"`,
|
|
673
|
-
'if [ -n "$VERSION" ]; then',
|
|
674
|
-
` gh release upload "${unit}-v$VERSION" dist/rust-release/${binary.binary}-* --clobber`,
|
|
675
|
-
"fi",
|
|
676
|
-
].join("\n");
|
|
677
|
-
})
|
|
678
|
-
.join("\n"),
|
|
679
|
-
},
|
|
680
|
-
],
|
|
681
|
-
};
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
export function rustGitHubReleaseJob(plan: RustReleasePlan): Job {
|
|
685
|
-
return {
|
|
686
|
-
if: "${{ github.event_name == 'push' }}",
|
|
687
|
-
needs: ["verify-context", ...(plan.hasTargetOutputs ? ["rust-assets"] : [])],
|
|
688
|
-
runsOn: ["ubuntu-latest"],
|
|
689
|
-
permissions: { contents: JobPermission.WRITE },
|
|
690
|
-
steps: [
|
|
691
|
-
...releaseSourceSteps(),
|
|
692
|
-
{
|
|
693
|
-
name: "Download release binaries",
|
|
694
|
-
if: "${{ needs.verify-context.outputs.build_mode == 'remote' }}",
|
|
695
|
-
uses: "actions/download-artifact@v8",
|
|
696
|
-
with: {
|
|
697
|
-
pattern: "*-binary",
|
|
698
|
-
path: "dist/rust-release",
|
|
699
|
-
"merge-multiple": true,
|
|
700
|
-
},
|
|
701
|
-
},
|
|
702
|
-
{
|
|
703
|
-
name: "Publish GitHub release assets",
|
|
704
|
-
if: "${{ needs.verify-context.outputs.build_mode == 'remote' }}",
|
|
705
|
-
uses: "softprops/action-gh-release@v2",
|
|
706
|
-
with: {
|
|
707
|
-
files: "dist/rust-release/*",
|
|
708
|
-
body_path: RELEASE_SUMMARY_FILE,
|
|
709
|
-
generate_release_notes: true,
|
|
710
|
-
tag_name: RELEASE_TAG,
|
|
711
|
-
target_commitish: RELEASE_SHA,
|
|
712
|
-
},
|
|
713
|
-
},
|
|
714
|
-
{
|
|
715
|
-
name: "Publish locally built GitHub release",
|
|
716
|
-
if: "${{ needs.verify-context.outputs.build_mode == 'local' }}",
|
|
717
|
-
env: {
|
|
718
|
-
GH_TOKEN: "${{ github.token }}",
|
|
719
|
-
RELEASE_NOTES: RELEASE_SUMMARY_FILE,
|
|
720
|
-
RELEASE_TAG,
|
|
721
|
-
},
|
|
722
|
-
run: 'gh release edit "$RELEASE_TAG" --draft=false --latest --notes-file "$RELEASE_NOTES"',
|
|
723
|
-
},
|
|
724
|
-
],
|
|
725
|
-
};
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
export function independentRustNativeNpmPublishJob(project: DBXToolsJavaScriptProject): Job {
|
|
729
|
-
return {
|
|
730
|
-
if: "${{ needs.release-plan.outputs.node == 'true' && (github.event_name == 'push' || inputs.stage == 'all' || inputs.stage == 'node') }}",
|
|
731
|
-
needs: ["release-plan", "rust-build"],
|
|
732
|
-
runsOn: ["ubuntu-latest"],
|
|
733
|
-
permissions: { contents: JobPermission.READ, idToken: JobPermission.WRITE },
|
|
734
|
-
timeoutMinutes: 15,
|
|
735
|
-
env: { BUN_VERSION, CI: "true" },
|
|
736
|
-
steps: [
|
|
737
|
-
...independentReleaseSetupSteps(project),
|
|
738
|
-
{
|
|
739
|
-
name: "Download native npm packages",
|
|
740
|
-
uses: "actions/download-artifact@v8",
|
|
741
|
-
with: {
|
|
742
|
-
pattern: "*-npm",
|
|
743
|
-
path: "dist/uniffi/native",
|
|
744
|
-
"merge-multiple": true,
|
|
745
|
-
},
|
|
746
|
-
},
|
|
747
|
-
{
|
|
748
|
-
name: "Publish affected native npm packages",
|
|
749
|
-
env: npmPublishEnvironment(),
|
|
750
|
-
run: "bun node_modules/@dbx-tools/projen/tasks/publish-npm.ts --directory dist/uniffi/native",
|
|
751
|
-
},
|
|
752
|
-
],
|
|
753
|
-
};
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
export function independentRustNodeFacadePublishJob(
|
|
757
|
-
project: DBXToolsJavaScriptProject,
|
|
758
|
-
bindings: readonly RustBindingMapping[],
|
|
759
|
-
): Job {
|
|
760
|
-
return {
|
|
761
|
-
if: "${{ needs.release-plan.outputs.node == 'true' && (github.event_name == 'push' || inputs.stage == 'all' || inputs.stage == 'node') }}",
|
|
762
|
-
needs: ["release-plan", "publish-node", "publish-native-npm"],
|
|
763
|
-
runsOn: ["ubuntu-latest"],
|
|
764
|
-
permissions: { contents: JobPermission.READ, idToken: JobPermission.WRITE },
|
|
765
|
-
timeoutMinutes: 30,
|
|
766
|
-
env: { BUN_VERSION, CI: "true" },
|
|
767
|
-
steps: [
|
|
768
|
-
...independentReleaseSetupSteps(project),
|
|
769
|
-
{
|
|
770
|
-
name: "Build and publish affected UniFFI npm facades",
|
|
771
|
-
env: npmPublishEnvironment(),
|
|
772
|
-
shell: "bash",
|
|
773
|
-
run: bindings
|
|
774
|
-
.flatMap((binding) => {
|
|
775
|
-
if (!binding.node || !binding.nodePackage) return [];
|
|
776
|
-
const unit = defaultReleaseUnitId("rust", binding.crate);
|
|
777
|
-
const output = `dist/uniffi/facades/${binding.crate}`;
|
|
778
|
-
return [
|
|
779
|
-
`VERSION="$(jq -r --arg unit "${unit}" '.units[] | select(.id == $unit) | .newVersion' dist/release-plan.json)"`,
|
|
780
|
-
'if [ -n "$VERSION" ]; then',
|
|
781
|
-
` node .projen/uniffi-release.mjs facade --node "${binding.node}" --node-package "${binding.nodePackage}" --node-triple "linux-x64-gnu" --version "$VERSION" --output "${output}"`,
|
|
782
|
-
` bun node_modules/@dbx-tools/projen/tasks/publish-npm.ts --directory "${output}/npm-facade" --version "$VERSION"`,
|
|
298
|
+
.map((crate) =>
|
|
299
|
+
[
|
|
300
|
+
`if cargo info "${crate}@$RELEASE_VERSION" >/dev/null 2>&1; then`,
|
|
301
|
+
` echo "skip published ${crate}@$RELEASE_VERSION"`,
|
|
302
|
+
"else",
|
|
303
|
+
` cargo publish --package "${crate}" --registry crates-io --locked`,
|
|
783
304
|
"fi",
|
|
784
|
-
]
|
|
785
|
-
|
|
786
|
-
.join("\n"),
|
|
787
|
-
},
|
|
788
|
-
],
|
|
789
|
-
};
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
export function rustNativeNpmPublishJob(project: DBXToolsJavaScriptProject): Job {
|
|
793
|
-
return {
|
|
794
|
-
if: "${{ always() && needs.verify-context.result == 'success' && needs.rust-assets.result == 'success' && (github.event_name == 'push' || inputs.stage == 'all' || inputs.stage == 'node') }}",
|
|
795
|
-
needs: ["verify-context", "rust-assets"],
|
|
796
|
-
runsOn: ["ubuntu-latest"],
|
|
797
|
-
permissions: {
|
|
798
|
-
actions: JobPermission.READ,
|
|
799
|
-
contents: JobPermission.READ,
|
|
800
|
-
idToken: JobPermission.WRITE,
|
|
801
|
-
},
|
|
802
|
-
timeoutMinutes: 15,
|
|
803
|
-
env: { BUN_VERSION, CI: "true" },
|
|
804
|
-
steps: [
|
|
805
|
-
...nodeReleaseSetupSteps(project),
|
|
806
|
-
...releaseArtifactSteps({
|
|
807
|
-
currentName: "Download native npm packages",
|
|
808
|
-
recoveredName: "Download recovered native npm packages",
|
|
809
|
-
pattern: "*-npm",
|
|
810
|
-
path: "dist/uniffi/native",
|
|
811
|
-
condition: "needs.verify-context.outputs.build_mode == 'remote'",
|
|
812
|
-
}),
|
|
813
|
-
{
|
|
814
|
-
name: "Download locally built native npm packages",
|
|
815
|
-
if: "${{ needs.verify-context.outputs.build_mode == 'local' }}",
|
|
816
|
-
env: { GH_TOKEN: "${{ github.token }}", RELEASE_TAG },
|
|
817
|
-
run: [
|
|
818
|
-
"mkdir -p dist/uniffi/native",
|
|
819
|
-
'gh release download "$RELEASE_TAG" --pattern "*.tgz" --dir dist/uniffi/native',
|
|
820
|
-
].join("\n"),
|
|
821
|
-
},
|
|
822
|
-
{
|
|
823
|
-
name: "Publish native npm packages",
|
|
824
|
-
env: { RELEASE_VERSION, ...npmPublishEnvironment() },
|
|
825
|
-
run: 'bun node_modules/@dbx-tools/projen/tasks/publish-npm.ts --directory dist/uniffi/native --version "$RELEASE_VERSION" $DRY_RUN',
|
|
826
|
-
},
|
|
827
|
-
],
|
|
828
|
-
};
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
export function rustNodeFacadePublishJob(
|
|
832
|
-
project: DBXToolsJavaScriptProject,
|
|
833
|
-
bindings: readonly RustReleaseBinding[],
|
|
834
|
-
): Job {
|
|
835
|
-
return {
|
|
836
|
-
if: releaseStageCondition("node"),
|
|
837
|
-
needs: ["verify-context", "publish-node"],
|
|
838
|
-
runsOn: ["ubuntu-latest"],
|
|
839
|
-
permissions: { contents: JobPermission.READ, idToken: JobPermission.WRITE },
|
|
840
|
-
timeoutMinutes: 30,
|
|
841
|
-
env: { BUN_VERSION, CI: "true" },
|
|
842
|
-
steps: [
|
|
843
|
-
...nodeReleaseSetupSteps(project),
|
|
844
|
-
{
|
|
845
|
-
name: "Build and publish UniFFI npm facades",
|
|
846
|
-
env: { RELEASE_VERSION, ...npmPublishEnvironment() },
|
|
847
|
-
run: bindings
|
|
848
|
-
.flatMap((binding) => {
|
|
849
|
-
const output = `dist/uniffi/facades/${binding.crate}`;
|
|
850
|
-
return [
|
|
851
|
-
`node .projen/uniffi-release.mjs facade --node "${binding.node}" --node-package "${binding.nodePackage}" --node-triple "linux-x64-gnu" --version "$RELEASE_VERSION" --output "${output}"`,
|
|
852
|
-
`bun node_modules/@dbx-tools/projen/tasks/publish-npm.ts --directory "${output}/npm-facade" --version "$RELEASE_VERSION" $DRY_RUN`,
|
|
853
|
-
];
|
|
854
|
-
})
|
|
305
|
+
].join("\n"),
|
|
306
|
+
)
|
|
855
307
|
.join("\n"),
|
|
856
308
|
},
|
|
857
|
-
{
|
|
858
|
-
name: "Smoke test published UniFFI npm facades",
|
|
859
|
-
if: "${{ github.event_name == 'push' && vars.UNIFFI_FACADE_SMOKE == 'true' }}",
|
|
860
|
-
continueOnError: true,
|
|
861
|
-
env: { RELEASE_VERSION },
|
|
862
|
-
run: [
|
|
863
|
-
'SMOKE_DIR="$(mktemp -d)"',
|
|
864
|
-
"trap 'rm -rf \"$SMOKE_DIR\"' EXIT",
|
|
865
|
-
'cd "$SMOKE_DIR"',
|
|
866
|
-
"npm init --yes >/dev/null",
|
|
867
|
-
...bindings.flatMap((binding) => [
|
|
868
|
-
`npm install --ignore-scripts --no-audit --no-fund --package-lock=false "${binding.nodePackage}@$RELEASE_VERSION"`,
|
|
869
|
-
`node -e 'import("${binding.nodePackage}")'`,
|
|
870
|
-
]),
|
|
871
|
-
].join("\n"),
|
|
872
|
-
},
|
|
873
309
|
],
|
|
874
310
|
};
|
|
875
311
|
}
|