Compare commits

...

1 Commits

2 changed files with 50 additions and 5 deletions
+20 -5
View File
@@ -1,7 +1,7 @@
import { spawnSync } from 'child_process';
import fs from 'fs';
import path from 'path';
import { GITEA_SERVER_URL, GITEA_REPOSITORY, GITEA_TOKEN, PR_HEAD_BRANCH, FINDINGS_PATH } from './config.js';
import { GITEA_SERVER_URL, GITEA_REPOSITORY, PR_HEAD_BRANCH, FINDINGS_PATH } from './config.js';
function git(args, cwd) {
const result = spawnSync('git', args, { cwd, encoding: 'utf8' });
@@ -11,21 +11,36 @@ function git(args, cwd) {
}
export async function commitAndPush(workspace) {
const remoteUrl = GITEA_SERVER_URL.replace(/\/$/, '')
.replace('https://', `https://${GITEA_TOKEN}@`)
.replace('http://', `http://${GITEA_TOKEN}@`) + `/${GITEA_REPOSITORY}.git`;
const remoteUrl = GITEA_SERVER_URL.replace(/\/$/, '') + `/${GITEA_REPOSITORY}.git`;
const repoDir = path.join(workspace, 'repo');
try {
if (!fs.existsSync(repoDir)) {
git(['clone', '--depth=1', '--branch', PR_HEAD_BRANCH, remoteUrl, repoDir], workspace);
// Use GIT_ASKPASS to provide token for authentication
gitWithToken(['clone', '--depth=1', '--branch', PR_HEAD_BRANCH, remoteUrl, repoDir], workspace);
}
git(['config', 'user.email', 'ai-review[bot]@gitea'], repoDir);
git(['config', 'user.name', 'AI Review Bot'], repoDir);
git(['fetch', 'origin', PR_HEAD_BRANCH], repoDir);
git(['checkout', PR_HEAD_BRANCH], repoDir);
// Helper to run git with GITEA_TOKEN via GIT_ASKPASS
import { GITEA_TOKEN } from './config.js';
function gitWithToken(args, cwd) {
const askPassScript = `#!/bin/sh\necho \"${GITEA_TOKEN}\"`;
const askPassPath = path.join(cwd, 'git-askpass.sh');
fs.writeFileSync(askPassPath, askPassScript, { mode: 0o700 });
const result = spawnSync('git', args, {
cwd,
encoding: 'utf8',
env: { ...process.env, GIT_ASKPASS: askPassPath },
});
fs.unlinkSync(askPassPath);
if (result.error) throw result.error;
if (result.status !== 0) throw new Error((result.stderr || result.stdout || '').trim());
return (result.stdout || '').trim();
}
// 將 findings.json 從 workspace 複製到 clone 的 repo
const srcFindings = path.join(workspace, FINDINGS_PATH);
+30
View File
@@ -0,0 +1,30 @@
import { commitAndPush } from './git.js';
import fs from 'fs';
import path from 'path';
// Mock dependencies and environment
jest.mock('fs');
jest.mock('child_process', () => ({
spawnSync: jest.fn(() => ({ status: 0, stdout: '', stderr: '' }))
}));
describe('commitAndPush', () => {
const workspace = '/tmp/workspace';
const repoDir = path.join(workspace, 'repo');
beforeEach(() => {
jest.clearAllMocks();
fs.existsSync.mockReturnValue(false);
fs.writeFileSync.mockImplementation(() => {});
fs.unlinkSync.mockImplementation(() => {});
});
it('should clone repo and configure git', async () => {
await expect(commitAndPush(workspace)).resolves.not.toThrow();
});
it('should not clone if repo exists', async () => {
fs.existsSync.mockReturnValue(true);
await expect(commitAndPush(workspace)).resolves.not.toThrow();
});
});