PRIX / lib /src /checkout.js
Rachit-Tw's picture
feat: implement autonomous Auto-PR and optimize Docker image
5cb7295
Raw
History Blame Contribute Delete
4.47 kB
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkoutRepo = void 0;
const fs_1 = require("fs");
const path_1 = require("path");
const simple_git_1 = require("simple-git");
const context_1 = require("./context");
const pino_1 = __importDefault(require("pino"));
const logger = (0, pino_1.default)({ level: process.env.LOG_LEVEL || 'info' });
const checkoutRepo = async (tempDir, options = {}) => {
const ctx = (0, context_1.getCurrentContext)();
if (!ctx)
throw new Error('No context available for checkout');
// Verify git is available
const git = (0, simple_git_1.simpleGit)();
try {
await git.raw(['--version']);
}
catch (e) {
throw new Error('git command not found in PATH. Please install git.');
}
const { owner, repo } = ctx.repo;
const installationId = ctx.probotContext.payload.installation?.id;
if (!installationId) {
throw new Error('Installation ID not found in payload');
}
const { token } = (await ctx.probotContext.octokit.auth({
type: 'installation'
}));
if (!token) {
throw new Error('Failed to create installation access token: token is undefined');
}
// Ensure gh CLI is authenticated for subsequent contexts
process.env.GH_TOKEN = token;
process.env.GITHUB_TOKEN = token;
// SECURITY: Use token via environment variable, NOT in URL
// This prevents token exposure in process listings and logs
const cloneUrl = `https://github.com/${owner}/${repo}.git`;
const isPullRequest = !!ctx.probotContext.payload.pull_request;
const headBranch = isPullRequest
? ctx.probotContext.payload.pull_request.head.ref
: (ctx.probotContext.payload.ref?.replace('refs/heads/', '') || ctx.probotContext.payload.repository?.default_branch || 'main');
const headSha = isPullRequest
? ctx.probotContext.payload.pull_request.head.sha
: (options.ref || ctx.probotContext.payload.after);
// Set up git credential helper for secure token authentication
process.env.GIT_ASKPASS = 'echo';
process.env.GIT_USERNAME = 'x-access-token';
process.env.GIT_PASSWORD = token;
if ((0, fs_1.existsSync)(tempDir)) {
(0, fs_1.rmSync)(tempDir, { recursive: true, force: true });
}
(0, fs_1.mkdirSync)(tempDir, { recursive: true });
logger.info({ owner, repo, tempDir }, 'Cloning repository');
const repoGit = (0, simple_git_1.simpleGit)(tempDir, {
timeout: { block: 120000 } // 2 minute timeout for all git operations
});
try {
if (options.sparse && options.files && options.files.length > 0) {
logger.info({ fileCount: options.files.length }, 'Using sparse checkout');
// Initialize empty repo and configure sparse checkout
await repoGit.init(['--bare']);
await repoGit.addRemote('origin', cloneUrl);
// Configure sparse checkout
await repoGit.raw(['config', 'core.sparseCheckout', 'true']);
(0, fs_1.writeFileSync)((0, path_1.join)(tempDir, '.git/info/sparse-checkout'), options.files.join('\n'));
// Fetch and checkout specific commit
await repoGit.fetch(['origin', headSha, '--depth', '1']);
await repoGit.checkout(['FETCH_HEAD']);
}
else {
logger.info('Performing full shallow clone');
// Clone with depth 1 for efficiency
await repoGit.clone(cloneUrl, '.', [
'--depth', '1',
'--single-branch',
'--branch', headBranch,
'--no-checkout'
]);
// Fetch and checkout specific SHA
await repoGit.fetch(['origin', headSha, '--depth', '1']);
await repoGit.checkout([headSha]);
}
// Configure git identity
await repoGit.addConfig('user.name', 'PRIX AI Auditor');
await repoGit.addConfig('user.email', 'bot@prix.ai');
logger.info({ owner, repo, headSha }, 'Repository cloned successfully');
}
catch (error) {
logger.error({ error, owner, repo }, 'Git operation failed');
throw new Error(`Failed to clone repository: ${error}`);
}
return tempDir;
};
exports.checkoutRepo = checkoutRepo;
//# sourceMappingURL=checkout.js.map