feat: Cancel builds!
This commit is contained in:
		| @@ -2,8 +2,16 @@ import { buildImage } from '$lib/docker'; | |||||||
| import { promises as fs } from 'fs'; | import { promises as fs } from 'fs'; | ||||||
|  |  | ||||||
| const createDockerfile = async (data, image): Promise<void> => { | const createDockerfile = async (data, image): Promise<void> => { | ||||||
| 	const { workdir, port, baseDirectory, secrets, pullmergeRequestId, denoMainFile, denoOptions } = | 	const { | ||||||
| 		data; | 		workdir, | ||||||
|  | 		port, | ||||||
|  | 		baseDirectory, | ||||||
|  | 		secrets, | ||||||
|  | 		pullmergeRequestId, | ||||||
|  | 		denoMainFile, | ||||||
|  | 		denoOptions, | ||||||
|  | 		buildId | ||||||
|  | 	} = data; | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
|  |  | ||||||
| 	let depsFound = false; | 	let depsFound = false; | ||||||
| @@ -14,7 +22,7 @@ const createDockerfile = async (data, image): Promise<void> => { | |||||||
|  |  | ||||||
| 	Dockerfile.push(`FROM ${image}`); | 	Dockerfile.push(`FROM ${image}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	if (secrets.length > 0) { | 	if (secrets.length > 0) { | ||||||
| 		secrets.forEach((secret) => { | 		secrets.forEach((secret) => { | ||||||
| 			if (secret.isBuildSecret) { | 			if (secret.isBuildSecret) { | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ export default async function ({ | |||||||
| 			.toString() | 			.toString() | ||||||
| 			.trim() | 			.trim() | ||||||
| 			.split('\n'); | 			.split('\n'); | ||||||
|  | 		Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 		if (secrets.length > 0) { | 		if (secrets.length > 0) { | ||||||
| 			secrets.forEach((secret) => { | 			secrets.forEach((secret) => { | ||||||
| 				if (secret.isBuildSecret) { | 				if (secret.isBuildSecret) { | ||||||
| @@ -42,6 +43,7 @@ export default async function ({ | |||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		await fs.writeFile(`${dockerFileOut}${dockerFileLocation}`, Dockerfile.join('\n')); | 		await fs.writeFile(`${dockerFileOut}${dockerFileLocation}`, Dockerfile.join('\n')); | ||||||
| 		await buildImage({ applicationId, tag, workdir, docker, buildId, debug, dockerFileLocation }); | 		await buildImage({ applicationId, tag, workdir, docker, buildId, debug, dockerFileLocation }); | ||||||
| 	} catch (error) { | 	} catch (error) { | ||||||
|   | |||||||
| @@ -2,12 +2,12 @@ import { buildCacheImageWithNode, buildImage } from '$lib/docker'; | |||||||
| import { promises as fs } from 'fs'; | import { promises as fs } from 'fs'; | ||||||
|  |  | ||||||
| const createDockerfile = async (data, imageforBuild): Promise<void> => { | const createDockerfile = async (data, imageforBuild): Promise<void> => { | ||||||
| 	const { applicationId, tag, workdir, publishDirectory, baseImage } = data; | 	const { applicationId, tag, workdir, publishDirectory, baseImage, buildId } = data; | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
|  |  | ||||||
| 	Dockerfile.push(`FROM ${imageforBuild}`); | 	Dockerfile.push(`FROM ${imageforBuild}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); | 	Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); | ||||||
| 	if (baseImage.includes('nginx')) { | 	if (baseImage.includes('nginx')) { | ||||||
| 		Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); | 		Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); | ||||||
|   | |||||||
| @@ -2,11 +2,11 @@ import { buildCacheImageForLaravel, buildImage } from '$lib/docker'; | |||||||
| import { promises as fs } from 'fs'; | import { promises as fs } from 'fs'; | ||||||
|  |  | ||||||
| const createDockerfile = async (data, image): Promise<void> => { | const createDockerfile = async (data, image): Promise<void> => { | ||||||
| 	const { workdir, applicationId, tag, baseImage } = data; | 	const { workdir, applicationId, tag, buildId } = data; | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
|  |  | ||||||
| 	Dockerfile.push(`FROM ${image}`); | 	Dockerfile.push(`FROM ${image}`); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`ENV WEB_DOCUMENT_ROOT /app/public`); | 	Dockerfile.push(`ENV WEB_DOCUMENT_ROOT /app/public`); | ||||||
| 	Dockerfile.push(`COPY --chown=application:application composer.* ./`); | 	Dockerfile.push(`COPY --chown=application:application composer.* ./`); | ||||||
|   | |||||||
| @@ -2,13 +2,13 @@ import { buildCacheImageWithNode, buildImage } from '$lib/docker'; | |||||||
| import { promises as fs } from 'fs'; | import { promises as fs } from 'fs'; | ||||||
|  |  | ||||||
| const createDockerfile = async (data, image): Promise<void> => { | const createDockerfile = async (data, image): Promise<void> => { | ||||||
| 	const { applicationId, tag, port, startCommand, workdir, baseDirectory } = data; | 	const { buildId, applicationId, tag, port, startCommand, workdir, baseDirectory } = data; | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
| 	const isPnpm = startCommand.includes('pnpm'); | 	const isPnpm = startCommand.includes('pnpm'); | ||||||
|  |  | ||||||
| 	Dockerfile.push(`FROM ${image}`); | 	Dockerfile.push(`FROM ${image}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	if (isPnpm) { | 	if (isPnpm) { | ||||||
| 		Dockerfile.push('RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm'); | 		Dockerfile.push('RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm'); | ||||||
| 		Dockerfile.push('RUN pnpm add -g pnpm'); | 		Dockerfile.push('RUN pnpm add -g pnpm'); | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ import { checkPnpm } from './common'; | |||||||
|  |  | ||||||
| const createDockerfile = async (data, image): Promise<void> => { | const createDockerfile = async (data, image): Promise<void> => { | ||||||
| 	const { | 	const { | ||||||
|  | 		buildId, | ||||||
| 		workdir, | 		workdir, | ||||||
| 		port, | 		port, | ||||||
| 		installCommand, | 		installCommand, | ||||||
| @@ -17,7 +18,7 @@ const createDockerfile = async (data, image): Promise<void> => { | |||||||
| 	const isPnpm = checkPnpm(installCommand, buildCommand, startCommand); | 	const isPnpm = checkPnpm(installCommand, buildCommand, startCommand); | ||||||
| 	Dockerfile.push(`FROM ${image}`); | 	Dockerfile.push(`FROM ${image}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	if (secrets.length > 0) { | 	if (secrets.length > 0) { | ||||||
| 		secrets.forEach((secret) => { | 		secrets.forEach((secret) => { | ||||||
| 			if (secret.isBuildSecret) { | 			if (secret.isBuildSecret) { | ||||||
|   | |||||||
| @@ -11,14 +11,15 @@ const createDockerfile = async (data, image): Promise<void> => { | |||||||
| 		startCommand, | 		startCommand, | ||||||
| 		baseDirectory, | 		baseDirectory, | ||||||
| 		secrets, | 		secrets, | ||||||
| 		pullmergeRequestId | 		pullmergeRequestId, | ||||||
|  | 		buildId | ||||||
| 	} = data; | 	} = data; | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
| 	const isPnpm = checkPnpm(installCommand, buildCommand, startCommand); | 	const isPnpm = checkPnpm(installCommand, buildCommand, startCommand); | ||||||
|  |  | ||||||
| 	Dockerfile.push(`FROM ${image}`); | 	Dockerfile.push(`FROM ${image}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	if (secrets.length > 0) { | 	if (secrets.length > 0) { | ||||||
| 		secrets.forEach((secret) => { | 		secrets.forEach((secret) => { | ||||||
| 			if (secret.isBuildSecret) { | 			if (secret.isBuildSecret) { | ||||||
|   | |||||||
| @@ -11,13 +11,14 @@ const createDockerfile = async (data, image): Promise<void> => { | |||||||
| 		startCommand, | 		startCommand, | ||||||
| 		baseDirectory, | 		baseDirectory, | ||||||
| 		secrets, | 		secrets, | ||||||
| 		pullmergeRequestId | 		pullmergeRequestId, | ||||||
|  | 		buildId | ||||||
| 	} = data; | 	} = data; | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
| 	const isPnpm = checkPnpm(installCommand, buildCommand, startCommand); | 	const isPnpm = checkPnpm(installCommand, buildCommand, startCommand); | ||||||
| 	Dockerfile.push(`FROM ${image}`); | 	Dockerfile.push(`FROM ${image}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	if (secrets.length > 0) { | 	if (secrets.length > 0) { | ||||||
| 		secrets.forEach((secret) => { | 		secrets.forEach((secret) => { | ||||||
| 			if (secret.isBuildSecret) { | 			if (secret.isBuildSecret) { | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ import { buildImage } from '$lib/docker'; | |||||||
| import { promises as fs } from 'fs'; | import { promises as fs } from 'fs'; | ||||||
|  |  | ||||||
| const createDockerfile = async (data, image, htaccessFound): Promise<void> => { | const createDockerfile = async (data, image, htaccessFound): Promise<void> => { | ||||||
| 	const { workdir, baseDirectory } = data; | 	const { workdir, baseDirectory, buildId } = data; | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
| 	let composerFound = false; | 	let composerFound = false; | ||||||
| 	try { | 	try { | ||||||
| @@ -11,7 +11,7 @@ const createDockerfile = async (data, image, htaccessFound): Promise<void> => { | |||||||
| 	} catch (error) {} | 	} catch (error) {} | ||||||
|  |  | ||||||
| 	Dockerfile.push(`FROM ${image}`); | 	Dockerfile.push(`FROM ${image}`); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`COPY .${baseDirectory || ''} /app`); | 	Dockerfile.push(`COPY .${baseDirectory || ''} /app`); | ||||||
| 	if (htaccessFound) { | 	if (htaccessFound) { | ||||||
|   | |||||||
| @@ -10,12 +10,13 @@ const createDockerfile = async (data, image): Promise<void> => { | |||||||
| 		pullmergeRequestId, | 		pullmergeRequestId, | ||||||
| 		pythonWSGI, | 		pythonWSGI, | ||||||
| 		pythonModule, | 		pythonModule, | ||||||
| 		pythonVariable | 		pythonVariable, | ||||||
|  | 		buildId | ||||||
| 	} = data; | 	} = data; | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
| 	Dockerfile.push(`FROM ${image}`); | 	Dockerfile.push(`FROM ${image}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	if (secrets.length > 0) { | 	if (secrets.length > 0) { | ||||||
| 		secrets.forEach((secret) => { | 		secrets.forEach((secret) => { | ||||||
| 			if (secret.isBuildSecret) { | 			if (secret.isBuildSecret) { | ||||||
|   | |||||||
| @@ -2,11 +2,11 @@ import { buildCacheImageWithNode, buildImage } from '$lib/docker'; | |||||||
| import { promises as fs } from 'fs'; | import { promises as fs } from 'fs'; | ||||||
|  |  | ||||||
| const createDockerfile = async (data, image): Promise<void> => { | const createDockerfile = async (data, image): Promise<void> => { | ||||||
| 	const { applicationId, tag, workdir, publishDirectory, baseImage } = data; | 	const { applicationId, tag, workdir, publishDirectory, baseImage, buildId } = data; | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
|  |  | ||||||
| 	Dockerfile.push(`FROM ${image}`); | 	Dockerfile.push(`FROM ${image}`); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); | 	Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); | ||||||
| 	if (baseImage.includes('nginx')) { | 	if (baseImage.includes('nginx')) { | ||||||
|   | |||||||
| @@ -4,11 +4,11 @@ import { promises as fs } from 'fs'; | |||||||
| import TOML from '@iarna/toml'; | import TOML from '@iarna/toml'; | ||||||
|  |  | ||||||
| const createDockerfile = async (data, image, name): Promise<void> => { | const createDockerfile = async (data, image, name): Promise<void> => { | ||||||
| 	const { workdir, port, applicationId, tag } = data; | 	const { workdir, port, applicationId, tag, buildId } = data; | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
| 	Dockerfile.push(`FROM ${image}`); | 	Dockerfile.push(`FROM ${image}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/target target`); | 	Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/target target`); | ||||||
| 	Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /usr/local/cargo /usr/local/cargo`); | 	Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /usr/local/cargo /usr/local/cargo`); | ||||||
| 	Dockerfile.push(`COPY . .`); | 	Dockerfile.push(`COPY . .`); | ||||||
|   | |||||||
| @@ -11,13 +11,14 @@ const createDockerfile = async (data, image): Promise<void> => { | |||||||
| 		publishDirectory, | 		publishDirectory, | ||||||
| 		secrets, | 		secrets, | ||||||
| 		pullmergeRequestId, | 		pullmergeRequestId, | ||||||
| 		baseImage | 		baseImage, | ||||||
|  | 		buildId | ||||||
| 	} = data; | 	} = data; | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
|  |  | ||||||
| 	Dockerfile.push(`FROM ${image}`); | 	Dockerfile.push(`FROM ${image}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	if (secrets.length > 0) { | 	if (secrets.length > 0) { | ||||||
| 		secrets.forEach((secret) => { | 		secrets.forEach((secret) => { | ||||||
| 			if (secret.isBuildSecret) { | 			if (secret.isBuildSecret) { | ||||||
|   | |||||||
| @@ -2,12 +2,12 @@ import { buildCacheImageWithNode, buildImage } from '$lib/docker'; | |||||||
| import { promises as fs } from 'fs'; | import { promises as fs } from 'fs'; | ||||||
|  |  | ||||||
| const createDockerfile = async (data, image): Promise<void> => { | const createDockerfile = async (data, image): Promise<void> => { | ||||||
| 	const { applicationId, tag, workdir, publishDirectory, baseImage } = data; | 	const { applicationId, tag, workdir, publishDirectory, baseImage, buildId } = data; | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
|  |  | ||||||
| 	Dockerfile.push(`FROM ${image}`); | 	Dockerfile.push(`FROM ${image}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); | 	Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); | ||||||
| 	if (baseImage.includes('nginx')) { | 	if (baseImage.includes('nginx')) { | ||||||
| 		Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); | 		Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); | ||||||
|   | |||||||
| @@ -2,12 +2,12 @@ import { buildCacheImageWithNode, buildImage } from '$lib/docker'; | |||||||
| import { promises as fs } from 'fs'; | import { promises as fs } from 'fs'; | ||||||
|  |  | ||||||
| const createDockerfile = async (data, image): Promise<void> => { | const createDockerfile = async (data, image): Promise<void> => { | ||||||
| 	const { applicationId, tag, workdir, publishDirectory, baseImage } = data; | 	const { applicationId, tag, workdir, publishDirectory, baseImage, buildId } = data; | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
|  |  | ||||||
| 	Dockerfile.push(`FROM ${image}`); | 	Dockerfile.push(`FROM ${image}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); | 	Dockerfile.push(`COPY --from=${applicationId}:${tag}-cache /app/${publishDirectory} ./`); | ||||||
| 	if (baseImage.includes('nginx')) { | 	if (baseImage.includes('nginx')) { | ||||||
| 		Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); | 		Dockerfile.push(`COPY /nginx.conf /etc/nginx/nginx.conf`); | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ export async function buildCacheImageForLaravel(data, imageForBuild) { | |||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
| 	Dockerfile.push(`FROM ${imageForBuild}`); | 	Dockerfile.push(`FROM ${imageForBuild}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	if (secrets.length > 0) { | 	if (secrets.length > 0) { | ||||||
| 		secrets.forEach((secret) => { | 		secrets.forEach((secret) => { | ||||||
| 			if (secret.isBuildSecret) { | 			if (secret.isBuildSecret) { | ||||||
| @@ -49,7 +49,7 @@ export async function buildCacheImageWithNode(data, imageForBuild) { | |||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
| 	Dockerfile.push(`FROM ${imageForBuild}`); | 	Dockerfile.push(`FROM ${imageForBuild}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push(`LABEL coolify.image=true`); | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	if (secrets.length > 0) { | 	if (secrets.length > 0) { | ||||||
| 		secrets.forEach((secret) => { | 		secrets.forEach((secret) => { | ||||||
| 			if (secret.isBuildSecret) { | 			if (secret.isBuildSecret) { | ||||||
| @@ -94,11 +94,13 @@ export async function buildCacheImageWithCargo(data, imageForBuild) { | |||||||
| 	} = data; | 	} = data; | ||||||
| 	const Dockerfile: Array<string> = []; | 	const Dockerfile: Array<string> = []; | ||||||
| 	Dockerfile.push(`FROM ${imageForBuild} as planner-${applicationId}`); | 	Dockerfile.push(`FROM ${imageForBuild} as planner-${applicationId}`); | ||||||
|  | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push('RUN cargo install cargo-chef'); | 	Dockerfile.push('RUN cargo install cargo-chef'); | ||||||
| 	Dockerfile.push('COPY . .'); | 	Dockerfile.push('COPY . .'); | ||||||
| 	Dockerfile.push('RUN cargo chef prepare --recipe-path recipe.json'); | 	Dockerfile.push('RUN cargo chef prepare --recipe-path recipe.json'); | ||||||
| 	Dockerfile.push(`FROM ${imageForBuild}`); | 	Dockerfile.push(`FROM ${imageForBuild}`); | ||||||
|  | 	Dockerfile.push(`LABEL coolify.buildId=${buildId}`); | ||||||
| 	Dockerfile.push('WORKDIR /app'); | 	Dockerfile.push('WORKDIR /app'); | ||||||
| 	Dockerfile.push('RUN cargo install cargo-chef'); | 	Dockerfile.push('RUN cargo install cargo-chef'); | ||||||
| 	Dockerfile.push(`COPY --from=planner-${applicationId} /app/recipe.json recipe.json`); | 	Dockerfile.push(`COPY --from=planner-${applicationId} /app/recipe.json recipe.json`); | ||||||
|   | |||||||
| @@ -184,8 +184,10 @@ | |||||||
| 		"git_source": "Git Source", | 		"git_source": "Git Source", | ||||||
| 		"git_repository": "Git Repository", | 		"git_repository": "Git Repository", | ||||||
| 		"build_pack": "Build Pack", | 		"build_pack": "Build Pack", | ||||||
| 		"base_image": "Base Image", | 		"base_image": "Deplyoment Image", | ||||||
| 		"base_build_image": "Base Build Image", | 		"base_image_explainer": "Image that will be used for the deployment.", | ||||||
|  | 		"base_build_image": "Build Image", | ||||||
|  | 		"base_build_image_explainer": "Image that will be used during the build process.", | ||||||
| 		"destination": "Destination", | 		"destination": "Destination", | ||||||
| 		"application": "Application", | 		"application": "Application", | ||||||
| 		"url_fqdn": "URL (FQDN)", | 		"url_fqdn": "URL (FQDN)", | ||||||
|   | |||||||
							
								
								
									
										71
									
								
								src/routes/applications/[id]/cancel.json.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/routes/applications/[id]/cancel.json.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | |||||||
|  | import { asyncExecShell, getEngine, removeDestinationDocker, saveBuildLog } from '$lib/common'; | ||||||
|  | import { buildQueue } from '$lib/queues'; | ||||||
|  | import type { RequestHandler } from '@sveltejs/kit'; | ||||||
|  | import * as db from '$lib/database'; | ||||||
|  |  | ||||||
|  | export const post: RequestHandler = async (event) => { | ||||||
|  | 	const { buildId, applicationId } = await event.request.json(); | ||||||
|  | 	if (!buildId) { | ||||||
|  | 		return { | ||||||
|  | 			status: 500, | ||||||
|  | 			body: { | ||||||
|  | 				message: 'Build ID not found.' | ||||||
|  | 			} | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | 	try { | ||||||
|  | 		let count = 0; | ||||||
|  | 		await new Promise(async (resolve, reject) => { | ||||||
|  | 			const job = await buildQueue.getJob(buildId); | ||||||
|  | 			const { | ||||||
|  | 				destinationDocker: { engine } | ||||||
|  | 			} = job.data; | ||||||
|  | 			const host = getEngine(engine); | ||||||
|  | 			let interval = setInterval(async () => { | ||||||
|  | 				console.log(`Checking build ${buildId}, try ${count}`); | ||||||
|  | 				if (count > 100) { | ||||||
|  | 					clearInterval(interval); | ||||||
|  | 					reject(new Error('Could not cancel build.')); | ||||||
|  | 				} | ||||||
|  | 				try { | ||||||
|  | 					const { stdout: buildContainers } = await asyncExecShell( | ||||||
|  | 						`DOCKER_HOST=${host} docker container ls --filter "label=coolify.buildId=${buildId}" --format '{{json .}}'` | ||||||
|  | 					); | ||||||
|  | 					if (buildContainers) { | ||||||
|  | 						const containersArray = buildContainers.trim().split('\n'); | ||||||
|  | 						for (const container of containersArray) { | ||||||
|  | 							const containerObj = JSON.parse(container); | ||||||
|  | 							const id = containerObj.ID; | ||||||
|  | 							if (!containerObj.Names.startsWith(`${applicationId}`)) { | ||||||
|  | 								await removeDestinationDocker({ id, engine }); | ||||||
|  | 								clearInterval(interval); | ||||||
|  | 								await saveBuildLog({ | ||||||
|  | 									line: 'Canceled by user!', | ||||||
|  | 									buildId: job.data.build_id, | ||||||
|  | 									applicationId: job.data.id | ||||||
|  | 								}); | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 					count++; | ||||||
|  | 				} catch (error) {} | ||||||
|  | 			}, 100); | ||||||
|  |  | ||||||
|  | 			resolve('Canceled'); | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		return { | ||||||
|  | 			status: 200, | ||||||
|  | 			body: { | ||||||
|  | 				message: 'Build canceled.' | ||||||
|  | 			} | ||||||
|  | 		}; | ||||||
|  | 	} catch (error) { | ||||||
|  | 		return { | ||||||
|  | 			status: 500, | ||||||
|  | 			body: { | ||||||
|  | 				message: error.message | ||||||
|  | 			} | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
| @@ -45,15 +45,23 @@ export const post: RequestHandler = async (event) => { | |||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| 		if (pullmergeRequestId) { | 		if (pullmergeRequestId) { | ||||||
| 			await buildQueue.add(buildId, { | 			await buildQueue.add( | ||||||
|  | 				buildId, | ||||||
|  | 				{ | ||||||
| 					build_id: buildId, | 					build_id: buildId, | ||||||
| 					type: 'manual', | 					type: 'manual', | ||||||
| 					...applicationFound, | 					...applicationFound, | ||||||
| 					sourceBranch: branch, | 					sourceBranch: branch, | ||||||
| 					pullmergeRequestId | 					pullmergeRequestId | ||||||
| 			}); | 				}, | ||||||
|  | 				{ jobId: buildId } | ||||||
|  | 			); | ||||||
| 		} else { | 		} else { | ||||||
| 			await buildQueue.add(buildId, { build_id: buildId, type: 'manual', ...applicationFound }); | 			await buildQueue.add( | ||||||
|  | 				buildId, | ||||||
|  | 				{ build_id: buildId, type: 'manual', ...applicationFound }, | ||||||
|  | 				{ jobId: buildId } | ||||||
|  | 			); | ||||||
| 		} | 		} | ||||||
| 		return { | 		return { | ||||||
| 			status: 200, | 			status: 200, | ||||||
|   | |||||||
| @@ -339,6 +339,7 @@ | |||||||
| 						isClearable={false} | 						isClearable={false} | ||||||
| 					/> | 					/> | ||||||
| 				</div> | 				</div> | ||||||
|  | 				<Explainer text={$t('application.base_image_explainer')} /> | ||||||
| 			</div> | 			</div> | ||||||
| 			{#if application.buildCommand || application.buildPack === 'rust' || application.buildPack === 'laravel'} | 			{#if application.buildCommand || application.buildPack === 'rust' || application.buildPack === 'laravel'} | ||||||
| 				<div class="grid grid-cols-2 items-center pb-8"> | 				<div class="grid grid-cols-2 items-center pb-8"> | ||||||
| @@ -360,6 +361,8 @@ | |||||||
| 					</div> | 					</div> | ||||||
| 					{#if application.buildPack === 'laravel'} | 					{#if application.buildPack === 'laravel'} | ||||||
| 						<Explainer text="For building frontend assets with webpack." /> | 						<Explainer text="For building frontend assets with webpack." /> | ||||||
|  | 					{:else} | ||||||
|  | 						<Explainer text={$t('application.base_build_image_explainer')} /> | ||||||
| 					{/if} | 					{/if} | ||||||
| 				</div> | 				</div> | ||||||
| 			{/if} | 			{/if} | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|  |  | ||||||
| 	import Loading from '$lib/components/Loading.svelte'; | 	import Loading from '$lib/components/Loading.svelte'; | ||||||
| 	import LoadingLogs from '../_Loading.svelte'; | 	import LoadingLogs from '../_Loading.svelte'; | ||||||
| 	import { get } from '$lib/api'; | 	import { get, post } from '$lib/api'; | ||||||
| 	import { errorNotification } from '$lib/form'; | 	import { errorNotification } from '$lib/form'; | ||||||
| 	import { t } from '$lib/translations'; | 	import { t } from '$lib/translations'; | ||||||
|  |  | ||||||
| @@ -67,6 +67,12 @@ | |||||||
| 			return errorNotification(error); | 			return errorNotification(error); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	async function cancelBuild() { | ||||||
|  | 		return await post(`/applications/${id}/cancel.json`, { | ||||||
|  | 			buildId, | ||||||
|  | 			applicationId: id | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
| 	onDestroy(() => { | 	onDestroy(() => { | ||||||
| 		clearInterval(streamInterval); | 		clearInterval(streamInterval); | ||||||
| 		clearInterval(followingInterval); | 		clearInterval(followingInterval); | ||||||
| @@ -111,7 +117,26 @@ | |||||||
| 						<line x1="16" y1="12" x2="12" y2="16" /> | 						<line x1="16" y1="12" x2="12" y2="16" /> | ||||||
| 					</svg> | 					</svg> | ||||||
| 				</button> | 				</button> | ||||||
|  | 				{#if currentStatus === 'running'} | ||||||
|  | 					<button on:click={cancelBuild} class="bg-transparent" data-tooltip="Cancel build"> | ||||||
|  | 						<svg | ||||||
|  | 							xmlns="http://www.w3.org/2000/svg" | ||||||
|  | 							class="w-6 h-6" | ||||||
|  | 							viewBox="0 0 24 24" | ||||||
|  | 							stroke-width="1.5" | ||||||
|  | 							stroke="currentColor" | ||||||
|  | 							fill="none" | ||||||
|  | 							stroke-linecap="round" | ||||||
|  | 							stroke-linejoin="round" | ||||||
|  | 						> | ||||||
|  | 							<path stroke="none" d="M0 0h24v24H0z" fill="none" /> | ||||||
|  | 							<line x1="18" y1="6" x2="6" y2="18" /> | ||||||
|  | 							<line x1="6" y1="6" x2="18" y2="18" /> | ||||||
|  | 						</svg> | ||||||
|  | 					</button> | ||||||
|  | 				{/if} | ||||||
| 			</div> | 			</div> | ||||||
|  |  | ||||||
| 			<div | 			<div | ||||||
| 				class="font-mono leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12 overflow-y-scroll scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200" | 				class="font-mono leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12 overflow-y-scroll scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200" | ||||||
| 				bind:this={logsEl} | 				bind:this={logsEl} | ||||||
|   | |||||||
| @@ -100,11 +100,15 @@ export const post: RequestHandler = async (event) => { | |||||||
| 						type: 'webhook_commit' | 						type: 'webhook_commit' | ||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
| 				await buildQueue.add(buildId, { | 				await buildQueue.add( | ||||||
|  | 					buildId, | ||||||
|  | 					{ | ||||||
| 						build_id: buildId, | 						build_id: buildId, | ||||||
| 						type: 'webhook_commit', | 						type: 'webhook_commit', | ||||||
| 						...applicationFound | 						...applicationFound | ||||||
| 				}); | 					}, | ||||||
|  | 					{ jobId: buildId } | ||||||
|  | 				); | ||||||
| 				return { | 				return { | ||||||
| 					status: 200, | 					status: 200, | ||||||
| 					body: { | 					body: { | ||||||
| @@ -160,13 +164,17 @@ export const post: RequestHandler = async (event) => { | |||||||
| 								type: 'webhook_pr' | 								type: 'webhook_pr' | ||||||
| 							} | 							} | ||||||
| 						}); | 						}); | ||||||
| 						await buildQueue.add(buildId, { | 						await buildQueue.add( | ||||||
|  | 							buildId, | ||||||
|  | 							{ | ||||||
| 								build_id: buildId, | 								build_id: buildId, | ||||||
| 								type: 'webhook_pr', | 								type: 'webhook_pr', | ||||||
| 								...applicationFound, | 								...applicationFound, | ||||||
| 								sourceBranch, | 								sourceBranch, | ||||||
| 								pullmergeRequestId | 								pullmergeRequestId | ||||||
| 						}); | 							}, | ||||||
|  | 							{ jobId: buildId } | ||||||
|  | 						); | ||||||
| 						return { | 						return { | ||||||
| 							status: 200, | 							status: 200, | ||||||
| 							body: { | 							body: { | ||||||
|   | |||||||
| @@ -73,11 +73,15 @@ export const post: RequestHandler = async (event) => { | |||||||
| 						type: 'webhook_commit' | 						type: 'webhook_commit' | ||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
| 				await buildQueue.add(buildId, { | 				await buildQueue.add( | ||||||
|  | 					buildId, | ||||||
|  | 					{ | ||||||
| 						build_id: buildId, | 						build_id: buildId, | ||||||
| 						type: 'webhook_commit', | 						type: 'webhook_commit', | ||||||
| 						...applicationFound | 						...applicationFound | ||||||
| 				}); | 					}, | ||||||
|  | 					{ jobId: buildId } | ||||||
|  | 				); | ||||||
| 				return { | 				return { | ||||||
| 					status: 200, | 					status: 200, | ||||||
| 					body: { | 					body: { | ||||||
| @@ -156,13 +160,17 @@ export const post: RequestHandler = async (event) => { | |||||||
| 								type: 'webhook_mr' | 								type: 'webhook_mr' | ||||||
| 							} | 							} | ||||||
| 						}); | 						}); | ||||||
| 						await buildQueue.add(buildId, { | 						await buildQueue.add( | ||||||
|  | 							buildId, | ||||||
|  | 							{ | ||||||
| 								build_id: buildId, | 								build_id: buildId, | ||||||
| 								type: 'webhook_mr', | 								type: 'webhook_mr', | ||||||
| 								...applicationFound, | 								...applicationFound, | ||||||
| 								sourceBranch, | 								sourceBranch, | ||||||
| 								pullmergeRequestId | 								pullmergeRequestId | ||||||
| 						}); | 							}, | ||||||
|  | 							{ jobId: buildId } | ||||||
|  | 						); | ||||||
| 						return { | 						return { | ||||||
| 							status: 200, | 							status: 200, | ||||||
| 							body: { | 							body: { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Andras Bacsai
					Andras Bacsai