@kungfu-tech/buildchain 3.0.1 → 3.0.2-alpha.1
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 +5 -3
- package/actions/promote-buildchain-ref/README.md +7 -0
- package/bin/buildchain.mjs +173 -513
- package/bin/internal/cli-options.mjs +79 -0
- package/bin/internal/trust-release-cli.mjs +469 -0
- package/dist/site/agent-index.json +2 -0
- package/dist/site/artifact-schemas.json +5 -0
- package/dist/site/badge-endpoint-registry.json +18 -18
- package/dist/site/badges/v1/kfd-12/aligned.json +1 -1
- package/dist/site/badges/v1/kfd-12/declared.json +1 -1
- package/dist/site/badges/v1/kfd-12/downgraded.json +1 -1
- package/dist/site/badges/v1/kfd-12/draft.json +1 -1
- package/dist/site/badges/v1/kfd-12/failed.json +1 -1
- package/dist/site/badges/v1/kfd-12/missing.json +1 -1
- package/dist/site/badges/v1/kfd-12/passed.json +1 -1
- package/dist/site/badges/v1/kfd-12/planned.json +1 -1
- package/dist/site/badges/v1/kfd-13/aligned.json +1 -1
- package/dist/site/badges/v1/kfd-13/declared.json +1 -1
- package/dist/site/badges/v1/kfd-13/downgraded.json +1 -1
- package/dist/site/badges/v1/kfd-13/draft.json +1 -1
- package/dist/site/badges/v1/kfd-13/failed.json +1 -1
- package/dist/site/badges/v1/kfd-13/missing.json +1 -1
- package/dist/site/badges/v1/kfd-13/passed.json +1 -1
- package/dist/site/badges/v1/kfd-13/planned.json +1 -1
- package/dist/site/buildchain-contract.json +68 -28
- package/dist/site/buildchain-site.json +28 -18
- package/dist/site/capability-registry.json +3 -3
- package/dist/site/cli-registry.json +108 -0
- package/dist/site/controller-registry.json +36 -4
- package/dist/site/kfd-claims.json +156 -12
- package/dist/site/kfd-upstream-aggregate.json +20 -11
- package/dist/site/manual-registry.json +3 -3
- package/dist/site/node-api-registry.json +36 -10
- package/dist/site/page-registry.json +20 -10
- package/dist/site/public-surface-audit.json +122 -10
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-passport-check-manifest.json +11 -0
- package/dist/site/release-provenance.json +4 -0
- package/dist/site/schemas/kfd-product-gate-input-v1.schema.json +164 -0
- package/dist/site/schemas/kfd-support-projection-v1.schema.json +106 -0
- package/dist/site/schemas/release-passport-v1.schema.json +3 -0
- package/dist/site/site-manifest.json +7 -7
- package/dist/site/workflow-registry.json +17 -5
- package/docs/cli.md +9 -2
- package/docs/kfd-support.md +43 -7
- package/docs/release-passport.md +15 -0
- package/package.json +7 -3
- package/packages/core/cache-evidence.js +288 -0
- package/packages/core/diagnostics.js +276 -10
- package/packages/core/github-governance-authority.js +71 -16
- package/packages/core/index.js +27 -0
- package/packages/core/kfd-product-gates.js +865 -0
- package/packages/core/kfd.js +16 -7
- package/packages/core/kfd3-surface-register.js +105 -1
- package/packages/core/public-surface-audit.js +6 -1
- package/packages/core/release-passport-contract.js +13 -0
- package/packages/core/release-passport.js +87 -3
- package/scripts/check-internal-architecture.mjs +171 -0
- package/scripts/check-inventory.mjs +4 -0
- package/scripts/generate-site-bundle.mjs +24 -0
- package/scripts/locked-source-checkout.mjs +48 -0
- package/scripts/promotion-routing-evidence.mjs +73 -0
- package/scripts/reconcile-github-governance.mjs +158 -25
- package/scripts/shifu-gate-profile.mjs +26 -20
|
@@ -19,6 +19,11 @@ import {
|
|
|
19
19
|
readBuildchainLogEvents,
|
|
20
20
|
summarizeBuildchainLogEvents,
|
|
21
21
|
} from "./logging.js";
|
|
22
|
+
import {
|
|
23
|
+
cacheEvidenceDigest,
|
|
24
|
+
createCacheEvidenceSet,
|
|
25
|
+
createCacheOperationReceipt,
|
|
26
|
+
} from "./cache-evidence.js";
|
|
22
27
|
|
|
23
28
|
export const BUILDCHAIN_DIAGNOSTICS_CONTRACT = "kungfu-buildchain-diagnostics";
|
|
24
29
|
export const BUILDCHAIN_LIFECYCLE_OBSERVABILITY_CONTRACT =
|
|
@@ -568,18 +573,37 @@ function collectCompilerCacheTool({ command, attempts, cwd, runCommand }) {
|
|
|
568
573
|
export function collectCompilerCacheDiagnostics({
|
|
569
574
|
cwd = process.cwd(),
|
|
570
575
|
runCommand = defaultDiagnosticCommandRunner,
|
|
576
|
+
env = process.env,
|
|
571
577
|
} = {}) {
|
|
572
578
|
const resolvedCwd = path.resolve(cwd);
|
|
579
|
+
const ccache = collectCompilerCacheTool({
|
|
580
|
+
command: "ccache",
|
|
581
|
+
attempts: [
|
|
582
|
+
{ args: ["--show-stats", "--json"], format: "json" },
|
|
583
|
+
{ args: ["--show-stats"], format: "text" },
|
|
584
|
+
],
|
|
585
|
+
cwd: resolvedCwd,
|
|
586
|
+
runCommand,
|
|
587
|
+
});
|
|
588
|
+
ccache.logStats = env.CCACHE_STATSLOG
|
|
589
|
+
? collectCompilerCacheTool({
|
|
590
|
+
command: "ccache",
|
|
591
|
+
attempts: [
|
|
592
|
+
{
|
|
593
|
+
args: ["--print-log-stats", "--format", "json"],
|
|
594
|
+
format: "json",
|
|
595
|
+
},
|
|
596
|
+
],
|
|
597
|
+
cwd: resolvedCwd,
|
|
598
|
+
runCommand,
|
|
599
|
+
})
|
|
600
|
+
: {
|
|
601
|
+
available: false,
|
|
602
|
+
command: "ccache",
|
|
603
|
+
error: "CCACHE_STATSLOG is not configured",
|
|
604
|
+
};
|
|
573
605
|
return {
|
|
574
|
-
ccache
|
|
575
|
-
command: "ccache",
|
|
576
|
-
attempts: [
|
|
577
|
-
{ args: ["--show-stats", "--json"], format: "json" },
|
|
578
|
-
{ args: ["--show-stats"], format: "text" },
|
|
579
|
-
],
|
|
580
|
-
cwd: resolvedCwd,
|
|
581
|
-
runCommand,
|
|
582
|
-
}),
|
|
606
|
+
ccache,
|
|
583
607
|
sccache: collectCompilerCacheTool({
|
|
584
608
|
command: "sccache",
|
|
585
609
|
attempts: [
|
|
@@ -591,6 +615,238 @@ export function collectCompilerCacheDiagnostics({
|
|
|
591
615
|
};
|
|
592
616
|
}
|
|
593
617
|
|
|
618
|
+
function unavailableMetric(unit, reason, source = null, evidenceRoot = null) {
|
|
619
|
+
return {
|
|
620
|
+
status: "unavailable",
|
|
621
|
+
unit,
|
|
622
|
+
value: null,
|
|
623
|
+
source,
|
|
624
|
+
reason,
|
|
625
|
+
evidenceRoot,
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
function notApplicableMetric(unit, reason) {
|
|
630
|
+
return {
|
|
631
|
+
status: "not-applicable",
|
|
632
|
+
unit,
|
|
633
|
+
value: null,
|
|
634
|
+
reason,
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
function observedMetric(unit, value, source, evidenceRoot) {
|
|
639
|
+
return {
|
|
640
|
+
status: "observed",
|
|
641
|
+
unit,
|
|
642
|
+
value: Number(value),
|
|
643
|
+
source,
|
|
644
|
+
evidenceRoot,
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
function cacheStatsCount(stats, names) {
|
|
649
|
+
return names.reduce((sum, name) => sum + Number(stats?.[name] || 0), 0);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
function compilerCacheOutcome(compilerCaches) {
|
|
653
|
+
const logStats = compilerCaches?.ccache?.logStats;
|
|
654
|
+
if (!logStats?.available || !logStats.stats) return "unavailable";
|
|
655
|
+
const hits = cacheStatsCount(logStats.stats, [
|
|
656
|
+
"direct_cache_hit",
|
|
657
|
+
"preprocessed_cache_hit",
|
|
658
|
+
]);
|
|
659
|
+
const misses = cacheStatsCount(logStats.stats, ["cache_miss"]);
|
|
660
|
+
if (hits > 0 && misses > 0) return "partial";
|
|
661
|
+
if (hits > 0) return "hit";
|
|
662
|
+
if (misses > 0) return "miss";
|
|
663
|
+
return "bypassed";
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
function createStructuredCacheEvidence({
|
|
667
|
+
sourceCheckout,
|
|
668
|
+
compilerCaches,
|
|
669
|
+
platform,
|
|
670
|
+
env = process.env,
|
|
671
|
+
}) {
|
|
672
|
+
const repository = env.GITHUB_REPOSITORY || sourceCheckout?.repository || "unknown/unknown";
|
|
673
|
+
const sourceCommit =
|
|
674
|
+
env.BUILDCHAIN_SOURCE_SHA ||
|
|
675
|
+
sourceCheckout?.source?.sha ||
|
|
676
|
+
sourceCheckout?.verification?.head ||
|
|
677
|
+
"unknown";
|
|
678
|
+
const sourceTree =
|
|
679
|
+
env.BUILDCHAIN_SOURCE_TREE_SHA ||
|
|
680
|
+
sourceCheckout?.source?.treeSha ||
|
|
681
|
+
sourceCheckout?.verification?.tree ||
|
|
682
|
+
"";
|
|
683
|
+
const runtimeCommit = env.BUILDCHAIN_RUNTIME_SHA || "";
|
|
684
|
+
const policyRoot = env.SHIFU_CACHE_PROFILE_DIGEST || "";
|
|
685
|
+
const bindings = {
|
|
686
|
+
sourceCommit,
|
|
687
|
+
...(sourceTree ? { sourceTree } : {}),
|
|
688
|
+
...(runtimeCommit ? { runtimeCommit } : {}),
|
|
689
|
+
...(env.BUILDCHAIN_DEPENDENCY_LOCK_ROOT
|
|
690
|
+
? { dependencyLockRoot: env.BUILDCHAIN_DEPENDENCY_LOCK_ROOT }
|
|
691
|
+
: {}),
|
|
692
|
+
...(env.BUILDCHAIN_TOOLCHAIN_ROOT
|
|
693
|
+
? { toolchainRoot: env.BUILDCHAIN_TOOLCHAIN_ROOT }
|
|
694
|
+
: {}),
|
|
695
|
+
...(env.BUILDCHAIN_CACHE_POLICY_ROOT
|
|
696
|
+
? { policyRoot: env.BUILDCHAIN_CACHE_POLICY_ROOT }
|
|
697
|
+
: {}),
|
|
698
|
+
...(policyRoot ? { cacheProfileRoot: policyRoot } : {}),
|
|
699
|
+
};
|
|
700
|
+
const operations = [];
|
|
701
|
+
if (sourceCheckout) {
|
|
702
|
+
const evidenceRoot = cacheEvidenceDigest(sourceCheckout);
|
|
703
|
+
const cache = sourceCheckout.cache || {};
|
|
704
|
+
const outcome = cache.hit
|
|
705
|
+
? "hit"
|
|
706
|
+
: cache.attempted === false || sourceCheckout.policy?.mode === "off"
|
|
707
|
+
? "bypassed"
|
|
708
|
+
: cache.fallbackUsed
|
|
709
|
+
? "miss"
|
|
710
|
+
: "unavailable";
|
|
711
|
+
operations.push(
|
|
712
|
+
createCacheOperationReceipt({
|
|
713
|
+
operationId: `source-checkout:${platform}`,
|
|
714
|
+
operation: "restore",
|
|
715
|
+
provider: `git-${cache.transport || "unknown"}`,
|
|
716
|
+
producer: "kungfu-systems/buildchain",
|
|
717
|
+
platform,
|
|
718
|
+
cacheKey: sourceCommit,
|
|
719
|
+
cacheRoot:
|
|
720
|
+
sourceCheckout.policy?.referenceRepository?.display ||
|
|
721
|
+
sourceCheckout.policy?.mirror?.display ||
|
|
722
|
+
`transport:${cache.transport || "unknown"}`,
|
|
723
|
+
outcome,
|
|
724
|
+
bindings,
|
|
725
|
+
metrics: {
|
|
726
|
+
lookupDuration:
|
|
727
|
+
cache.attempted === false
|
|
728
|
+
? notApplicableMetric("ms", "source checkout cache was disabled")
|
|
729
|
+
: observedMetric(
|
|
730
|
+
"ms",
|
|
731
|
+
cache.lookupDurationMs || 0,
|
|
732
|
+
"locked-source-checkout",
|
|
733
|
+
evidenceRoot,
|
|
734
|
+
),
|
|
735
|
+
restoreDuration: cache.hit
|
|
736
|
+
? observedMetric(
|
|
737
|
+
"ms",
|
|
738
|
+
cache.restoreDurationMs || 0,
|
|
739
|
+
"locked-source-checkout",
|
|
740
|
+
evidenceRoot,
|
|
741
|
+
)
|
|
742
|
+
: notApplicableMetric(
|
|
743
|
+
"ms",
|
|
744
|
+
"no cache payload was admitted for restore",
|
|
745
|
+
),
|
|
746
|
+
saveDuration: notApplicableMetric(
|
|
747
|
+
"ms",
|
|
748
|
+
"locked source checkout does not save cache state",
|
|
749
|
+
),
|
|
750
|
+
restoredBytes:
|
|
751
|
+
cache.restoredBytesStatus === "observed"
|
|
752
|
+
? observedMetric(
|
|
753
|
+
"bytes",
|
|
754
|
+
cache.restoredBytes || 0,
|
|
755
|
+
cache.restoredBytesMethod || "git-object-store-delta",
|
|
756
|
+
evidenceRoot,
|
|
757
|
+
)
|
|
758
|
+
: unavailableMetric(
|
|
759
|
+
"bytes",
|
|
760
|
+
"checkout provider did not expose restored byte evidence",
|
|
761
|
+
"locked-source-checkout",
|
|
762
|
+
evidenceRoot,
|
|
763
|
+
),
|
|
764
|
+
writtenBytes: notApplicableMetric(
|
|
765
|
+
"bytes",
|
|
766
|
+
"locked source checkout does not save cache state",
|
|
767
|
+
),
|
|
768
|
+
savedTime: unavailableMetric(
|
|
769
|
+
"ms",
|
|
770
|
+
"checkout provider did not report a measured cold-path comparison",
|
|
771
|
+
"locked-source-checkout",
|
|
772
|
+
evidenceRoot,
|
|
773
|
+
),
|
|
774
|
+
},
|
|
775
|
+
evidence: {
|
|
776
|
+
kind: "locked-source-checkout",
|
|
777
|
+
root: evidenceRoot,
|
|
778
|
+
locator: ".buildchain/diagnostics/source-checkout.json",
|
|
779
|
+
},
|
|
780
|
+
}),
|
|
781
|
+
);
|
|
782
|
+
}
|
|
783
|
+
const compilerEvidenceRoot = cacheEvidenceDigest(compilerCaches || {});
|
|
784
|
+
operations.push(
|
|
785
|
+
createCacheOperationReceipt({
|
|
786
|
+
operationId: `compiler-cache:${platform}`,
|
|
787
|
+
operation: "restore",
|
|
788
|
+
provider: compilerCaches?.ccache?.available ? "ccache" : "compiler-cache",
|
|
789
|
+
producer: compilerCaches?.ccache?.available ? "ccache" : "unavailable",
|
|
790
|
+
platform,
|
|
791
|
+
cacheKey: policyRoot || null,
|
|
792
|
+
cacheRoot: policyRoot || null,
|
|
793
|
+
outcome: compilerCacheOutcome(compilerCaches),
|
|
794
|
+
bindings,
|
|
795
|
+
metrics: {
|
|
796
|
+
lookupDuration: unavailableMetric(
|
|
797
|
+
"ms",
|
|
798
|
+
"ccache stats log exposes outcomes but not lookup duration",
|
|
799
|
+
"ccache-stats-log",
|
|
800
|
+
compilerEvidenceRoot,
|
|
801
|
+
),
|
|
802
|
+
restoreDuration: unavailableMetric(
|
|
803
|
+
"ms",
|
|
804
|
+
"ccache stats log exposes outcomes but not transfer duration",
|
|
805
|
+
"ccache-stats-log",
|
|
806
|
+
compilerEvidenceRoot,
|
|
807
|
+
),
|
|
808
|
+
saveDuration: unavailableMetric(
|
|
809
|
+
"ms",
|
|
810
|
+
"ccache stats log exposes writes but not save duration",
|
|
811
|
+
"ccache-stats-log",
|
|
812
|
+
compilerEvidenceRoot,
|
|
813
|
+
),
|
|
814
|
+
restoredBytes: unavailableMetric(
|
|
815
|
+
"bytes",
|
|
816
|
+
"ccache does not expose per-run restored bytes",
|
|
817
|
+
"ccache-stats-log",
|
|
818
|
+
compilerEvidenceRoot,
|
|
819
|
+
),
|
|
820
|
+
writtenBytes: unavailableMetric(
|
|
821
|
+
"bytes",
|
|
822
|
+
"ccache does not expose per-run written bytes",
|
|
823
|
+
"ccache-stats-log",
|
|
824
|
+
compilerEvidenceRoot,
|
|
825
|
+
),
|
|
826
|
+
savedTime: unavailableMetric(
|
|
827
|
+
"ms",
|
|
828
|
+
"ccache does not report evidence-backed compile time saved",
|
|
829
|
+
"ccache-stats-log",
|
|
830
|
+
compilerEvidenceRoot,
|
|
831
|
+
),
|
|
832
|
+
},
|
|
833
|
+
evidence: {
|
|
834
|
+
kind: "compiler-cache-diagnostics",
|
|
835
|
+
root: compilerEvidenceRoot,
|
|
836
|
+
locator: ".buildchain/artifacts/<platform>/diagnostics.json#compilerCaches",
|
|
837
|
+
},
|
|
838
|
+
}),
|
|
839
|
+
);
|
|
840
|
+
return createCacheEvidenceSet({
|
|
841
|
+
repository,
|
|
842
|
+
sourceCommit,
|
|
843
|
+
sourceTree,
|
|
844
|
+
runtimeCommit,
|
|
845
|
+
platform,
|
|
846
|
+
operations,
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
|
|
594
850
|
export function collectCacheDiagnostics({ cwd = process.cwd(), cacheDirs = [], runCommand = defaultDiagnosticCommandRunner } = {}) {
|
|
595
851
|
const resolvedCwd = path.resolve(cwd);
|
|
596
852
|
return {
|
|
@@ -1095,6 +1351,11 @@ export function createDiagnosticsArtifact({
|
|
|
1095
1351
|
const nativeProfile = getNativeDiagnosticsProfile(loadedConfig);
|
|
1096
1352
|
const native = collectNativeDiagnostics({ cwd: resolvedCwd, profile: nativeProfile });
|
|
1097
1353
|
const cache = collectCacheDiagnostics({ cwd: resolvedCwd, cacheDirs });
|
|
1354
|
+
const compilerCaches = native.compilerCaches || cache.compilerCaches || {};
|
|
1355
|
+
const platform =
|
|
1356
|
+
links.platformId ||
|
|
1357
|
+
process.env.BUILDCHAIN_PLATFORM_ID ||
|
|
1358
|
+
`${process.env.RUNNER_OS || os.platform()}-${process.env.RUNNER_ARCH || os.arch()}`;
|
|
1098
1359
|
return {
|
|
1099
1360
|
schemaVersion: 1,
|
|
1100
1361
|
contract: BUILDCHAIN_DIAGNOSTICS_CONTRACT,
|
|
@@ -1105,7 +1366,12 @@ export function createDiagnosticsArtifact({
|
|
|
1105
1366
|
tools: collectToolDiagnostics({ cwd: resolvedCwd }),
|
|
1106
1367
|
cache,
|
|
1107
1368
|
native,
|
|
1108
|
-
compilerCaches
|
|
1369
|
+
compilerCaches,
|
|
1370
|
+
cacheEvidence: createStructuredCacheEvidence({
|
|
1371
|
+
sourceCheckout,
|
|
1372
|
+
compilerCaches,
|
|
1373
|
+
platform,
|
|
1374
|
+
}),
|
|
1109
1375
|
nativeCacheDirs: native.cacheDirs || [],
|
|
1110
1376
|
git: collectGitDiagnostics({ cwd: resolvedCwd }),
|
|
1111
1377
|
lifecycleObservability: lifecycleObservability || summarizeLifecycleObservability({ events, logPath }),
|
|
@@ -1191,20 +1191,38 @@ export function createGithubRulesetGovernanceRolloutPlan({
|
|
|
1191
1191
|
repository,
|
|
1192
1192
|
targetRef,
|
|
1193
1193
|
rulesetId,
|
|
1194
|
+
rulesetName,
|
|
1194
1195
|
inventory,
|
|
1195
1196
|
rollbackSnapshot,
|
|
1196
1197
|
desiredProtection,
|
|
1197
1198
|
} = {}) {
|
|
1198
1199
|
const fullName = requiredString(repository, "repository");
|
|
1199
1200
|
const branch = normalizedRef(targetRef);
|
|
1200
|
-
const
|
|
1201
|
-
|
|
1202
|
-
|
|
1201
|
+
const creating = rulesetId === null || rulesetId === undefined || rulesetId === "";
|
|
1202
|
+
const id = creating ? null : Number(rulesetId);
|
|
1203
|
+
if (!creating && (!Number.isInteger(id) || id <= 0)) {
|
|
1204
|
+
throw new Error("ruleset id must be a positive integer when supplied");
|
|
1203
1205
|
}
|
|
1204
|
-
if (!inventory || !rollbackSnapshot) {
|
|
1205
|
-
throw new Error(
|
|
1206
|
+
if (!inventory || (!creating && !rollbackSnapshot)) {
|
|
1207
|
+
throw new Error(
|
|
1208
|
+
"read-only inventory and any existing frozen rollback snapshot are required",
|
|
1209
|
+
);
|
|
1206
1210
|
}
|
|
1207
|
-
const before =
|
|
1211
|
+
const before = creating
|
|
1212
|
+
? {
|
|
1213
|
+
name: requiredString(rulesetName, "ruleset name"),
|
|
1214
|
+
target: "branch",
|
|
1215
|
+
enforcement: "active",
|
|
1216
|
+
bypass_actors: [],
|
|
1217
|
+
conditions: {
|
|
1218
|
+
ref_name: {
|
|
1219
|
+
include: [`refs/heads/${branch}`],
|
|
1220
|
+
exclude: [],
|
|
1221
|
+
},
|
|
1222
|
+
},
|
|
1223
|
+
rules: [],
|
|
1224
|
+
}
|
|
1225
|
+
: normalizeGithubRulesetSnapshot(rollbackSnapshot);
|
|
1208
1226
|
const exactInclude = before.conditions?.ref_name?.include || [];
|
|
1209
1227
|
const exactExclude = before.conditions?.ref_name?.exclude || [];
|
|
1210
1228
|
if (
|
|
@@ -1265,28 +1283,53 @@ export function createGithubRulesetGovernanceRolloutPlan({
|
|
|
1265
1283
|
});
|
|
1266
1284
|
if (pullRequestRules.length === 0) desiredRules.push(desiredPullRequestRule);
|
|
1267
1285
|
if (statusCheckRules.length === 0) desiredRules.push(desiredStatusCheckRule);
|
|
1286
|
+
if (
|
|
1287
|
+
desiredProtection?.blockDeletions === true &&
|
|
1288
|
+
!desiredRules.some((rule) => rule.type === "deletion")
|
|
1289
|
+
) {
|
|
1290
|
+
desiredRules.push({ type: "deletion" });
|
|
1291
|
+
}
|
|
1292
|
+
if (
|
|
1293
|
+
desiredProtection?.blockNonFastForward === true &&
|
|
1294
|
+
!desiredRules.some((rule) => rule.type === "non_fast_forward")
|
|
1295
|
+
) {
|
|
1296
|
+
desiredRules.push({ type: "non_fast_forward" });
|
|
1297
|
+
}
|
|
1268
1298
|
const desired = {
|
|
1269
1299
|
...before,
|
|
1300
|
+
name: rulesetName
|
|
1301
|
+
? requiredString(rulesetName, "ruleset name")
|
|
1302
|
+
: before.name,
|
|
1270
1303
|
bypass_actors: providerRulesetBypassActors(
|
|
1271
1304
|
desiredProtection?.rulesetBypassActors,
|
|
1272
1305
|
),
|
|
1273
1306
|
rules: desiredRules,
|
|
1274
1307
|
};
|
|
1275
|
-
const endpoint =
|
|
1308
|
+
const endpoint = creating
|
|
1309
|
+
? `repos/${fullName}/rulesets`
|
|
1310
|
+
: `repos/${fullName}/rulesets/${id}`;
|
|
1276
1311
|
const core = {
|
|
1277
1312
|
schemaVersion: 1,
|
|
1278
1313
|
contract: GITHUB_GOVERNANCE_RULESET_ROLLOUT_CONTRACT,
|
|
1279
1314
|
repository: fullName,
|
|
1280
1315
|
targetRef: branch,
|
|
1281
1316
|
rulesetId: id,
|
|
1317
|
+
rulesetName: desired.name,
|
|
1318
|
+
action: creating ? "create" : "update",
|
|
1282
1319
|
inventoryRoot: githubGovernanceDigest(inventory),
|
|
1283
|
-
rollbackSnapshotRoot:
|
|
1284
|
-
|
|
1320
|
+
rollbackSnapshotRoot: creating
|
|
1321
|
+
? githubGovernanceDigest({ rulesetExists: false, targetRef: branch })
|
|
1322
|
+
: githubGovernanceDigest(before),
|
|
1323
|
+
operations: [
|
|
1324
|
+
{ method: creating ? "POST" : "PUT", endpoint, body: desired },
|
|
1325
|
+
],
|
|
1285
1326
|
impact: [
|
|
1286
1327
|
"replace ruleset bypass actors with the exact provider-admitted desired set",
|
|
1287
1328
|
"require fresh Code Owner review and resolved review threads",
|
|
1288
1329
|
"bind required status checks and strictness to the authoritative target descriptor",
|
|
1289
|
-
|
|
1330
|
+
creating
|
|
1331
|
+
? "create one exact-branch active ruleset because no matching ruleset exists"
|
|
1332
|
+
: "preserve unrelated ruleset rules and exact target conditions",
|
|
1290
1333
|
],
|
|
1291
1334
|
expectedObservation: {
|
|
1292
1335
|
rulesetRoot: githubGovernanceDigest(desired),
|
|
@@ -1296,12 +1339,24 @@ export function createGithubRulesetGovernanceRolloutPlan({
|
|
|
1296
1339
|
desiredProtection?.strictRequiredChecks === true,
|
|
1297
1340
|
requiredApprovals,
|
|
1298
1341
|
},
|
|
1299
|
-
rollback:
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1342
|
+
rollback: creating
|
|
1343
|
+
? [
|
|
1344
|
+
{
|
|
1345
|
+
method: "DELETE",
|
|
1346
|
+
endpoint: `repos/${fullName}/rulesets/{ruleset_id}`,
|
|
1347
|
+
body: null,
|
|
1348
|
+
preconditionRoot: githubGovernanceDigest(desired),
|
|
1349
|
+
requiresApplyReceipt: true,
|
|
1350
|
+
},
|
|
1351
|
+
]
|
|
1352
|
+
: [
|
|
1353
|
+
{
|
|
1354
|
+
method: "PUT",
|
|
1355
|
+
endpoint,
|
|
1356
|
+
body: before,
|
|
1357
|
+
preconditionRoot: githubGovernanceDigest(before),
|
|
1358
|
+
},
|
|
1359
|
+
],
|
|
1305
1360
|
};
|
|
1306
1361
|
return { ...core, planRoot: githubGovernanceDigest(core) };
|
|
1307
1362
|
}
|
package/packages/core/index.js
CHANGED
|
@@ -64,6 +64,16 @@ export {
|
|
|
64
64
|
verifyPortableDevCachePlan,
|
|
65
65
|
} from "./portable-dev-cache.js";
|
|
66
66
|
|
|
67
|
+
export {
|
|
68
|
+
BUILDCHAIN_CACHE_EVIDENCE_SET_CONTRACT,
|
|
69
|
+
BUILDCHAIN_CACHE_OPERATION_RECEIPT_CONTRACT,
|
|
70
|
+
cacheEvidenceDigest,
|
|
71
|
+
createCacheEvidenceSet,
|
|
72
|
+
createCacheOperationReceipt,
|
|
73
|
+
verifyCacheEvidenceSet,
|
|
74
|
+
verifyCacheOperationReceipt,
|
|
75
|
+
} from "./cache-evidence.js";
|
|
76
|
+
|
|
67
77
|
export {
|
|
68
78
|
explainReleaseLineDryRun,
|
|
69
79
|
formatReleaseLineDryRun,
|
|
@@ -370,6 +380,23 @@ export {
|
|
|
370
380
|
testKfdAgentHub,
|
|
371
381
|
} from "./kfd-agent-hub.js";
|
|
372
382
|
|
|
383
|
+
export {
|
|
384
|
+
KFD_PRODUCT_GATE_CONTRACT,
|
|
385
|
+
KFD_PRODUCT_GATE_INPUT_CONTRACT,
|
|
386
|
+
KFD_PRODUCT_GATE_INPUT_SCHEMA,
|
|
387
|
+
KFD_PRODUCT_GATE_INPUT_SCHEMA_ID,
|
|
388
|
+
KFD_SUPPORT_PROJECTION_CONTRACT,
|
|
389
|
+
KFD_SUPPORT_PROJECTION_SCHEMA,
|
|
390
|
+
KFD_SUPPORT_PROJECTION_SCHEMA_ID,
|
|
391
|
+
createKfdSupportProjection,
|
|
392
|
+
evaluateKfdProductGate,
|
|
393
|
+
kfdProductGateDigest,
|
|
394
|
+
kfdProductGates,
|
|
395
|
+
validateKfdProductGateResult,
|
|
396
|
+
validateKfdSupportProjection,
|
|
397
|
+
verifyKfdRecord,
|
|
398
|
+
} from "./kfd-product-gates.js";
|
|
399
|
+
|
|
373
400
|
export {
|
|
374
401
|
RELEASE_PASSPORT_CHECK_MANIFEST_CONTRACT,
|
|
375
402
|
RELEASE_PASSPORT_SCHEMA,
|