@vivswan/github-settings-as-code 2.0.1-main.1081.gc25bbfe → 2.0.1-main.1089.g2dd2ba5
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.
Potentially problematic release.
This version of @vivswan/github-settings-as-code might be problematic. Click here for more details.
- package/LICENSE.md +1 -1
- package/lib/pkg/cli.js +1 -1
- package/lib/pkg/index.d.ts +38 -20
- package/lib/pkg/index.js +1 -1
- package/lib/pkg/{src-BFMt0V_E.js → src-L_4G-LmP.js} +37 -18
- package/package.json +1 -1
package/LICENSE.md
CHANGED
|
@@ -557,5 +557,5 @@ software incorporates into what it produces are output. The software's
|
|
|
557
557
|
**Use** means anything you do with the software requiring one of your
|
|
558
558
|
licenses.
|
|
559
559
|
|
|
560
|
-
<!-- The license text between the BEGIN/END markers is managed by
|
|
560
|
+
<!-- The license text between the BEGIN/END markers is managed by the platform and replaced on every sync. Repository-specific license notices (third-party components, differently licensed paths) go below the END marker; they are this repository's own and survive every sync. -->
|
|
561
561
|
<!-- END REPO-PLATFORM MANAGED -->
|
package/lib/pkg/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as SNAPSHOT_ONLY_INPUTS, E as parseSnapshotFileConfig, F as concludeMerge, I as concludeRun, Kt as redactRanges, L as failRun, Rt as GithubApi, S as SNAPSHOT_INPUTS, T as parseConfig, U as PRIVATE_REPORT_CHANNELS, Wt as maskRegistry, _ as INPUT_DECLS, d as runSnapshot, f as runSingle, j as readSettingsFile, k as runMulti, o as snapshotRepository, pt as SECTIONS, s as validateSettings, t as runMerge, tt as describeProblem, u as concludeSnapshot, v as MERGE_INPUTS, y as MERGE_ONLY_INPUTS, yt as sectionGrant } from "./src-
|
|
2
|
+
import { C as SNAPSHOT_ONLY_INPUTS, E as parseSnapshotFileConfig, F as concludeMerge, I as concludeRun, Kt as redactRanges, L as failRun, Rt as GithubApi, S as SNAPSHOT_INPUTS, T as parseConfig, U as PRIVATE_REPORT_CHANNELS, Wt as maskRegistry, _ as INPUT_DECLS, d as runSnapshot, f as runSingle, j as readSettingsFile, k as runMulti, o as snapshotRepository, pt as SECTIONS, s as validateSettings, t as runMerge, tt as describeProblem, u as concludeSnapshot, v as MERGE_INPUTS, y as MERGE_ONLY_INPUTS, yt as sectionGrant } from "./src-L_4G-LmP.js";
|
|
3
3
|
import { appendFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { dirname } from "node:path";
|
|
5
5
|
import { ResultAsync, err, ok } from "neverthrow";
|
package/lib/pkg/index.d.ts
CHANGED
|
@@ -1619,12 +1619,12 @@ interface SectionSnapshot<K extends SectionKey = SectionKey> {
|
|
|
1619
1619
|
* repository; the engine renders them as drift in check mode and executes them in apply mode.
|
|
1620
1620
|
* Modules register in ../registry.ts.
|
|
1621
1621
|
*
|
|
1622
|
-
* snapshot() present -> reads through the same port, so it cannot write either
|
|
1622
|
+
* snapshot() present -> reads through the same port (plus the run's denial policy), so it cannot write either
|
|
1623
1623
|
* snapshot() absent -> the section is unsupported by snapshot (snapshotUnsupportedNote)
|
|
1624
1624
|
*/
|
|
1625
1625
|
interface SectionModule<K extends SectionKey = SectionKey, E extends EndpointDict = EndpointDict, G extends GraphqlDict = GraphqlDict> extends SectionModuleBase<K, E, G> {
|
|
1626
1626
|
plan(ctx: PlanContext<E, G>, desired: SectionInput<K>): Promise<SectionPlan<PlannedOp<E, G>>>;
|
|
1627
|
-
snapshot?(ctx:
|
|
1627
|
+
snapshot?(ctx: SnapshotContext<E, G>): Promise<SectionSnapshot<K>>;
|
|
1628
1628
|
/** Pinned so a non-literal object carrying a run() handler is not assignable either. */
|
|
1629
1629
|
run?: never;
|
|
1630
1630
|
}
|
|
@@ -1799,6 +1799,24 @@ interface PlanContext<E extends EndpointDict = EndpointDict, G extends GraphqlDi
|
|
|
1799
1799
|
readonly repo: RepoRef;
|
|
1800
1800
|
readonly read: BoundReads<E, G>;
|
|
1801
1801
|
}
|
|
1802
|
+
/**
|
|
1803
|
+
* The policy as a snapshot() sees it. Only snapshotContext() mints one: the constructor is private
|
|
1804
|
+
* and the class nominal, so a section cannot hand readOrNote a literal "warn" and turn a denial the
|
|
1805
|
+
* run should fail on into a note.
|
|
1806
|
+
*/
|
|
1807
|
+
declare class DenialPolicy {
|
|
1808
|
+
private readonly input;
|
|
1809
|
+
private constructor();
|
|
1810
|
+
/** Under warn a denied sub-read is noted and left out; under fail it propagates. */
|
|
1811
|
+
get notesDenials(): boolean;
|
|
1812
|
+
}
|
|
1813
|
+
/**
|
|
1814
|
+
* What snapshot() reads through: the plan port plus the run's denial policy, so a helper over one
|
|
1815
|
+
* sub-read (readOrNote) classifies a denial where it happens instead of noting it under both.
|
|
1816
|
+
*/
|
|
1817
|
+
interface SnapshotContext<E extends EndpointDict = EndpointDict, G extends GraphqlDict = GraphqlDict> extends PlanContext<E, G> {
|
|
1818
|
+
readonly onMissingPermission: DenialPolicy;
|
|
1819
|
+
}
|
|
1802
1820
|
/**
|
|
1803
1821
|
* `D` is the drift type its arm demands: an ordinary operation must justify itself with at least one
|
|
1804
1822
|
* drift line (DriftFor), so "check reported clean while apply mutated" is unrepresentable.
|
|
@@ -2095,7 +2113,7 @@ interface ListSectionModule<K extends ListSectionKey, Ends extends ListEndpoints
|
|
|
2095
2113
|
readonly secretValues?: (declared: Declared<K>) => DeclaredSecretValue[];
|
|
2096
2114
|
readonly layering?: KeyedListLayering;
|
|
2097
2115
|
readonly plan: (ctx: PlanContext<Ends>, desired: Declared<K>) => Promise<SectionPlan<PlannedOp<Ends>>>;
|
|
2098
|
-
readonly snapshot: (ctx:
|
|
2116
|
+
readonly snapshot: (ctx: SnapshotContext<Ends>) => Promise<SectionSnapshot<K>>;
|
|
2099
2117
|
/** The declaration, for the harness derivations (the mock's transformers, the fuzz witness). */
|
|
2100
2118
|
readonly decl: ListSectionDecl<K, Ends, Live, F>;
|
|
2101
2119
|
}
|
|
@@ -2626,7 +2644,7 @@ interface RepoSecretsSectionModule<K extends RepoSecretsKey> {
|
|
|
2626
2644
|
readonly secretValues: typeof listSecretValues;
|
|
2627
2645
|
readonly closedSurface: typeof CLOSED_SURFACE;
|
|
2628
2646
|
readonly plan: RepoSecretsPlan<K>;
|
|
2629
|
-
readonly snapshot: (ctx:
|
|
2647
|
+
readonly snapshot: (ctx: SnapshotContext<RepoSecretsEndpoints<SecretsSegment<K>>>) => Promise<SectionSnapshot<K>>;
|
|
2630
2648
|
}
|
|
2631
2649
|
//#endregion
|
|
2632
2650
|
//#region src/sections/shared/setup-section.d.ts
|
|
@@ -2721,7 +2739,7 @@ interface SetupSectionModule<K extends SetupKey> {
|
|
|
2721
2739
|
readonly endpoints: SetupEndpoints<K>;
|
|
2722
2740
|
readonly shape: z.ZodType;
|
|
2723
2741
|
readonly plan: SetupPlan<K>;
|
|
2724
|
-
readonly snapshot: (ctx:
|
|
2742
|
+
readonly snapshot: (ctx: SnapshotContext<SetupEndpoints<K>>) => Promise<SectionSnapshot<K>>;
|
|
2725
2743
|
}
|
|
2726
2744
|
//#endregion
|
|
2727
2745
|
//#region src/sections/shared/repo-variables.d.ts
|
|
@@ -2788,7 +2806,7 @@ interface RepoVariablesSectionModule<K extends RepoVariablesKey> {
|
|
|
2788
2806
|
readonly endpoints: RepoVariablesEndpoints<VariablesSegment<K>>;
|
|
2789
2807
|
readonly shape: z.ZodType;
|
|
2790
2808
|
readonly plan: RepoVariablesPlan<K>;
|
|
2791
|
-
readonly snapshot: (ctx:
|
|
2809
|
+
readonly snapshot: (ctx: SnapshotContext<RepoVariablesEndpoints<VariablesSegment<K>>>) => Promise<SectionSnapshot<K>>;
|
|
2792
2810
|
}
|
|
2793
2811
|
//#endregion
|
|
2794
2812
|
//#region src/sections/registry.d.ts
|
|
@@ -3296,7 +3314,7 @@ declare const byKey: {
|
|
|
3296
3314
|
}> | undefined;
|
|
3297
3315
|
readonly variables?: never;
|
|
3298
3316
|
})>>;
|
|
3299
|
-
snapshot(ctx:
|
|
3317
|
+
snapshot(ctx: SnapshotContext<{
|
|
3300
3318
|
readonly get: {
|
|
3301
3319
|
readonly route: "GET /repos/{owner}/{repo}";
|
|
3302
3320
|
readonly statuses: {
|
|
@@ -3663,7 +3681,7 @@ declare const byKey: {
|
|
|
3663
3681
|
}> | undefined;
|
|
3664
3682
|
readonly variables?: never;
|
|
3665
3683
|
})>>;
|
|
3666
|
-
snapshot(ctx:
|
|
3684
|
+
snapshot(ctx: SnapshotContext<{
|
|
3667
3685
|
readonly list: {
|
|
3668
3686
|
readonly route: "GET /repos/{owner}/{repo}/rulesets";
|
|
3669
3687
|
readonly statuses: {
|
|
@@ -4179,7 +4197,7 @@ declare const byKey: {
|
|
|
4179
4197
|
}[];
|
|
4180
4198
|
} | undefined;
|
|
4181
4199
|
}[]): Promise<EnvironmentsPlan>;
|
|
4182
|
-
snapshot(ctx:
|
|
4200
|
+
snapshot(ctx: SnapshotContext<{
|
|
4183
4201
|
readonly list: {
|
|
4184
4202
|
readonly route: "GET /repos/{owner}/{repo}/environments";
|
|
4185
4203
|
readonly statuses: {
|
|
@@ -4802,7 +4820,7 @@ declare const byKey: {
|
|
|
4802
4820
|
} | null | undefined;
|
|
4803
4821
|
} | null;
|
|
4804
4822
|
}[]): Promise<BranchesPlan>;
|
|
4805
|
-
snapshot(ctx:
|
|
4823
|
+
snapshot(ctx: SnapshotContext<{
|
|
4806
4824
|
readonly getProtection: {
|
|
4807
4825
|
readonly route: "GET /repos/{owner}/{repo}/branches/{branch}/protection";
|
|
4808
4826
|
readonly statuses: {
|
|
@@ -5517,7 +5535,7 @@ declare const byKey: {
|
|
|
5517
5535
|
}> | undefined;
|
|
5518
5536
|
readonly variables?: never;
|
|
5519
5537
|
})>>;
|
|
5520
|
-
snapshot(ctx:
|
|
5538
|
+
snapshot(ctx: SnapshotContext<{
|
|
5521
5539
|
readonly getPermissions: {
|
|
5522
5540
|
readonly route: "GET /repos/{owner}/{repo}/actions/permissions";
|
|
5523
5541
|
readonly statuses: {
|
|
@@ -5770,7 +5788,7 @@ declare const byKey: {
|
|
|
5770
5788
|
}> | undefined;
|
|
5771
5789
|
readonly variables?: never;
|
|
5772
5790
|
})>>;
|
|
5773
|
-
snapshot(ctx:
|
|
5791
|
+
snapshot(ctx: SnapshotContext<{
|
|
5774
5792
|
readonly list: {
|
|
5775
5793
|
readonly route: "GET /repos/{owner}/{repo}/actions/workflows";
|
|
5776
5794
|
readonly statuses: {
|
|
@@ -5961,7 +5979,7 @@ declare const byKey: {
|
|
|
5961
5979
|
}> | undefined;
|
|
5962
5980
|
readonly variables?: never;
|
|
5963
5981
|
})>>;
|
|
5964
|
-
snapshot(ctx:
|
|
5982
|
+
snapshot(ctx: SnapshotContext<{
|
|
5965
5983
|
readonly get: {
|
|
5966
5984
|
readonly route: "GET /repos/{owner}/{repo}/pages";
|
|
5967
5985
|
readonly statuses: {
|
|
@@ -6172,7 +6190,7 @@ declare const byKey: {
|
|
|
6172
6190
|
}> | undefined;
|
|
6173
6191
|
readonly variables?: never;
|
|
6174
6192
|
})>>;
|
|
6175
|
-
snapshot(ctx:
|
|
6193
|
+
snapshot(ctx: SnapshotContext<{
|
|
6176
6194
|
readonly list: {
|
|
6177
6195
|
readonly route: "GET /repos/{owner}/{repo}/collaborators";
|
|
6178
6196
|
readonly statuses: {
|
|
@@ -6321,7 +6339,7 @@ declare const byKey: {
|
|
|
6321
6339
|
}> | undefined;
|
|
6322
6340
|
readonly variables?: never;
|
|
6323
6341
|
}>>;
|
|
6324
|
-
snapshot(ctx:
|
|
6342
|
+
snapshot(ctx: SnapshotContext<{
|
|
6325
6343
|
readonly org: {
|
|
6326
6344
|
readonly route: "GET /orgs/{org}";
|
|
6327
6345
|
readonly statuses: {
|
|
@@ -6474,7 +6492,7 @@ declare const byKey: {
|
|
|
6474
6492
|
}> | undefined;
|
|
6475
6493
|
readonly variables?: never;
|
|
6476
6494
|
})>>;
|
|
6477
|
-
snapshot(ctx:
|
|
6495
|
+
snapshot(ctx: SnapshotContext<{
|
|
6478
6496
|
readonly list: {
|
|
6479
6497
|
readonly route: "GET /repos/{owner}/{repo}/milestones";
|
|
6480
6498
|
readonly statuses: {
|
|
@@ -6760,7 +6778,7 @@ declare const byKey: {
|
|
|
6760
6778
|
}> | undefined;
|
|
6761
6779
|
readonly variables?: never;
|
|
6762
6780
|
})>>;
|
|
6763
|
-
snapshot(ctx:
|
|
6781
|
+
snapshot(ctx: SnapshotContext<{
|
|
6764
6782
|
readonly get: {
|
|
6765
6783
|
readonly route: "GET /repos/{owner}/{repo}/interaction-limits";
|
|
6766
6784
|
readonly statuses: {
|
|
@@ -7012,7 +7030,7 @@ declare const byKey: {
|
|
|
7012
7030
|
}> | undefined;
|
|
7013
7031
|
readonly variables?: never;
|
|
7014
7032
|
})>>;
|
|
7015
|
-
snapshot(ctx:
|
|
7033
|
+
snapshot(ctx: SnapshotContext<{
|
|
7016
7034
|
readonly list: {
|
|
7017
7035
|
readonly route: "GET /repos/{owner}/{repo}/hooks";
|
|
7018
7036
|
readonly statuses: {
|
|
@@ -7171,7 +7189,7 @@ declare const byKey: {
|
|
|
7171
7189
|
}> | undefined;
|
|
7172
7190
|
readonly variables?: never;
|
|
7173
7191
|
}>>;
|
|
7174
|
-
snapshot(ctx:
|
|
7192
|
+
snapshot(ctx: SnapshotContext<{
|
|
7175
7193
|
readonly org: {
|
|
7176
7194
|
readonly route: "GET /orgs/{org}";
|
|
7177
7195
|
readonly statuses: {
|
|
@@ -7420,7 +7438,7 @@ declare const byKey: {
|
|
|
7420
7438
|
}> | undefined;
|
|
7421
7439
|
readonly variables?: never;
|
|
7422
7440
|
})>>;
|
|
7423
|
-
snapshot(ctx:
|
|
7441
|
+
snapshot(ctx: SnapshotContext<{
|
|
7424
7442
|
readonly list: {
|
|
7425
7443
|
readonly route: "GET /repos/{owner}/{repo}/secret-scanning/custom-patterns";
|
|
7426
7444
|
readonly statuses: {
|
package/lib/pkg/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as renderSnapshotYaml, A as parseSettingsDoc, At as parseReposInput, B as planRedaction, Bt as SECRET_TRANSPORT_WITHHELD, C as SNAPSHOT_ONLY_INPUTS, Ct as endpointMethod, D as DEFAULT_SETTINGS_FILE, Dt as SECTION_KEYS, E as parseSnapshotFileConfig, Et as PROBOT_PARITY_KEYS, F as concludeMerge, Ft as VISIBILITY_FILTERS, G as openReportChannel, Gt as prefixedIo, H as toPublicView, Ht as isRateLimitError, I as concludeRun, It as discoverRepos, J as MARKER_LABEL_CONFIG, Jt as resolveCentralTargets, K as ISSUE_TITLE, Kt as redactRanges, L as failRun, Lt as DEFAULT_API_VERSION, M as createVisibilityResolver, Mt as ARCHIVED_FILTERS, N as getRepoFile, Nt as DEFAULT_DISCOVERY_FILTERS, O as resolveTargets, Ot as SettingsFile, P as MERGE_RESULT, Pt as FORKS_FILTERS, Q as parseRecipient, R as PRIVATE_REPOS_POLICIES, Rt as GithubApi, S as SNAPSHOT_INPUTS, St as grantFor, T as parseConfig, Tt as DOCUMENT_DIRECTIVE_KEYS, U as PRIVATE_REPORT_CHANNELS, Ut as collectingIo, V as publicDetail, Vt as isPermissionError, W as applyMarkerInjection, Wt as maskRegistry, X as deliverArtifactReport, Xt as parseRepoSlug, Y as composeReport, Yt as dedupeTargets, Z as encryptReport, _ as INPUT_DECLS, _t as denialPosture, a as snapshotRepositories, at as preflightProbe, b as MERGE_REJECTED_INPUTS, bt as sectionOperations, c as SNAPSHOT_RESULTS, ct as validateSettingsDoc, d as runSnapshot, dt as mergeLayers, et as RERUN_ADVICE, f as runSingle, ft as stripNulls, g as FILTER_INPUTS, gt as sectionModule, h as DEFAULT_PRIVATE_REPOS, ht as allGraphqlOps, i as renderMergedYaml, it as REPO_RESULTS, j as readSettingsFile, jt as AFFILIATIONS, k as runMulti, kt as UNDECLARED_POLICY_SECTIONS, l as SNAPSHOT_SCHEMA_URL, lt as worstOf, m as readLayerFiles, mt as allEndpoints, n as applyRepository, nt as quoteList, o as snapshotRepository, ot as runForRepo, p as foldLayers, pt as SECTIONS, q as MARKER_LABEL, qt as silentIo, r as checkRepository, rt as SectionSelection, s as validateSettings, st as skippedSectionKeys, t as runMerge, tt as describeProblem, u as concludeSnapshot, ut as describeOptOut, v as MERGE_INPUTS, vt as readGating, w as SNAPSHOT_REJECTED_INPUTS, wt as endpointPath, x as MODES, xt as writeGatedReads, y as MERGE_ONLY_INPUTS, yt as sectionGrant, z as capturingIo, zt as SECRET_RESPONSE_WITHHELD } from "./src-
|
|
1
|
+
import { $ as renderSnapshotYaml, A as parseSettingsDoc, At as parseReposInput, B as planRedaction, Bt as SECRET_TRANSPORT_WITHHELD, C as SNAPSHOT_ONLY_INPUTS, Ct as endpointMethod, D as DEFAULT_SETTINGS_FILE, Dt as SECTION_KEYS, E as parseSnapshotFileConfig, Et as PROBOT_PARITY_KEYS, F as concludeMerge, Ft as VISIBILITY_FILTERS, G as openReportChannel, Gt as prefixedIo, H as toPublicView, Ht as isRateLimitError, I as concludeRun, It as discoverRepos, J as MARKER_LABEL_CONFIG, Jt as resolveCentralTargets, K as ISSUE_TITLE, Kt as redactRanges, L as failRun, Lt as DEFAULT_API_VERSION, M as createVisibilityResolver, Mt as ARCHIVED_FILTERS, N as getRepoFile, Nt as DEFAULT_DISCOVERY_FILTERS, O as resolveTargets, Ot as SettingsFile, P as MERGE_RESULT, Pt as FORKS_FILTERS, Q as parseRecipient, R as PRIVATE_REPOS_POLICIES, Rt as GithubApi, S as SNAPSHOT_INPUTS, St as grantFor, T as parseConfig, Tt as DOCUMENT_DIRECTIVE_KEYS, U as PRIVATE_REPORT_CHANNELS, Ut as collectingIo, V as publicDetail, Vt as isPermissionError, W as applyMarkerInjection, Wt as maskRegistry, X as deliverArtifactReport, Xt as parseRepoSlug, Y as composeReport, Yt as dedupeTargets, Z as encryptReport, _ as INPUT_DECLS, _t as denialPosture, a as snapshotRepositories, at as preflightProbe, b as MERGE_REJECTED_INPUTS, bt as sectionOperations, c as SNAPSHOT_RESULTS, ct as validateSettingsDoc, d as runSnapshot, dt as mergeLayers, et as RERUN_ADVICE, f as runSingle, ft as stripNulls, g as FILTER_INPUTS, gt as sectionModule, h as DEFAULT_PRIVATE_REPOS, ht as allGraphqlOps, i as renderMergedYaml, it as REPO_RESULTS, j as readSettingsFile, jt as AFFILIATIONS, k as runMulti, kt as UNDECLARED_POLICY_SECTIONS, l as SNAPSHOT_SCHEMA_URL, lt as worstOf, m as readLayerFiles, mt as allEndpoints, n as applyRepository, nt as quoteList, o as snapshotRepository, ot as runForRepo, p as foldLayers, pt as SECTIONS, q as MARKER_LABEL, qt as silentIo, r as checkRepository, rt as SectionSelection, s as validateSettings, st as skippedSectionKeys, t as runMerge, tt as describeProblem, u as concludeSnapshot, ut as describeOptOut, v as MERGE_INPUTS, vt as readGating, w as SNAPSHOT_REJECTED_INPUTS, wt as endpointPath, x as MODES, xt as writeGatedReads, y as MERGE_ONLY_INPUTS, yt as sectionGrant, z as capturingIo, zt as SECRET_RESPONSE_WITHHELD } from "./src-L_4G-LmP.js";
|
|
2
2
|
export { AFFILIATIONS, ARCHIVED_FILTERS, DEFAULT_API_VERSION, DEFAULT_DISCOVERY_FILTERS, DEFAULT_PRIVATE_REPOS, DEFAULT_SETTINGS_FILE, DOCUMENT_DIRECTIVE_KEYS, FILTER_INPUTS, FORKS_FILTERS, GithubApi, INPUT_DECLS, ISSUE_TITLE, MARKER_LABEL, MARKER_LABEL_CONFIG, MERGE_INPUTS, MERGE_ONLY_INPUTS, MERGE_REJECTED_INPUTS, MERGE_RESULT, MODES, PRIVATE_REPORT_CHANNELS, PRIVATE_REPOS_POLICIES, PROBOT_PARITY_KEYS, REPO_RESULTS, RERUN_ADVICE, SECRET_RESPONSE_WITHHELD, SECRET_TRANSPORT_WITHHELD, SECTIONS, SECTION_KEYS, SNAPSHOT_INPUTS, SNAPSHOT_ONLY_INPUTS, SNAPSHOT_REJECTED_INPUTS, SNAPSHOT_RESULTS, SNAPSHOT_SCHEMA_URL, SectionSelection, SettingsFile, UNDECLARED_POLICY_SECTIONS, VISIBILITY_FILTERS, allEndpoints, allGraphqlOps, applyMarkerInjection, applyRepository, capturingIo, checkRepository, collectingIo, composeReport, concludeMerge, concludeRun, concludeSnapshot, createVisibilityResolver, dedupeTargets, deliverArtifactReport, denialPosture, describeOptOut, describeProblem, discoverRepos, encryptReport, endpointMethod, endpointPath, failRun, foldLayers, getRepoFile, grantFor, isPermissionError, isRateLimitError, maskRegistry, mergeLayers, openReportChannel, parseConfig, parseRecipient, parseRepoSlug, parseReposInput, parseSettingsDoc, parseSnapshotFileConfig, planRedaction, prefixedIo, preflightProbe, publicDetail, quoteList, readGating, readLayerFiles, readSettingsFile, redactRanges, renderMergedYaml, renderSnapshotYaml, resolveCentralTargets, resolveTargets, runForRepo, runMerge, runMulti, runSingle, runSnapshot, sectionGrant, sectionModule, sectionOperations, silentIo, skippedSectionKeys, snapshotRepositories, snapshotRepository, stripNulls, toPublicView, validateSettings, validateSettingsDoc, worstOf, writeGatedReads };
|
|
@@ -2635,6 +2635,20 @@ function plainData(value) {
|
|
|
2635
2635
|
function gated(bound) {
|
|
2636
2636
|
return Object.fromEntries(Object.entries(bound).map(([name, helper]) => [name, typeof helper === "function" ? (_exec, ...args) => helper(...args) : helper]));
|
|
2637
2637
|
}
|
|
2638
|
+
let mintPolicy;
|
|
2639
|
+
(class DenialPolicy {
|
|
2640
|
+
input;
|
|
2641
|
+
constructor(input) {
|
|
2642
|
+
this.input = input;
|
|
2643
|
+
}
|
|
2644
|
+
static {
|
|
2645
|
+
mintPolicy = (input) => new DenialPolicy(input);
|
|
2646
|
+
}
|
|
2647
|
+
/** Under warn a denied sub-read is noted and left out; under fail it propagates. */
|
|
2648
|
+
get notesDenials() {
|
|
2649
|
+
return this.input === "warn";
|
|
2650
|
+
}
|
|
2651
|
+
});
|
|
2638
2652
|
function driftOf(op) {
|
|
2639
2653
|
return "unverifiable" in op.drift ? op.drift.lines : op.drift;
|
|
2640
2654
|
}
|
|
@@ -2698,6 +2712,12 @@ function planContext(meta, api, repo) {
|
|
|
2698
2712
|
read: boundReads(meta, api, repo)
|
|
2699
2713
|
};
|
|
2700
2714
|
}
|
|
2715
|
+
function snapshotContext(meta, api, repo, onMissingPermission) {
|
|
2716
|
+
return {
|
|
2717
|
+
...planContext(meta, api, repo),
|
|
2718
|
+
onMissingPermission: mintPolicy(onMissingPermission)
|
|
2719
|
+
};
|
|
2720
|
+
}
|
|
2701
2721
|
//#endregion
|
|
2702
2722
|
//#region src/sections/shared/snapshot-helpers.ts
|
|
2703
2723
|
function defOf(schema) {
|
|
@@ -2770,15 +2790,17 @@ function rejectLiveDuplicates(section, noun, items, keyOf, describe) {
|
|
|
2770
2790
|
if (collisions.length > 0) throw new Error(`${section.key}: GitHub holds ${noun}s that resolve to one identity: ${collisions.join("; ")}. This section manages one ${noun} per identity, so the snapshot cannot declare them; delete all but one of each on GitHub, then snapshot again`);
|
|
2771
2791
|
}
|
|
2772
2792
|
/**
|
|
2773
|
-
* One read of a snapshot
|
|
2774
|
-
*
|
|
2775
|
-
*
|
|
2793
|
+
* One read of a snapshot whose denial is that read's alone, for a section whose keys sit behind
|
|
2794
|
+
* different grants (repository, actions, environments). Under `warn` a PermissionDenied becomes a
|
|
2795
|
+
* note naming the key left out and the grant advice; under `fail` it propagates, so the engine
|
|
2796
|
+
* fails the section exactly as it does a primary read's denial. Anything else propagates. The
|
|
2797
|
+
* policy arrives as the carrier only snapshotContext() mints, so a section cannot pick "warn".
|
|
2776
2798
|
*/
|
|
2777
|
-
async function readOrNote(notes, label, read) {
|
|
2799
|
+
async function readOrNote(ctx, notes, label, read) {
|
|
2778
2800
|
try {
|
|
2779
2801
|
return { value: await read() };
|
|
2780
2802
|
} catch (error) {
|
|
2781
|
-
if (error instanceof PermissionDenied) {
|
|
2803
|
+
if (error instanceof PermissionDenied && ctx.onMissingPermission.notesDenials) {
|
|
2782
2804
|
notes.push(`${label}: left out of the snapshot - ${error.detail}`);
|
|
2783
2805
|
return { denied: true };
|
|
2784
2806
|
}
|
|
@@ -3002,7 +3024,7 @@ const KEY_DESTINATION = {
|
|
|
3002
3024
|
snapshot: async (ctx, _section, _base, notes) => {
|
|
3003
3025
|
const limits = {};
|
|
3004
3026
|
for (const [key, wiring] of Object.entries(CACHE_ENDPOINT_BY_KEY)) {
|
|
3005
|
-
const read = await readOrNote(notes, `actions.cache.${key}`, () => ctx.read[wiring.get].call());
|
|
3027
|
+
const read = await readOrNote(ctx, notes, `actions.cache.${key}`, () => ctx.read[wiring.get].call());
|
|
3006
3028
|
if (!("denied" in read)) Object.assign(limits, read.value);
|
|
3007
3029
|
}
|
|
3008
3030
|
return Object.keys(limits).length === 0 ? void 0 : sliceOf("cache")(limits);
|
|
@@ -3054,7 +3076,7 @@ async function planRouted(key, ctx, section, desired, plan) {
|
|
|
3054
3076
|
}
|
|
3055
3077
|
/** Read one routed key back; generic so the handler and the value stay correlated to one key. */
|
|
3056
3078
|
async function snapshotRouted(key, ctx, section, base, notes) {
|
|
3057
|
-
const read = await readOrNote(notes, `actions.${key}`, () => ROUTED_DESTINATIONS[key].snapshot(ctx, section, base, notes));
|
|
3079
|
+
const read = await readOrNote(ctx, notes, `actions.${key}`, () => ROUTED_DESTINATIONS[key].snapshot(ctx, section, base, notes));
|
|
3058
3080
|
return "denied" in read ? void 0 : read.value;
|
|
3059
3081
|
}
|
|
3060
3082
|
function keysTo(destination) {
|
|
@@ -3114,7 +3136,7 @@ const actionsSection = {
|
|
|
3114
3136
|
const notes = [];
|
|
3115
3137
|
const base = projectOntoSchema(ActionsConfig, await ctx.read.getPermissions.call());
|
|
3116
3138
|
const value = { ...base };
|
|
3117
|
-
const workflow = await readOrNote(notes, `actions.${[...WORKFLOW_KEYS].join("/")}`, () => ctx.read.getWorkflow.call());
|
|
3139
|
+
const workflow = await readOrNote(ctx, notes, `actions.${[...WORKFLOW_KEYS].join("/")}`, () => ctx.read.getWorkflow.call());
|
|
3118
3140
|
if (!("denied" in workflow)) Object.assign(value, projectOntoSchema(ActionsConfig, workflow.value));
|
|
3119
3141
|
for (const key of ROUTED_KEYS) {
|
|
3120
3142
|
const read = await snapshotRouted(key, ctx, this, base, notes);
|
|
@@ -5936,10 +5958,7 @@ function liveRuleId(rule, envName) {
|
|
|
5936
5958
|
* spec, so an ABSENT list reads as empty, while a PRESENT off-shape value fails loudly in parseLive.
|
|
5937
5959
|
*/
|
|
5938
5960
|
async function listProtectionRules(ctx, section, envName) {
|
|
5939
|
-
return parseLive(section, ENDPOINTS$10.listProtectionRules, z.looseObject({ custom_deployment_protection_rules: z.array(LiveProtectionRule).optional() }).nullable(), await ctx.read.listProtectionRules.call({
|
|
5940
|
-
params: { environment_name: envName },
|
|
5941
|
-
describe: `listing deployment protection rules of environment "${envName}"`
|
|
5942
|
-
}), `environment "${envName}"`)?.custom_deployment_protection_rules ?? [];
|
|
5961
|
+
return parseLive(section, ENDPOINTS$10.listProtectionRules, z.looseObject({ custom_deployment_protection_rules: z.array(LiveProtectionRule).optional() }).nullable(), await ctx.read.listProtectionRules.call({ params: { environment_name: envName } }), `environment "${envName}"`)?.custom_deployment_protection_rules ?? [];
|
|
5943
5962
|
}
|
|
5944
5963
|
/** An unlisted slug means the App is not installed, which nothing this section may call can change. */
|
|
5945
5964
|
function resolveIntegrationId(apps, slug, envName) {
|
|
@@ -6498,7 +6517,7 @@ function wrapped(key, entries) {
|
|
|
6498
6517
|
* flag enables them (the endpoint 404s otherwise); a disabled protection rule is not an active
|
|
6499
6518
|
* gate, so it is not declared. Each secret becomes a `$NAME` reference with a note asking for it.
|
|
6500
6519
|
* The policy and rule lists sit behind the Actions grant, not the section's, so a denial there
|
|
6501
|
-
*
|
|
6520
|
+
* is the key's own: a note under the warn policy, the section's failure under fail.
|
|
6502
6521
|
*/
|
|
6503
6522
|
async function snapshotNested(ctx, section, envName, liveEnv) {
|
|
6504
6523
|
const nested = {};
|
|
@@ -6518,10 +6537,10 @@ async function snapshotNested(ctx, section, envName, liveEnv) {
|
|
|
6518
6537
|
for (const { name, variable } of references) notes.push(`environments[${envName}].secrets[${name}]: value of ${name} is not readable; export it into the environment as ${variable} before apply`);
|
|
6519
6538
|
}
|
|
6520
6539
|
if (liveEnv.deployment_branch_policy?.custom_branch_policies === true) {
|
|
6521
|
-
const policies = await readOrNote(notes, `environments[${envName}].deployment_branch_policies`, () => listBranchPolicies(ctx, section, envName));
|
|
6540
|
+
const policies = await readOrNote(ctx, notes, `environments[${envName}].deployment_branch_policies`, () => listBranchPolicies(ctx, section, envName));
|
|
6522
6541
|
if ("value" in policies && policies.value.length > 0) nested.deployment_branch_policies = wrapped("deployment_branch_policies", policies.value.map((policy) => projectOntoSchema(DeploymentBranchPolicyConfig, policy)));
|
|
6523
6542
|
}
|
|
6524
|
-
const rules = await readOrNote(notes, `environments[${envName}].deployment_protection_rules`, () => listProtectionRules(ctx, section, envName));
|
|
6543
|
+
const rules = await readOrNote(ctx, notes, `environments[${envName}].deployment_protection_rules`, () => listProtectionRules(ctx, section, envName));
|
|
6525
6544
|
if ("value" in rules) {
|
|
6526
6545
|
const enabled = rules.value.filter((rule) => rule.enabled !== false);
|
|
6527
6546
|
if (enabled.length > 0) nested.deployment_protection_rules = wrapped("deployment_protection_rules", enabled.map((rule) => ({ app: liveRuleSlug(rule, envName) })));
|
|
@@ -7647,7 +7666,7 @@ const repositorySection = {
|
|
|
7647
7666
|
if (live.topics !== void 0 && live.topics !== null && live.topics.length > 0) value.topics = [...live.topics];
|
|
7648
7667
|
const probes = [];
|
|
7649
7668
|
for (const toggle of READABLE_TOGGLES) {
|
|
7650
|
-
const read = await readOrNote(notes, `repository.${toggle.key}`, async () => {
|
|
7669
|
+
const read = await readOrNote(ctx, notes, `repository.${toggle.key}`, async () => {
|
|
7651
7670
|
const answer = await ctx.read[toggle.get].tryCall();
|
|
7652
7671
|
if ("error" in answer) return {
|
|
7653
7672
|
live: void 0,
|
|
@@ -7670,7 +7689,7 @@ const repositorySection = {
|
|
|
7670
7689
|
if (live !== void 0 && toggle.isEnforced?.(live) === true) notes.push(`repository.${toggle.key}: ${OWNER_ENFORCED}, so it reads back as ${enabled} but cannot be changed from the repository`);
|
|
7671
7690
|
}
|
|
7672
7691
|
for (const toggle of WRITE_ONLY_TOGGLES) notes.push(`repository.${toggle.key}: GitHub exposes no endpoint to read ${toggle.label} back, so the snapshot leaves it out; declare it yourself to manage it`);
|
|
7673
|
-
const routed = await readOrNote(notes, GRAPHQL_ROUTED_KEYS.map((entry) => `repository.${entry.key}`).join(" and "), () => ctx.read.featuresQuery.call(repoVariables(ctx)));
|
|
7692
|
+
const routed = await readOrNote(ctx, notes, GRAPHQL_ROUTED_KEYS.map((entry) => `repository.${entry.key}`).join(" and "), () => ctx.read.featuresQuery.call(repoVariables(ctx)));
|
|
7674
7693
|
if (!("denied" in routed)) {
|
|
7675
7694
|
const repository = repositoryNode(routed.value);
|
|
7676
7695
|
for (const entry of GRAPHQL_ROUTED_KEYS) {
|
|
@@ -9719,7 +9738,7 @@ async function snapshotRepository$1(api, opts, io) {
|
|
|
9719
9738
|
const seen = { notFound: false };
|
|
9720
9739
|
let snapshot;
|
|
9721
9740
|
try {
|
|
9722
|
-
snapshot = await section.snapshot(
|
|
9741
|
+
snapshot = await section.snapshot(snapshotContext(section, watchingNotFound(api, absentRead, seen), opts.repo, opts.onMissingPermission));
|
|
9723
9742
|
} catch (error) {
|
|
9724
9743
|
if (error instanceof PermissionDenied) {
|
|
9725
9744
|
const status = opts.onMissingPermission === "warn" ? "skipped" : "failed";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vivswan/github-settings-as-code",
|
|
3
|
-
"version": "2.0.1-main.
|
|
3
|
+
"version": "2.0.1-main.1089.g2dd2ba5",
|
|
4
4
|
"description": "GitHub Action applying declarative repository settings: rulesets, labels, branch protection, and more.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"type": "module",
|