@rightkit/release 0.6.8 → 0.6.11
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 +30 -12
- package/admission-files.mjs +4 -1
- package/admission.mjs +2 -2
- package/advisory-exceptions.mjs +41 -5
- package/android-play-upload.mjs +16 -15
- package/app-check.mjs +105 -27
- package/assemble-app-command.mjs +151 -0
- package/assembled-app.mjs +445 -0
- package/bin/darwin/rightkit-swap +0 -0
- package/bin/darwin/rightkit-swap.sign.json +6 -0
- package/bin/rightkit-gate.mjs +1608 -345
- package/broker-pins.mjs +152 -0
- package/build-launch.mjs +88 -0
- package/build-ownership.mjs +1231 -0
- package/build-release.mjs +82 -28
- package/cargo-contract.mjs +3 -1
- package/cargo-ledger.mjs +62 -0
- package/cargo-target-shim.mjs +238 -0
- package/class-a-launch-guard.mjs +126 -0
- package/cli/right-release.mjs +31 -5
- package/clippy-equivalence.mjs +202 -0
- package/clippy-route.mjs +543 -0
- package/codesign-shim.mjs +11 -1
- package/committed-source.mjs +39 -5
- package/crate-workspaces.mjs +87 -0
- package/create-mac-updater.mjs +14 -2
- package/deterministic-scans.mjs +997 -71
- package/development-signing.mjs +4 -1
- package/development.mjs +120 -21
- package/direct-receipt.mjs +135 -0
- package/door-policy.mjs +71 -6
- package/door.mjs +6 -6
- package/freshness-census.mjs +257 -0
- package/gate-executor.mjs +14 -2
- package/gate-stages.mjs +91 -15
- package/heavy-command.mjs +3 -2
- package/hook-retirement.mjs +65 -0
- package/init-command.mjs +1 -1
- package/install-app.mjs +11 -2
- package/install-assembled-app.mjs +423 -0
- package/inventory-check.mjs +11 -8
- package/ios-dev.mjs +70 -3
- package/ios-upload.mjs +20 -15
- package/linux-artifacts.mjs +93 -0
- package/local-publish.mjs +224 -53
- package/local-qualify.mjs +5 -3
- package/local-runtime.mjs +5 -4
- package/mac-package-recipe.mjs +4 -1
- package/managed-cargo.mjs +47 -5
- package/managed-root-guard.mjs +34 -0
- package/mirror-root-artifact.mjs +18 -5
- package/native-helpers.mjs +355 -0
- package/ownership-class-rules.mjs +1 -1
- package/ownership-evidence.mjs +37 -13
- package/ownership-hooks.mjs +20 -59
- package/ownership-lockfiles.mjs +14 -1
- package/ownership-policy-bundle.mjs +3 -2
- package/ownership-staged.mjs +2 -1
- package/ownership.mjs +24 -0
- package/package-recipe-targets.mjs +84 -10
- package/package.json +4 -3
- package/pipeline-admission.mjs +4 -4
- package/pipeline-receipts.mjs +302 -302
- package/preflight.mjs +27 -4
- package/project-type.mjs +2 -2
- package/provenance-verify.mjs +115 -0
- package/publish-cargo.mjs +12 -9
- package/qa-admission-policy.json +10 -1
- package/recipe-build.mjs +106 -14
- package/release-artifact-path.mjs +341 -0
- package/release-config.mjs +1 -1
- package/release-invocation.mjs +8 -1
- package/release-qa-command.mjs +25 -9
- package/release-source-brand.mjs +17 -0
- package/release-source-identity.mjs +171 -0
- package/release.mjs +59 -22
- package/rightkit-versions.json +73 -47
- package/runtime-budgets.mjs +6 -2
- package/scan-digest.mjs +71 -5
- package/sign-updater.mjs +6 -3
- package/snapshot-broker.mjs +172 -0
- package/snapshot-check.mjs +312 -0
- package/snapshot-git.mjs +166 -0
- package/snapshot-request.mjs +363 -0
- package/snapshot-root-config.mjs +76 -0
- package/snapshot.mjs +969 -0
- package/source-split.mjs +73 -0
- package/stage-commands.mjs +60 -0
- package/stage-ledger.mjs +204 -0
- package/stage-sidecar-command.mjs +5 -1
- package/stage-sidecar.mjs +157 -27
- package/swap-helper-bundle.mjs +5 -2
- package/test-command.mjs +17 -4
- package/unit-gate.mjs +301 -0
- package/web-build.mjs +40 -6
- package/win-package-recipe.mjs +20 -7
package/rightkit-versions.json
CHANGED
|
@@ -26,13 +26,13 @@
|
|
|
26
26
|
"@rightkit/logs": "0.1.6",
|
|
27
27
|
"@rightkit/media-ui": "0.3.4",
|
|
28
28
|
"@rightkit/onboarding": "0.6.3",
|
|
29
|
-
"@rightkit/outdated": "0.
|
|
29
|
+
"@rightkit/outdated": "0.3.0",
|
|
30
30
|
"@rightkit/pdf-ui": "0.2.0",
|
|
31
31
|
"@rightkit/platform-ui": "0.4.0",
|
|
32
|
-
"@rightkit/qa": "0.6.
|
|
32
|
+
"@rightkit/qa": "0.6.2",
|
|
33
33
|
"@rightkit/qa-chrome": "0.1.12",
|
|
34
34
|
"@rightkit/react-shell": "0.7.2",
|
|
35
|
-
"@rightkit/release": "0.6.
|
|
35
|
+
"@rightkit/release": "0.6.11",
|
|
36
36
|
"@rightkit/settings-ui": "0.7.0",
|
|
37
37
|
"@rightkit/tauri": "0.3.0",
|
|
38
38
|
"@rightkit/tauri-shell": "0.1.3",
|
|
@@ -236,7 +236,8 @@
|
|
|
236
236
|
"0.4.9",
|
|
237
237
|
"0.5.0",
|
|
238
238
|
"0.5.1",
|
|
239
|
-
"0.5.2"
|
|
239
|
+
"0.5.2",
|
|
240
|
+
"0.6.1"
|
|
240
241
|
],
|
|
241
242
|
"@rightkit/qa-chrome": [
|
|
242
243
|
"0.1.0",
|
|
@@ -374,7 +375,10 @@
|
|
|
374
375
|
"0.6.3",
|
|
375
376
|
"0.6.4",
|
|
376
377
|
"0.6.5",
|
|
377
|
-
"0.6.6"
|
|
378
|
+
"0.6.6",
|
|
379
|
+
"0.6.7",
|
|
380
|
+
"0.6.8",
|
|
381
|
+
"0.6.10"
|
|
378
382
|
],
|
|
379
383
|
"@rightkit/settings-ui": [
|
|
380
384
|
"0.1.0",
|
|
@@ -424,6 +428,9 @@
|
|
|
424
428
|
],
|
|
425
429
|
"@rightkit/updates": [
|
|
426
430
|
"0.2.4"
|
|
431
|
+
],
|
|
432
|
+
"@rightkit/outdated": [
|
|
433
|
+
"0.2.0"
|
|
427
434
|
]
|
|
428
435
|
},
|
|
429
436
|
"cargo": {
|
|
@@ -440,6 +447,7 @@
|
|
|
440
447
|
"rightkit-pdf": "0.1.0",
|
|
441
448
|
"rightkit-playback": "0.1.0",
|
|
442
449
|
"rightkit-process": "0.1.0",
|
|
450
|
+
"rightkit-qa": "0.9.1",
|
|
443
451
|
"rightkit-search": "0.1.0",
|
|
444
452
|
"rightkit-tauri": "0.1.0"
|
|
445
453
|
},
|
|
@@ -451,57 +459,57 @@
|
|
|
451
459
|
"rightkit-asr": "0.3.1",
|
|
452
460
|
"rightkit-audio": "0.3.1",
|
|
453
461
|
"rightkit-automation": "0.6.1",
|
|
454
|
-
"rightkit-browser": "0.3.
|
|
462
|
+
"rightkit-browser": "0.3.7",
|
|
455
463
|
"rightkit-cache": "0.2.3",
|
|
456
|
-
"rightkit-channel-memory": "0.2.
|
|
457
|
-
"rightkit-child-process": "0.5.
|
|
464
|
+
"rightkit-channel-memory": "0.2.2",
|
|
465
|
+
"rightkit-child-process": "0.5.7",
|
|
458
466
|
"rightkit-compose": "0.2.0",
|
|
459
|
-
"rightkit-contracts": "0.1.
|
|
467
|
+
"rightkit-contracts": "0.1.8",
|
|
460
468
|
"rightkit-crash": "0.3.6",
|
|
461
469
|
"rightkit-credentials": "0.4.2",
|
|
462
470
|
"rightkit-crypto": "0.1.0",
|
|
463
471
|
"rightkit-daemon": "0.4.0",
|
|
464
|
-
"rightkit-db": "0.5.
|
|
472
|
+
"rightkit-db": "0.5.3",
|
|
465
473
|
"rightkit-device": "0.4.0",
|
|
466
|
-
"rightkit-docs": "0.1.
|
|
467
|
-
"rightkit-embed": "0.6.
|
|
474
|
+
"rightkit-docs": "0.1.3",
|
|
475
|
+
"rightkit-embed": "0.6.2",
|
|
468
476
|
"rightkit-ffmpeg": "0.2.11",
|
|
469
|
-
"rightkit-file-watch": "0.4.
|
|
477
|
+
"rightkit-file-watch": "0.4.2",
|
|
470
478
|
"rightkit-fs": "0.4.7",
|
|
471
|
-
"rightkit-fsindex": "0.
|
|
479
|
+
"rightkit-fsindex": "0.6.0",
|
|
472
480
|
"rightkit-google-identity": "0.2.0",
|
|
473
481
|
"rightkit-hooks": "0.2.0",
|
|
474
482
|
"rightkit-hotkeys": "0.1.2",
|
|
475
|
-
"rightkit-http": "0.3.
|
|
483
|
+
"rightkit-http": "0.3.9",
|
|
476
484
|
"rightkit-identity": "0.1.0",
|
|
477
485
|
"rightkit-job-queue": "0.5.1",
|
|
478
486
|
"rightkit-license": "0.2.5",
|
|
479
487
|
"rightkit-llm": "0.3.1",
|
|
480
|
-
"rightkit-logs": "0.3.
|
|
481
|
-
"rightkit-mcp": "0.7.
|
|
482
|
-
"rightkit-models": "0.5.
|
|
488
|
+
"rightkit-logs": "0.3.6",
|
|
489
|
+
"rightkit-mcp": "0.7.1",
|
|
490
|
+
"rightkit-models": "0.5.2",
|
|
483
491
|
"rightkit-motion": "0.2.0",
|
|
484
492
|
"rightkit-oauth": "0.10.0",
|
|
485
493
|
"rightkit-ocr": "0.2.3",
|
|
486
494
|
"rightkit-onnx": "0.2.8",
|
|
487
495
|
"rightkit-overlay": "0.2.0",
|
|
488
496
|
"rightkit-overlay-win": "0.1.0",
|
|
489
|
-
"rightkit-ownership": "0.4.
|
|
490
|
-
"rightkit-pdf": "0.3.
|
|
497
|
+
"rightkit-ownership": "0.4.3",
|
|
498
|
+
"rightkit-pdf": "0.3.4",
|
|
491
499
|
"rightkit-platform-rules": "0.1.0",
|
|
492
500
|
"rightkit-playback": "0.3.0",
|
|
493
|
-
"rightkit-qa": "0.9.
|
|
501
|
+
"rightkit-qa": "0.9.2",
|
|
494
502
|
"rightkit-qa-driver": "0.7.0",
|
|
495
503
|
"rightkit-record": "0.3.3",
|
|
496
504
|
"rightkit-review": "0.4.0",
|
|
497
505
|
"rightkit-sandbox": "0.6.1",
|
|
498
|
-
"rightkit-search": "0.4.
|
|
499
|
-
"rightkit-send": "0.
|
|
506
|
+
"rightkit-search": "0.4.1",
|
|
507
|
+
"rightkit-send": "0.3.0",
|
|
500
508
|
"rightkit-sidecar": "0.3.0",
|
|
501
509
|
"rightkit-speech-client": "0.4.0",
|
|
502
510
|
"rightkit-spend": "0.2.0",
|
|
503
511
|
"rightkit-sync": "0.2.2",
|
|
504
|
-
"rightkit-tauri-shell": "0.
|
|
512
|
+
"rightkit-tauri-shell": "0.7.0",
|
|
505
513
|
"rightkit-time": "0.1.0",
|
|
506
514
|
"rightkit-transcript": "0.4.0",
|
|
507
515
|
"rightkit-tts": "0.2.3",
|
|
@@ -537,7 +545,7 @@
|
|
|
537
545
|
"rightkit-browser": "0.3.6",
|
|
538
546
|
"rightkit-cache": "0.2.3",
|
|
539
547
|
"rightkit-channel-memory": "0.2.1",
|
|
540
|
-
"rightkit-child-process": "0.5.
|
|
548
|
+
"rightkit-child-process": "0.5.7",
|
|
541
549
|
"rightkit-compose": "0.2.0",
|
|
542
550
|
"rightkit-contracts": "0.1.7",
|
|
543
551
|
"rightkit-control": "0.3.0",
|
|
@@ -579,7 +587,7 @@
|
|
|
579
587
|
"rightkit-platform-rules": "0.1.0",
|
|
580
588
|
"rightkit-playback": "0.3.0",
|
|
581
589
|
"rightkit-process": "0.4.0",
|
|
582
|
-
"rightkit-qa": "0.9.
|
|
590
|
+
"rightkit-qa": "0.9.1",
|
|
583
591
|
"rightkit-qa-driver": "0.7.0",
|
|
584
592
|
"rightkit-qts": "0.2.6",
|
|
585
593
|
"rightkit-qts-ggml": "0.1.2",
|
|
@@ -626,13 +634,13 @@
|
|
|
626
634
|
"@rightkit/logs": "0.1.6",
|
|
627
635
|
"@rightkit/media-ui": "0.3.4",
|
|
628
636
|
"@rightkit/onboarding": "0.6.3",
|
|
629
|
-
"@rightkit/outdated": "0.
|
|
637
|
+
"@rightkit/outdated": "0.3.0",
|
|
630
638
|
"@rightkit/pdf-ui": "0.2.0",
|
|
631
639
|
"@rightkit/platform-ui": "0.4.0",
|
|
632
640
|
"@rightkit/qa": "0.6.1",
|
|
633
|
-
"@rightkit/qa-chrome": "0.1.
|
|
641
|
+
"@rightkit/qa-chrome": "0.1.12",
|
|
634
642
|
"@rightkit/react-shell": "0.7.2",
|
|
635
|
-
"@rightkit/release": "0.6.
|
|
643
|
+
"@rightkit/release": "0.6.10",
|
|
636
644
|
"@rightkit/settings-ui": "0.7.0",
|
|
637
645
|
"@rightkit/shell": "0.1.1",
|
|
638
646
|
"@rightkit/tauri": "0.3.0",
|
|
@@ -647,7 +655,8 @@
|
|
|
647
655
|
"0.2.1",
|
|
648
656
|
"0.3.1",
|
|
649
657
|
"0.4.0",
|
|
650
|
-
"0.4.1"
|
|
658
|
+
"0.4.1",
|
|
659
|
+
"0.4.2"
|
|
651
660
|
],
|
|
652
661
|
"rightkit-browser": [
|
|
653
662
|
"0.2.0",
|
|
@@ -656,7 +665,8 @@
|
|
|
656
665
|
"0.3.0",
|
|
657
666
|
"0.3.1",
|
|
658
667
|
"0.3.4",
|
|
659
|
-
"0.3.5"
|
|
668
|
+
"0.3.5",
|
|
669
|
+
"0.3.6"
|
|
660
670
|
],
|
|
661
671
|
"rightkit-models": [
|
|
662
672
|
"0.2.1",
|
|
@@ -669,7 +679,8 @@
|
|
|
669
679
|
"0.3.0",
|
|
670
680
|
"0.3.1",
|
|
671
681
|
"0.3.2",
|
|
672
|
-
"0.4.4"
|
|
682
|
+
"0.4.4",
|
|
683
|
+
"0.5.1"
|
|
673
684
|
],
|
|
674
685
|
"rightkit-audio": [
|
|
675
686
|
"0.1.0",
|
|
@@ -685,7 +696,8 @@
|
|
|
685
696
|
"0.3.1",
|
|
686
697
|
"0.4.0",
|
|
687
698
|
"0.4.3",
|
|
688
|
-
"0.5.1"
|
|
699
|
+
"0.5.1",
|
|
700
|
+
"0.5.2"
|
|
689
701
|
],
|
|
690
702
|
"rightkit-embed": [
|
|
691
703
|
"0.2.1",
|
|
@@ -695,7 +707,8 @@
|
|
|
695
707
|
"0.3.2",
|
|
696
708
|
"0.4.0",
|
|
697
709
|
"0.5.0",
|
|
698
|
-
"0.6.0"
|
|
710
|
+
"0.6.0",
|
|
711
|
+
"0.6.1"
|
|
699
712
|
],
|
|
700
713
|
"rightkit-jobs": [
|
|
701
714
|
"0.2.1",
|
|
@@ -715,7 +728,8 @@
|
|
|
715
728
|
"0.5.1",
|
|
716
729
|
"0.5.2",
|
|
717
730
|
"0.5.3",
|
|
718
|
-
"0.6.0"
|
|
731
|
+
"0.6.0",
|
|
732
|
+
"0.7.0"
|
|
719
733
|
],
|
|
720
734
|
"rightkit-media": [
|
|
721
735
|
"0.2.2",
|
|
@@ -767,7 +781,8 @@
|
|
|
767
781
|
"0.7.0",
|
|
768
782
|
"0.7.1",
|
|
769
783
|
"0.8.0",
|
|
770
|
-
"0.9.0"
|
|
784
|
+
"0.9.0",
|
|
785
|
+
"0.9.1"
|
|
771
786
|
],
|
|
772
787
|
"rightkit-sandbox": [
|
|
773
788
|
"0.1.0",
|
|
@@ -828,7 +843,8 @@
|
|
|
828
843
|
"0.3.0",
|
|
829
844
|
"0.3.5",
|
|
830
845
|
"0.3.6",
|
|
831
|
-
"0.3.7"
|
|
846
|
+
"0.3.7",
|
|
847
|
+
"0.3.8"
|
|
832
848
|
],
|
|
833
849
|
"rightkit-fs": [
|
|
834
850
|
"0.1.0",
|
|
@@ -864,7 +880,8 @@
|
|
|
864
880
|
"rightkit-pdf": [
|
|
865
881
|
"0.1.0",
|
|
866
882
|
"0.3.0",
|
|
867
|
-
"0.3.2"
|
|
883
|
+
"0.3.2",
|
|
884
|
+
"0.3.3"
|
|
868
885
|
],
|
|
869
886
|
"rightkit-speech-client": [
|
|
870
887
|
"0.3.0",
|
|
@@ -893,7 +910,8 @@
|
|
|
893
910
|
"0.2.0",
|
|
894
911
|
"0.2.1",
|
|
895
912
|
"0.3.0",
|
|
896
|
-
"0.4.1"
|
|
913
|
+
"0.4.1",
|
|
914
|
+
"0.5.0"
|
|
897
915
|
],
|
|
898
916
|
"rightkit-asr": [
|
|
899
917
|
"0.0.2",
|
|
@@ -907,7 +925,8 @@
|
|
|
907
925
|
"0.2.2",
|
|
908
926
|
"0.3.0",
|
|
909
927
|
"0.3.2",
|
|
910
|
-
"0.3.3"
|
|
928
|
+
"0.3.3",
|
|
929
|
+
"0.3.5"
|
|
911
930
|
],
|
|
912
931
|
"rightkit-ocr": [
|
|
913
932
|
"0.1.2",
|
|
@@ -985,20 +1004,23 @@
|
|
|
985
1004
|
"0.5.2",
|
|
986
1005
|
"0.5.3",
|
|
987
1006
|
"0.5.4",
|
|
988
|
-
"0.5.5"
|
|
1007
|
+
"0.5.5",
|
|
1008
|
+
"0.5.6"
|
|
989
1009
|
],
|
|
990
1010
|
"rightkit-hotkeys": [
|
|
991
1011
|
"0.1.0",
|
|
992
1012
|
"0.1.1"
|
|
993
1013
|
],
|
|
994
1014
|
"rightkit-channel-memory": [
|
|
995
|
-
"0.1.0"
|
|
1015
|
+
"0.1.0",
|
|
1016
|
+
"0.2.1"
|
|
996
1017
|
],
|
|
997
1018
|
"rightkit-compose": [
|
|
998
1019
|
"0.1.0"
|
|
999
1020
|
],
|
|
1000
1021
|
"rightkit-contracts": [
|
|
1001
|
-
"0.1.5"
|
|
1022
|
+
"0.1.5",
|
|
1023
|
+
"0.1.7"
|
|
1002
1024
|
],
|
|
1003
1025
|
"rightkit-hooks": [
|
|
1004
1026
|
"0.1.0",
|
|
@@ -1062,7 +1084,8 @@
|
|
|
1062
1084
|
],
|
|
1063
1085
|
"rightkit-docs": [
|
|
1064
1086
|
"0.1.0",
|
|
1065
|
-
"0.1.1"
|
|
1087
|
+
"0.1.1",
|
|
1088
|
+
"0.1.2"
|
|
1066
1089
|
],
|
|
1067
1090
|
"rightkit-tts-qwen": [
|
|
1068
1091
|
"0.2.6"
|
|
@@ -1072,10 +1095,12 @@
|
|
|
1072
1095
|
"0.2.2"
|
|
1073
1096
|
],
|
|
1074
1097
|
"rightkit-send": [
|
|
1075
|
-
"0.1.0"
|
|
1098
|
+
"0.1.0",
|
|
1099
|
+
"0.2.0"
|
|
1076
1100
|
],
|
|
1077
1101
|
"rightkit-file-watch": [
|
|
1078
|
-
"0.4.0"
|
|
1102
|
+
"0.4.0",
|
|
1103
|
+
"0.4.1"
|
|
1079
1104
|
],
|
|
1080
1105
|
"rightkit-sync": [
|
|
1081
1106
|
"0.1.1"
|
|
@@ -1086,7 +1111,8 @@
|
|
|
1086
1111
|
"0.3.3",
|
|
1087
1112
|
"0.4.0",
|
|
1088
1113
|
"0.5.0",
|
|
1089
|
-
"0.5.1"
|
|
1114
|
+
"0.5.1",
|
|
1115
|
+
"0.6.0"
|
|
1090
1116
|
],
|
|
1091
1117
|
"rightkit-android": [
|
|
1092
1118
|
"0.2.0"
|
package/runtime-budgets.mjs
CHANGED
|
@@ -251,10 +251,13 @@ const posix = (p) => p.split(path.sep).join("/");
|
|
|
251
251
|
* The git pathspecs (relative to the workspace root) whose change makes a measurement stale: the
|
|
252
252
|
* crate's src, benches, Cargo.toml (features) and build.rs, plus src, Cargo.toml and build.rs of every
|
|
253
253
|
* workspace crate it reaches through `path` dependencies (transitively). Returns { root, specs, problems }.
|
|
254
|
+
* Every crate is its own Cargo workspace (rightkit#1285), so `root` is the crate directory (its own Cargo.toml and Cargo.lock)
|
|
255
|
+
* and a sibling crate's paths are `../<x>/...`. `deps.base` names the directory the specs are relative to (default: the
|
|
256
|
+
* workspace root); a caller that runs git at the repository root passes it so the specs read crates/<x>/....
|
|
254
257
|
* Callers must refuse incomplete metadata rather than using a partial dependency scope.
|
|
255
258
|
*/
|
|
256
259
|
export function measuredPathspecs(crateDir, deps = {}) {
|
|
257
|
-
const { exists = existsSync, readFile = readFileSync } = deps;
|
|
260
|
+
const { exists = existsSync, readFile = readFileSync, base } = deps;
|
|
258
261
|
const problems = [];
|
|
259
262
|
// Workspace discovery deliberately tolerates bad ancestor manifests elsewhere. Freshness cannot:
|
|
260
263
|
// a swallowed read/parse failure could hide inherited dependencies and shrink the measured graph.
|
|
@@ -271,7 +274,7 @@ export function measuredPathspecs(crateDir, deps = {}) {
|
|
|
271
274
|
const checked = { exists, readFile: checkedRead };
|
|
272
275
|
let root = path.resolve(crateDir);
|
|
273
276
|
const specs = [];
|
|
274
|
-
const add = (dir, names) => { for (const name of names) specs.push(posix(path.relative(root, path.join(dir, name)))); };
|
|
277
|
+
const add = (dir, names) => { for (const name of names) specs.push(posix(path.relative(base ? path.resolve(base) : root, path.join(dir, name)))); };
|
|
275
278
|
try {
|
|
276
279
|
root = findWorkspaceRoot(crateDir, checked) ?? root;
|
|
277
280
|
add(path.resolve(crateDir), CRATE_PATHS);
|
|
@@ -365,6 +368,7 @@ export function measurementStaleness(commit, crateDir, git = defaultGit, deps =
|
|
|
365
368
|
}
|
|
366
369
|
} catch (error) { return `cannot resolve Cargo.lock package identity: ${error.message}`; }
|
|
367
370
|
if (name) {
|
|
371
|
+
// The crate's own workspace lock: root is the crate directory when the crate is its own workspace (#1285).
|
|
368
372
|
const lockPath = path.join(root, "Cargo.lock");
|
|
369
373
|
let now;
|
|
370
374
|
try { now = exists(lockPath) ? readFile(lockPath, "utf8") : null; }
|
package/scan-digest.mjs
CHANGED
|
@@ -54,6 +54,60 @@ export function rustCratePlan(own = {}) {
|
|
|
54
54
|
return { lintSets, defaultCheck, checkSets };
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
// ---- Clippy batching (GATE-CONTRACT §1 "Clippy route & batching"; item 8 rows 8.6, 8.8, 8.15) -----------------------------------------
|
|
58
|
+
// Lives here, beside the scan ids, so the credentialed verifiers (requiredScanIds) and the planner (planScans) spell a batch's id from
|
|
59
|
+
// one function. Pure: no file reads.
|
|
60
|
+
|
|
61
|
+
/** The feature flags that mean the same thing on every package they are applied to: any other set names features of one crate. */
|
|
62
|
+
export const CLIPPY_UNIVERSAL_FEATURE_FLAGS = Object.freeze(["--all-features", "--no-default-features"]);
|
|
63
|
+
const optionValue = (set, names) => {
|
|
64
|
+
for (let i = 0; i < set.length; i += 1) for (const n of names) { if (set[i] === n) return set[i + 1] ?? null; if (set[i].startsWith(`${n}=`)) return set[i].slice(n.length + 1); }
|
|
65
|
+
return null;
|
|
66
|
+
};
|
|
67
|
+
/** The target and profile a feature-set argv selects (null: the toolchain's host target and the dev profile). */
|
|
68
|
+
export const clippySelectionOf = (set) => ({ target: optionValue(set, ["--target"]), profile: set.includes("--release") || set.includes("-r") ? "release" : optionValue(set, ["--profile"]) });
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Groups the Clippy configurations of a plan into invocations. `entries`: `[{ name, crate, ws, set, count, env }]`, one per crate
|
|
72
|
+
* and lint feature set (`count` is how many sets the crate declares). Entries are batched when workspace, feature set, target,
|
|
73
|
+
* profile, lint policy, toolchain and environment are all equal (they share one `-p` list); an entry is its own invocation, with
|
|
74
|
+
* the reason recorded, when:
|
|
75
|
+
* - its crate is in `solo` (ci/shards.json `solo`: a crate that always gets a job of its own);
|
|
76
|
+
* - it is in `separate` (a name to a reason): batching changed what compiles for it (feature unification, item 8 row 8.7);
|
|
77
|
+
* - its feature set names crate-specific features (anything but --all-features / --no-default-features): such a set is
|
|
78
|
+
* per-configuration by construction, for example rightkit-db's SQLCipher variants or rightkit-qa-driver's wv2 generations
|
|
79
|
+
* (ci/gate.config.json featureSets);
|
|
80
|
+
* - its crate is sidecar-bound: it is scheduled after every independent batch and never joins one.
|
|
81
|
+
* A batch never widens a package set: it names exactly its members with `-p`. A batch's id is `clippy:batch:[<ws>:]<8 hex>` over its
|
|
82
|
+
* workspace, feature set, target, profile, lint policy and member list (never the toolchain or the output directory, which a
|
|
83
|
+
* verifier does not know), so the planner and requiredScanIds agree and the id names exactly the crates it covers. Returns
|
|
84
|
+
* `{ batches, notes }`; batches are ordered independent first, then sidecar-bound, each group by workspace then key.
|
|
85
|
+
*/
|
|
86
|
+
export function clippyBatchPlan(entries, { solo = [], separate = new Map(), sidecarBound = new Set(), toolchain = null, lint = ["-D", "warnings"] } = {}) {
|
|
87
|
+
const soloSet = new Set(solo);
|
|
88
|
+
const groups = new Map();
|
|
89
|
+
for (const e of entries) {
|
|
90
|
+
const set = [...e.set];
|
|
91
|
+
const crate = e.crate ?? e.name;
|
|
92
|
+
const sel = clippySelectionOf(set);
|
|
93
|
+
let reason = null;
|
|
94
|
+
if (soloSet.has(e.name) || soloSet.has(crate)) reason = "ci/shards.json solo: the crate always gets an invocation of its own";
|
|
95
|
+
else if (separate instanceof Map && separate.has(e.name)) reason = separate.get(e.name);
|
|
96
|
+
else if (set.some((w) => !CLIPPY_UNIVERSAL_FEATURE_FLAGS.includes(w))) reason = `ci/gate.config.json featureSets names crate-specific features (${set.join(" ")})${e.count > 1 ? `; ${crate} declares ${e.count} feature configurations that are separate invocations by construction` : ""}`;
|
|
97
|
+
const bound = sidecarBound.has(e.name) || sidecarBound.has(crate);
|
|
98
|
+
const identity = { ws: e.ws, set, target: sel.target, profile: sel.profile, lint, ...(reason || bound ? { only: e.name, sidecar: bound } : {}) };
|
|
99
|
+
const key = canonicalJson({ ...identity, toolchain, env: e.env ?? null });
|
|
100
|
+
if (!groups.has(key)) groups.set(key, { key, identity: canonicalJson(identity), ws: e.ws, set, target: sel.target, profile: sel.profile, units: [], crates: [], reason: reason ?? (bound ? "sidecar-bound: scheduled after its sidecar prerequisite, never batched with independent crates" : null), order: bound ? "sidecar" : "independent" });
|
|
101
|
+
const g = groups.get(key);
|
|
102
|
+
g.units.push(e.name); if (!g.crates.includes(crate)) g.crates.push(crate);
|
|
103
|
+
}
|
|
104
|
+
const batches = [...groups.values()].map((g) => ({ ...g, units: g.units.sort(), crates: g.crates.sort() })).map((g) => ({ ...g, id: `clippy:batch:${g.ws === "." ? "" : `${g.ws}:`}${sha256(`${g.identity}\0${g.units.join("\0")}`).slice(0, 8)}` }));
|
|
105
|
+
batches.sort((a, b) => (a.order === b.order ? (a.ws === b.ws ? (a.key < b.key ? -1 : 1) : a.ws < b.ws ? -1 : 1) : a.order === "independent" ? -1 : 1));
|
|
106
|
+
const notes = batches.filter((b) => b.reason).map((b) => `clippy batching: ${b.units.join(", ")} (${b.set.join(" ") || "default features"}) stays its own invocation: ${b.reason}`);
|
|
107
|
+
notes.push(`clippy batching: ${entries.length} crate configuration(s) in ${batches.length} invocation(s), each \`-p\` list exactly its members, \`--locked\` and \`--no-deps\` on every one; no batch is \`--workspace\``);
|
|
108
|
+
return { batches, notes };
|
|
109
|
+
}
|
|
110
|
+
|
|
57
111
|
/** Scan ids every scan of the whole repository always has when it holds Rust units (cargo.toml, workflows, YAML, JSON and licences). */
|
|
58
112
|
export const WORKSPACE_SCAN_IDS = Object.freeze(["cargo-metadata", "cargo-deny", "cargo-audit", "actionlint", "yaml-parse", "toml-parse", "json-parse", "license", "secret-scan"]);
|
|
59
113
|
/** Prefixes at least one scan id must carry (rustfmt groups by edition, so its exact ids depend on the files). */
|
|
@@ -62,25 +116,35 @@ export const REQUIRED_SCAN_PREFIXES = Object.freeze(["rustfmt:"]);
|
|
|
62
116
|
/**
|
|
63
117
|
* The scan ids a LOCAL scan record must contain, each with status pass, for these publishable Rust `units` ([names], crates/<name>).
|
|
64
118
|
* `exists(repoPath)` answers from the AUTHENTICATED source (never from the record): src/lib.rs decides `doc`, CHANGELOG.md decides
|
|
65
|
-
* `changelog-version`, and the repository's own ci/advisory-exceptions.json, ownership catalog and docs generator decide theirs.
|
|
119
|
+
* `changelog-version`, and the repository's own ci/advisory-exceptions.json (or, per crate, crates/<name>/.rightkit/advisory-exceptions.json), ownership catalog and docs generator decide theirs.
|
|
66
120
|
* `crateFeatures` is ci/gate.config.json `rust`. `includeTests` adds the per-feature-set test scans. Extra scans in a record are
|
|
67
121
|
* allowed; a missing one is not. planScans builds its ids from the same helpers, and a test holds the two in agreement.
|
|
68
122
|
*/
|
|
69
|
-
export function requiredScanIds({ units, crateFeatures = {}, exists, includeTests = false }) {
|
|
123
|
+
export function requiredScanIds({ units, crateFeatures = {}, exists, includeTests = false, perCrateWorkspaces = undefined, clippyBatching = false, shardSolo = [], clippySeparate = new Map(), sidecarBound = new Set() }) {
|
|
70
124
|
if (!Array.isArray(units) || units.length === 0 || !units.every((n) => typeof n === "string" && n)) throw new TypeError("requiredScanIds: units must be a non-empty array of names");
|
|
71
125
|
if (typeof exists !== "function") throw new TypeError("requiredScanIds: exists(repoPath) is required");
|
|
72
|
-
|
|
73
|
-
|
|
126
|
+
// One Cargo workspace and lock per crate (rightkit#1285): every unit has its own crates/<name>/Cargo.lock, so the per-workspace scans
|
|
127
|
+
// (metadata, deny, audit and the advisory ledger where the crate has one) are required per unit and carry the crate name; there is no
|
|
128
|
+
// repository-level ledger. A repository with one root workspace has no per-crate lock and keeps the unsuffixed ids.
|
|
129
|
+
const perCrate = perCrateWorkspaces ?? units.every((n) => exists(`crates/${n}/Cargo.lock`));
|
|
130
|
+
const ids = new Set(WORKSPACE_SCAN_IDS.filter((id) => !(perCrate && /^cargo-(metadata|deny|audit)$/.test(id))));
|
|
131
|
+
if (!perCrate && exists("ci/advisory-exceptions.json")) ids.add("advisory-exceptions");
|
|
74
132
|
if (exists("packages/release/rightkit-ownership.json") && exists("crates/rightkit-ownership/catalog/ownership-catalog.json")) ids.add("ownership-catalog");
|
|
75
133
|
if (exists("scripts/generate-index.mjs")) ids.add("generated-docs");
|
|
134
|
+
const clippyEntries = [];
|
|
76
135
|
for (const name of units) {
|
|
77
136
|
const own = crateFeatures?.[name] ?? {};
|
|
78
137
|
const { lintSets, defaultCheck, checkSets } = rustCratePlan(own);
|
|
138
|
+
if (perCrate) {
|
|
139
|
+
for (const id of ["cargo-metadata", "cargo-deny", "cargo-audit"]) ids.add(`${id}:${name}`);
|
|
140
|
+
if (exists(`crates/${name}/.rightkit/advisory-exceptions.json`)) ids.add(`advisory-exceptions:${name}`);
|
|
141
|
+
}
|
|
79
142
|
ids.add(rustScanId.packageList(name));
|
|
80
143
|
if (exists(`crates/${name}/CHANGELOG.md`)) ids.add(rustScanId.changelog(name));
|
|
81
144
|
if (defaultCheck) ids.add(rustScanId.check(name));
|
|
82
145
|
checkSets.forEach((_set, i) => ids.add(rustScanId.checkFeatures(name, i)));
|
|
83
|
-
lintSets.forEach((
|
|
146
|
+
if (clippyBatching) lintSets.forEach((set) => clippyEntries.push({ name, crate: name, ws: ".", set, count: lintSets.length, env: null }));
|
|
147
|
+
else lintSets.forEach((_set, i) => ids.add(rustScanId.clippy(name, lintSets.length, i)));
|
|
84
148
|
if (exists(`crates/${name}/src/lib.rs`)) ids.add(rustScanId.doc(name));
|
|
85
149
|
if (includeTests) {
|
|
86
150
|
lintSets.forEach((_set, i) => {
|
|
@@ -89,6 +153,8 @@ export function requiredScanIds({ units, crateFeatures = {}, exists, includeTest
|
|
|
89
153
|
});
|
|
90
154
|
}
|
|
91
155
|
}
|
|
156
|
+
// With batching on, the Clippy ids are the batches' (the same function the planner calls), never the per-crate ones.
|
|
157
|
+
if (clippyBatching) for (const b of clippyBatchPlan(clippyEntries, { solo: shardSolo, separate: clippySeparate, sidecarBound }).batches) ids.add(b.id);
|
|
92
158
|
return [...ids].sort();
|
|
93
159
|
}
|
|
94
160
|
|
package/sign-updater.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import { refuseManagedEnvSecrets } from "./managed-host-secrets.mjs";
|
|
|
7
7
|
import { execWithUpdaterCredential } from "./protected-credentials.mjs";
|
|
8
8
|
import { resolvePnpmCli } from "./development.mjs";
|
|
9
9
|
import { UPDATER_KEY_ID_RE, updaterSignatureKeyId } from "./github-updater-release.mjs";
|
|
10
|
+
import { ArtifactPathError, loadSplitArtifactContext, resolveArtifactPath } from "./release-artifact-path.mjs";
|
|
10
11
|
|
|
11
12
|
export const UPDATER_SIGNING_SECRET = "updater-signing-key";
|
|
12
13
|
|
|
@@ -14,6 +15,8 @@ export function runSignUpdater(args, {
|
|
|
14
15
|
env = process.env, platform = process.platform, cwd = process.cwd(),
|
|
15
16
|
execCredential = execWithUpdaterCredential, resolvePnpm = resolvePnpmCli,
|
|
16
17
|
signMac = signMacUpdaterFiles, exists = existsSync, remove = rmSync, read = (file) => readFileSync(file, "utf8"), log = console.log,
|
|
18
|
+
// The artifact-path context of a door split (release-artifact-path.mjs, row 7.04c): `--file` is then the bound Cargo target's, never the checkout's.
|
|
19
|
+
artifactPaths = null,
|
|
17
20
|
} = {}) {
|
|
18
21
|
const files = [];
|
|
19
22
|
let dryRun = false;
|
|
@@ -21,7 +24,7 @@ export function runSignUpdater(args, {
|
|
|
21
24
|
for (let i = 0; i < args.length; i++) {
|
|
22
25
|
if (args[i] === "--file") {
|
|
23
26
|
if (!args[i + 1] || args[i + 1].startsWith("--")) throw new Error("--file requires an artifact path");
|
|
24
|
-
files.push(path.resolve(cwd, args[++i]));
|
|
27
|
+
files.push(artifactPaths?.mode === "split" ? resolveArtifactPath(args[++i], artifactPaths) : path.resolve(cwd, args[++i]));
|
|
25
28
|
} else if (args[i] === "--key-id") {
|
|
26
29
|
if (keyId !== undefined) throw new Error("--key-id may be given only once");
|
|
27
30
|
if (!UPDATER_KEY_ID_RE.test(args[i + 1] ?? "")) throw new Error("--key-id requires the 16 upper-case hex digits of the updater key id");
|
|
@@ -77,9 +80,9 @@ export function runSignUpdater(args, {
|
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
80
|
-
try { runSignUpdater(process.argv.slice(2)); }
|
|
83
|
+
try { runSignUpdater(process.argv.slice(2), { artifactPaths: await loadSplitArtifactContext({ cwd: process.cwd() }) }); }
|
|
81
84
|
catch (error) {
|
|
82
|
-
console.error(`sign-updater: ${error.code ? `[${error.code}] ` : ""}${error.message}`);
|
|
85
|
+
console.error(`sign-updater: ${error instanceof ArtifactPathError ? "" : error.code ? `[${error.code}] ` : ""}${error.message}`);
|
|
83
86
|
process.exitCode = error.exitCode ?? 1;
|
|
84
87
|
}
|
|
85
88
|
}
|