@dbx-tools/projen 0.6.168 → 0.6.174

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/src/project-rs.ts CHANGED
@@ -5,14 +5,14 @@ import { fileURLToPath } from "node:url";
5
5
  import { project as coreProject } from "@dbx-tools/core";
6
6
  import { string } from "@dbx-tools/shared-core";
7
7
  import { Project, TextFile, YamlFile, javascript } from "projen";
8
- import { BUN_VERSION, bunCacheRestoreSteps, bunCacheSaveStep } from "./bun-workflow.ts";
9
- import type { DBXToolsProject } from "./project.ts";
10
8
  import {
11
9
  DBXToolsTypeScriptProject,
12
10
  projectReleaseBranch,
13
11
  projectRepositoryUrl,
14
12
  } from "./project-js.ts";
13
+ import { isDBXToolsJavaScriptProject } from "./project-predicate.ts";
15
14
  import { pythonModuleName, type PythonPackageOptions } from "./project-py.ts";
15
+ import type { DBXToolsProject } from "./project.ts";
16
16
  import {
17
17
  DOWNSTREAM_RELEASE_EVENT,
18
18
  RELEASE_SHA,
@@ -21,7 +21,6 @@ import {
21
21
  releaseSourceSteps,
22
22
  } from "./release-dispatch.ts";
23
23
  import { readWorkspaceVersion } from "./workspace-version.ts";
24
- import { isDBXToolsJavaScriptProject } from "./project-predicate.ts";
25
24
 
26
25
  export interface CargoDependencyOptions {
27
26
  readonly version?: string;
@@ -62,8 +61,6 @@ export interface DBXToolsRustWorkspaceOptions {
62
61
  readonly rustVersion?: string;
63
62
  /** Rust toolchain used by release builds. Defaults to `stable`. */
64
63
  readonly releaseRustVersion?: string;
65
- /** Rust toolchain used to compile the host-side UBRN generator. Defaults to releaseRustVersion. */
66
- readonly ubrnRustVersion?: string;
67
64
  readonly license?: string;
68
65
  readonly repository?: string;
69
66
  readonly workspaceDependencies?: Readonly<Record<string, CargoDependency>>;
@@ -80,6 +77,8 @@ export interface DBXToolsRustWorkspaceOptions {
80
77
  readonly releasePlatforms?: readonly RustReleasePlatform[];
81
78
  /** Workflow name used by downstream release stages. Defaults to `rust-release`. */
82
79
  readonly releaseWorkflowName?: string;
80
+ /** Workflow that publishes generated Python wheels. Defaults to `python-release`. */
81
+ readonly pythonReleaseWorkflowName?: string;
83
82
  /** Tag prefix dispatched into the branch-scoped release workflow. Defaults to `v`. */
84
83
  readonly releaseTagPrefix?: string;
85
84
  }
@@ -268,8 +267,9 @@ export function orderRustBindings(bindings: readonly RustBindingMapping[]): Rust
268
267
  const completed = new Set<string>();
269
268
  const visit = (binding: RustBindingMapping): void => {
270
269
  if (completed.has(binding.crate)) return;
271
- if (visiting.has(binding.crate))
270
+ if (visiting.has(binding.crate)) {
272
271
  throw new Error(`Cyclic Rust binding dependency: ${binding.crate}`);
272
+ }
273
273
  visiting.add(binding.crate);
274
274
  for (const name of binding.dependencies ?? []) {
275
275
  const dependency = bindings.find((candidate) => candidate.crate === name);
@@ -446,7 +446,7 @@ export class DBXToolsRustProject extends Project implements DBXToolsProject {
446
446
  }
447
447
  }
448
448
 
449
- /** Generated Rust workspace plus convention-derived private UniFFI packages. */
449
+ /** Generated Rust workspace plus convention-derived UniFFI facade packages. */
450
450
  export class DBXToolsRustWorkspace {
451
451
  readonly packages: readonly DBXToolsRustProject[];
452
452
  readonly nodePackages: readonly DBXToolsTypeScriptProject[];
@@ -585,13 +585,16 @@ export class DBXToolsRustWorkspace {
585
585
  name: pkg.crateName,
586
586
  module,
587
587
  description: `Python bindings for ${pkg.crateName}`,
588
- private: true,
588
+ uniffi: true,
589
589
  internalDependencies: bindingDependencies(pkg, "python").map(
590
590
  (dependency) => dependency.packageOptions.directory,
591
591
  ),
592
- generatedSources: [`src/${module.replaceAll(".", "/")}/bindings.py`],
592
+ generatedSources: [
593
+ `src/${module.replaceAll(".", "/")}/bindings.py`,
594
+ `src/${module.replaceAll(".", "/")}/__init__.py`,
595
+ ],
593
596
  trustedPublisher: {
594
- workflowName: options.releaseWorkflowName ?? "rust-release",
597
+ workflowName: options.pythonReleaseWorkflowName ?? "python-release",
595
598
  environment: `pypi-${pkg.crateName}`,
596
599
  artifacts: `platform-specific wheels for ${releaseTargets(options)
597
600
  .map((target) => `${target.os}-${target.cpu}`)
@@ -610,21 +613,23 @@ export class DBXToolsRustWorkspace {
610
613
  const directory = binding.packageOptions.directory;
611
614
  const memberPath = `${nodeRoot}/${directory}`;
612
615
  const found = existing.get(memberPath);
613
- const node =
614
- found instanceof DBXToolsTypeScriptProject
615
- ? found
616
- : new DBXToolsTypeScriptProject({
617
- parent: project,
618
- outdir: memberPath,
619
- name: `@${scope}/${directory.toLowerCase().replace(/[^a-z0-9-]+/g, "-")}`,
620
- tags: ["node"],
621
- });
616
+ const existingNode = found instanceof DBXToolsTypeScriptProject ? found : undefined;
617
+ const node = existingNode
618
+ ? existingNode
619
+ : new DBXToolsTypeScriptProject({
620
+ parent: project,
621
+ outdir: memberPath,
622
+ name: `@${scope}/${directory.toLowerCase().replace(/[^a-z0-9-]+/g, "-")}`,
623
+ tags: ["node"],
624
+ });
622
625
  node.package.addField(
623
626
  "name",
624
627
  `@${scope}/${directory.toLowerCase().replace(/[^a-z0-9-]+/g, "-")}`,
625
628
  );
626
- node.package.addField("private", true);
627
- node.package.addField("description", `Node bindings for ${binding.crateName}`);
629
+ node.dbxToolsConfig.uniffi = true;
630
+ if (!existingNode) {
631
+ node.package.addField("description", `Node bindings for ${binding.crateName}`);
632
+ }
628
633
  const nativeTargets = releaseTargets(options);
629
634
  if (options.release ?? true) {
630
635
  node.package.addField(
@@ -650,9 +655,6 @@ export class DBXToolsRustWorkspace {
650
655
  if (binding.packageOptions.nodeDevDependencies?.length) {
651
656
  node.addDevDeps(...binding.packageOptions.nodeDevDependencies);
652
657
  }
653
- new TextFile(node, "exports.ts", {
654
- lines: ['export * from "./src/bindings.ts";', ""],
655
- });
656
658
  nodePackages.push(node);
657
659
  }
658
660
  this.nodePackages = nodePackages;
@@ -723,15 +725,6 @@ export class DBXToolsRustWorkspace {
723
725
  const workflowName = options.releaseWorkflowName ?? "rust-release";
724
726
  const releaseTagPrefix = options.releaseTagPrefix ?? "v";
725
727
  const releaseRustVersion = options.releaseRustVersion ?? "stable";
726
- const ubrnRustVersion = options.ubrnRustVersion ?? releaseRustVersion;
727
- const ubrnToolchainInstall =
728
- ubrnRustVersion === releaseRustVersion
729
- ? ""
730
- : `rustup toolchain install ${ubrnRustVersion} --profile minimal\n`;
731
- const ubrnExecutable =
732
- "${{ github.workspace }}/.cache/ubrn/uniffi-bindgen-react-native${{ matrix.target.os == 'win32' && '.exe' || '' }}";
733
- const builtUbrnExecutable =
734
- "target/ubrn/debug/uniffi-bindgen-react-native${{ matrix.target.os == 'win32' && '.exe' || '' }}";
735
728
  const releaseBranch = projectReleaseBranch(project);
736
729
  const bindings = this.bindingMappings.map((binding) => ({
737
730
  ...binding,
@@ -753,14 +746,8 @@ export class DBXToolsRustWorkspace {
753
746
  return order.indexOf(first.crateName) - order.indexOf(second.crateName);
754
747
  })
755
748
  .map((pkg) => pkg.crateName);
756
- const targetMatrix = targets.map((target, index) => ({
757
- target: { ...target, facade: index === 0 },
758
- }));
759
- const hasNodeBindings = bindings.some((binding) => binding.node);
749
+ const targetMatrix = targets.map((target) => ({ target }));
760
750
  const hasPythonBindings = bindings.some((binding) => binding.python);
761
- const facadeCondition = "matrix.target.facade";
762
- const facadeCacheMissCondition =
763
- "matrix.target.facade && steps.ubrn_cache.outputs.cache-hit != 'true'";
764
751
  const usePreinstalledWindowsRust = releaseRustVersion === "stable";
765
752
  const hasTargetOutputs =
766
753
  bindings.length > 0 || releaseBinaries.length > 0 || publicCrates.length > 0;
@@ -783,16 +770,12 @@ export class DBXToolsRustWorkspace {
783
770
  `--python "${binding.python}"`,
784
771
  `--node-package "${binding.nodePackage}"`,
785
772
  `--python-package "${binding.pythonPackage}"`,
786
- ...(binding.node
787
- ? ['--node-generator "projen/tasks/uniffi.ts"', '--ubrn "$UBRN_EXECUTABLE"']
788
- : []),
789
773
  '--cargo-target "${{ matrix.target.cargo }}"',
790
774
  '--node-triple "${{ matrix.target.node }}"',
791
775
  '--python-tag "${{ matrix.target.python }}"',
792
776
  '--os "${{ matrix.target.os }}"',
793
777
  '--cpu "${{ matrix.target.cpu }}"',
794
778
  '--libc "${{ matrix.target.libc }}"',
795
- '--facade "${{ matrix.target.facade }}"',
796
779
  `--version "\${VERSION#${releaseTagPrefix}}"`,
797
780
  `--output "dist/release/${binding.crate}/\${{ matrix.target.node }}"`,
798
781
  "--skip-build",
@@ -820,15 +803,7 @@ export class DBXToolsRustWorkspace {
820
803
  with: {
821
804
  name: `${binding.crate}-\${{ matrix.target.node }}-npm`,
822
805
  path: `dist/release/${binding.crate}/\${{ matrix.target.node }}/npm/*.tgz`,
823
- },
824
- },
825
- {
826
- name: `Upload ${binding.crate} npm facade`,
827
- if: "${{ matrix.target.facade }}",
828
- uses: "actions/upload-artifact@v7",
829
- with: {
830
- name: `${binding.crate}-npm-facade`,
831
- path: `dist/release/${binding.crate}/\${{ matrix.target.node }}/npm-facade/*.tgz`,
806
+ "retention-days": 7,
832
807
  },
833
808
  },
834
809
  ]
@@ -839,8 +814,9 @@ export class DBXToolsRustWorkspace {
839
814
  name: `Upload ${binding.crate} Python wheel`,
840
815
  uses: "actions/upload-artifact@v7",
841
816
  with: {
842
- name: `${binding.crate}-\${{ matrix.target.python }}-python-wheel`,
817
+ name: `${binding.crate}--\${{ matrix.target.python }}--python-wheel`,
843
818
  path: `dist/release/${binding.crate}/\${{ matrix.target.node }}/python/*.whl`,
819
+ "retention-days": 7,
844
820
  },
845
821
  },
846
822
  ]
@@ -852,6 +828,7 @@ export class DBXToolsRustWorkspace {
852
828
  with: {
853
829
  name: `${pkg.crate}-\${{ matrix.target.node }}-binary`,
854
830
  path: `dist/release/${pkg.crate}/\${{ matrix.target.node }}/binary/*`,
831
+ "retention-days": 7,
855
832
  },
856
833
  })),
857
834
  ];
@@ -861,7 +838,6 @@ export class DBXToolsRustWorkspace {
861
838
  "runs-on": "${{ matrix.target.runner }}",
862
839
  env: {
863
840
  ...RUST_CACHE_ENV,
864
- BUN_VERSION,
865
841
  SCCACHE_GHA_VERSION: `release-\${{ matrix.target.cargo }}-rust-${releaseRustVersion}`,
866
842
  },
867
843
  strategy: {
@@ -893,26 +869,6 @@ export class DBXToolsRustWorkspace {
893
869
  ]
894
870
  : []),
895
871
  ...rustCacheSteps(`release-\${{ matrix.target.cargo }}-rust-${releaseRustVersion}`),
896
- ...(hasNodeBindings
897
- ? [
898
- {
899
- name: "Restore UBRN executable",
900
- id: "ubrn_cache",
901
- if: "${{ matrix.target.facade }}",
902
- uses: "actions/cache/restore@v5",
903
- with: {
904
- path: ".cache/ubrn",
905
- key: `ubrn-executable-\${{ runner.os }}-\${{ runner.arch }}-rust-${ubrnRustVersion}-${UBRN_VERSION}`,
906
- },
907
- },
908
- ]
909
- : []),
910
- ...(hasNodeBindings
911
- ? bunCacheRestoreSteps(project, {
912
- setupCondition: facadeCondition,
913
- condition: facadeCacheMissCondition,
914
- })
915
- : []),
916
872
  {
917
873
  name: "Log cache configuration",
918
874
  shell: "bash",
@@ -921,13 +877,6 @@ export class DBXToolsRustWorkspace {
921
877
  'echo "cargo_cache_hit=${{ steps.cargo_cache.outputs.cache-hit }}"',
922
878
  'echo "sccache_scope=${{ github.ref }}"',
923
879
  'echo "sccache_namespace=${SCCACHE_GHA_VERSION}"',
924
- `echo "ubrn_rust_toolchain=${ubrnRustVersion}"`,
925
- ...(hasNodeBindings
926
- ? [
927
- `echo "ubrn_executable_cache_key=ubrn-executable-\${{ runner.os }}-\${{ runner.arch }}-rust-${ubrnRustVersion}-${UBRN_VERSION}"`,
928
- 'echo "ubrn_executable_cache_hit=${{ steps.ubrn_cache.outputs.cache-hit }}"',
929
- ]
930
- : []),
931
880
  ].join("\n"),
932
881
  },
933
882
  {
@@ -935,57 +884,6 @@ export class DBXToolsRustWorkspace {
935
884
  if: "${{ matrix.target.os == 'linux' }}",
936
885
  run: "sudo apt-get update && sudo apt-get install --yes libdbus-1-dev pkg-config",
937
886
  },
938
- ...(hasNodeBindings
939
- ? [
940
- {
941
- name: "Install Node tooling",
942
- if: "${{ matrix.target.facade && steps.ubrn_cache.outputs.cache-hit != 'true' }}",
943
- shell: "bash",
944
- run: timedBash("node_tooling", "bun install"),
945
- },
946
- bunCacheSaveStep({
947
- condition: facadeCacheMissCondition,
948
- }),
949
- ]
950
- : []),
951
- ...(hasNodeBindings
952
- ? [
953
- {
954
- name: "Prepare UBRN generator",
955
- if: "${{ matrix.target.facade && steps.ubrn_cache.outputs.cache-hit != 'true' }}",
956
- env: {
957
- CARGO_TARGET_DIR: "${{ github.workspace }}/target/ubrn",
958
- UBRN_EXECUTABLE: ubrnExecutable,
959
- },
960
- shell: "bash",
961
- run: timedBash(
962
- "ubrn_generator",
963
- [
964
- `${ubrnToolchainInstall}cargo +${ubrnRustVersion} build --manifest-path node_modules/uniffi-bindgen-react-native/crates/ubrn_cli/Cargo.toml`,
965
- 'mkdir -p "$(dirname "$UBRN_EXECUTABLE")"',
966
- `cp "${builtUbrnExecutable}" "$UBRN_EXECUTABLE"`,
967
- 'chmod +x "$UBRN_EXECUTABLE"',
968
- ].join("\n"),
969
- ),
970
- },
971
- {
972
- name: "Verify UBRN executable",
973
- if: "${{ matrix.target.facade }}",
974
- env: { UBRN_EXECUTABLE: ubrnExecutable },
975
- shell: "bash",
976
- run: 'test -f "$UBRN_EXECUTABLE"',
977
- },
978
- {
979
- name: "Save UBRN executable",
980
- if: "${{ matrix.target.facade && steps.ubrn_cache.outputs.cache-hit != 'true' }}",
981
- uses: "actions/cache/save@v5",
982
- with: {
983
- path: ".cache/ubrn",
984
- key: "${{ steps.ubrn_cache.outputs.cache-primary-key }}",
985
- },
986
- },
987
- ]
988
- : []),
989
887
  {
990
888
  name: "Build Rust outputs",
991
889
  shell: "bash",
@@ -1003,14 +901,7 @@ export class DBXToolsRustWorkspace {
1003
901
  {
1004
902
  name: "Package UniFFI outputs",
1005
903
  shell: "bash",
1006
- env: {
1007
- VERSION: RELEASE_TAG,
1008
- ...(hasNodeBindings
1009
- ? {
1010
- UBRN_EXECUTABLE: ubrnExecutable,
1011
- }
1012
- : {}),
1013
- },
904
+ env: { VERSION: RELEASE_TAG },
1014
905
  run: timedBash("uniffi_packaging", bindingCommands.join("\n")),
1015
906
  },
1016
907
  ]
@@ -1033,83 +924,8 @@ export class DBXToolsRustWorkspace {
1033
924
  },
1034
925
  ],
1035
926
  };
1036
- const bindingPublishJobs = Object.fromEntries(
1037
- bindings.map((binding) => [
1038
- `publish-${binding.crate}`,
1039
- {
1040
- if: "${{ github.event_name == 'repository_dispatch' }}",
1041
- needs: [
1042
- "build",
1043
- ...(binding.dependencies ?? []).map((dependency) => `publish-${dependency}`),
1044
- ],
1045
- "runs-on": "ubuntu-latest",
1046
- permissions: {
1047
- contents: "read",
1048
- ...(binding.python ? { "id-token": "write" } : {}),
1049
- },
1050
- ...(binding.python ? { environment: { name: `pypi-${binding.crate}` } } : {}),
1051
- steps: [
1052
- ...(binding.node
1053
- ? [
1054
- {
1055
- name: "Setup Node.js",
1056
- uses: "actions/setup-node@v6",
1057
- with: { "registry-url": "https://registry.npmjs.org" },
1058
- },
1059
- {
1060
- name: "Download native npm packages",
1061
- uses: "actions/download-artifact@v8",
1062
- with: {
1063
- pattern: `${binding.crate}-*-npm`,
1064
- path: "dist/npm",
1065
- "merge-multiple": true,
1066
- },
1067
- },
1068
- {
1069
- name: "Download npm facade",
1070
- uses: "actions/download-artifact@v8",
1071
- with: {
1072
- name: `${binding.crate}-npm-facade`,
1073
- path: "dist/npm-facade",
1074
- },
1075
- },
1076
- {
1077
- name: "Publish native npm packages",
1078
- env: { NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}" },
1079
- run: 'for package in dist/npm/*.tgz; do npm publish "$package" --access public; done',
1080
- },
1081
- {
1082
- name: "Publish npm facade",
1083
- env: { NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}" },
1084
- run: 'for package in dist/npm-facade/*.tgz; do npm publish "$package" --access public; done',
1085
- },
1086
- ]
1087
- : []),
1088
- ...(binding.python
1089
- ? [
1090
- { name: "Setup uv", uses: "astral-sh/setup-uv@v7" },
1091
- {
1092
- name: "Download Python wheels",
1093
- uses: "actions/download-artifact@v8",
1094
- with: {
1095
- pattern: `${binding.crate}-*-python-wheel`,
1096
- path: "dist/python",
1097
- "merge-multiple": true,
1098
- },
1099
- },
1100
- {
1101
- name: "Publish Python wheels",
1102
- run: "uv publish --trusted-publishing always dist/python/*.whl",
1103
- },
1104
- ]
1105
- : []),
1106
- ],
1107
- },
1108
- ]),
1109
- );
1110
927
  const releaseCompletionJobs = [
1111
928
  "build",
1112
- ...bindings.map((binding) => `publish-${binding.crate}`),
1113
929
  ...(publicCrates.length ? ["publish-cargo"] : []),
1114
930
  ...(releaseBinaries.length ? ["publish-github-release"] : []),
1115
931
  ];
@@ -1177,7 +993,6 @@ export class DBXToolsRustWorkspace {
1177
993
  ],
1178
994
  },
1179
995
  ...(hasTargetOutputs && targetMatrix.length ? { build: buildJob } : {}),
1180
- ...bindingPublishJobs,
1181
996
  ...(publicCrates.length
1182
997
  ? {
1183
998
  "publish-cargo": {
@@ -1205,79 +1020,6 @@ export class DBXToolsRustWorkspace {
1205
1020
  },
1206
1021
  }
1207
1022
  : {}),
1208
- ...(bindings.length
1209
- ? {
1210
- "publish-local-bindings": {
1211
- if: "${{ github.event_name == 'repository_dispatch' && vars.LOCAL_REPOSITORIES == 'true' }}",
1212
- needs: ["build"],
1213
- "runs-on": ["self-hosted"],
1214
- permissions: { contents: "read" },
1215
- steps: [
1216
- ...(hasNodeBindings
1217
- ? [
1218
- {
1219
- name: "Setup Node.js",
1220
- uses: "actions/setup-node@v6",
1221
- with: {
1222
- "registry-url": "${{ vars.LOCAL_NPM_REGISTRY }}",
1223
- },
1224
- },
1225
- {
1226
- name: "Download native npm packages",
1227
- uses: "actions/download-artifact@v8",
1228
- with: {
1229
- pattern: "*-npm",
1230
- path: "dist/npm",
1231
- "merge-multiple": true,
1232
- },
1233
- },
1234
- {
1235
- name: "Download npm facades",
1236
- uses: "actions/download-artifact@v8",
1237
- with: {
1238
- pattern: "*-npm-facade",
1239
- path: "dist/npm-facade",
1240
- "merge-multiple": true,
1241
- },
1242
- },
1243
- {
1244
- name: "Publish npm packages locally",
1245
- env: {
1246
- NODE_AUTH_TOKEN: "${{ secrets.LOCAL_NPM_TOKEN }}",
1247
- },
1248
- run: [
1249
- 'for package in dist/npm/*.tgz; do npm publish "$package" --access public; done',
1250
- 'for package in dist/npm-facade/*.tgz; do npm publish "$package" --access public; done',
1251
- ].join("\n"),
1252
- },
1253
- ]
1254
- : []),
1255
- ...(hasPythonBindings
1256
- ? [
1257
- { name: "Setup uv", uses: "astral-sh/setup-uv@v7" },
1258
- {
1259
- name: "Download Python wheels",
1260
- uses: "actions/download-artifact@v8",
1261
- with: {
1262
- pattern: "*-python-wheel",
1263
- path: "dist/python",
1264
- "merge-multiple": true,
1265
- },
1266
- },
1267
- {
1268
- name: "Publish Python wheels locally",
1269
- env: {
1270
- UV_PUBLISH_USERNAME: "${{ secrets.LOCAL_PYPI_USERNAME }}",
1271
- UV_PUBLISH_PASSWORD: "${{ secrets.LOCAL_PYPI_PASSWORD }}",
1272
- },
1273
- run: 'uv publish --publish-url "${{ vars.LOCAL_PYPI_PUBLISH_URL }}" dist/python/*.whl',
1274
- },
1275
- ]
1276
- : []),
1277
- ],
1278
- },
1279
- }
1280
- : {}),
1281
1023
  ...(publicCrates.length
1282
1024
  ? {
1283
1025
  "publish-local-cargo": {
@@ -1352,6 +1094,8 @@ export class DBXToolsRustWorkspace {
1352
1094
  RELEASE_TAG,
1353
1095
  EXPECTED_SHA: RELEASE_SHA,
1354
1096
  RELEASE_EVENT: DOWNSTREAM_RELEASE_EVENT,
1097
+ RUST_RUN_ID: "${{ github.run_id }}",
1098
+ RUST_RUN_ATTEMPT: "${{ github.run_attempt }}",
1355
1099
  },
1356
1100
  run: [
1357
1101
  [
@@ -1359,6 +1103,8 @@ export class DBXToolsRustWorkspace {
1359
1103
  '--raw-field event_type="$RELEASE_EVENT"',
1360
1104
  '--raw-field "client_payload[release_tag]=$RELEASE_TAG"',
1361
1105
  '--raw-field "client_payload[expected_sha]=$EXPECTED_SHA"',
1106
+ '--raw-field "client_payload[rust_run_id]=$RUST_RUN_ID"',
1107
+ '--raw-field "client_payload[rust_run_attempt]=$RUST_RUN_ATTEMPT"',
1362
1108
  ].join(" \\\n "),
1363
1109
  ].join("\n"),
1364
1110
  },