github-settings-as-code 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +33 -31
- package/src/cmd/gh-apply-all.mts +18 -0
- package/src/cmd/gh-backup-all.mts +12 -0
- package/src/github/constants.mts +1 -1
- package/src/github/index.mts +0 -1
- package/src/github/repository/api/get-repository.mts +2 -1
- package/src/github/repository/apply.mts +65 -57
- package/src/github/repository/backup.mts +4 -2
- package/src/github/repository/constants.mts +0 -1
- package/src/github/repository/index.mts +1 -0
- package/src/github/ruleset/api/get-all-rulesets.mts +2 -1
- package/src/github/ruleset/api/get-ruleset.mts +2 -1
- package/src/github/ruleset/apply.mts +58 -49
- package/src/github/ruleset/backup.mts +4 -2
- package/src/github/ruleset/constants.mts +1 -1
- package/src/github/ruleset/index.mts +1 -0
- package/src/github/ruleset/read-rule-set-contents.mts +1 -1
- package/src/github/variables/api/list-repo-variables.mts +1 -0
- package/src/github/variables/apply.mts +26 -17
- package/src/github/variables/index.mts +1 -0
- package/src/index.mts +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "github-settings-as-code",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"keywords": [
|
|
6
6
|
"github",
|
|
@@ -15,36 +15,37 @@
|
|
|
15
15
|
"sideEffects": false,
|
|
16
16
|
"type": "module",
|
|
17
17
|
"bin": {
|
|
18
|
-
"gh:apply-all": "
|
|
19
|
-
"gh:apply-repository-settings": "
|
|
20
|
-
"gh:apply-rulesets": "
|
|
21
|
-
"gh:apply-variables": "
|
|
22
|
-
"gh:backup-all": "
|
|
23
|
-
"gh:backup-repository-settings": "
|
|
24
|
-
"gh:backup-rulesets": "
|
|
18
|
+
"gh:apply-all": "./dist/cmd/gh-apply-all.mjs",
|
|
19
|
+
"gh:apply-repository-settings": "./dist/github/repository/apply.mjs",
|
|
20
|
+
"gh:apply-rulesets": "./dist/github/ruleset/apply.mjs",
|
|
21
|
+
"gh:apply-variables": "./dist/github/variables/apply.mjs",
|
|
22
|
+
"gh:backup-all": "./dist/cmd/gh-backup-all.mjs",
|
|
23
|
+
"gh:backup-repository-settings": "./dist/github/repository/backup.mjs",
|
|
24
|
+
"gh:backup-rulesets": "./dist/github/ruleset/backup.mjs"
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
|
+
"dist",
|
|
27
28
|
"src",
|
|
28
29
|
"README.md",
|
|
29
30
|
"LICENSE"
|
|
30
31
|
],
|
|
31
32
|
"scripts": {
|
|
33
|
+
"build": "tsx ./scripts/cmd/build.mts",
|
|
32
34
|
"check-all": "tsx ./scripts/cmd/check-all.mts",
|
|
33
35
|
"check:ext": "tsx ./scripts/cmd/check-ext.mts",
|
|
34
36
|
"cspell": "cspell \"**\" --gitignore --gitignore-root ./ --no-progress",
|
|
35
37
|
"fmt": "format-uncommitted",
|
|
36
38
|
"fmt:diff": "format-diff-from origin/main",
|
|
37
39
|
"fmt:full": "prettier --write .",
|
|
38
|
-
"gh:apply-all": "
|
|
39
|
-
"gh:apply-repository-settings": "tsx
|
|
40
|
-
"gh:apply-rulesets": "tsx
|
|
41
|
-
"gh:apply-variables": "tsx
|
|
42
|
-
"gh:backup-all": "
|
|
43
|
-
"gh:backup-repository-settings": "tsx
|
|
44
|
-
"gh:backup-rulesets": "tsx
|
|
45
|
-
"gi": "run-s gi:
|
|
46
|
-
"gi:
|
|
47
|
-
"gi:src": "gen-index-ts ./src --index-ext .mts --export-ext .mjs --target-ext .mts --target-ext .tsx --exclude apply.mts",
|
|
40
|
+
"gh:apply-all": "tsx ./src/cmd/gh-apply-all.mts",
|
|
41
|
+
"gh:apply-repository-settings": "tsx ./src/github/repository/apply.mts",
|
|
42
|
+
"gh:apply-rulesets": "tsx ./src/github/ruleset/apply.mts",
|
|
43
|
+
"gh:apply-variables": "tsx ./src/github/variables/apply.mts",
|
|
44
|
+
"gh:backup-all": "tsx ./src/cmd/gh-backup-all.mts",
|
|
45
|
+
"gh:backup-repository-settings": "tsx ./src/github/repository/backup.mts",
|
|
46
|
+
"gh:backup-rulesets": "tsx ./src/github/ruleset/backup.mts",
|
|
47
|
+
"gi": "run-s gi:src fmt",
|
|
48
|
+
"gi:src": "gen-index-ts ./src/github --index-ext .mts --export-ext .mjs --target-ext .mts --exclude cmd --exclude octokit.mts",
|
|
48
49
|
"lint": "eslint .",
|
|
49
50
|
"lint:fix": "eslint . --fix",
|
|
50
51
|
"md": "markdownlint-cli2",
|
|
@@ -60,8 +61,7 @@
|
|
|
60
61
|
"z:vitest": "vitest --config ./configs/vitest.config.ts"
|
|
61
62
|
},
|
|
62
63
|
"dependencies": {
|
|
63
|
-
"
|
|
64
|
-
"tsx": "^4.20.6"
|
|
64
|
+
"dotenv": "^17.2.3"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
67
|
"@octokit/core": "7.0.6",
|
|
@@ -70,33 +70,35 @@
|
|
|
70
70
|
"@semantic-release/exec": "^7.1.0",
|
|
71
71
|
"@semantic-release/git": "^10.0.1",
|
|
72
72
|
"@semantic-release/github": "^12.0.2",
|
|
73
|
-
"@semantic-release/npm": "^13.1.
|
|
73
|
+
"@semantic-release/npm": "^13.1.2",
|
|
74
74
|
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
75
|
-
"@types/node": "^24.10.
|
|
76
|
-
"@vitest/coverage-v8": "^4.0.
|
|
77
|
-
"@vitest/ui": "^4.0.
|
|
75
|
+
"@types/node": "^24.10.1",
|
|
76
|
+
"@vitest/coverage-v8": "^4.0.9",
|
|
77
|
+
"@vitest/ui": "^4.0.9",
|
|
78
78
|
"conventional-changelog-conventionalcommits": "^9.1.0",
|
|
79
|
-
"cspell": "^9.3.
|
|
79
|
+
"cspell": "^9.3.2",
|
|
80
80
|
"eslint": "9.39.1",
|
|
81
|
-
"eslint-config-typed": "^3.
|
|
81
|
+
"eslint-config-typed": "^3.13.1",
|
|
82
82
|
"fast-glob": "^3.3.3",
|
|
83
83
|
"jiti": "^2.6.1",
|
|
84
84
|
"markdownlint": "^0.39.0",
|
|
85
|
-
"markdownlint-cli2": "^0.
|
|
85
|
+
"markdownlint-cli2": "^0.19.0",
|
|
86
|
+
"npm-run-all2": "^8.0.4",
|
|
86
87
|
"octokit-safe-types": "^1.2.0",
|
|
87
88
|
"prettier": "^3.6.2",
|
|
88
89
|
"prettier-plugin-organize-imports": "^4.3.0",
|
|
89
90
|
"prettier-plugin-packagejson": "^2.5.19",
|
|
90
91
|
"semantic-release": "^25.0.2",
|
|
91
|
-
"ts-data-forge": "^5.0.
|
|
92
|
-
"ts-fortress": "^6.
|
|
93
|
-
"ts-repo-utils": "^7.8.
|
|
92
|
+
"ts-data-forge": "^5.0.1",
|
|
93
|
+
"ts-fortress": "^6.1.0",
|
|
94
|
+
"ts-repo-utils": "^7.8.2",
|
|
94
95
|
"ts-type-forge": "^2.3.0",
|
|
95
96
|
"tslib": "^2.8.1",
|
|
97
|
+
"tsx": "^4.20.6",
|
|
96
98
|
"typedoc": "^0.28.14",
|
|
97
99
|
"typedoc-plugin-markdown": "^4.9.0",
|
|
98
100
|
"typescript": "^5.9.3",
|
|
99
|
-
"vitest": "^4.0.
|
|
101
|
+
"vitest": "^4.0.9"
|
|
100
102
|
},
|
|
101
103
|
"volta": {
|
|
102
104
|
"node": "25.0.0",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import 'dotenv/config';
|
|
4
|
+
import {
|
|
5
|
+
applyRepositorySettings,
|
|
6
|
+
applyRulesets,
|
|
7
|
+
applyVariables,
|
|
8
|
+
} from '../github/index.mjs';
|
|
9
|
+
|
|
10
|
+
const runApplyAll = async (): Promise<void> => {
|
|
11
|
+
await applyVariables();
|
|
12
|
+
|
|
13
|
+
await applyRulesets();
|
|
14
|
+
|
|
15
|
+
await applyRepositorySettings();
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
await runApplyAll();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import 'dotenv/config';
|
|
4
|
+
import { backupRepositorySettings, backupRulesets } from '../github/index.mjs';
|
|
5
|
+
|
|
6
|
+
const runBackupAll = async (): Promise<void> => {
|
|
7
|
+
await backupRulesets();
|
|
8
|
+
|
|
9
|
+
await backupRepositorySettings();
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
await runBackupAll();
|
package/src/github/constants.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import 'ts-repo-utils';
|
|
1
2
|
import packageJson from '../../package.json' with { type: 'json' };
|
|
2
3
|
|
|
3
4
|
export const OWNER = 'noshiro-pf';
|
|
@@ -11,7 +12,6 @@ export const repositorySettingsDir = path.resolve(
|
|
|
11
12
|
);
|
|
12
13
|
|
|
13
14
|
export const repositorySettingsJsonName = 'settings.json';
|
|
14
|
-
|
|
15
15
|
export const rulesetsDir = path.resolve(githubDir, './rulesets');
|
|
16
16
|
|
|
17
17
|
export const octokitHeaders = {
|
package/src/github/index.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GetRepositoryResponse, type EndpointKeys } from 'octokit-safe-types';
|
|
2
2
|
import { validationErrorsToMessages } from 'ts-fortress';
|
|
3
|
-
import
|
|
3
|
+
import 'ts-repo-utils';
|
|
4
4
|
import { octokitHeaders, OWNER, REPO } from '../../constants.mjs';
|
|
5
5
|
import { octokit } from '../../octokit.mjs';
|
|
6
6
|
|
|
@@ -18,6 +18,7 @@ export const getRepositorySettings =
|
|
|
18
18
|
|
|
19
19
|
{
|
|
20
20
|
const res = GetRepositoryResponse.validate(getRepositoryResult.data);
|
|
21
|
+
|
|
21
22
|
if (Result.isErr(res)) {
|
|
22
23
|
console.warn(validationErrorsToMessages(res.value));
|
|
23
24
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import 'dotenv/config';
|
|
1
3
|
import { type UpdateRepositoryRequest } from 'octokit-safe-types';
|
|
2
4
|
import { Obj } from 'ts-data-forge';
|
|
3
5
|
import { validationErrorsToMessages } from 'ts-fortress';
|
|
4
|
-
import {
|
|
6
|
+
import { formatUncommittedFiles } from 'ts-repo-utils';
|
|
5
7
|
import {
|
|
6
8
|
repositorySettingsDir,
|
|
7
9
|
repositorySettingsJsonName,
|
|
@@ -14,6 +16,66 @@ import {
|
|
|
14
16
|
RepositoryPicked,
|
|
15
17
|
} from './constants.mjs';
|
|
16
18
|
|
|
19
|
+
export const applyRepositorySettings = async (): Promise<void> => {
|
|
20
|
+
await backupRepositorySettings(false);
|
|
21
|
+
|
|
22
|
+
const settings = await readSettings();
|
|
23
|
+
|
|
24
|
+
await updateRepository({
|
|
25
|
+
payload: {
|
|
26
|
+
// name: settings.name,
|
|
27
|
+
// description: settings.description ?? undefined,
|
|
28
|
+
// homepage: settings.homepage ?? undefined,
|
|
29
|
+
// private: settings.private,
|
|
30
|
+
// visibility: settings.visibility === 'public' ? 'public' : 'private',
|
|
31
|
+
security_and_analysis: settings.security_and_analysis,
|
|
32
|
+
has_issues: settings.has_issues,
|
|
33
|
+
has_projects: settings.has_projects,
|
|
34
|
+
has_wiki: settings.has_wiki,
|
|
35
|
+
// is_template: settings.is_template,
|
|
36
|
+
// default_branch: settings.default_branch,
|
|
37
|
+
allow_squash_merge: settings.allow_squash_merge,
|
|
38
|
+
allow_merge_commit: settings.allow_merge_commit,
|
|
39
|
+
allow_rebase_merge: settings.allow_rebase_merge,
|
|
40
|
+
allow_auto_merge: settings.allow_auto_merge,
|
|
41
|
+
delete_branch_on_merge: settings.delete_branch_on_merge,
|
|
42
|
+
allow_update_branch: settings.allow_update_branch,
|
|
43
|
+
use_squash_pr_title_as_default: settings.use_squash_pr_title_as_default,
|
|
44
|
+
squash_merge_commit_title: settings.squash_merge_commit_title,
|
|
45
|
+
squash_merge_commit_message: settings.squash_merge_commit_message,
|
|
46
|
+
merge_commit_title: settings.merge_commit_title,
|
|
47
|
+
merge_commit_message: settings.merge_commit_message,
|
|
48
|
+
// archived: settings.archived,
|
|
49
|
+
// NOTE: "RequestError [HttpError]: Allow forks can only be changed on org-owned repositories"
|
|
50
|
+
// allow_forking: settings.allow_forking,
|
|
51
|
+
web_commit_signoff_required: settings.web_commit_signoff_required,
|
|
52
|
+
} satisfies Pick<UpdateRepositoryRequest, RepositoryKeysToPick>,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// update local setting file
|
|
56
|
+
{
|
|
57
|
+
const repositorySettings = await getRepositorySettings();
|
|
58
|
+
|
|
59
|
+
const str = JSON.stringify(
|
|
60
|
+
Obj.pick(repositorySettings, repositoryKeysToPick),
|
|
61
|
+
undefined,
|
|
62
|
+
2,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
await fs.writeFile(
|
|
66
|
+
path.resolve(repositorySettingsDir, repositorySettingsJsonName),
|
|
67
|
+
str,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
await fs.writeFile(
|
|
71
|
+
path.resolve(repositorySettingsDir, 'bk', repositorySettingsJsonName),
|
|
72
|
+
str,
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
await formatUncommittedFiles();
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
17
79
|
const readSettings = async (): Promise<RepositoryPicked> => {
|
|
18
80
|
const settingsText = await fs.readFile(
|
|
19
81
|
path.resolve(repositorySettingsDir, repositorySettingsJsonName),
|
|
@@ -33,60 +95,6 @@ const readSettings = async (): Promise<RepositoryPicked> => {
|
|
|
33
95
|
return validationResult.value;
|
|
34
96
|
};
|
|
35
97
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const settings = await readSettings();
|
|
39
|
-
|
|
40
|
-
await updateRepository({
|
|
41
|
-
payload: {
|
|
42
|
-
// name: settings.name,
|
|
43
|
-
// description: settings.description ?? undefined,
|
|
44
|
-
// homepage: settings.homepage ?? undefined,
|
|
45
|
-
// private: settings.private,
|
|
46
|
-
// visibility: settings.visibility === 'public' ? 'public' : 'private',
|
|
47
|
-
security_and_analysis: settings.security_and_analysis,
|
|
48
|
-
has_issues: settings.has_issues,
|
|
49
|
-
has_projects: settings.has_projects,
|
|
50
|
-
has_wiki: settings.has_wiki,
|
|
51
|
-
// is_template: settings.is_template,
|
|
52
|
-
// default_branch: settings.default_branch,
|
|
53
|
-
allow_squash_merge: settings.allow_squash_merge,
|
|
54
|
-
allow_merge_commit: settings.allow_merge_commit,
|
|
55
|
-
allow_rebase_merge: settings.allow_rebase_merge,
|
|
56
|
-
allow_auto_merge: settings.allow_auto_merge,
|
|
57
|
-
delete_branch_on_merge: settings.delete_branch_on_merge,
|
|
58
|
-
allow_update_branch: settings.allow_update_branch,
|
|
59
|
-
use_squash_pr_title_as_default: settings.use_squash_pr_title_as_default,
|
|
60
|
-
squash_merge_commit_title: settings.squash_merge_commit_title,
|
|
61
|
-
squash_merge_commit_message: settings.squash_merge_commit_message,
|
|
62
|
-
merge_commit_title: settings.merge_commit_title,
|
|
63
|
-
merge_commit_message: settings.merge_commit_message,
|
|
64
|
-
// archived: settings.archived,
|
|
65
|
-
// NOTE: "RequestError [HttpError]: Allow forks can only be changed on org-owned repositories"
|
|
66
|
-
// allow_forking: settings.allow_forking,
|
|
67
|
-
web_commit_signoff_required: settings.web_commit_signoff_required,
|
|
68
|
-
} satisfies Pick<UpdateRepositoryRequest, RepositoryKeysToPick>,
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// update local setting file
|
|
72
|
-
{
|
|
73
|
-
const repositorySettings = await getRepositorySettings();
|
|
74
|
-
|
|
75
|
-
const str = JSON.stringify(
|
|
76
|
-
Obj.pick(repositorySettings, repositoryKeysToPick),
|
|
77
|
-
undefined,
|
|
78
|
-
2,
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
await fs.writeFile(
|
|
82
|
-
path.resolve(repositorySettingsDir, repositorySettingsJsonName),
|
|
83
|
-
str,
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
await fs.writeFile(
|
|
87
|
-
path.resolve(repositorySettingsDir, 'bk', repositorySettingsJsonName),
|
|
88
|
-
str,
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
await $('pnpm run fmt');
|
|
98
|
+
if (isDirectlyExecuted(import.meta.url)) {
|
|
99
|
+
await applyRepositorySettings();
|
|
92
100
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import 'dotenv/config';
|
|
1
3
|
import { Obj } from 'ts-data-forge';
|
|
2
|
-
import { makeEmptyDir } from 'ts-repo-utils';
|
|
4
|
+
import { formatUncommittedFiles, makeEmptyDir } from 'ts-repo-utils';
|
|
3
5
|
import {
|
|
4
6
|
repositorySettingsDir,
|
|
5
7
|
repositorySettingsJsonName,
|
|
@@ -26,7 +28,7 @@ export const backupRepositorySettings = async (
|
|
|
26
28
|
);
|
|
27
29
|
|
|
28
30
|
if (fmt) {
|
|
29
|
-
await
|
|
31
|
+
await formatUncommittedFiles();
|
|
30
32
|
}
|
|
31
33
|
};
|
|
32
34
|
|
|
@@ -63,5 +63,4 @@ export type RepositoryKeysToPick = StrictExclude<
|
|
|
63
63
|
expectType<keyof UpdateRepositoryRequest, RepositoryKeysToPick>('>=');
|
|
64
64
|
|
|
65
65
|
export const RepositoryPicked = t.pick(FullRepository, repositoryKeysToPick);
|
|
66
|
-
|
|
67
66
|
export type RepositoryPicked = t.TypeOf<typeof RepositoryPicked>;
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from 'octokit-safe-types';
|
|
7
7
|
import { expectType } from 'ts-data-forge';
|
|
8
8
|
import { validationErrorsToMessages } from 'ts-fortress';
|
|
9
|
-
import
|
|
9
|
+
import 'ts-repo-utils';
|
|
10
10
|
import { octokitHeaders, OWNER, REPO } from '../../constants.mjs';
|
|
11
11
|
import { octokit } from '../../octokit.mjs';
|
|
12
12
|
|
|
@@ -64,6 +64,7 @@ export const getAllRulesets = async (): Promise<GetAllRulesetsResponse> => {
|
|
|
64
64
|
|
|
65
65
|
{
|
|
66
66
|
const res = GetAllRulesetsResponse.validate(getAllRulesetsResponse.data);
|
|
67
|
+
|
|
67
68
|
if (Result.isErr(res)) {
|
|
68
69
|
console.warn(validationErrorsToMessages(res.value));
|
|
69
70
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GetRulesetResponse, type EndpointKeys } from 'octokit-safe-types';
|
|
2
2
|
import { validationErrorsToMessages } from 'ts-fortress';
|
|
3
|
-
import
|
|
3
|
+
import 'ts-repo-utils';
|
|
4
4
|
import { octokitHeaders, OWNER, REPO } from '../../constants.mjs';
|
|
5
5
|
import { octokit } from '../../octokit.mjs';
|
|
6
6
|
|
|
@@ -20,6 +20,7 @@ export const getRuleset = async (
|
|
|
20
20
|
|
|
21
21
|
{
|
|
22
22
|
const res = GetRulesetResponse.validate(getRulesetResult.data);
|
|
23
|
+
|
|
23
24
|
if (Result.isErr(res)) {
|
|
24
25
|
console.warn(validationErrorsToMessages(res.value));
|
|
25
26
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import 'dotenv/config';
|
|
1
3
|
import { Obj } from 'ts-data-forge';
|
|
2
|
-
import 'ts-repo-utils';
|
|
4
|
+
import { formatUncommittedFiles } from 'ts-repo-utils';
|
|
3
5
|
import { rulesetsDir } from '../constants.mjs';
|
|
4
6
|
import {
|
|
5
7
|
createRuleset,
|
|
@@ -14,64 +16,71 @@ import {
|
|
|
14
16
|
readRulesetFiles,
|
|
15
17
|
} from './read-rule-set-contents.mjs';
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
export const applyRulesets = async (): Promise<void> => {
|
|
20
|
+
await backupRulesets(false);
|
|
18
21
|
|
|
19
|
-
const rulesets = await readRulesetFiles();
|
|
22
|
+
const rulesets = await readRulesetFiles();
|
|
20
23
|
|
|
21
|
-
const backupIds: ReadonlySet<number> = await readRulesetBackupFiles().then(
|
|
22
|
-
|
|
23
|
-
);
|
|
24
|
+
const backupIds: ReadonlySet<number> = await readRulesetBackupFiles().then(
|
|
25
|
+
(rs) => new Set(rs.map((r) => r.id)),
|
|
26
|
+
);
|
|
24
27
|
|
|
25
|
-
const rulesetsToUpdate = rulesets.filter((r) => backupIds.has(r.id));
|
|
26
|
-
const rulesetsToCreate = rulesets.filter((r) => !backupIds.has(r.id));
|
|
28
|
+
const rulesetsToUpdate = rulesets.filter((r) => backupIds.has(r.id));
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
await updateRuleset({
|
|
30
|
-
rulesetId: ruleset.id,
|
|
31
|
-
payload: {
|
|
32
|
-
bypass_actors: ruleset.bypass_actors,
|
|
33
|
-
conditions: ruleset.conditions ?? undefined,
|
|
34
|
-
enforcement: ruleset.enforcement,
|
|
35
|
-
name: ruleset.name,
|
|
36
|
-
rules: ruleset.rules,
|
|
37
|
-
target: ruleset.target === 'repository' ? undefined : ruleset.target,
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
}
|
|
30
|
+
const rulesetsToCreate = rulesets.filter((r) => !backupIds.has(r.id));
|
|
41
31
|
|
|
42
|
-
for (const ruleset of
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
32
|
+
for (const ruleset of rulesetsToUpdate) {
|
|
33
|
+
await updateRuleset({
|
|
34
|
+
rulesetId: ruleset.id,
|
|
35
|
+
payload: {
|
|
36
|
+
bypass_actors: ruleset.bypass_actors,
|
|
37
|
+
conditions: ruleset.conditions ?? undefined,
|
|
38
|
+
enforcement: ruleset.enforcement,
|
|
39
|
+
name: ruleset.name,
|
|
40
|
+
rules: ruleset.rules,
|
|
41
|
+
target: ruleset.target === 'repository' ? undefined : ruleset.target,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
for (const ruleset of rulesetsToCreate) {
|
|
47
|
+
await createRuleset({
|
|
48
|
+
payload: {
|
|
49
|
+
bypass_actors: ruleset.bypass_actors,
|
|
50
|
+
conditions: ruleset.conditions ?? undefined,
|
|
51
|
+
enforcement: ruleset.enforcement,
|
|
52
|
+
name: ruleset.name,
|
|
53
|
+
rules: ruleset.rules,
|
|
54
|
+
target: ruleset.target === 'repository' ? undefined : ruleset.target,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// update local ruleset files
|
|
60
|
+
{
|
|
61
|
+
const rulesetsResult = await getAllRulesets();
|
|
54
62
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const rulesetsResult = await getAllRulesets();
|
|
63
|
+
for (const rule of rulesetsResult) {
|
|
64
|
+
const content = await getRuleset(rule.id);
|
|
58
65
|
|
|
59
|
-
|
|
60
|
-
|
|
66
|
+
const str = JSON.stringify(
|
|
67
|
+
Obj.pick(content, rulesetKeysToPick),
|
|
68
|
+
undefined,
|
|
69
|
+
2,
|
|
70
|
+
);
|
|
61
71
|
|
|
62
|
-
|
|
63
|
-
Obj.pick(content, rulesetKeysToPick),
|
|
64
|
-
undefined,
|
|
65
|
-
2,
|
|
66
|
-
);
|
|
72
|
+
await fs.writeFile(path.resolve(rulesetsDir, `${rule.name}.json`), str);
|
|
67
73
|
|
|
68
|
-
|
|
74
|
+
await fs.writeFile(
|
|
75
|
+
path.resolve(rulesetsDir, `./bk/${rule.name}.json`),
|
|
76
|
+
str,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
69
79
|
|
|
70
|
-
await
|
|
71
|
-
path.resolve(rulesetsDir, `./bk/${rule.name}.json`),
|
|
72
|
-
str,
|
|
73
|
-
);
|
|
80
|
+
await formatUncommittedFiles();
|
|
74
81
|
}
|
|
82
|
+
};
|
|
75
83
|
|
|
76
|
-
|
|
84
|
+
if (isDirectlyExecuted(import.meta.url)) {
|
|
85
|
+
await applyRulesets();
|
|
77
86
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import 'dotenv/config';
|
|
1
3
|
import { Obj } from 'ts-data-forge';
|
|
2
|
-
import { makeEmptyDir } from 'ts-repo-utils';
|
|
4
|
+
import { formatUncommittedFiles, makeEmptyDir } from 'ts-repo-utils';
|
|
3
5
|
import { rulesetsDir } from '../constants.mjs';
|
|
4
6
|
import { getAllRulesets, getRuleset } from './api/index.mjs';
|
|
5
7
|
import { rulesetKeysToPick } from './constants.mjs';
|
|
@@ -21,7 +23,7 @@ export const backupRulesets = async (fmt: boolean = true): Promise<void> => {
|
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
if (fmt) {
|
|
24
|
-
await
|
|
26
|
+
await formatUncommittedFiles();
|
|
25
27
|
}
|
|
26
28
|
};
|
|
27
29
|
|
|
@@ -19,8 +19,8 @@ export const rulesetKeysToPick = [
|
|
|
19
19
|
type KeysToPick = (typeof rulesetKeysToPick)[number];
|
|
20
20
|
|
|
21
21
|
expectType<keyof UpdateRulesetRequest | 'id', KeysToPick>('=');
|
|
22
|
+
|
|
22
23
|
expectType<keyof CreateRulesetRequest, keyof UpdateRulesetRequest>('=');
|
|
23
24
|
|
|
24
25
|
export const RulesetPicked = t.pick(RepositoryRuleset, rulesetKeysToPick);
|
|
25
|
-
|
|
26
26
|
export type RulesetPicked = t.TypeOf<typeof RulesetPicked>;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import 'dotenv/config';
|
|
1
3
|
import 'ts-repo-utils';
|
|
2
4
|
import {
|
|
3
5
|
createRepoVariable,
|
|
@@ -5,24 +7,31 @@ import {
|
|
|
5
7
|
updateRepoVariable,
|
|
6
8
|
} from './api/index.mjs';
|
|
7
9
|
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
export const applyVariables = async (): Promise<void> => {
|
|
11
|
+
const variables = [
|
|
12
|
+
{
|
|
13
|
+
name: 'DEPENDABOT_AUTO_MERGE_BOT_APP_ID',
|
|
14
|
+
value: '1442916',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'SEMANTIC_RELEASE_GIT_PERMISSION_BOT_APP_ID',
|
|
18
|
+
value: '1442563',
|
|
19
|
+
},
|
|
20
|
+
] as const;
|
|
18
21
|
|
|
19
|
-
const variableListSaved = await listRepoVariables();
|
|
20
|
-
const variablesSaved: ReadonlySet<string> = new Set(
|
|
21
|
-
variableListSaved.map((v) => v.name),
|
|
22
|
-
);
|
|
22
|
+
const variableListSaved = await listRepoVariables();
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
const variablesSaved: ReadonlySet<string> = new Set(
|
|
25
|
+
variableListSaved.map((v) => v.name),
|
|
26
|
+
);
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
for (const variable of variables) {
|
|
29
|
+
const found = variablesSaved.has(variable.name);
|
|
30
|
+
|
|
31
|
+
await (found ? updateRepoVariable(variable) : createRepoVariable(variable));
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
if (isDirectlyExecuted(import.meta.url)) {
|
|
36
|
+
await applyVariables();
|
|
28
37
|
}
|
package/src/index.mts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './github/index.mjs';
|