github-settings-as-code 4.0.6 → 4.0.7
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 +9 -5
- package/dist/github/environments/apply.d.mts.map +1 -1
- package/dist/github/environments/apply.mjs +4 -1
- package/dist/github/environments/apply.mjs.map +1 -1
- package/dist/github/environments/index.d.mts +1 -0
- package/dist/github/environments/index.d.mts.map +1 -1
- package/dist/github/environments/index.mjs +1 -0
- package/dist/github/environments/index.mjs.map +1 -1
- package/dist/github/environments/select-declared-environments.d.mts +12 -0
- package/dist/github/environments/select-declared-environments.d.mts.map +1 -0
- package/dist/github/environments/select-declared-environments.mjs +11 -0
- package/dist/github/environments/select-declared-environments.mjs.map +1 -0
- package/dist/github/ruleset/api/create-ruleset.d.mts +1 -1
- package/dist/github/ruleset/api/create-ruleset.d.mts.map +1 -1
- package/dist/github/ruleset/api/create-ruleset.mjs +3 -1
- package/dist/github/ruleset/api/create-ruleset.mjs.map +1 -1
- package/dist/github/ruleset/apply.d.mts.map +1 -1
- package/dist/github/ruleset/apply.mjs +18 -5
- package/dist/github/ruleset/apply.mjs.map +1 -1
- package/package.json +11 -10
- package/src/github/environments/apply.mts +8 -2
- package/src/github/environments/index.mts +1 -0
- package/src/github/environments/select-declared-environments.mts +18 -0
- package/src/github/environments/select-declared-environments.test.mts +28 -0
- package/src/github/ruleset/api/create-ruleset.mts +5 -2
- package/src/github/ruleset/apply.mts +22 -7
package/README.md
CHANGED
|
@@ -42,11 +42,15 @@ repo-settings backup
|
|
|
42
42
|
repo-settings apply --owner noshiro-pf --repo ts-repo-utils
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
`backup` rewrites the settings files themselves from what GitHub currently
|
|
46
|
-
|
|
47
|
-
`apply` reads the values back from GitHub afterwards and rewrites the files
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
`backup` rewrites the settings files themselves from what GitHub currently has —
|
|
46
|
+
there is one copy of each resource, not a declaration and a mirror of it.
|
|
47
|
+
`apply` reads the values back from GitHub afterwards and rewrites the files with
|
|
48
|
+
what was actually applied, so a value GitHub canonicalized or refused shows up
|
|
49
|
+
as a diff; `variables` writes nothing back. For rulesets and environments, only
|
|
50
|
+
the ones a declaration file names are rewritten (a ruleset by its id, or by the
|
|
51
|
+
id GitHub gave it when created; an environment by name). One that exists only on
|
|
52
|
+
GitHub stays undeclared, so the drift check keeps reporting it; importing it is
|
|
53
|
+
an explicit `backup`.
|
|
50
54
|
|
|
51
55
|
## Resolving the target repository
|
|
52
56
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.d.mts","sourceRoot":"","sources":["../../../src/github/environments/apply.mts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"apply.d.mts","sourceRoot":"","sources":["../../../src/github/environments/apply.mts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AAWvB;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,IAAI,CAiCtD,CAAC"}
|
|
@@ -7,6 +7,7 @@ import { environmentsDir } from '../constants.mjs';
|
|
|
7
7
|
import { settingsFilePath } from '../settings-file-path.mjs';
|
|
8
8
|
import { getAllEnvironments, setEnvironment } from './api/index.mjs';
|
|
9
9
|
import { readEnvironmentFiles } from './read-environment-contents.mjs';
|
|
10
|
+
import { selectDeclaredEnvironments } from './select-declared-environments.mjs';
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
|
|
@@ -23,8 +24,10 @@ export const applyEnvironments = async () => {
|
|
|
23
24
|
await setEnvironment(environment);
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
|
|
28
|
+
|
|
26
29
|
{
|
|
27
|
-
const applied = await getAllEnvironments();
|
|
30
|
+
const applied = selectDeclaredEnvironments(await getAllEnvironments(), environments);
|
|
28
31
|
for (const environment of applied) {
|
|
29
32
|
const str = JSON.stringify(environment, undefined, 2);
|
|
30
33
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.mjs","sourceRoot":"","sources":["../../../src/github/environments/apply.mts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAErE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"apply.mjs","sourceRoot":"","sources":["../../../src/github/environments/apply.mts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAErE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAEhF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,IAAmB,EAAE;IACzD,MAAM,YAAY,GAAG,MAAM,oBAAoB,EAAE,CAAC;IAElD,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,MAAM,cAAc,CAAC,WAAW,CAAC,CAAC;IACpC,CAAC;IAED,wCAAwC;IACxC,0CAA0C;IAC1C,yCAAyC;IACzC,CAAC;QACC,MAAM,OAAO,GAAG,0BAA0B,CACxC,MAAM,kBAAkB,EAAE,EAC1B,YAAY,CACb,CAAC;QAEF,KAAK,MAAM,WAAW,IAAI,OAAO,EAAE,CAAC;YAClC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;YAEtD,0DAA0D;YAC1D,mEAAmE;YACnE,MAAM,EAAE,CAAC,SAAS,CAChB,gBAAgB,CAAC,eAAe,EAAE,WAAW,CAAC,IAAI,CAAC,EACnD,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,MAAM,sBAAsB,EAAE,CAAC;IACjC,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,gBAAgB,GAAG,CAAC,WAAgC,EAAQ,EAAE;IAClE,MAAM,MAAM,GACV,WAAW,CAAC,wBAAwB,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAExE,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,0BAA0B,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CACb;YACE,OAAO,WAAW,CAAC,IAAI,0CAA0C;YACjE,iEAAiE;YACjE,wDAAwD;SACzD,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC;IAED,+DAA+D;IAC/D,gDAAgD;IAChD,mBAAmB;IACnB,IAAI,MAAM,IAAI,WAAW,CAAC,wBAAwB,CAAC,kBAAkB,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CACb,OAAO,WAAW,CAAC,IAAI,kEAAkE,CAC1F,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEF,IAAI,kBAAkB,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IACxC,MAAM,iBAAiB,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../../src/github/environments/index.mts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../../src/github/environments/index.mts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oCAAoC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../../src/github/environments/index.mts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../../src/github/environments/index.mts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oCAAoC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The live environments `apply` may write back: those whose name a declaration
|
|
3
|
+
* file names. One that exists only on GitHub (made in the UI, or created by
|
|
4
|
+
* GitHub when a workflow names it) is left to the drift check rather than
|
|
5
|
+
* adopted as a declaration.
|
|
6
|
+
*/
|
|
7
|
+
export declare const selectDeclaredEnvironments: <const E extends Readonly<{
|
|
8
|
+
name: string;
|
|
9
|
+
}>>(live: readonly E[], declared: readonly Readonly<{
|
|
10
|
+
name: string;
|
|
11
|
+
}>[]) => readonly E[];
|
|
12
|
+
//# sourceMappingURL=select-declared-environments.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-declared-environments.d.mts","sourceRoot":"","sources":["../../../src/github/environments/select-declared-environments.mts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,GACrC,KAAK,CAAC,CAAC,SAAS,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,QAEpC,SAAS,CAAC,EAAE,YACR,SAAS,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,KAC9C,SAAS,CAAC,EAMZ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export const selectDeclaredEnvironments = (live, declared) => {
|
|
8
|
+
const declaredNames = new Set(declared.map((e) => e.name));
|
|
9
|
+
return live.filter((e) => declaredNames.has(e.name));
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=select-declared-environments.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-declared-environments.mjs","sourceRoot":"","sources":["../../../src/github/environments/select-declared-environments.mts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAGxC,IAAkB,EAClB,QAA+C,EACjC,EAAE;IAChB,MAAM,aAAa,GAAwB,IAAI,GAAG,CAChD,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAC5B,CAAC;IAEF,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CreateRulesetRequest } from 'octokit-safe-types';
|
|
2
2
|
export declare const createRuleset: ({ payload: { name, target, enforcement, bypass_actors, conditions, rules }, }: Readonly<{
|
|
3
3
|
payload: CreateRulesetRequest;
|
|
4
|
-
}>) => Promise<
|
|
4
|
+
}>) => Promise<number>;
|
|
5
5
|
//# sourceMappingURL=create-ruleset.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-ruleset.d.mts","sourceRoot":"","sources":["../../../../src/github/ruleset/api/create-ruleset.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,oBAAoB,EAErB,MAAM,oBAAoB,CAAC;AAK5B,eAAO,MAAM,aAAa,kFAEvB,QAAQ,CAAC;IACV,OAAO,EAAE,oBAAoB,CAAC;CAC/B,CAAC,KAAG,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"create-ruleset.d.mts","sourceRoot":"","sources":["../../../../src/github/ruleset/api/create-ruleset.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,oBAAoB,EAErB,MAAM,oBAAoB,CAAC;AAK5B,eAAO,MAAM,aAAa,kFAEvB,QAAQ,CAAC;IACV,OAAO,EAAE,oBAAoB,CAAC;CAC/B,CAAC,KAAG,OAAO,CAAC,MAAM,CAwBlB,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { octokitHeaders, OWNER, REPO } from '../../constants.mjs';
|
|
|
3
3
|
import { octokit } from '../../octokit.mjs';
|
|
4
4
|
export const createRuleset = async ({ payload: { name, target, enforcement, bypass_actors, conditions, rules }, }) => {
|
|
5
5
|
|
|
6
|
-
await octokit.request('POST /repos/{owner}/{repo}/rulesets',
|
|
6
|
+
const { data } = await octokit.request('POST /repos/{owner}/{repo}/rulesets',
|
|
7
7
|
|
|
8
8
|
{
|
|
9
9
|
owner: OWNER,
|
|
@@ -17,5 +17,7 @@ export const createRuleset = async ({ payload: { name, target, enforcement, bypa
|
|
|
17
17
|
|
|
18
18
|
rules: rules,
|
|
19
19
|
});
|
|
20
|
+
|
|
21
|
+
return data.id;
|
|
20
22
|
};
|
|
21
23
|
//# sourceMappingURL=create-ruleset.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-ruleset.mjs","sourceRoot":"","sources":["../../../../src/github/ruleset/api/create-ruleset.mts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,EAClC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,GAGxE,
|
|
1
|
+
{"version":3,"file":"create-ruleset.mjs","sourceRoot":"","sources":["../../../../src/github/ruleset/api/create-ruleset.mts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,EAClC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,GAGxE,EAAmB,EAAE;IACrB,gGAAgG;IAChG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,CAAC,OAAO,CACpC,qCAA4D;IAC5D,mDAAmD;IACnD;QACE,KAAK,EAAE,KAAK;QACZ,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,cAAc;QAEvB,IAAI;QACJ,MAAM;QACN,WAAW;QACX,aAAa,EAAE,eAAe,CAAC,aAAa,CAAC;QAC7C,UAAU,EAAE,eAAe,CAAC,UAAU,CAAC;QACvC,oEAAoE;QACpE,KAAK,EAAE,eAAe,CACpB,KAAK,CACwC;KAChD,CACF,CAAC;IAEF,wDAAwD;IACxD,OAAO,IAAI,CAAC,EAAE,CAAC;AACjB,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.d.mts","sourceRoot":"","sources":["../../../src/github/ruleset/apply.mts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AAevB,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"apply.d.mts","sourceRoot":"","sources":["../../../src/github/ruleset/apply.mts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AAevB,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,IAAI,CA4ElD,CAAC"}
|
|
@@ -29,8 +29,9 @@ export const applyRulesets = async () => {
|
|
|
29
29
|
},
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
|
+
const mut_createdIds = [];
|
|
32
33
|
for (const ruleset of rulesetsToCreate) {
|
|
33
|
-
await createRuleset({
|
|
34
|
+
const createdId = await createRuleset({
|
|
34
35
|
payload: {
|
|
35
36
|
bypass_actors: ruleset.bypass_actors,
|
|
36
37
|
conditions: ruleset.conditions ?? undefined,
|
|
@@ -40,16 +41,28 @@ export const applyRulesets = async () => {
|
|
|
40
41
|
target: ruleset.target === 'repository' ? undefined : ruleset.target,
|
|
41
42
|
},
|
|
42
43
|
});
|
|
44
|
+
mut_createdIds.push(createdId);
|
|
43
45
|
}
|
|
44
46
|
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
const appliedIds = new Set([
|
|
52
|
+
...rulesetsToUpdate.map((r) => r.id),
|
|
53
|
+
...mut_createdIds,
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
45
59
|
{
|
|
46
|
-
const
|
|
47
|
-
for (const
|
|
48
|
-
const content = await getRuleset(rule.id);
|
|
60
|
+
const contents = await Promise.all(Array.from(appliedIds, getRuleset));
|
|
61
|
+
for (const content of contents) {
|
|
49
62
|
const str = JSON.stringify(Obj.pick(content, rulesetKeysToPick), undefined, 2);
|
|
50
63
|
|
|
51
64
|
|
|
52
|
-
await fs.writeFile(settingsFilePath(rulesetsDir,
|
|
65
|
+
await fs.writeFile(settingsFilePath(rulesetsDir, content.name), str);
|
|
53
66
|
}
|
|
54
67
|
await formatUncommittedFiles();
|
|
55
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.mjs","sourceRoot":"","sources":["../../../src/github/ruleset/apply.mts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EACL,aAAa,EACb,cAAc,EACd,UAAU,EACV,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAEhE,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,IAAmB,EAAE;IACrD,MAAM,QAAQ,GAAG,MAAM,gBAAgB,EAAE,CAAC;IAE1C,8CAA8C;IAC9C,2CAA2C;IAC3C,mCAAmC;IACnC,MAAM,WAAW,GAAwB,MAAM,cAAc,EAAE,CAAC,IAAI,CAClE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CACrC,CAAC;IAEF,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEvE,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAExE,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;QACvC,MAAM,aAAa,CAAC;YAClB,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,OAAO,EAAE;gBACP,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,SAAS;gBAC3C,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,MAAM,EAAE,OAAO,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM;aACrE;SACF,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;QACvC,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"apply.mjs","sourceRoot":"","sources":["../../../src/github/ruleset/apply.mts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "github-settings-as-code",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"keywords": [
|
|
6
6
|
"github",
|
|
@@ -30,20 +30,20 @@
|
|
|
30
30
|
"dotenv": "^18.0.8",
|
|
31
31
|
"octokit-safe-types": "^1.2.28",
|
|
32
32
|
"ts-data-forge": "^14.11.0",
|
|
33
|
-
"ts-fortress": "^12.4.
|
|
34
|
-
"ts-repo-utils": "^10.7.
|
|
33
|
+
"ts-fortress": "^12.4.4",
|
|
34
|
+
"ts-repo-utils": "^10.7.3",
|
|
35
35
|
"ts-type-forge": "^9.2.2"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "26.6.5",
|
|
39
|
-
"@vitest/coverage-
|
|
39
|
+
"@vitest/coverage-istanbul": "5.0.5",
|
|
40
40
|
"@vitest/ui": "5.0.5",
|
|
41
41
|
"cspell": "10.4.0",
|
|
42
42
|
"eslint": "10.13.0",
|
|
43
|
-
"eslint-config-typed": "7.
|
|
44
|
-
"eslint-plugin-ts-data-forge": "0.10.
|
|
45
|
-
"eslint-plugin-ts-fortress": "1.3.
|
|
46
|
-
"eslint-plugin-ts-type-forge": "0.8.
|
|
43
|
+
"eslint-config-typed": "7.5.0",
|
|
44
|
+
"eslint-plugin-ts-data-forge": "0.10.10",
|
|
45
|
+
"eslint-plugin-ts-fortress": "1.3.14",
|
|
46
|
+
"eslint-plugin-ts-type-forge": "0.8.19",
|
|
47
47
|
"jiti": "2.7.0",
|
|
48
48
|
"npm-run-all2": "9.0.4",
|
|
49
49
|
"prettier": "3.9.10",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"pnpm": ">=9.0.0"
|
|
60
60
|
},
|
|
61
61
|
"volta": {
|
|
62
|
-
"node": "26.
|
|
62
|
+
"node": "26.13.0"
|
|
63
63
|
},
|
|
64
64
|
"publishConfig": {
|
|
65
65
|
"access": "public",
|
|
@@ -83,9 +83,10 @@
|
|
|
83
83
|
"fix:fmt:full": "prettier --write .",
|
|
84
84
|
"fix:lint": "node ../../tools/scripts/cmd/assert-deps-built.mts && oxlint . --fix && eslint . --fix",
|
|
85
85
|
"fmt": "pnpm run fix:fmt",
|
|
86
|
-
"gen": "run-s gen:index",
|
|
86
|
+
"gen": "run-s gen:index gen:readme",
|
|
87
87
|
"gen:index": "run-s gen:index:src fix:fmt",
|
|
88
88
|
"gen:index:src": "tsx --tsconfig ../../tools/configs/tsconfig.tsx.json ../../libs/ts-repo-utils/src/cmd/gen-index-ts.mts ./src/github --index-ext .mts --export-ext .mjs --target-ext .mts --exclude cmd --exclude octokit.mts",
|
|
89
|
+
"gen:readme": "tsx --tsconfig ../../tools/configs/tsconfig.tsx.json ./scripts/cmd/embed-examples.mts",
|
|
89
90
|
"test": "pnpm run check:test",
|
|
90
91
|
"test:cov:ui": "vite preview --outDir ./coverage",
|
|
91
92
|
"test:ui": "pnpm run z:vitest:node --ui",
|
|
@@ -8,6 +8,7 @@ import { settingsFilePath } from '../settings-file-path.mjs';
|
|
|
8
8
|
import { getAllEnvironments, setEnvironment } from './api/index.mjs';
|
|
9
9
|
import type { EnvironmentSettings } from './constants.mjs';
|
|
10
10
|
import { readEnvironmentFiles } from './read-environment-contents.mjs';
|
|
11
|
+
import { selectDeclaredEnvironments } from './select-declared-environments.mjs';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* `repo-settings/environments/*.json` を Settings > Environments に反映する。
|
|
@@ -27,9 +28,14 @@ export const applyEnvironments = async (): Promise<void> => {
|
|
|
27
28
|
await setEnvironment(environment);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
//
|
|
31
|
+
// 反映後の実際の値で、宣言したファイルだけを更新する。 GitHub が値を
|
|
32
|
+
// 正規化したり受け付けなかったりしたものが diff に出る。宣言に無い環境まで
|
|
33
|
+
// 書くと、 drift 検査が報せるはずのものが宣言として取り込まれてしまう。
|
|
31
34
|
{
|
|
32
|
-
const applied =
|
|
35
|
+
const applied = selectDeclaredEnvironments(
|
|
36
|
+
await getAllEnvironments(),
|
|
37
|
+
environments,
|
|
38
|
+
);
|
|
33
39
|
|
|
34
40
|
for (const environment of applied) {
|
|
35
41
|
const str = JSON.stringify(environment, undefined, 2);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The live environments `apply` may write back: those whose name a declaration
|
|
3
|
+
* file names. One that exists only on GitHub (made in the UI, or created by
|
|
4
|
+
* GitHub when a workflow names it) is left to the drift check rather than
|
|
5
|
+
* adopted as a declaration.
|
|
6
|
+
*/
|
|
7
|
+
export const selectDeclaredEnvironments = <
|
|
8
|
+
const E extends Readonly<{ name: string }>,
|
|
9
|
+
>(
|
|
10
|
+
live: readonly E[],
|
|
11
|
+
declared: readonly Readonly<{ name: string }>[],
|
|
12
|
+
): readonly E[] => {
|
|
13
|
+
const declaredNames: ReadonlySet<string> = new Set(
|
|
14
|
+
declared.map((e) => e.name),
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
return live.filter((e) => declaredNames.has(e.name));
|
|
18
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { selectDeclaredEnvironments } from './select-declared-environments.mjs';
|
|
2
|
+
|
|
3
|
+
describe(selectDeclaredEnvironments, () => {
|
|
4
|
+
test('keeps the live environments that are declared, by name', () => {
|
|
5
|
+
const live = [
|
|
6
|
+
{ name: 'npm-publish', wait_timer: 0 },
|
|
7
|
+
{ name: 'made-in-the-ui', wait_timer: 0 },
|
|
8
|
+
{ name: 'github-pages', wait_timer: 5 },
|
|
9
|
+
] as const;
|
|
10
|
+
|
|
11
|
+
const declared = [
|
|
12
|
+
{ name: 'github-pages' },
|
|
13
|
+
{ name: 'npm-publish' },
|
|
14
|
+
] as const;
|
|
15
|
+
|
|
16
|
+
assert.deepStrictEqual(selectDeclaredEnvironments(live, declared), [
|
|
17
|
+
{ name: 'npm-publish', wait_timer: 0 },
|
|
18
|
+
{ name: 'github-pages', wait_timer: 5 },
|
|
19
|
+
]);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('writes nothing back when nothing is declared', () => {
|
|
23
|
+
assert.deepStrictEqual(
|
|
24
|
+
selectDeclaredEnvironments([{ name: 'made-in-the-ui' }], []),
|
|
25
|
+
[],
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -11,9 +11,9 @@ export const createRuleset = async ({
|
|
|
11
11
|
payload: { name, target, enforcement, bypass_actors, conditions, rules },
|
|
12
12
|
}: Readonly<{
|
|
13
13
|
payload: CreateRulesetRequest;
|
|
14
|
-
}>): Promise<
|
|
14
|
+
}>): Promise<number> => {
|
|
15
15
|
// https://docs.github.com/ja/rest/repos/rules?apiVersion=2022-11-28#create-a-repository-ruleset
|
|
16
|
-
await octokit.request(
|
|
16
|
+
const { data } = await octokit.request(
|
|
17
17
|
'POST /repos/{owner}/{repo}/rulesets' satisfies EndpointKeys,
|
|
18
18
|
// transformer-ignore-next-line convert-to-readonly
|
|
19
19
|
{
|
|
@@ -32,4 +32,7 @@ export const createRuleset = async ({
|
|
|
32
32
|
) as components['schemas']['repository-rule'][],
|
|
33
33
|
},
|
|
34
34
|
);
|
|
35
|
+
|
|
36
|
+
// 作られた ruleset の id。 apply の書き戻しは、送った ruleset をこれで特定する。
|
|
37
|
+
return data.id;
|
|
35
38
|
};
|
|
@@ -42,8 +42,10 @@ export const applyRulesets = async (): Promise<void> => {
|
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
const mut_createdIds: number[] = [];
|
|
46
|
+
|
|
45
47
|
for (const ruleset of rulesetsToCreate) {
|
|
46
|
-
await createRuleset({
|
|
48
|
+
const createdId = await createRuleset({
|
|
47
49
|
payload: {
|
|
48
50
|
bypass_actors: ruleset.bypass_actors,
|
|
49
51
|
conditions: ruleset.conditions ?? undefined,
|
|
@@ -53,15 +55,28 @@ export const applyRulesets = async (): Promise<void> => {
|
|
|
53
55
|
target: ruleset.target === 'repository' ? undefined : ruleset.target,
|
|
54
56
|
},
|
|
55
57
|
});
|
|
58
|
+
|
|
59
|
+
mut_createdIds.push(createdId);
|
|
56
60
|
}
|
|
57
61
|
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
// 書き戻すのは、いま送った ruleset だけ — 更新したものは宣言の id で、
|
|
63
|
+
// 作ったものは GitHub が付けた id で特定する。宣言に無い ruleset(GUI で
|
|
64
|
+
// 作られたもの、 organization の ruleset)まで書くと、 drift 検査が報せる
|
|
65
|
+
// はずのものが宣言として取り込まれてしまう。名前では特定しない。親の
|
|
66
|
+
// ruleset が同じ名前を持てるので、別物が同じファイルに書かれうる。
|
|
67
|
+
const appliedIds: ReadonlySet<number> = new Set<number>([
|
|
68
|
+
...rulesetsToUpdate.map((r) => r.id),
|
|
69
|
+
...mut_createdIds,
|
|
70
|
+
]);
|
|
61
71
|
|
|
62
|
-
|
|
63
|
-
|
|
72
|
+
// 反映後の実際の値で、送った ruleset のファイルを更新する。 GitHub が値を
|
|
73
|
+
// 正規化したり受け付けなかったりしたものが diff に出る。一覧は読み直さず
|
|
74
|
+
// id ごとに取る(一覧はページ分割され、親の ruleset も含む)。全部取って
|
|
75
|
+
// から書くので、途中で取得に失敗しても一部だけ書き換わることはない。
|
|
76
|
+
{
|
|
77
|
+
const contents = await Promise.all(Array.from(appliedIds, getRuleset));
|
|
64
78
|
|
|
79
|
+
for (const content of contents) {
|
|
65
80
|
const str = JSON.stringify(
|
|
66
81
|
Obj.pick(content, rulesetKeysToPick),
|
|
67
82
|
undefined,
|
|
@@ -70,7 +85,7 @@ export const applyRulesets = async (): Promise<void> => {
|
|
|
70
85
|
|
|
71
86
|
// `settingsFilePath` が `rulesetsDir` の直下であることを確かめている。
|
|
72
87
|
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
|
73
|
-
await fs.writeFile(settingsFilePath(rulesetsDir,
|
|
88
|
+
await fs.writeFile(settingsFilePath(rulesetsDir, content.name), str);
|
|
74
89
|
}
|
|
75
90
|
|
|
76
91
|
await formatUncommittedFiles();
|