ai-git-tools 2.0.30 → 2.0.32
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
CHANGED
|
@@ -10,70 +10,6 @@ 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;
|
|
77
13
|
}
|
|
78
14
|
|
|
79
15
|
/**
|
|
@@ -181,9 +117,13 @@ export class GitHubAPI {
|
|
|
181
117
|
// 先檢查認證狀態
|
|
182
118
|
const authStatus = this.checkAuth();
|
|
183
119
|
if (!authStatus.authenticated) {
|
|
184
|
-
log.
|
|
185
|
-
log
|
|
186
|
-
|
|
120
|
+
log.error('\n❌ GitHub CLI 未認證\n');
|
|
121
|
+
console.log('請先執行認證:');
|
|
122
|
+
console.log(` ${colors.green}gh auth login${colors.reset}\n`);
|
|
123
|
+
console.log('選擇認證範圍時,請確保包含:');
|
|
124
|
+
console.log(' - repo (必需)');
|
|
125
|
+
console.log(' - read:org (如需使用 reviewer 功能)\n');
|
|
126
|
+
throw new Error('GitHub CLI 未認證,無法創建 PR');
|
|
187
127
|
}
|
|
188
128
|
|
|
189
129
|
log.step(`正在從 GitHub 抓取 ${orgName} 的團隊資訊...`);
|
|
@@ -271,12 +211,6 @@ export class GitHubAPI {
|
|
|
271
211
|
const bodyFile = '/tmp/pr-body.md';
|
|
272
212
|
writeFileSync(bodyFile, body);
|
|
273
213
|
|
|
274
|
-
// 檢查帳號是否匹配
|
|
275
|
-
if (!this.checkAccountMatch()) {
|
|
276
|
-
this.safeUnlink(bodyFile);
|
|
277
|
-
throw new Error('GitHub 帳號與倉庫擁有者不匹配,無法創建 PR');
|
|
278
|
-
}
|
|
279
|
-
|
|
280
214
|
try {
|
|
281
215
|
// 檢查 PR 是否已存在
|
|
282
216
|
let existingPRUrl = null;
|
|
@@ -312,21 +246,13 @@ export class GitHubAPI {
|
|
|
312
246
|
// 創建新 PR
|
|
313
247
|
log.step('正在創建 Pull Request...');
|
|
314
248
|
|
|
315
|
-
//
|
|
316
|
-
//
|
|
317
|
-
// 2. 如果是 fork 環境(有 upstream),需要加 'org:' 前綴
|
|
318
|
-
// 3. 如果不是 fork(在同一倉庫內操作),直接使用分支名稱
|
|
249
|
+
// 如果有 orgName 且是組織 repo,使用完整的分支格式
|
|
250
|
+
// 如果沒有 orgName,直接使用分支名稱(gh CLI 會自動處理)
|
|
319
251
|
let headRef = headBranch;
|
|
320
252
|
if (headBranch.includes(':')) {
|
|
321
|
-
// 用戶已明確指定格式,直接使用
|
|
322
253
|
headRef = headBranch;
|
|
323
|
-
} else if (this.
|
|
324
|
-
// Fork 環境,需要加 org: 前綴以正確標識來源
|
|
254
|
+
} else if (this.orgName) {
|
|
325
255
|
headRef = `${this.orgName}:${headBranch}`;
|
|
326
|
-
log.info(`Fork 環境:使用完整分支格式 ${headRef}\n`);
|
|
327
|
-
} else {
|
|
328
|
-
// 同一倉庫內操作,直接使用分支名稱
|
|
329
|
-
headRef = headBranch;
|
|
330
256
|
}
|
|
331
257
|
const createCmd = `gh pr create --base "${baseBranch}" --head "${headRef}" --title "${escapedTitle}" --body-file "${bodyFile}"`;
|
|
332
258
|
|