ai-git-tools 2.0.28 → 2.0.30
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/bin/cli.js +32 -4
- package/package.json +1 -1
- package/src/pr-modules/core/github-api.js +81 -3
package/bin/cli.js
CHANGED
|
@@ -34,7 +34,14 @@ program
|
|
|
34
34
|
program
|
|
35
35
|
.command('init')
|
|
36
36
|
.description('初始化配置檔案 (.ai-git-config.mjs)')
|
|
37
|
-
.action(
|
|
37
|
+
.action(async (options) => {
|
|
38
|
+
try {
|
|
39
|
+
await initCommand(options);
|
|
40
|
+
process.exit(0);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
38
45
|
|
|
39
46
|
// Commit 命令
|
|
40
47
|
program
|
|
@@ -44,7 +51,14 @@ program
|
|
|
44
51
|
.option('-v, --verbose', '顯示詳細輸出')
|
|
45
52
|
.option('--max-diff <number>', '最大 diff 長度')
|
|
46
53
|
.option('--max-retries <number>', '最大重試次數')
|
|
47
|
-
.action(
|
|
54
|
+
.action(async (options) => {
|
|
55
|
+
try {
|
|
56
|
+
await commitCommand(options);
|
|
57
|
+
process.exit(0);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
48
62
|
|
|
49
63
|
// Commit All 命令
|
|
50
64
|
program
|
|
@@ -54,7 +68,14 @@ program
|
|
|
54
68
|
.option('-v, --verbose', '顯示詳細輸出')
|
|
55
69
|
.option('--max-diff <number>', '最大 diff 長度')
|
|
56
70
|
.option('--max-retries <number>', '最大重試次數')
|
|
57
|
-
.action(
|
|
71
|
+
.action(async (options) => {
|
|
72
|
+
try {
|
|
73
|
+
await commitAllCommand(options);
|
|
74
|
+
process.exit(0);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
58
79
|
|
|
59
80
|
// PR 命令
|
|
60
81
|
program
|
|
@@ -66,6 +87,13 @@ program
|
|
|
66
87
|
.option('--no-confirm', '跳過確認直接創建')
|
|
67
88
|
.option('--auto-labels', '自動添加 Labels (預設啟用)')
|
|
68
89
|
.option('--include-impact', '在 PR 中包含影響範圍分析和注意事項 (預設關閉)')
|
|
69
|
-
.action(
|
|
90
|
+
.action(async (options) => {
|
|
91
|
+
try {
|
|
92
|
+
await prCommand(options);
|
|
93
|
+
process.exit(0);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
70
98
|
|
|
71
99
|
program.parse();
|
package/package.json
CHANGED
|
@@ -10,6 +10,70 @@ export class GitHubAPI {
|
|
|
10
10
|
constructor() {
|
|
11
11
|
// 自動從 git remote 偵測組織名稱
|
|
12
12
|
this.orgName = this.detectOrgFromRemote();
|
|
13
|
+
// 檢測是否為 fork 環境
|
|
14
|
+
this.isFork = this.detectForkEnvironment();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 檢測是否為 fork 環境(有 upstream remote)
|
|
19
|
+
*/
|
|
20
|
+
detectForkEnvironment() {
|
|
21
|
+
try {
|
|
22
|
+
execSync('git remote get-url upstream', {
|
|
23
|
+
encoding: 'utf-8',
|
|
24
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
25
|
+
});
|
|
26
|
+
log.info('偵測到 fork 環境(有 upstream remote)\n');
|
|
27
|
+
return true;
|
|
28
|
+
} catch (error) {
|
|
29
|
+
// 沒有 upstream,不是 fork
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 獲取當前 gh CLI 登入的帳號
|
|
36
|
+
*/
|
|
37
|
+
getGHAccount() {
|
|
38
|
+
try {
|
|
39
|
+
const account = execSync('gh api user --jq ".login"', {
|
|
40
|
+
encoding: 'utf-8',
|
|
41
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
42
|
+
}).trim();
|
|
43
|
+
return account;
|
|
44
|
+
} catch (error) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 檢查 gh 帳號是否與倉庫擁有者匹配
|
|
51
|
+
*/
|
|
52
|
+
checkAccountMatch() {
|
|
53
|
+
const ghAccount = this.getGHAccount();
|
|
54
|
+
if (!ghAccount) {
|
|
55
|
+
log.warning('⚠️ 無法取得 gh CLI 登入帳號\n');
|
|
56
|
+
return true; // 無法確認就不阻止
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!this.orgName) {
|
|
60
|
+
return true; // 無法確認倉庫擁有者
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (ghAccount.toLowerCase() !== this.orgName.toLowerCase()) {
|
|
64
|
+
log.error(`\n❌ 帳號不匹配!\n`);
|
|
65
|
+
console.log(` 倉庫擁有者: ${colors.cyan}${this.orgName}${colors.reset}`);
|
|
66
|
+
console.log(` gh 登入帳號: ${colors.yellow}${ghAccount}${colors.reset}\n`);
|
|
67
|
+
console.log(`${colors.yellow}⚠️ GitHub 不允許非 collaborator 創建 PR${colors.reset}\n`);
|
|
68
|
+
console.log('解決方法:');
|
|
69
|
+
console.log(` 1. ${colors.cyan}切換 gh 帳號到倉庫擁有者${colors.reset}`);
|
|
70
|
+
console.log(` 執行: ${colors.green}gh auth switch${colors.reset}`);
|
|
71
|
+
console.log(` 或: ${colors.green}gh auth login${colors.reset}\n`);
|
|
72
|
+
console.log(` 2. 或者將 ${ghAccount} 加為倉庫 collaborator\n`);
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return true;
|
|
13
77
|
}
|
|
14
78
|
|
|
15
79
|
/**
|
|
@@ -207,6 +271,12 @@ export class GitHubAPI {
|
|
|
207
271
|
const bodyFile = '/tmp/pr-body.md';
|
|
208
272
|
writeFileSync(bodyFile, body);
|
|
209
273
|
|
|
274
|
+
// 檢查帳號是否匹配
|
|
275
|
+
if (!this.checkAccountMatch()) {
|
|
276
|
+
this.safeUnlink(bodyFile);
|
|
277
|
+
throw new Error('GitHub 帳號與倉庫擁有者不匹配,無法創建 PR');
|
|
278
|
+
}
|
|
279
|
+
|
|
210
280
|
try {
|
|
211
281
|
// 檢查 PR 是否已存在
|
|
212
282
|
let existingPRUrl = null;
|
|
@@ -242,13 +312,21 @@ export class GitHubAPI {
|
|
|
242
312
|
// 創建新 PR
|
|
243
313
|
log.step('正在創建 Pull Request...');
|
|
244
314
|
|
|
245
|
-
//
|
|
246
|
-
//
|
|
315
|
+
// 判斷是否需要加 org: 前綴
|
|
316
|
+
// 1. 如果 headBranch 已經包含 ':',直接使用
|
|
317
|
+
// 2. 如果是 fork 環境(有 upstream),需要加 'org:' 前綴
|
|
318
|
+
// 3. 如果不是 fork(在同一倉庫內操作),直接使用分支名稱
|
|
247
319
|
let headRef = headBranch;
|
|
248
320
|
if (headBranch.includes(':')) {
|
|
321
|
+
// 用戶已明確指定格式,直接使用
|
|
249
322
|
headRef = headBranch;
|
|
250
|
-
} else if (this.orgName) {
|
|
323
|
+
} else if (this.isFork && this.orgName) {
|
|
324
|
+
// Fork 環境,需要加 org: 前綴以正確標識來源
|
|
251
325
|
headRef = `${this.orgName}:${headBranch}`;
|
|
326
|
+
log.info(`Fork 環境:使用完整分支格式 ${headRef}\n`);
|
|
327
|
+
} else {
|
|
328
|
+
// 同一倉庫內操作,直接使用分支名稱
|
|
329
|
+
headRef = headBranch;
|
|
252
330
|
}
|
|
253
331
|
const createCmd = `gh pr create --base "${baseBranch}" --head "${headRef}" --title "${escapedTitle}" --body-file "${bodyFile}"`;
|
|
254
332
|
|