From d55fe0c251ad488e4b36e748697aa19897dc2be2 Mon Sep 17 00:00:00 2001 From: chyoo Date: Tue, 7 Jul 2026 17:48:09 +0900 Subject: [PATCH] paginate app operations and refine runtime settings layout --- src/apps/apps.service.ts | 24 +++++++++--------------- src/gitea/gitea.service.ts | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/apps/apps.service.ts b/src/apps/apps.service.ts index 2947fdf..58f03f3 100644 --- a/src/apps/apps.service.ts +++ b/src/apps/apps.service.ts @@ -669,8 +669,6 @@ export class AppsService { targetBranch, ], { cwd: workDir }).catch(() => undefined); - const pushArgs: string[] = ['push', 'origin', `HEAD:refs/heads/${targetBranch}`]; - const targetExists = await gitRefExists(workDir, `refs/remotes/origin/${targetBranch}`, gitBin); if (targetExists) { await execFileAsync(gitBin, [ @@ -679,7 +677,6 @@ export class AppsService { targetBranch, `origin/${targetBranch}`, ], { cwd: workDir }); - let forcePush = false; try { await execFileAsync(gitBin, [ 'merge', @@ -691,17 +688,10 @@ export class AppsService { 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}`); + throw new BadRequestException( + `${repository} release 브랜치 승격 실패: ${message}.` + + ' release 브랜치가 다른 시작점 히스토리를 가지고 있어 fast-forward로 병합할 수 없습니다.', + ); } } else { await execFileAsync(gitBin, [ @@ -712,7 +702,11 @@ export class AppsService { ], { cwd: workDir }); } - await execFileAsync(gitBin, pushArgs, { cwd: workDir }); + await execFileAsync(gitBin, [ + 'push', + 'origin', + `HEAD:refs/heads/${targetBranch}`, + ], { cwd: workDir }); } catch (error) { const message = error instanceof Error ? error.message : 'Unknown git promotion failure'; throw new BadRequestException(`${repository} release 브랜치 승격 실패: ${message}`); diff --git a/src/gitea/gitea.service.ts b/src/gitea/gitea.service.ts index 7367df8..39d4f3d 100644 --- a/src/gitea/gitea.service.ts +++ b/src/gitea/gitea.service.ts @@ -175,6 +175,8 @@ export class GiteaService { await this.createDefaultBranches(repo.owner.login, repo.name, repo.default_branch, body); } + await this.setDefaultBranch(repo.owner.login, repo.name, 'develop'); + if (body.createReleaseBranch !== false) { await this.protectReleaseBranch(repo.owner.login, repo.name); } @@ -194,6 +196,8 @@ export class GiteaService { await this.createDefaultBranches(org, repo.name, repo.default_branch, body); } + await this.setDefaultBranch(org, repo.name, 'develop'); + if (body.createReleaseBranch !== false) { await this.protectReleaseBranch(org, repo.name); } @@ -201,6 +205,22 @@ export class GiteaService { return { repo: mapRepo(repo), branches: await this.listBranches(org, repo.name) }; } + private async setDefaultBranch(owner: string, repo: string, branch: string) { + const branches = await this.listBranches(owner, repo); + const hasBranch = Array.isArray(branches.branches) && branches.branches.some((item) => { + return typeof item === 'object' && item && 'name' in item && item.name === branch; + }); + + if (!hasBranch) { + return; + } + + await this.request(`/api/v1/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`, { + method: 'PATCH', + body: JSON.stringify({ default_branch: branch }), + }); + } + async createUserSshKey(username: string, body: { title: string; key: string }) { this.assertToken();