feat(ai-pull-request): 以 opencode 分析 diff 自動產生並建立 Pull Request
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import { log } from './util.js';
|
||||
|
||||
/**
|
||||
* 從環境變數讀取並驗證所有輸入參數。
|
||||
*
|
||||
* @returns {{
|
||||
* serverUrl: string,
|
||||
* repository: string,
|
||||
* owner: string,
|
||||
* repo: string,
|
||||
* token: string,
|
||||
* sourceBranch: string,
|
||||
* targetBranch: string,
|
||||
* opencode: { baseUrl: string, model: string, provider: string },
|
||||
* language: string,
|
||||
* maxDiffChars: number,
|
||||
* workspace: string,
|
||||
* }}
|
||||
*/
|
||||
export function loadInputs() {
|
||||
const serverUrl = trimSlash(required('GITEA_SERVER_URL'));
|
||||
const repository = required('GITEA_REPOSITORY'); // owner/repo
|
||||
const token = required('GITEA_TOKEN');
|
||||
const sourceBranch = required('SOURCE_BRANCH');
|
||||
const targetBranch = required('TARGET_BRANCH');
|
||||
|
||||
const [owner, repo] = repository.split('/');
|
||||
if (!owner || !repo) {
|
||||
throw new Error(`GITEA_REPOSITORY 格式應為 owner/repo,收到: ${repository}`);
|
||||
}
|
||||
|
||||
if (sourceBranch === targetBranch) {
|
||||
throw new Error(`來源分支與目標分支不可相同: ${sourceBranch}`);
|
||||
}
|
||||
|
||||
const opencode = {
|
||||
baseUrl: trimSlash(process.env.OPENCODE_BASE_URL || ''),
|
||||
model: process.env.OPENCODE_MODEL || '',
|
||||
provider: process.env.OPENCODE_PROVIDER || '',
|
||||
};
|
||||
|
||||
// PR 標題/描述固定使用繁體中文,diff 截斷上限固定,皆不透過參數控制
|
||||
const language = 'Traditional Chinese (繁體中文)';
|
||||
const maxDiffChars = 60000;
|
||||
const workspace = process.env.GITHUB_WORKSPACE || process.cwd();
|
||||
|
||||
return {
|
||||
serverUrl,
|
||||
repository,
|
||||
owner,
|
||||
repo,
|
||||
token,
|
||||
sourceBranch,
|
||||
targetBranch,
|
||||
opencode,
|
||||
language,
|
||||
maxDiffChars,
|
||||
workspace,
|
||||
};
|
||||
}
|
||||
|
||||
function required(name) {
|
||||
const value = process.env[name];
|
||||
if (!value || !value.trim()) {
|
||||
throw new Error(`缺少必要的環境變數: ${name}`);
|
||||
}
|
||||
return value.trim();
|
||||
}
|
||||
|
||||
function trimSlash(url) {
|
||||
return url.replace(/\/+$/, '');
|
||||
}
|
||||
|
||||
/** 印出輸入摘要(遮蔽敏感資訊)。 */
|
||||
export function logInputs(inputs) {
|
||||
log.info(`Gitea Server : ${inputs.serverUrl}`);
|
||||
log.info(`Repository : ${inputs.repository}`);
|
||||
log.info(`來源分支 : ${inputs.sourceBranch}`);
|
||||
log.info(`目標分支 : ${inputs.targetBranch}`);
|
||||
log.info(`opencode : provider=${inputs.opencode.provider || '(未設定)'} model=${inputs.opencode.model || '(未設定)'} baseUrl=${inputs.opencode.baseUrl || '(未設定)'}`);
|
||||
}
|
||||
Reference in New Issue
Block a user