Files
ai-code-review/src/config.js
T
jiantw83 21687fd2bd
CI / 1. BUILD (pull_request) Successful in 3s
CI / 2. TEST (pull_request) Skipped
CI / 3. RESULT (pull_request) Skipped
refactor: switch ai-code-review to CLIProxyAPI
2026-08-06 17:42:49 +00:00

92 lines
4.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import https from 'https';
import fs from 'fs';
// 本 action 會連接自架 Gitea / OpenCode,部署環境可能使用內部 CA 或自簽憑證。
// 對外部服務請優先使用預設 TLS 驗證;需要內部服務相容時才使用 getInsecureHttpsAgent()。
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
/**
* 讀取 runner 寫入的事件 payload JSON(`GITHUB_EVENT_PATH` / `GITEA_EVENT_PATH`)。
* 讀不到或解析失敗時回傳空物件,讓後續取值一律走 fallback,不讓 import 期噴錯。
*
* @returns {Record<string, any>} 事件 payload 物件,失敗時為 `{}`。
*/
function readEventPayload() {
const eventPath = process.env.GITHUB_EVENT_PATH || process.env.GITEA_EVENT_PATH;
if (!eventPath) return {};
try {
return JSON.parse(fs.readFileSync(eventPath, 'utf8'));
} catch {
return {};
}
}
const EVENT = readEventPayload();
const PR = EVENT.pull_request || {};
// 取值優先序:有對應 `with:` 輸入的欄位一律 INPUT_* 優先(使用端明確傳入的值最權威,
// 蓋過環境中剛好存在的 ambient env)→ 專用 env(相容舊 Docker 版與測試)→ 內建預設。
// 無對應輸入的欄位(server url / repository / PR_*)則走專用 env → runner 內建 / 事件 payload。
// 使用端 workflow 只需傳 `with: token`。
export const GITEA_TOKEN = process.env.INPUT_TOKEN || process.env.GITEA_TOKEN || '';
export const GITEA_COMMENT_TOKEN = process.env.INPUT_COMMENT_TOKEN || process.env.GITEA_COMMENT_TOKEN || process.env.INPUT_TOKEN || process.env.GITEA_TOKEN || '';
export const GITEA_SERVER_URL = process.env.GITEA_SERVER_URL || process.env.GITHUB_SERVER_URL || 'https://gitea.com';
export const GITEA_REPOSITORY = process.env.GITEA_REPOSITORY || process.env.GITHUB_REPOSITORY || '';
export const PR_NUMBER = process.env.PR_NUMBER || (PR.number != null ? String(PR.number) : '');
export const PR_HEAD_SHA = process.env.PR_HEAD_SHA || PR.head?.sha || process.env.GITHUB_SHA || '';
export const PR_HEAD_BRANCH = process.env.PR_HEAD_BRANCH || PR.head?.ref || process.env.GITHUB_HEAD_REF || '';
export const PR_BASE_BRANCH = process.env.PR_BASE_BRANCH || PR.base?.ref || process.env.GITHUB_BASE_REF || '';
export const CLI_PROXY_API = process.env.INPUT_CLI_PROXY_API || process.env.CLI_PROXY_API || '';
export const CLI_PROXY_API_KEY = process.env.INPUT_CLI_PROXY_API_KEY || process.env.CLI_PROXY_API_KEY || '';
export const LLM_PROVIDER = 'cliproxyapi';
export const FINDINGS_PATH = '.gitea/ai-review/findings.json';
export const EXCLUSIONS_PATH = '.gitea/ai-review/exclusions.json';
/**
* 建立一個停用 TLS 憑證驗證(`rejectUnauthorized: false`)的 HTTPS Agent,
* 供連接使用自簽或無效憑證的內部服務時使用。
*
* @remarks 首次呼叫時建立,之後快取為模組層級單例(singleton)重複使用,
* 避免每次都新建 Agent 與連線池、浪費 TCP 三次握手。
* 停用憑證驗證有中間人攻擊風險,僅限受信任的內部環境使用。
* @returns {import('https').Agent} 已關閉憑證驗證的 HTTPS Agent 單例。
*/
let _insecureHttpsAgent = null;
/**
* 取得一個關閉 TLS 憑證驗證的 HTTPS Agent 單例,供內部服務連線使用。
*
* @remarks 只應在信任的內網或測試環境使用;若需要完整 TLS 安全性,應改用預設
* `https.Agent`,不要調用這個函式。
*/
export function getInsecureHttpsAgent() {
return (_insecureHttpsAgent ??= new https.Agent({ rejectUnauthorized: false }));
}
// 過渡別名:既有呼叫端仍可用 OpenCode 語意名稱;新程式碼請直接使用 getInsecureHttpsAgent。
export const getOpenCodeHttpsAgent = getInsecureHttpsAgent;
/**
* 依環境變數解析並回傳 CLIProxyAPI 設定。
*
* 優先讀取 `INPUT_CLI_PROXY_API` / `CLI_PROXY_API` 作為 base URL,`INPUT_MODEL` / `MODEL`
* 作為模型名稱,`INPUT_CLI_PROXY_API_KEY` / `CLI_PROXY_API_KEY` 作為存取金鑰。
*
* @returns {{ provider: ('cliproxyapi'|null), apiKeys: string[], baseURL: (string|null), model: (string|null), command: null }}
* 設定物件;`provider` 為 `null` 表示沒有可用的 proxy 設定。
*/
export function getLLMConfig() {
const baseURL = String(process.env.INPUT_CLI_PROXY_API || process.env.CLI_PROXY_API || '').trim().replace(/\/$/, '');
const model = process.env.INPUT_MODEL || process.env.MODEL || process.env.OPENCODE_MODEL || '';
const apiKey = String(process.env.INPUT_CLI_PROXY_API_KEY || process.env.CLI_PROXY_API_KEY || '').trim();
if (!baseURL) return { provider: null, apiKeys: [], baseURL: null, model: model || null, command: null };
return {
provider: LLM_PROVIDER,
apiKeys: apiKey ? [apiKey] : [],
baseURL,
model: model || null,
command: null,
};
}