feat: Cancel builds!

This commit is contained in:
Andras Bacsai
2022-05-02 14:15:50 +02:00
parent b92bc9eebb
commit 00cab67e73
23 changed files with 207 additions and 65 deletions

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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`);

View File

@@ -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.* ./`);

View File

@@ -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');

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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')) {

View File

@@ -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 . .`);

View File

@@ -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) {

View File

@@ -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`);

View File

@@ -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`);

View File

@@ -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`);

View File

@@ -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)",

View 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
}
};
}
};

View File

@@ -45,15 +45,23 @@ export const post: RequestHandler = async (event) => {
} }
}); });
if (pullmergeRequestId) { if (pullmergeRequestId) {
await buildQueue.add(buildId, { await buildQueue.add(
build_id: buildId, buildId,
type: 'manual', {
...applicationFound, build_id: buildId,
sourceBranch: branch, type: 'manual',
pullmergeRequestId ...applicationFound,
}); sourceBranch: branch,
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,

View File

@@ -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}

View File

@@ -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}

View File

@@ -100,11 +100,15 @@ export const post: RequestHandler = async (event) => {
type: 'webhook_commit' type: 'webhook_commit'
} }
}); });
await buildQueue.add(buildId, { await buildQueue.add(
build_id: buildId, buildId,
type: 'webhook_commit', {
...applicationFound build_id: buildId,
}); type: 'webhook_commit',
...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(
build_id: buildId, buildId,
type: 'webhook_pr', {
...applicationFound, build_id: buildId,
sourceBranch, type: 'webhook_pr',
pullmergeRequestId ...applicationFound,
}); sourceBranch,
pullmergeRequestId
},
{ jobId: buildId }
);
return { return {
status: 200, status: 200,
body: { body: {

View File

@@ -73,11 +73,15 @@ export const post: RequestHandler = async (event) => {
type: 'webhook_commit' type: 'webhook_commit'
} }
}); });
await buildQueue.add(buildId, { await buildQueue.add(
build_id: buildId, buildId,
type: 'webhook_commit', {
...applicationFound build_id: buildId,
}); type: 'webhook_commit',
...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(
build_id: buildId, buildId,
type: 'webhook_mr', {
...applicationFound, build_id: buildId,
sourceBranch, type: 'webhook_mr',
pullmergeRequestId ...applicationFound,
}); sourceBranch,
pullmergeRequestId
},
{ jobId: buildId }
);
return { return {
status: 200, status: 200,
body: { body: {