forked from syntaxbullet/aurorabot
feat: Enable Git operations within a specified deployment directory by adding cwd options and configuring Git to trust the deploy directory.
This commit is contained in:
@@ -19,10 +19,11 @@ const BUILD_TIMEOUT_MS = 180_000; // 3 minutes for web build
|
||||
*/
|
||||
async function execWithTimeout(
|
||||
cmd: string,
|
||||
timeoutMs: number = DEFAULT_TIMEOUT_MS
|
||||
timeoutMs: number = DEFAULT_TIMEOUT_MS,
|
||||
options: { cwd?: string } = {}
|
||||
): Promise<{ stdout: string; stderr: string }> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const process = exec(cmd, (error: ExecException | null, stdout: string, stderr: string) => {
|
||||
const process = exec(cmd, { cwd: options.cwd }, (error: ExecException | null, stdout: string, stderr: string) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
@@ -51,22 +52,24 @@ export class UpdateService {
|
||||
* Optimized: Parallel git commands and combined requirements check
|
||||
*/
|
||||
static async checkForUpdates(): Promise<UpdateInfo & { requirements: UpdateCheckResult }> {
|
||||
const cwd = this.getDeployDir();
|
||||
|
||||
// Get branch first (needed for subsequent commands)
|
||||
const { stdout: branchName } = await execWithTimeout("git rev-parse --abbrev-ref HEAD");
|
||||
const { stdout: branchName } = await execWithTimeout("git rev-parse --abbrev-ref HEAD", DEFAULT_TIMEOUT_MS, { cwd });
|
||||
const branch = branchName.trim();
|
||||
|
||||
// Parallel execution: get current commit while fetching
|
||||
const [currentResult] = await Promise.all([
|
||||
execWithTimeout("git rev-parse --short HEAD"),
|
||||
execWithTimeout(`git fetch origin ${branch} --prune`) // Only fetch current branch
|
||||
execWithTimeout("git rev-parse --short HEAD", DEFAULT_TIMEOUT_MS, { cwd }),
|
||||
execWithTimeout(`git fetch origin ${branch} --prune`, DEFAULT_TIMEOUT_MS, { cwd }) // Only fetch current branch
|
||||
]);
|
||||
const currentCommit = currentResult.stdout.trim();
|
||||
|
||||
// After fetch completes, get remote info in parallel
|
||||
const [latestResult, logResult, diffResult] = await Promise.all([
|
||||
execWithTimeout(`git rev-parse --short origin/${branch}`),
|
||||
execWithTimeout(`git log HEAD..origin/${branch} --format="%h|%s|%an" --no-merges`),
|
||||
execWithTimeout(`git diff HEAD..origin/${branch} --name-only`)
|
||||
execWithTimeout(`git rev-parse --short origin/${branch}`, DEFAULT_TIMEOUT_MS, { cwd }),
|
||||
execWithTimeout(`git log HEAD..origin/${branch} --format="%h|%s|%an" --no-merges`, DEFAULT_TIMEOUT_MS, { cwd }),
|
||||
execWithTimeout(`git diff HEAD..origin/${branch} --name-only`, DEFAULT_TIMEOUT_MS, { cwd })
|
||||
]);
|
||||
|
||||
const latestCommit = latestResult.stdout.trim();
|
||||
@@ -135,8 +138,9 @@ export class UpdateService {
|
||||
* Kept for backwards compatibility
|
||||
*/
|
||||
static async checkUpdateRequirements(branch: string): Promise<UpdateCheckResult> {
|
||||
const cwd = this.getDeployDir();
|
||||
try {
|
||||
const { stdout } = await execWithTimeout(`git diff HEAD..origin/${branch} --name-only`);
|
||||
const { stdout } = await execWithTimeout(`git diff HEAD..origin/${branch} --name-only`, DEFAULT_TIMEOUT_MS, { cwd });
|
||||
const changedFiles = stdout.trim().split("\n").filter(f => f.length > 0);
|
||||
return this.analyzeChangedFiles(changedFiles);
|
||||
} catch (e) {
|
||||
@@ -179,7 +183,8 @@ export class UpdateService {
|
||||
* Save the current commit for potential rollback
|
||||
*/
|
||||
static async saveRollbackPoint(): Promise<string> {
|
||||
const { stdout } = await execWithTimeout("git rev-parse HEAD");
|
||||
const cwd = this.getDeployDir();
|
||||
const { stdout } = await execWithTimeout("git rev-parse HEAD", DEFAULT_TIMEOUT_MS, { cwd });
|
||||
const commit = stdout.trim();
|
||||
await writeFile(this.ROLLBACK_FILE, commit);
|
||||
this.rollbackPointExists = true; // Cache the state
|
||||
@@ -190,9 +195,10 @@ export class UpdateService {
|
||||
* Rollback to the previous commit
|
||||
*/
|
||||
static async rollback(): Promise<{ success: boolean; message: string }> {
|
||||
const cwd = this.getDeployDir();
|
||||
try {
|
||||
const rollbackCommit = await readFile(this.ROLLBACK_FILE, "utf-8");
|
||||
await execWithTimeout(`git reset --hard ${rollbackCommit.trim()}`);
|
||||
await execWithTimeout(`git reset --hard ${rollbackCommit.trim()}`, DEFAULT_TIMEOUT_MS, { cwd });
|
||||
await unlink(this.ROLLBACK_FILE);
|
||||
this.rollbackPointExists = false;
|
||||
return { success: true, message: `Rolled back to ${rollbackCommit.trim().substring(0, 7)}` };
|
||||
@@ -226,7 +232,8 @@ export class UpdateService {
|
||||
* Perform the git update
|
||||
*/
|
||||
static async performUpdate(branch: string): Promise<void> {
|
||||
await execWithTimeout(`git reset --hard origin/${branch}`);
|
||||
const cwd = this.getDeployDir();
|
||||
await execWithTimeout(`git reset --hard origin/${branch}`, DEFAULT_TIMEOUT_MS, { cwd });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,6 +243,11 @@ export class UpdateService {
|
||||
static async installDependencies(options: { root: boolean; web: boolean }): Promise<string> {
|
||||
const tasks: Promise<{ label: string; output: string }>[] = [];
|
||||
|
||||
// Install dependencies in the App directory (not deploy dir) because we are updating the RUNNING app
|
||||
// NOTE: If we hot-reload, we want to install in the current directory.
|
||||
// If we restart, dependencies should be in the image.
|
||||
// Assuming this method is used for hot-patching/minor updates without container rebuild.
|
||||
|
||||
if (options.root) {
|
||||
tasks.push(
|
||||
execWithTimeout("bun install", INSTALL_TIMEOUT_MS)
|
||||
|
||||
Reference in New Issue
Block a user