github-settings-as-code 3.0.2 → 3.2.0

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.
Files changed (104) hide show
  1. package/README.md +54 -34
  2. package/dist/cmd/repo-settings.mjs +13 -0
  3. package/dist/cmd/repo-settings.mjs.map +1 -1
  4. package/dist/github/actions-settings/api/get-actions-settings.d.mts +1 -1
  5. package/dist/github/actions-settings/api/get-actions-settings.d.mts.map +1 -1
  6. package/dist/github/actions-settings/api/get-actions-settings.mjs +4 -0
  7. package/dist/github/actions-settings/api/get-actions-settings.mjs.map +1 -1
  8. package/dist/github/actions-settings/api/set-actions-settings.d.mts.map +1 -1
  9. package/dist/github/actions-settings/api/set-actions-settings.mjs +8 -0
  10. package/dist/github/actions-settings/api/set-actions-settings.mjs.map +1 -1
  11. package/dist/github/actions-settings/constants.d.mts +67 -0
  12. package/dist/github/actions-settings/constants.d.mts.map +1 -1
  13. package/dist/github/actions-settings/constants.mjs +22 -0
  14. package/dist/github/actions-settings/constants.mjs.map +1 -1
  15. package/dist/github/constants.d.mts +2 -0
  16. package/dist/github/constants.d.mts.map +1 -1
  17. package/dist/github/constants.mjs +2 -0
  18. package/dist/github/constants.mjs.map +1 -1
  19. package/dist/github/environments/api/get-environments.d.mts +16 -0
  20. package/dist/github/environments/api/get-environments.d.mts.map +1 -0
  21. package/dist/github/environments/api/get-environments.mjs +98 -0
  22. package/dist/github/environments/api/get-environments.mjs.map +1 -0
  23. package/dist/github/environments/api/index.d.mts +3 -0
  24. package/dist/github/environments/api/index.d.mts.map +1 -0
  25. package/dist/github/environments/api/index.mjs +3 -0
  26. package/dist/github/environments/api/index.mjs.map +1 -0
  27. package/dist/github/environments/api/set-environment.d.mts +10 -0
  28. package/dist/github/environments/api/set-environment.d.mts.map +1 -0
  29. package/dist/github/environments/api/set-environment.mjs +73 -0
  30. package/dist/github/environments/api/set-environment.mjs.map +1 -0
  31. package/dist/github/environments/apply.d.mts +11 -0
  32. package/dist/github/environments/apply.d.mts.map +1 -0
  33. package/dist/github/environments/apply.mjs +67 -0
  34. package/dist/github/environments/apply.mjs.map +1 -0
  35. package/dist/github/environments/backup.d.mts +5 -0
  36. package/dist/github/environments/backup.d.mts.map +1 -0
  37. package/dist/github/environments/backup.mjs +24 -0
  38. package/dist/github/environments/backup.mjs.map +1 -0
  39. package/dist/github/environments/constants.d.mts +354 -0
  40. package/dist/github/environments/constants.d.mts.map +1 -0
  41. package/dist/github/environments/constants.mjs +62 -0
  42. package/dist/github/environments/constants.mjs.map +1 -0
  43. package/dist/github/environments/index.d.mts +6 -0
  44. package/dist/github/environments/index.d.mts.map +1 -0
  45. package/dist/github/environments/index.mjs +6 -0
  46. package/dist/github/environments/index.mjs.map +1 -0
  47. package/dist/github/environments/read-environment-contents.d.mts +4 -0
  48. package/dist/github/environments/read-environment-contents.d.mts.map +1 -0
  49. package/dist/github/environments/read-environment-contents.mjs +32 -0
  50. package/dist/github/environments/read-environment-contents.mjs.map +1 -0
  51. package/dist/github/index.d.mts +2 -0
  52. package/dist/github/index.d.mts.map +1 -1
  53. package/dist/github/index.mjs +2 -0
  54. package/dist/github/index.mjs.map +1 -1
  55. package/dist/github/vulnerability-alerts/api/get-vulnerability-alerts.d.mts +10 -0
  56. package/dist/github/vulnerability-alerts/api/get-vulnerability-alerts.d.mts.map +1 -0
  57. package/dist/github/vulnerability-alerts/api/get-vulnerability-alerts.mjs +25 -0
  58. package/dist/github/vulnerability-alerts/api/get-vulnerability-alerts.mjs.map +1 -0
  59. package/dist/github/vulnerability-alerts/api/index.d.mts +3 -0
  60. package/dist/github/vulnerability-alerts/api/index.d.mts.map +1 -0
  61. package/dist/github/vulnerability-alerts/api/index.mjs +3 -0
  62. package/dist/github/vulnerability-alerts/api/index.mjs.map +1 -0
  63. package/dist/github/vulnerability-alerts/api/set-vulnerability-alerts.d.mts +10 -0
  64. package/dist/github/vulnerability-alerts/api/set-vulnerability-alerts.d.mts.map +1 -0
  65. package/dist/github/vulnerability-alerts/api/set-vulnerability-alerts.mjs +19 -0
  66. package/dist/github/vulnerability-alerts/api/set-vulnerability-alerts.mjs.map +1 -0
  67. package/dist/github/vulnerability-alerts/apply.d.mts +11 -0
  68. package/dist/github/vulnerability-alerts/apply.d.mts.map +1 -0
  69. package/dist/github/vulnerability-alerts/apply.mjs +47 -0
  70. package/dist/github/vulnerability-alerts/apply.mjs.map +1 -0
  71. package/dist/github/vulnerability-alerts/backup.d.mts +5 -0
  72. package/dist/github/vulnerability-alerts/backup.d.mts.map +1 -0
  73. package/dist/github/vulnerability-alerts/backup.mjs +22 -0
  74. package/dist/github/vulnerability-alerts/backup.mjs.map +1 -0
  75. package/dist/github/vulnerability-alerts/constants.d.mts +72 -0
  76. package/dist/github/vulnerability-alerts/constants.d.mts.map +1 -0
  77. package/dist/github/vulnerability-alerts/constants.mjs +21 -0
  78. package/dist/github/vulnerability-alerts/constants.mjs.map +1 -0
  79. package/dist/github/vulnerability-alerts/index.d.mts +5 -0
  80. package/dist/github/vulnerability-alerts/index.d.mts.map +1 -0
  81. package/dist/github/vulnerability-alerts/index.mjs +5 -0
  82. package/dist/github/vulnerability-alerts/index.mjs.map +1 -0
  83. package/package.json +15 -15
  84. package/src/cmd/repo-settings.mts +17 -0
  85. package/src/github/actions-settings/api/get-actions-settings.mts +11 -1
  86. package/src/github/actions-settings/api/set-actions-settings.mts +13 -0
  87. package/src/github/actions-settings/constants.mts +24 -0
  88. package/src/github/constants.mts +7 -0
  89. package/src/github/environments/api/get-environments.mts +155 -0
  90. package/src/github/environments/api/index.mts +2 -0
  91. package/src/github/environments/api/set-environment.mts +106 -0
  92. package/src/github/environments/apply.mts +87 -0
  93. package/src/github/environments/backup.mts +38 -0
  94. package/src/github/environments/constants.mts +78 -0
  95. package/src/github/environments/index.mts +5 -0
  96. package/src/github/environments/read-environment-contents.mts +53 -0
  97. package/src/github/index.mts +2 -0
  98. package/src/github/vulnerability-alerts/api/get-vulnerability-alerts.mts +31 -0
  99. package/src/github/vulnerability-alerts/api/index.mts +2 -0
  100. package/src/github/vulnerability-alerts/api/set-vulnerability-alerts.mts +31 -0
  101. package/src/github/vulnerability-alerts/apply.mts +77 -0
  102. package/src/github/vulnerability-alerts/backup.mts +36 -0
  103. package/src/github/vulnerability-alerts/constants.mts +25 -0
  104. package/src/github/vulnerability-alerts/index.mts +4 -0
@@ -0,0 +1,4 @@
1
+ import { EnvironmentSettings } from './constants.mjs';
2
+ export declare const readEnvironmentFiles: () => Promise<readonly EnvironmentSettings[]>;
3
+ export declare const readEnvironmentBackupFiles: () => Promise<readonly EnvironmentSettings[]>;
4
+ //# sourceMappingURL=read-environment-contents.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-environment-contents.d.mts","sourceRoot":"","sources":["../../../src/github/environments/read-environment-contents.mts"],"names":[],"mappings":"AAMA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,eAAO,MAAM,oBAAoB,QAAa,OAAO,CACnD,SAAS,mBAAmB,EAAE,CACC,CAAC;AAElC,eAAO,MAAM,0BAA0B,QAAa,OAAO,CACzD,SAAS,mBAAmB,EAAE,CACuB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import * as path from 'node:path';
3
+ import * as t from 'ts-fortress';
4
+ import { isDirectlyExecuted, Result } from 'ts-repo-utils';
5
+ import { environmentsDir } from '../constants.mjs';
6
+ import { EnvironmentSettings } from './constants.mjs';
7
+ export const readEnvironmentFiles = async () => readFilesIn(environmentsDir);
8
+ export const readEnvironmentBackupFiles = async () => readFilesIn(path.resolve(environmentsDir, './bk'));
9
+ const readFilesIn = async (dir) => {
10
+
11
+ const files = await fs.readdir(dir, {
12
+ withFileTypes: true,
13
+ });
14
+ const fileContents = await Promise.all(files
15
+ .filter((d) => d.isFile())
16
+ .map((d) =>
17
+
18
+ fs.readFile(path.resolve(dir, d.name), { encoding: 'utf8' })));
19
+ const validationResults = fileContents.map((content) => EnvironmentSettings.validate(JSON.parse(content)));
20
+ const mut_values = [];
21
+ for (const r of validationResults) {
22
+ if (Result.isErr(r)) {
23
+ throw new Error(t.validationErrorsToMessages(r.value).join('\n'));
24
+ }
25
+ mut_values.push(r.value);
26
+ }
27
+ return mut_values;
28
+ };
29
+ if (isDirectlyExecuted(import.meta.url)) {
30
+ await readEnvironmentFiles();
31
+ }
32
+ //# sourceMappingURL=read-environment-contents.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-environment-contents.mjs","sourceRoot":"","sources":["../../../src/github/environments/read-environment-contents.mts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,IAEvC,EAAE,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;AAElC,MAAM,CAAC,MAAM,0BAA0B,GAAG,KAAK,IAE7C,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;AAExD,MAAM,WAAW,GAAG,KAAK,EACvB,GAAW,EAC8B,EAAE;IAC3C,mEAAmE;IACnE,MAAM,KAAK,GAA8B,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;QAC7D,aAAa,EAAE,IAAI;KACpB,CAAC,CAAC;IAEH,MAAM,YAAY,GAAsB,MAAM,OAAO,CAAC,GAAG,CACvD,KAAK;SACF,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;IACT,mEAAmE;IACnE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAC7D,CACJ,CAAC;IAEF,MAAM,iBAAiB,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACrD,mBAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAClD,CAAC;IAEF,MAAM,UAAU,GAA0B,EAAE,CAAC;IAE7C,KAAK,MAAM,CAAC,IAAI,iBAAiB,EAAE,CAAC;QAClC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACpE,CAAC;QAED,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AAEF,IAAI,kBAAkB,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IACxC,MAAM,oBAAoB,EAAE,CAAC;AAC/B,CAAC"}
@@ -1,8 +1,10 @@
1
1
  export * from './actions-settings/index.mjs';
2
2
  export * from './constants.mjs';
3
+ export * from './environments/index.mjs';
3
4
  export * from './pages/index.mjs';
4
5
  export * from './repository/index.mjs';
5
6
  export * from './resolve-target-repo.mjs';
6
7
  export * from './ruleset/index.mjs';
7
8
  export * from './variables/index.mjs';
9
+ export * from './vulnerability-alerts/index.mjs';
8
10
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/github/index.mts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/github/index.mts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC"}
@@ -1,8 +1,10 @@
1
1
  export * from './actions-settings/index.mjs';
2
2
  export * from './constants.mjs';
3
+ export * from './environments/index.mjs';
3
4
  export * from './pages/index.mjs';
4
5
  export * from './repository/index.mjs';
5
6
  export * from './resolve-target-repo.mjs';
6
7
  export * from './ruleset/index.mjs';
7
8
  export * from './variables/index.mjs';
9
+ export * from './vulnerability-alerts/index.mjs';
8
10
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/github/index.mts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/github/index.mts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { VulnerabilityAlertsSettings } from '../constants.mjs';
2
+ /**
3
+ * Dependabot alerts が有効かどうかを取得する。
4
+ *
5
+ * このエンドポイントは body を返さない: 有効なら 204、無効なら 404。
6
+ * octokit は 404 を例外にするので、それを `enabled: false` として扱う。
7
+ * 「無効」と「読めなかった」は区別する必要があるため、 404 以外は投げ直す。
8
+ */
9
+ export declare const getVulnerabilityAlerts: () => Promise<VulnerabilityAlertsSettings>;
10
+ //# sourceMappingURL=get-vulnerability-alerts.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-vulnerability-alerts.d.mts","sourceRoot":"","sources":["../../../../src/github/vulnerability-alerts/api/get-vulnerability-alerts.mts"],"names":[],"mappings":"AAIA,OAAO,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAE/D;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,QACvB,OAAO,CAAC,2BAA2B,CAgB5C,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { hasKey, isRecord } from 'ts-data-forge';
2
+ import { octokitHeaders, OWNER, REPO } from '../../constants.mjs';
3
+ import { octokit } from '../../octokit.mjs';
4
+ import { VulnerabilityAlertsSettings } from '../constants.mjs';
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+ export const getVulnerabilityAlerts = async () => {
13
+ try {
14
+
15
+ await octokit.request('GET /repos/{owner}/{repo}/vulnerability-alerts', { owner: OWNER, repo: REPO, headers: octokitHeaders });
16
+ return VulnerabilityAlertsSettings.fill({ enabled: true });
17
+ }
18
+ catch (error) {
19
+ if (isRecord(error) && hasKey(error, 'status') && error.status === 404) {
20
+ return VulnerabilityAlertsSettings.fill({ enabled: false });
21
+ }
22
+ throw error;
23
+ }
24
+ };
25
+ //# sourceMappingURL=get-vulnerability-alerts.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-vulnerability-alerts.mjs","sourceRoot":"","sources":["../../../../src/github/vulnerability-alerts/api/get-vulnerability-alerts.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAE/D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GACjC,KAAK,IAA0C,EAAE;IAC/C,IAAI,CAAC;QACH,sGAAsG;QACtG,MAAM,OAAO,CAAC,OAAO,CACnB,gDAAuE,EACvE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,CACtD,CAAC;QAEF,OAAO,2BAA2B,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvE,OAAO,2BAA2B,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './get-vulnerability-alerts.mjs';
2
+ export * from './set-vulnerability-alerts.mjs';
3
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../../../src/github/vulnerability-alerts/api/index.mts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './get-vulnerability-alerts.mjs';
2
+ export * from './set-vulnerability-alerts.mjs';
3
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../../../src/github/vulnerability-alerts/api/index.mts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type VulnerabilityAlertsSettings } from '../constants.mjs';
2
+ /**
3
+ * Dependabot alerts を JSON の内容に合わせる。
4
+ *
5
+ * 有効化と無効化で別メソッドなので、書き込みは 1 回で済むように分岐する。
6
+ * `enabled: false` はきちんと無効化する — 宣言が現状に合わせて黙るなら、
7
+ * ファイルを読んでも何が有効なのか分からなくなる。
8
+ */
9
+ export declare const setVulnerabilityAlerts: (settings: VulnerabilityAlertsSettings) => Promise<void>;
10
+ //# sourceMappingURL=set-vulnerability-alerts.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-vulnerability-alerts.d.mts","sourceRoot":"","sources":["../../../../src/github/vulnerability-alerts/api/set-vulnerability-alerts.mts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAEpE;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,aACvB,2BAA2B,KACpC,OAAO,CAAC,IAAI,CAgBd,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { octokitHeaders, OWNER, REPO } from '../../constants.mjs';
2
+ import { octokit } from '../../octokit.mjs';
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+ export const setVulnerabilityAlerts = async (settings) => {
11
+ if (settings.enabled) {
12
+
13
+ await octokit.request('PUT /repos/{owner}/{repo}/vulnerability-alerts', { owner: OWNER, repo: REPO, headers: octokitHeaders });
14
+ return;
15
+ }
16
+
17
+ await octokit.request('DELETE /repos/{owner}/{repo}/vulnerability-alerts', { owner: OWNER, repo: REPO, headers: octokitHeaders });
18
+ };
19
+ //# sourceMappingURL=set-vulnerability-alerts.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-vulnerability-alerts.mjs","sourceRoot":"","sources":["../../../../src/github/vulnerability-alerts/api/set-vulnerability-alerts.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAG5C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EACzC,QAAqC,EACtB,EAAE;IACjB,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrB,uEAAuE;QACvE,MAAM,OAAO,CAAC,OAAO,CACnB,gDAAuE,EACvE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,CACtD,CAAC;QAEF,OAAO;IACT,CAAC;IAED,wEAAwE;IACxE,MAAM,OAAO,CAAC,OAAO,CACnB,mDAA0E,EAC1E,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,CACtD,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import 'dotenv/config';
3
+ /**
4
+ * `repo-settings/vulnerability-alerts/settings.json` を Dependabot alerts に反映する。
5
+ *
6
+ * 設定ファイルを置いていない repository では何もしない。 pages と同じ理由 —
7
+ * この package は他の repository からも使われるので、ファイルの不在を
8
+ * 「無効にせよ」と読むと、宣言していない設定を勝手に落としてしまう。
9
+ */
10
+ export declare const applyVulnerabilityAlerts: () => Promise<void>;
11
+ //# sourceMappingURL=apply.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.d.mts","sourceRoot":"","sources":["../../../src/github/vulnerability-alerts/apply.mts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AAiBvB;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,QAAa,OAAO,CAAC,IAAI,CA4B7D,CAAC"}
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+ import 'dotenv/config';
3
+ import * as fs from 'node:fs/promises';
4
+ import * as path from 'node:path';
5
+ import * as t from 'ts-fortress';
6
+ import { formatUncommittedFiles, isDirectlyExecuted, pathExists, Result, } from 'ts-repo-utils';
7
+ import { settingsJsonName, vulnerabilityAlertsDir } from '../constants.mjs';
8
+ import { getVulnerabilityAlerts, setVulnerabilityAlerts, } from './api/index.mjs';
9
+ import { VulnerabilityAlertsSettings } from './constants.mjs';
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+ export const applyVulnerabilityAlerts = async () => {
18
+ const settingsPath = path.resolve(vulnerabilityAlertsDir, settingsJsonName);
19
+ if (!(await pathExists(settingsPath))) {
20
+ return;
21
+ }
22
+ const settings = await readSettings(settingsPath);
23
+ await setVulnerabilityAlerts(settings);
24
+
25
+ {
26
+ const applied = await getVulnerabilityAlerts();
27
+ const str = JSON.stringify(applied, undefined, 2);
28
+
29
+ await fs.writeFile(settingsPath, str);
30
+
31
+ await fs.writeFile(path.resolve(vulnerabilityAlertsDir, 'bk', settingsJsonName), str);
32
+ await formatUncommittedFiles();
33
+ }
34
+ };
35
+ const readSettings = async (settingsPath) => {
36
+
37
+ const settingsText = await fs.readFile(settingsPath, { encoding: 'utf8' });
38
+ const validationResult = VulnerabilityAlertsSettings.validate(JSON.parse(settingsText));
39
+ if (Result.isErr(validationResult)) {
40
+ throw new Error(t.validationErrorsToMessages(validationResult.value).join('\n'));
41
+ }
42
+ return validationResult.value;
43
+ };
44
+ if (isDirectlyExecuted(import.meta.url)) {
45
+ await applyVulnerabilityAlerts();
46
+ }
47
+ //# sourceMappingURL=apply.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.mjs","sourceRoot":"","sources":["../../../src/github/vulnerability-alerts/apply.mts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,UAAU,EACV,MAAM,GACP,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EACL,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAE9D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,IAAmB,EAAE;IAChE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,gBAAgB,CAAC,CAAC;IAE5E,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QACtC,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,CAAC;IAElD,MAAM,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAEvC,0BAA0B;IAC1B,CAAC;QACC,MAAM,OAAO,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAE/C,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QAElD,mEAAmE;QACnE,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAEtC,mEAAmE;QACnE,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,IAAI,EAAE,gBAAgB,CAAC,EAC5D,GAAG,CACJ,CAAC;QAEF,MAAM,sBAAsB,EAAE,CAAC;IACjC,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,KAAK,EACxB,YAAoB,EACkB,EAAE;IACxC,mEAAmE;IACnE,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAE3E,MAAM,gBAAgB,GAAG,2BAA2B,CAAC,QAAQ,CAC3D,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CACzB,CAAC;IAEF,IAAI,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,CAAC,CAAC,0BAA0B,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAChE,CAAC;IACJ,CAAC;IAED,OAAO,gBAAgB,CAAC,KAAK,CAAC;AAChC,CAAC,CAAC;AAEF,IAAI,kBAAkB,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IACxC,MAAM,wBAAwB,EAAE,CAAC;AACnC,CAAC"}
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import 'dotenv/config';
3
+ /** Dependabot alerts の現在値を `bk/` に保存する。 */
4
+ export declare const backupVulnerabilityAlerts: (fmt?: boolean) => Promise<void>;
5
+ //# sourceMappingURL=backup.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.d.mts","sourceRoot":"","sources":["../../../src/github/vulnerability-alerts/backup.mts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AAavB,2CAA2C;AAC3C,eAAO,MAAM,yBAAyB,SAC/B,OAAO,KACX,OAAO,CAAC,IAAI,CAcd,CAAC"}
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ import 'dotenv/config';
3
+ import * as fs from 'node:fs/promises';
4
+ import * as path from 'node:path';
5
+ import { formatUncommittedFiles, isDirectlyExecuted, makeEmptyDir, } from 'ts-repo-utils';
6
+ import { settingsJsonName, vulnerabilityAlertsDir } from '../constants.mjs';
7
+ import { getVulnerabilityAlerts } from './api/index.mjs';
8
+ const backupDir = path.resolve(vulnerabilityAlertsDir, './bk');
9
+
10
+ export const backupVulnerabilityAlerts = async (fmt = true) => {
11
+ await makeEmptyDir(backupDir);
12
+ const settings = await getVulnerabilityAlerts();
13
+
14
+ await fs.writeFile(path.resolve(backupDir, settingsJsonName), JSON.stringify(settings, undefined, 2));
15
+ if (fmt) {
16
+ await formatUncommittedFiles();
17
+ }
18
+ };
19
+ if (isDirectlyExecuted(import.meta.url)) {
20
+ await backupVulnerabilityAlerts();
21
+ }
22
+ //# sourceMappingURL=backup.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.mjs","sourceRoot":"","sources":["../../../src/github/vulnerability-alerts/backup.mts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;AAE/D,2CAA2C;AAC3C,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,EAC5C,GAAG,GAAY,IAAI,EACJ,EAAE;IACjB,MAAM,YAAY,CAAC,SAAS,CAAC,CAAC;IAE9B,MAAM,QAAQ,GAAG,MAAM,sBAAsB,EAAE,CAAC;IAEhD,mEAAmE;IACnE,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,gBAAgB,CAAC,EACzC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,CACvC,CAAC;IAEF,IAAI,GAAG,EAAE,CAAC;QACR,MAAM,sBAAsB,EAAE,CAAC;IACjC,CAAC;AACH,CAAC,CAAC;AAEF,IAAI,kBAAkB,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IACxC,MAAM,yBAAyB,EAAE,CAAC;AACpC,CAAC"}
@@ -0,0 +1,72 @@
1
+ import * as t from 'ts-fortress';
2
+ /**
3
+ * `repo-settings/vulnerability-alerts/settings.json` の型。
4
+ *
5
+ * Settings > Advanced Security > Dependabot alerts に対応する。
6
+ *
7
+ * `security_and_analysis` とは別の API
8
+ * (`GET|PUT|DELETE /repos/{owner}/{repo}/vulnerability-alerts`) で、
9
+ * 値も JSON body ではなく 204 / 404 で返ってくる。そのため
10
+ * `repository-settings/settings.json` には載せられず、 pages と同じく
11
+ * 独立した設定ファイルにしている。
12
+ *
13
+ * `repository-settings/settings.json` の `dependabot_security_updates` は
14
+ * これとは別物 — あちらは「脆弱な依存を直す PR を自動で作るか」で、
15
+ * この repository では `pnpm-update` が lockfile を持っているため無効のまま。
16
+ * ここで管理するのは「既知の脆弱性を知らせるか」だけ。
17
+ */
18
+ export declare const VulnerabilityAlertsSettings: Readonly<{
19
+ typeName: string;
20
+ defaultValue: Readonly<{
21
+ enabled: boolean;
22
+ }>;
23
+ is: (a: unknown) => a is Readonly<{
24
+ enabled: boolean;
25
+ }>;
26
+ assertIs: (a: unknown) => asserts a is Readonly<{
27
+ enabled: boolean;
28
+ }>;
29
+ cast: (a: unknown) => Readonly<{
30
+ enabled: boolean;
31
+ }>;
32
+ fill: (a: unknown) => Readonly<{
33
+ enabled: boolean;
34
+ }>;
35
+ prune: <B extends Readonly<{
36
+ enabled: boolean;
37
+ }>>(a: B) => Readonly<{
38
+ enabled: boolean;
39
+ }>;
40
+ validate: (a: unknown) => t.Result<Readonly<{
41
+ enabled: boolean;
42
+ }>, readonly Readonly<{
43
+ path: readonly string[];
44
+ actualValue: unknown;
45
+ expectedType: string;
46
+ typeName: string;
47
+ details?: t.ValidationErrorDetails | undefined;
48
+ }>[]>;
49
+ optional?: true;
50
+ }> & Readonly<{
51
+ shape: {
52
+ readonly enabled: Readonly<{
53
+ typeName: string;
54
+ defaultValue: boolean;
55
+ is: (a: unknown) => a is boolean;
56
+ assertIs: (a: unknown) => asserts a is boolean;
57
+ cast: (a: unknown) => boolean;
58
+ fill: (a: unknown) => boolean;
59
+ prune: <B extends boolean>(a: B) => boolean;
60
+ validate: (a: unknown) => t.Result<boolean, readonly Readonly<{
61
+ path: readonly string[];
62
+ actualValue: unknown;
63
+ expectedType: string;
64
+ typeName: string;
65
+ details?: t.ValidationErrorDetails | undefined;
66
+ }>[]>;
67
+ optional?: true;
68
+ }>;
69
+ };
70
+ }>;
71
+ export type VulnerabilityAlertsSettings = t.TypeOf<typeof VulnerabilityAlertsSettings>;
72
+ //# sourceMappingURL=constants.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.mts","sourceRoot":"","sources":["../../../src/github/vulnerability-alerts/constants.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AAEjC;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEtC,CAAC;AAEH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAChD,OAAO,2BAA2B,CACnC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import * as t from 'ts-fortress';
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+ export const VulnerabilityAlertsSettings = t.record({
19
+ enabled: t.boolean(false),
20
+ });
21
+ //# sourceMappingURL=constants.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../../../src/github/vulnerability-alerts/constants.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AAEjC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;CAC1B,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './api/index.mjs';
2
+ export * from './apply.mjs';
3
+ export * from './backup.mjs';
4
+ export * from './constants.mjs';
5
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../../src/github/vulnerability-alerts/index.mts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './api/index.mjs';
2
+ export * from './apply.mjs';
3
+ export * from './backup.mjs';
4
+ export * from './constants.mjs';
5
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../../src/github/vulnerability-alerts/index.mts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "github-settings-as-code",
3
- "version": "3.0.2",
3
+ "version": "3.2.0",
4
4
  "private": false,
5
5
  "keywords": [
6
6
  "github",
@@ -29,37 +29,37 @@
29
29
  "dedent": "^1.7.2",
30
30
  "dotenv": "^17.4.2",
31
31
  "octokit-safe-types": "^1.2.28",
32
- "ts-data-forge": "^14.6.3",
33
- "ts-fortress": "^12.1.1",
34
- "ts-repo-utils": "^10.6.0",
32
+ "ts-data-forge": "^14.7.1",
33
+ "ts-fortress": "^12.1.3",
34
+ "ts-repo-utils": "^10.6.2",
35
35
  "ts-type-forge": "^9.2.2"
36
36
  },
37
37
  "devDependencies": {
38
- "@types/node": "26.4.1",
39
- "@vitest/coverage-v8": "4.1.11",
40
- "@vitest/ui": "4.1.11",
41
- "cspell": "10.1.1",
38
+ "@types/node": "26.5.0",
39
+ "@vitest/coverage-v8": "5.0.0",
40
+ "@vitest/ui": "5.0.0",
41
+ "cspell": "10.2.1",
42
42
  "eslint": "10.9.1",
43
- "eslint-config-typed": "5.11.2",
44
- "eslint-plugin-ts-data-forge": "0.7.0",
45
- "eslint-plugin-ts-fortress": "1.2.0",
46
- "eslint-plugin-ts-type-forge": "0.8.1",
43
+ "eslint-config-typed": "5.11.7",
44
+ "eslint-plugin-ts-data-forge": "0.7.4",
45
+ "eslint-plugin-ts-fortress": "1.2.2",
46
+ "eslint-plugin-ts-type-forge": "0.8.3",
47
47
  "jiti": "2.7.0",
48
48
  "npm-run-all2": "9.0.3",
49
49
  "prettier": "3.9.6",
50
50
  "prettier-plugin-organize-imports": "4.3.0",
51
51
  "prettier-plugin-packagejson": "3.0.2",
52
- "tsx": "4.23.12",
52
+ "tsx": "4.23.13",
53
53
  "typescript": "6.0.3",
54
54
  "typescript-native": "npm:typescript@7.0.2",
55
- "vitest": "4.1.11"
55
+ "vitest": "5.0.0"
56
56
  },
57
57
  "engines": {
58
58
  "node": ">=22.22.2",
59
59
  "pnpm": ">=9.0.0"
60
60
  },
61
61
  "volta": {
62
- "node": "26.3.1"
62
+ "node": "26.8.1"
63
63
  },
64
64
  "publishConfig": {
65
65
  "access": "public",
@@ -22,6 +22,9 @@ const HELP = dedent`
22
22
  variables repository variables ( apply のみ )
23
23
  actions repo-settings/actions-settings/settings.json
24
24
  pages repo-settings/pages/settings.json
25
+ environments repo-settings/environments/*.json
26
+ vulnerability-alerts
27
+ repo-settings/vulnerability-alerts/settings.json
25
28
 
26
29
  Options:
27
30
  --owner <owner> 対象の owner
@@ -54,6 +57,8 @@ const TARGETS = [
54
57
  'variables',
55
58
  'actions',
56
59
  'pages',
60
+ 'environments',
61
+ 'vulnerability-alerts',
57
62
  ] as const;
58
63
 
59
64
  type Target = (typeof TARGETS)[number];
@@ -125,12 +130,18 @@ const runners: ReadonlyRecord<
125
130
  await github.applyActionsSettings();
126
131
 
127
132
  await github.applyPagesSettings();
133
+
134
+ await github.applyEnvironments();
135
+
136
+ await github.applyVulnerabilityAlerts();
128
137
  },
129
138
  repository: github.applyRepositorySettings,
130
139
  rulesets: github.applyRulesets,
131
140
  variables: github.applyVariables,
132
141
  actions: github.applyActionsSettings,
133
142
  pages: github.applyPagesSettings,
143
+ environments: github.applyEnvironments,
144
+ 'vulnerability-alerts': github.applyVulnerabilityAlerts,
134
145
  },
135
146
  backup: {
136
147
  all: async () => {
@@ -141,11 +152,17 @@ const runners: ReadonlyRecord<
141
152
  await github.backupActionsSettings();
142
153
 
143
154
  await github.backupPagesSettings();
155
+
156
+ await github.backupEnvironments();
157
+
158
+ await github.backupVulnerabilityAlerts();
144
159
  },
145
160
  repository: github.backupRepositorySettings,
146
161
  rulesets: github.backupRulesets,
147
162
  actions: github.backupActionsSettings,
148
163
  pages: github.backupPagesSettings,
164
+ environments: github.backupEnvironments,
165
+ 'vulnerability-alerts': github.backupVulnerabilityAlerts,
149
166
  },
150
167
  } as const;
151
168
 
@@ -6,7 +6,7 @@ import { ActionsSettings } from '../constants.mjs';
6
6
  /**
7
7
  * Settings > Actions > General の現在値を取得する。
8
8
  *
9
- * 2 つのエンドポイントの結果を 1 つのオブジェクトにまとめる。
9
+ * 3 つのエンドポイントの結果を 1 つのオブジェクトにまとめる。
10
10
  */
11
11
  export const getActionsSettings = async (): Promise<ActionsSettings> => {
12
12
  // https://docs.github.com/rest/actions/permissions#get-github-actions-permissions-for-a-repository
@@ -15,6 +15,12 @@ export const getActionsSettings = async (): Promise<ActionsSettings> => {
15
15
  { owner: OWNER, repo: REPO, headers: octokitHeaders },
16
16
  );
17
17
 
18
+ // https://docs.github.com/rest/actions/permissions#get-default-workflow-permissions-for-a-repository
19
+ const workflowPermissions = await octokit.request(
20
+ 'GET /repos/{owner}/{repo}/actions/permissions/workflow' satisfies EndpointKeys,
21
+ { owner: OWNER, repo: REPO, headers: octokitHeaders },
22
+ );
23
+
18
24
  // https://docs.github.com/rest/actions/permissions#get-fork-pr-contributor-approval-permissions-for-a-repository
19
25
  const forkPrApproval = await octokit.request(
20
26
  'GET /repos/{owner}/{repo}/actions/permissions/fork-pr-contributor-approval' satisfies EndpointKeys,
@@ -25,6 +31,10 @@ export const getActionsSettings = async (): Promise<ActionsSettings> => {
25
31
  enabled: permissions.data.enabled,
26
32
  allowed_actions: permissions.data.allowed_actions,
27
33
  sha_pinning_required: permissions.data.sha_pinning_required,
34
+ default_workflow_permissions:
35
+ workflowPermissions.data.default_workflow_permissions,
36
+ can_approve_pull_request_reviews:
37
+ workflowPermissions.data.can_approve_pull_request_reviews,
28
38
  fork_pr_contributor_approval_policy: forkPrApproval.data.approval_policy,
29
39
  });
30
40
  };
@@ -26,6 +26,19 @@ export const setActionsSettings = async (
26
26
  permissionsParams,
27
27
  );
28
28
 
29
+ // https://docs.github.com/rest/actions/permissions#set-default-workflow-permissions-for-a-repository
30
+ await octokit.request(
31
+ 'PUT /repos/{owner}/{repo}/actions/permissions/workflow' satisfies EndpointKeys,
32
+ {
33
+ owner: OWNER,
34
+ repo: REPO,
35
+ headers: octokitHeaders,
36
+ default_workflow_permissions: settings.default_workflow_permissions,
37
+ can_approve_pull_request_reviews:
38
+ settings.can_approve_pull_request_reviews,
39
+ },
40
+ );
41
+
29
42
  // https://docs.github.com/rest/actions/permissions#set-fork-pr-contributor-approval-permissions-for-a-repository
30
43
  await octokit.request(
31
44
  'PUT /repos/{owner}/{repo}/actions/permissions/fork-pr-contributor-approval' satisfies EndpointKeys,
@@ -7,6 +7,7 @@ import * as t from 'ts-fortress';
7
7
  * 管理する:
8
8
  *
9
9
  * - `GET|PUT /repos/{owner}/{repo}/actions/permissions`
10
+ * - `GET|PUT /repos/{owner}/{repo}/actions/permissions/workflow`
10
11
  * - `GET|PUT /repos/{owner}/{repo}/actions/permissions/fork-pr-contributor-approval`
11
12
  */
12
13
  export const ActionsSettings = t.record({
@@ -27,6 +28,29 @@ export const ActionsSettings = t.record({
27
28
  */
28
29
  sha_pinning_required: t.boolean(false),
29
30
 
31
+ /**
32
+ * 「 Workflow permissions 」。 job が `permissions` を宣言しなかったときに
33
+ * `GITHUB_TOKEN` が受け取る既定値。
34
+ *
35
+ * `read` にできるのは、 workflow 側が全て明示的に `permissions` を宣言して
36
+ * いる場合だけ。宣言の無い job はこの既定値をそのまま受け取るため、
37
+ * `write` のままだと「 branch の中身が何であれ書き込めるトークン」が
38
+ * 渡る。 .github/workflows/type-check.yml 冒頭の注記を参照。
39
+ */
40
+ default_workflow_permissions: t.enumType(['read', 'write'], {
41
+ typeName: 'DefaultWorkflowPermissions',
42
+ defaultValue: 'read',
43
+ }),
44
+
45
+ /**
46
+ * 「 Allow GitHub Actions to create and approve pull requests 」。
47
+ *
48
+ * `main` の ruleset は `required_approving_review_count` が 0 なので
49
+ * 承認そのものは merge 条件ではないが、 Actions に PR を作らせる必要が
50
+ * あるのは App token を使う workflow だけで、 `GITHUB_TOKEN` には要らない。
51
+ */
52
+ can_approve_pull_request_reviews: t.boolean(false),
53
+
30
54
  /**
31
55
  * 「 Approval for running fork pull request workflows from contributors 」。
32
56
  *