safe-push 0.2.0 → 0.3.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.
- package/dist/index.js +84 -11
- package/package.json +1 -1
- package/src/checker.ts +34 -1
- package/src/commands/check.ts +21 -1
- package/src/commands/config.ts +3 -0
- package/src/commands/push.ts +17 -1
- package/src/commands/utils.ts +7 -0
- package/src/config.ts +5 -1
- package/src/git.ts +49 -11
- package/src/types.ts +9 -0
package/dist/index.js
CHANGED
|
@@ -6704,9 +6704,11 @@ var coerce = {
|
|
|
6704
6704
|
var NEVER = INVALID;
|
|
6705
6705
|
// src/types.ts
|
|
6706
6706
|
var OnForbiddenSchema = exports_external.enum(["error", "prompt"]);
|
|
6707
|
+
var RepoVisibilitySchema = exports_external.enum(["public", "private", "internal"]);
|
|
6707
6708
|
var ConfigSchema = exports_external.object({
|
|
6708
6709
|
forbiddenPaths: exports_external.array(exports_external.string()).default([".github/"]),
|
|
6709
|
-
onForbidden: OnForbiddenSchema.default("error")
|
|
6710
|
+
onForbidden: OnForbiddenSchema.default("error"),
|
|
6711
|
+
allowedVisibility: exports_external.array(RepoVisibilitySchema).optional()
|
|
6710
6712
|
});
|
|
6711
6713
|
|
|
6712
6714
|
class GitError extends Error {
|
|
@@ -6775,12 +6777,15 @@ function saveConfig(config, configPath) {
|
|
|
6775
6777
|
if (!fs.existsSync(dir)) {
|
|
6776
6778
|
fs.mkdirSync(dir, { recursive: true });
|
|
6777
6779
|
}
|
|
6780
|
+
const allowedVisibilitySection = config.allowedVisibility ? `,
|
|
6781
|
+
// \u8A31\u53EF\u3059\u308B\u30EA\u30DD\u30B8\u30C8\u30EA visibility: "public" | "private" | "internal"
|
|
6782
|
+
"allowedVisibility": ${JSON.stringify(config.allowedVisibility)}` : "";
|
|
6778
6783
|
const content = `{
|
|
6779
6784
|
// \u7981\u6B62\u30A8\u30EA\u30A2\uFF08Glob\u30D1\u30BF\u30FC\u30F3\uFF09
|
|
6780
6785
|
"forbiddenPaths": ${JSON.stringify(config.forbiddenPaths, null, 4).replace(/\n/g, `
|
|
6781
6786
|
`)},
|
|
6782
6787
|
// \u7981\u6B62\u6642\u306E\u52D5\u4F5C: "error" | "prompt"
|
|
6783
|
-
"onForbidden": "${config.onForbidden}"
|
|
6788
|
+
"onForbidden": "${config.onForbidden}"${allowedVisibilitySection}
|
|
6784
6789
|
}
|
|
6785
6790
|
`;
|
|
6786
6791
|
fs.writeFileSync(filePath, content, "utf-8");
|
|
@@ -6859,15 +6864,21 @@ async function getDiffFiles(remote = "origin") {
|
|
|
6859
6864
|
`).filter(Boolean);
|
|
6860
6865
|
}
|
|
6861
6866
|
async function execPush(args = [], remote = "origin") {
|
|
6862
|
-
|
|
6863
|
-
const
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
|
|
6867
|
+
let pushArgs;
|
|
6868
|
+
const hasUserRefspec = args.some((arg) => !arg.startsWith("-"));
|
|
6869
|
+
if (hasUserRefspec) {
|
|
6870
|
+
pushArgs = ["push", ...args];
|
|
6871
|
+
} else {
|
|
6872
|
+
const branch = await getCurrentBranch();
|
|
6873
|
+
const isNew = await isNewBranch(remote);
|
|
6874
|
+
pushArgs = ["push"];
|
|
6875
|
+
const hasSetUpstream = args.some((a) => a === "-u" || a === "--set-upstream");
|
|
6876
|
+
if (isNew || hasSetUpstream) {
|
|
6877
|
+
pushArgs.push("-u");
|
|
6878
|
+
}
|
|
6879
|
+
pushArgs.push(remote, branch);
|
|
6880
|
+
const remainingFlags = args.filter((a) => a !== "-u" && a !== "--set-upstream");
|
|
6881
|
+
pushArgs.push(...remainingFlags);
|
|
6871
6882
|
}
|
|
6872
6883
|
try {
|
|
6873
6884
|
const output = await execGit(pushArgs);
|
|
@@ -6882,6 +6893,20 @@ async function execPush(args = [], remote = "origin") {
|
|
|
6882
6893
|
};
|
|
6883
6894
|
}
|
|
6884
6895
|
}
|
|
6896
|
+
async function getRepoVisibility() {
|
|
6897
|
+
const command = "gh repo view --json visibility --jq '.visibility'";
|
|
6898
|
+
try {
|
|
6899
|
+
const result = await $`gh repo view --json visibility --jq .visibility`.quiet();
|
|
6900
|
+
return result.stdout.toString().trim().toLowerCase();
|
|
6901
|
+
} catch (error) {
|
|
6902
|
+
if (error && typeof error === "object" && "exitCode" in error) {
|
|
6903
|
+
const exitCode = error.exitCode;
|
|
6904
|
+
const stderr = "stderr" in error ? String(error.stderr) : "";
|
|
6905
|
+
throw new GitError(`Failed to get repository visibility: ${stderr || command}`, command, exitCode);
|
|
6906
|
+
}
|
|
6907
|
+
throw new GitError(`Failed to get repository visibility: ${command}`, command, null);
|
|
6908
|
+
}
|
|
6909
|
+
}
|
|
6885
6910
|
async function isGitRepository() {
|
|
6886
6911
|
try {
|
|
6887
6912
|
await execGit(["rev-parse", "--git-dir"]);
|
|
@@ -6900,6 +6925,18 @@ async function hasCommits() {
|
|
|
6900
6925
|
}
|
|
6901
6926
|
|
|
6902
6927
|
// src/checker.ts
|
|
6928
|
+
async function checkVisibility(allowedVisibility) {
|
|
6929
|
+
if (!allowedVisibility || allowedVisibility.length === 0) {
|
|
6930
|
+
return null;
|
|
6931
|
+
}
|
|
6932
|
+
const visibility = await getRepoVisibility();
|
|
6933
|
+
const allowed = allowedVisibility.includes(visibility);
|
|
6934
|
+
return {
|
|
6935
|
+
allowed,
|
|
6936
|
+
reason: allowed ? `Repository visibility "${visibility}" is allowed` : `Repository visibility "${visibility}" is not in allowed list: [${allowedVisibility.join(", ")}]`,
|
|
6937
|
+
visibility
|
|
6938
|
+
};
|
|
6939
|
+
}
|
|
6903
6940
|
function matchesForbiddenPath(filePath, forbiddenPaths) {
|
|
6904
6941
|
for (const pattern of forbiddenPaths) {
|
|
6905
6942
|
if (pattern.endsWith("/")) {
|
|
@@ -6998,6 +7035,10 @@ function printCheckResultHuman(result) {
|
|
|
6998
7035
|
console.log(` Local user email: ${details.localEmail}`);
|
|
6999
7036
|
console.log(` Own last commit: ${details.isOwnLastCommit ? "Yes" : "No"}`);
|
|
7000
7037
|
console.log(` Forbidden changes: ${details.hasForbiddenChanges ? "Yes" : "No"}`);
|
|
7038
|
+
if (details.repoVisibility !== undefined) {
|
|
7039
|
+
console.log(` Repo visibility: ${details.repoVisibility}`);
|
|
7040
|
+
console.log(` Visibility allowed: ${details.visibilityAllowed ? "Yes" : "No"}`);
|
|
7041
|
+
}
|
|
7001
7042
|
if (details.forbiddenFiles.length > 0) {
|
|
7002
7043
|
console.log("");
|
|
7003
7044
|
console.log("Forbidden files changed:");
|
|
@@ -7031,6 +7072,24 @@ function createCheckCommand() {
|
|
|
7031
7072
|
}
|
|
7032
7073
|
const config = loadConfig();
|
|
7033
7074
|
const result = await checkPush(config);
|
|
7075
|
+
if (config.allowedVisibility && config.allowedVisibility.length > 0) {
|
|
7076
|
+
try {
|
|
7077
|
+
const visibilityResult = await checkVisibility(config.allowedVisibility);
|
|
7078
|
+
if (visibilityResult) {
|
|
7079
|
+
result.details.repoVisibility = visibilityResult.visibility;
|
|
7080
|
+
result.details.visibilityAllowed = visibilityResult.allowed;
|
|
7081
|
+
if (!visibilityResult.allowed) {
|
|
7082
|
+
result.allowed = false;
|
|
7083
|
+
result.reason = visibilityResult.reason;
|
|
7084
|
+
}
|
|
7085
|
+
}
|
|
7086
|
+
} catch (error) {
|
|
7087
|
+
result.details.repoVisibility = "unknown";
|
|
7088
|
+
result.details.visibilityAllowed = false;
|
|
7089
|
+
result.allowed = false;
|
|
7090
|
+
result.reason = `Failed to check repository visibility. Ensure 'gh' CLI is installed and authenticated.`;
|
|
7091
|
+
}
|
|
7092
|
+
}
|
|
7034
7093
|
if (options.json) {
|
|
7035
7094
|
printCheckResultJson(result);
|
|
7036
7095
|
} else {
|
|
@@ -7058,6 +7117,19 @@ function createPushCommand() {
|
|
|
7058
7117
|
process.exit(1);
|
|
7059
7118
|
}
|
|
7060
7119
|
const config = loadConfig();
|
|
7120
|
+
if (config.allowedVisibility && config.allowedVisibility.length > 0) {
|
|
7121
|
+
try {
|
|
7122
|
+
const visibilityResult = await checkVisibility(config.allowedVisibility);
|
|
7123
|
+
if (visibilityResult && !visibilityResult.allowed) {
|
|
7124
|
+
printError(visibilityResult.reason);
|
|
7125
|
+
process.exit(1);
|
|
7126
|
+
}
|
|
7127
|
+
} catch (error) {
|
|
7128
|
+
printError(`Failed to check repository visibility. Ensure 'gh' CLI is installed and authenticated.
|
|
7129
|
+
${error instanceof Error ? error.message : String(error)}`);
|
|
7130
|
+
process.exit(1);
|
|
7131
|
+
}
|
|
7132
|
+
}
|
|
7061
7133
|
if (options.force) {
|
|
7062
7134
|
printWarning("Safety checks bypassed with --force");
|
|
7063
7135
|
if (options.dryRun) {
|
|
@@ -7154,6 +7226,7 @@ function createConfigCommand() {
|
|
|
7154
7226
|
console.log("Settings:");
|
|
7155
7227
|
console.log(` forbiddenPaths: ${JSON.stringify(configData.forbiddenPaths)}`);
|
|
7156
7228
|
console.log(` onForbidden: ${configData.onForbidden}`);
|
|
7229
|
+
console.log(` allowedVisibility: ${configData.allowedVisibility ? JSON.stringify(configData.allowedVisibility) : "(not set - all visibilities allowed)"}`);
|
|
7157
7230
|
console.log("");
|
|
7158
7231
|
}
|
|
7159
7232
|
} catch (error) {
|
package/package.json
CHANGED
package/src/checker.ts
CHANGED
|
@@ -1,12 +1,45 @@
|
|
|
1
|
-
import type { Config, CheckResult } from "./types";
|
|
1
|
+
import type { Config, CheckResult, RepoVisibility } from "./types";
|
|
2
2
|
import {
|
|
3
3
|
getCurrentBranch,
|
|
4
4
|
isNewBranch,
|
|
5
5
|
getLastCommitAuthorEmail,
|
|
6
6
|
getLocalEmail,
|
|
7
7
|
getDiffFiles,
|
|
8
|
+
getRepoVisibility,
|
|
8
9
|
} from "./git";
|
|
9
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Visibility チェック結果
|
|
13
|
+
*/
|
|
14
|
+
export interface VisibilityCheckResult {
|
|
15
|
+
allowed: boolean;
|
|
16
|
+
reason: string;
|
|
17
|
+
visibility: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* リポジトリの visibility が許可リストに含まれるかチェック
|
|
22
|
+
* allowedVisibility が未設定または空配列の場合は null を返す(チェック不要)
|
|
23
|
+
*/
|
|
24
|
+
export async function checkVisibility(
|
|
25
|
+
allowedVisibility?: RepoVisibility[]
|
|
26
|
+
): Promise<VisibilityCheckResult | null> {
|
|
27
|
+
if (!allowedVisibility || allowedVisibility.length === 0) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const visibility = await getRepoVisibility();
|
|
32
|
+
const allowed = allowedVisibility.includes(visibility as RepoVisibility);
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
allowed,
|
|
36
|
+
reason: allowed
|
|
37
|
+
? `Repository visibility "${visibility}" is allowed`
|
|
38
|
+
: `Repository visibility "${visibility}" is not in allowed list: [${allowedVisibility.join(", ")}]`,
|
|
39
|
+
visibility,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
10
43
|
/**
|
|
11
44
|
* ファイルパスが禁止パターンにマッチするか判定
|
|
12
45
|
*/
|
package/src/commands/check.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { loadConfig } from "../config";
|
|
3
|
-
import { checkPush } from "../checker";
|
|
3
|
+
import { checkPush, checkVisibility } from "../checker";
|
|
4
4
|
import { isGitRepository, hasCommits } from "../git";
|
|
5
5
|
import { printError, printCheckResultJson, printCheckResultHuman } from "./utils";
|
|
6
6
|
|
|
@@ -28,6 +28,26 @@ export function createCheckCommand(): Command {
|
|
|
28
28
|
const config = loadConfig();
|
|
29
29
|
const result = await checkPush(config);
|
|
30
30
|
|
|
31
|
+
// visibility チェック
|
|
32
|
+
if (config.allowedVisibility && config.allowedVisibility.length > 0) {
|
|
33
|
+
try {
|
|
34
|
+
const visibilityResult = await checkVisibility(config.allowedVisibility);
|
|
35
|
+
if (visibilityResult) {
|
|
36
|
+
result.details.repoVisibility = visibilityResult.visibility;
|
|
37
|
+
result.details.visibilityAllowed = visibilityResult.allowed;
|
|
38
|
+
if (!visibilityResult.allowed) {
|
|
39
|
+
result.allowed = false;
|
|
40
|
+
result.reason = visibilityResult.reason;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} catch (error) {
|
|
44
|
+
result.details.repoVisibility = "unknown";
|
|
45
|
+
result.details.visibilityAllowed = false;
|
|
46
|
+
result.allowed = false;
|
|
47
|
+
result.reason = `Failed to check repository visibility. Ensure 'gh' CLI is installed and authenticated.`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
31
51
|
if (options.json) {
|
|
32
52
|
printCheckResultJson(result);
|
|
33
53
|
} else {
|
package/src/commands/config.ts
CHANGED
|
@@ -68,6 +68,9 @@ export function createConfigCommand(): Command {
|
|
|
68
68
|
` forbiddenPaths: ${JSON.stringify(configData.forbiddenPaths)}`
|
|
69
69
|
);
|
|
70
70
|
console.log(` onForbidden: ${configData.onForbidden}`);
|
|
71
|
+
console.log(
|
|
72
|
+
` allowedVisibility: ${configData.allowedVisibility ? JSON.stringify(configData.allowedVisibility) : "(not set - all visibilities allowed)"}`
|
|
73
|
+
);
|
|
71
74
|
console.log("");
|
|
72
75
|
}
|
|
73
76
|
} catch (error) {
|
package/src/commands/push.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { loadConfig } from "../config";
|
|
3
|
-
import { checkPush } from "../checker";
|
|
3
|
+
import { checkPush, checkVisibility } from "../checker";
|
|
4
4
|
import { isGitRepository, hasCommits, execPush } from "../git";
|
|
5
5
|
import {
|
|
6
6
|
printError,
|
|
@@ -36,6 +36,22 @@ export function createPushCommand(): Command {
|
|
|
36
36
|
|
|
37
37
|
const config = loadConfig();
|
|
38
38
|
|
|
39
|
+
// visibility チェック(--force でもバイパスできない)
|
|
40
|
+
if (config.allowedVisibility && config.allowedVisibility.length > 0) {
|
|
41
|
+
try {
|
|
42
|
+
const visibilityResult = await checkVisibility(config.allowedVisibility);
|
|
43
|
+
if (visibilityResult && !visibilityResult.allowed) {
|
|
44
|
+
printError(visibilityResult.reason);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
} catch (error) {
|
|
48
|
+
printError(
|
|
49
|
+
`Failed to check repository visibility. Ensure 'gh' CLI is installed and authenticated.\n ${error instanceof Error ? error.message : String(error)}`
|
|
50
|
+
);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
39
55
|
// --forceオプションが指定されている場合はチェックをスキップ
|
|
40
56
|
if (options.force) {
|
|
41
57
|
printWarning("Safety checks bypassed with --force");
|
package/src/commands/utils.ts
CHANGED
|
@@ -60,6 +60,13 @@ export function printCheckResultHuman(result: CheckResult): void {
|
|
|
60
60
|
` Forbidden changes: ${details.hasForbiddenChanges ? "Yes" : "No"}`
|
|
61
61
|
);
|
|
62
62
|
|
|
63
|
+
if (details.repoVisibility !== undefined) {
|
|
64
|
+
console.log(` Repo visibility: ${details.repoVisibility}`);
|
|
65
|
+
console.log(
|
|
66
|
+
` Visibility allowed: ${details.visibilityAllowed ? "Yes" : "No"}`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
63
70
|
if (details.forbiddenFiles.length > 0) {
|
|
64
71
|
console.log("");
|
|
65
72
|
console.log("Forbidden files changed:");
|
package/src/config.ts
CHANGED
|
@@ -88,11 +88,15 @@ export function saveConfig(config: Config, configPath?: string): void {
|
|
|
88
88
|
fs.mkdirSync(dir, { recursive: true });
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
const allowedVisibilitySection = config.allowedVisibility
|
|
92
|
+
? `,\n // 許可するリポジトリ visibility: "public" | "private" | "internal"\n "allowedVisibility": ${JSON.stringify(config.allowedVisibility)}`
|
|
93
|
+
: "";
|
|
94
|
+
|
|
91
95
|
const content = `{
|
|
92
96
|
// 禁止エリア(Globパターン)
|
|
93
97
|
"forbiddenPaths": ${JSON.stringify(config.forbiddenPaths, null, 4).replace(/\n/g, "\n ")},
|
|
94
98
|
// 禁止時の動作: "error" | "prompt"
|
|
95
|
-
"onForbidden": "${config.onForbidden}"
|
|
99
|
+
"onForbidden": "${config.onForbidden}"${allowedVisibilitySection}
|
|
96
100
|
}
|
|
97
101
|
`;
|
|
98
102
|
|
package/src/git.ts
CHANGED
|
@@ -106,21 +106,36 @@ export async function execPush(
|
|
|
106
106
|
args: string[] = [],
|
|
107
107
|
remote = "origin"
|
|
108
108
|
): Promise<{ success: boolean; output: string }> {
|
|
109
|
-
|
|
110
|
-
const isNew = await isNewBranch(remote);
|
|
109
|
+
let pushArgs: string[];
|
|
111
110
|
|
|
112
|
-
|
|
111
|
+
// ユーザーがremote/refspecを明示的に指定したか判定
|
|
112
|
+
const hasUserRefspec = args.some((arg) => !arg.startsWith("-"));
|
|
113
113
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
pushArgs
|
|
117
|
-
}
|
|
114
|
+
if (hasUserRefspec) {
|
|
115
|
+
// ユーザー指定のremote/refspecをそのまま使用
|
|
116
|
+
pushArgs = ["push", ...args];
|
|
117
|
+
} else {
|
|
118
|
+
// 自動でremote/branchを決定
|
|
119
|
+
const branch = await getCurrentBranch();
|
|
120
|
+
const isNew = await isNewBranch(remote);
|
|
121
|
+
|
|
122
|
+
pushArgs = ["push"];
|
|
123
|
+
|
|
124
|
+
// 新規ブランチ、またはユーザーが-uを指定した場合に追加
|
|
125
|
+
const hasSetUpstream = args.some(
|
|
126
|
+
(a) => a === "-u" || a === "--set-upstream"
|
|
127
|
+
);
|
|
128
|
+
if (isNew || hasSetUpstream) {
|
|
129
|
+
pushArgs.push("-u");
|
|
130
|
+
}
|
|
118
131
|
|
|
119
|
-
|
|
132
|
+
pushArgs.push(remote, branch);
|
|
120
133
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
134
|
+
// -u/--set-upstream以外のフラグを追加
|
|
135
|
+
const remainingFlags = args.filter(
|
|
136
|
+
(a) => a !== "-u" && a !== "--set-upstream"
|
|
137
|
+
);
|
|
138
|
+
pushArgs.push(...remainingFlags);
|
|
124
139
|
}
|
|
125
140
|
|
|
126
141
|
try {
|
|
@@ -137,6 +152,29 @@ export async function execPush(
|
|
|
137
152
|
}
|
|
138
153
|
}
|
|
139
154
|
|
|
155
|
+
/**
|
|
156
|
+
* リポジトリの visibility を取得(gh CLI を使用)
|
|
157
|
+
*/
|
|
158
|
+
export async function getRepoVisibility(): Promise<string> {
|
|
159
|
+
const command = "gh repo view --json visibility --jq '.visibility'";
|
|
160
|
+
try {
|
|
161
|
+
const result = await $`gh repo view --json visibility --jq .visibility`.quiet();
|
|
162
|
+
return result.stdout.toString().trim().toLowerCase();
|
|
163
|
+
} catch (error) {
|
|
164
|
+
if (error && typeof error === "object" && "exitCode" in error) {
|
|
165
|
+
const exitCode = (error as { exitCode: number }).exitCode;
|
|
166
|
+
const stderr =
|
|
167
|
+
"stderr" in error ? String((error as { stderr: unknown }).stderr) : "";
|
|
168
|
+
throw new GitError(
|
|
169
|
+
`Failed to get repository visibility: ${stderr || command}`,
|
|
170
|
+
command,
|
|
171
|
+
exitCode
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
throw new GitError(`Failed to get repository visibility: ${command}`, command, null);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
140
178
|
/**
|
|
141
179
|
* Gitリポジトリ内かどうかを確認
|
|
142
180
|
*/
|
package/src/types.ts
CHANGED
|
@@ -6,12 +6,19 @@ import { z } from "zod";
|
|
|
6
6
|
export const OnForbiddenSchema = z.enum(["error", "prompt"]);
|
|
7
7
|
export type OnForbidden = z.infer<typeof OnForbiddenSchema>;
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* リポジトリの visibility
|
|
11
|
+
*/
|
|
12
|
+
export const RepoVisibilitySchema = z.enum(["public", "private", "internal"]);
|
|
13
|
+
export type RepoVisibility = z.infer<typeof RepoVisibilitySchema>;
|
|
14
|
+
|
|
9
15
|
/**
|
|
10
16
|
* 設定ファイルのスキーマ
|
|
11
17
|
*/
|
|
12
18
|
export const ConfigSchema = z.object({
|
|
13
19
|
forbiddenPaths: z.array(z.string()).default([".github/"]),
|
|
14
20
|
onForbidden: OnForbiddenSchema.default("error"),
|
|
21
|
+
allowedVisibility: z.array(RepoVisibilitySchema).optional(),
|
|
15
22
|
});
|
|
16
23
|
export type Config = z.infer<typeof ConfigSchema>;
|
|
17
24
|
|
|
@@ -29,6 +36,8 @@ export interface CheckResult {
|
|
|
29
36
|
currentBranch: string;
|
|
30
37
|
authorEmail: string;
|
|
31
38
|
localEmail: string;
|
|
39
|
+
repoVisibility?: string;
|
|
40
|
+
visibilityAllowed?: boolean;
|
|
32
41
|
};
|
|
33
42
|
}
|
|
34
43
|
|