paginate app operations and refine runtime settings layout
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2026-07-07 17:42:31 +09:00
parent cc5a15a01c
commit 36acfedaee
3 changed files with 59 additions and 36 deletions
+38 -16
View File
@@ -640,6 +640,11 @@ export class AppsService {
if (byRepository.size === 0) return;
const gitBin = this.configService.get<string>('GIT_BIN', 'git');
const isUnrelatedHistoryError = (message: string) => {
const normalized = message.toLowerCase();
return normalized.includes('refusing to merge unrelated histories') || normalized.includes('not possible to fast-forward');
};
const workRoot = path.join(os.tmpdir(), 'studio-admin-release-promotions');
await fs.mkdir(workRoot, { recursive: true });
@@ -647,38 +652,59 @@ export class AppsService {
const workDir = path.join(workRoot, `${sanitizeImageName(repository)}-${Date.now()}`);
try {
await fs.rm(workDir, { recursive: true, force: true });
await execFileAsync(this.configService.get<string>('GIT_BIN', 'git'), [
await execFileAsync(gitBin, [
'clone',
'--no-checkout',
await this.getAuthenticatedHttpCloneUrl(repository),
workDir,
]);
await execFileAsync(this.configService.get<string>('GIT_BIN', 'git'), [
await execFileAsync(gitBin, [
'fetch',
'origin',
sourceBranch,
], { cwd: workDir });
await execFileAsync(this.configService.get<string>('GIT_BIN', 'git'), [
await execFileAsync(gitBin, [
'fetch',
'origin',
targetBranch,
], { cwd: workDir }).catch(() => undefined);
const targetExists = await gitRefExists(workDir, `refs/remotes/origin/${targetBranch}`, this.configService.get<string>('GIT_BIN', 'git'));
const pushArgs: string[] = ['push', 'origin', `HEAD:refs/heads/${targetBranch}`];
const targetExists = await gitRefExists(workDir, `refs/remotes/origin/${targetBranch}`, gitBin);
if (targetExists) {
await execFileAsync(this.configService.get<string>('GIT_BIN', 'git'), [
await execFileAsync(gitBin, [
'checkout',
'-B',
targetBranch,
`origin/${targetBranch}`,
], { cwd: workDir });
await execFileAsync(this.configService.get<string>('GIT_BIN', 'git'), [
'merge',
'--ff-only',
commitSha,
], { cwd: workDir });
let forcePush = false;
try {
await execFileAsync(gitBin, [
'merge',
'--ff-only',
commitSha,
], { cwd: workDir });
} catch (error) {
const message = String(error instanceof Error ? error.message : error);
if (!isUnrelatedHistoryError(message)) {
throw error;
}
forcePush = true;
await execFileAsync(gitBin, [
'checkout',
'-B',
targetBranch,
commitSha,
], { cwd: workDir });
}
if (forcePush) {
pushArgs.splice(0, pushArgs.length, 'push', '--force-with-lease', 'origin', `HEAD:refs/heads/${targetBranch}`);
}
} else {
await execFileAsync(this.configService.get<string>('GIT_BIN', 'git'), [
await execFileAsync(gitBin, [
'checkout',
'-B',
targetBranch,
@@ -686,11 +712,7 @@ export class AppsService {
], { cwd: workDir });
}
await execFileAsync(this.configService.get<string>('GIT_BIN', 'git'), [
'push',
'origin',
`HEAD:refs/heads/${targetBranch}`,
], { cwd: workDir });
await execFileAsync(gitBin, pushArgs, { cwd: workDir });
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown git promotion failure';
throw new BadRequestException(`${repository} release 브랜치 승격 실패: ${message}`);