feat: add quick deploy for launcher backend builds
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
+62
-22
@@ -954,31 +954,70 @@ export class AppsService {
|
||||
async createDeploymentJob(body: CreateDeploymentJobDto, requester?: AdminRequester) {
|
||||
const namespace = normalizeNamespace(body.namespace);
|
||||
const environment = body.environment.trim();
|
||||
const release = await this.prisma.appRelease.findUnique({
|
||||
where: { id: body.releaseId },
|
||||
include: {
|
||||
app: {
|
||||
include: {
|
||||
components: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (body.releaseId && body.buildJobId) {
|
||||
throw new BadRequestException('릴리즈 또는 빌드 중 하나만 배포 대상으로 선택할 수 있습니다.');
|
||||
}
|
||||
|
||||
if (!release) {
|
||||
const release = body.releaseId
|
||||
? await this.prisma.appRelease.findUnique({
|
||||
where: { id: body.releaseId },
|
||||
include: {
|
||||
app: {
|
||||
include: {
|
||||
components: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
: null;
|
||||
const quickBuild = body.buildJobId
|
||||
? await this.prisma.buildJob.findUnique({
|
||||
where: { id: body.buildJobId },
|
||||
include: {
|
||||
component: {
|
||||
include: {
|
||||
app: {
|
||||
include: { components: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
: null;
|
||||
|
||||
if (body.releaseId && !release) {
|
||||
throw new NotFoundException('릴리즈를 찾을 수 없습니다.');
|
||||
}
|
||||
|
||||
if (release.status !== 'SUCCEEDED') {
|
||||
if (body.buildJobId && !quickBuild) {
|
||||
throw new NotFoundException('빌드 작업을 찾을 수 없습니다.');
|
||||
}
|
||||
if (!release && !quickBuild) {
|
||||
throw new BadRequestException('배포할 릴리즈 또는 빌드를 선택하세요.');
|
||||
}
|
||||
if (release && release.status !== 'SUCCEEDED') {
|
||||
throw new BadRequestException('성공한 릴리즈만 배포할 수 있습니다.');
|
||||
}
|
||||
if (quickBuild && quickBuild.status !== 'SUCCEEDED') {
|
||||
throw new BadRequestException('성공한 빌드만 빠른 배포할 수 있습니다.');
|
||||
}
|
||||
if (quickBuild && !['CONTAINER', 'STATIC_WEB'].includes(quickBuild.component.type)) {
|
||||
throw new BadRequestException('컨테이너 이미지 빌드만 빠른 배포할 수 있습니다.');
|
||||
}
|
||||
if (quickBuild && !quickBuild.image) {
|
||||
throw new BadRequestException('배포할 컨테이너 이미지가 없습니다.');
|
||||
}
|
||||
|
||||
const imageTags = parseReleaseImageTags(release.imageTags);
|
||||
const images = imageTags.images;
|
||||
const app = release?.app ?? quickBuild!.component.app;
|
||||
const images = release
|
||||
? parseReleaseImageTags(release.imageTags).images
|
||||
: { [quickBuild!.component.name]: quickBuild!.image! };
|
||||
const deploymentLabel = release
|
||||
? `${app.name} ${release.version}`
|
||||
: `${app.name} ${quickBuild!.component.name} ${quickBuild!.commitSha?.slice(0, 7) ?? 'quick'}`;
|
||||
const requestedResources = body.resources;
|
||||
const runtimeProfile = await this.prisma.runtimeEnvProfile.findFirst({
|
||||
where: {
|
||||
appId: release.appId,
|
||||
appId: app.id,
|
||||
environment,
|
||||
namespace,
|
||||
},
|
||||
@@ -1002,8 +1041,8 @@ export class AppsService {
|
||||
|
||||
const deploymentJob = await this.prisma.deploymentJob.create({
|
||||
data: {
|
||||
appId: release.appId,
|
||||
releaseId: release.id,
|
||||
appId: app.id,
|
||||
releaseId: release?.id,
|
||||
environment,
|
||||
namespace,
|
||||
status: 'RUNNING',
|
||||
@@ -1011,7 +1050,8 @@ export class AppsService {
|
||||
...this.requesterData(requester),
|
||||
startedAt: new Date(),
|
||||
logs: [
|
||||
`[running] deployment started: ${release.app.name} ${release.version}`,
|
||||
`[running] deployment started: ${deploymentLabel}`,
|
||||
...(quickBuild ? [`[source] quick build ${quickBuild.id} ${quickBuild.image}`] : []),
|
||||
`[target] environment=${environment} namespace=${namespace}`,
|
||||
].join('\n'),
|
||||
},
|
||||
@@ -1026,7 +1066,7 @@ export class AppsService {
|
||||
|
||||
for (const [componentName, image] of Object.entries(images)) {
|
||||
const deploymentName = sanitizeK8sName(componentName);
|
||||
const component = release.app.components.find((item) => item.name === componentName);
|
||||
const component = app.components.find((item) => item.name === componentName);
|
||||
const workloadType = normalizeWorkloadType(component?.workloadType, component?.type);
|
||||
const deploymentExists = workloadType === 'StatefulSet'
|
||||
? await this.statefulSetExists(namespace, deploymentName)
|
||||
@@ -1173,7 +1213,7 @@ export class AppsService {
|
||||
}
|
||||
}
|
||||
|
||||
if (body.updateLauncherAppVersion !== false) {
|
||||
if (release && body.updateLauncherAppVersion !== false) {
|
||||
try {
|
||||
await this.launcherService.publishAppReleaseToLauncher(release.id);
|
||||
logs.push('[launcher] app version updated');
|
||||
@@ -1182,7 +1222,7 @@ export class AppsService {
|
||||
logs.push(`[launcher] app version update failed: ${launcherMessage}`);
|
||||
}
|
||||
} else {
|
||||
logs.push('[launcher] app version update skipped');
|
||||
logs.push(quickBuild ? '[launcher] app version update skipped for quick deployment' : '[launcher] app version update skipped');
|
||||
}
|
||||
|
||||
logs.push('[done] deployment completed');
|
||||
|
||||
+6
-1
@@ -220,8 +220,13 @@ export class DeploymentResourceLimitsDto {
|
||||
}
|
||||
|
||||
export class CreateDeploymentJobDto {
|
||||
@IsOptional()
|
||||
@IsUUID()
|
||||
releaseId!: string;
|
||||
releaseId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsUUID()
|
||||
buildJobId?: string;
|
||||
|
||||
@IsString()
|
||||
environment!: string;
|
||||
|
||||
Reference in New Issue
Block a user