feat: force rebuild + env.PORT for port + public repo build

This commit is contained in:
Andras Bacsai
2022-08-18 16:33:32 +02:00
parent 4e7e9b2cfc
commit 0922fd66a4
11 changed files with 286 additions and 197 deletions

View File

@@ -56,6 +56,7 @@ import * as buildpacks from '../lib/buildPacks';
baseImage, baseImage,
baseBuildImage, baseBuildImage,
deploymentType, deploymentType,
forceRebuild
} = message } = message
let { let {
branch, branch,
@@ -174,7 +175,6 @@ import * as buildpacks from '../lib/buildPacks';
if (!pullmergeRequestId) { if (!pullmergeRequestId) {
if (configHash !== currentHash) { if (configHash !== currentHash) {
deployNeeded = true; deployNeeded = true;
if (configHash) { if (configHash) {
@@ -198,6 +198,8 @@ import * as buildpacks from '../lib/buildPacks';
// //
} }
await copyBaseConfigurationFiles(buildPack, workdir, buildId, applicationId, baseImage); await copyBaseConfigurationFiles(buildPack, workdir, buildId, applicationId, baseImage);
if (forceRebuild) deployNeeded = true
if (!imageFound || deployNeeded) { if (!imageFound || deployNeeded) {
// if (true) { // if (true) {
if (buildpacks[buildPack]) if (buildpacks[buildPack])
@@ -248,7 +250,9 @@ import * as buildpacks from '../lib/buildPacks';
} catch (error) { } catch (error) {
// //
} }
const envs = []; const envs = [
`PORT=${port}`
];
if (secrets.length > 0) { if (secrets.length > 0) {
secrets.forEach((secret) => { secrets.forEach((secret) => {
if (pullmergeRequestId) { if (pullmergeRequestId) {

View File

@@ -1189,9 +1189,7 @@ export async function checkExposedPort({ id, configuredPort, exposePort, dockerI
} }
} }
} else { } else {
const availablePort = await getFreeExposedPort(id, exposePort, dockerId, remoteIpAddress); const availablePort = await getFreeExposedPort(id, exposePort, dockerId, remoteIpAddress);
console.log(availablePort, exposePort)
if (availablePort.toString() !== exposePort.toString()) { if (availablePort.toString() !== exposePort.toString()) {
throw { status: 500, message: `Port ${exposePort} is already in use.` } throw { status: 500, message: `Port ${exposePort} is already in use.` }
} }

View File

@@ -71,7 +71,6 @@ export async function removeContainer({
}): Promise<void> { }): Promise<void> {
try { try {
const { stdout } = await executeDockerCmd({ dockerId, command: `docker inspect --format '{{json .State}}' ${id}` }) const { stdout } = await executeDockerCmd({ dockerId, command: `docker inspect --format '{{json .State}}' ${id}` })
console.log(id)
if (JSON.parse(stdout).Running) { if (JSON.parse(stdout).Running) {
await executeDockerCmd({ dockerId, command: `docker stop -t 0 ${id}` }) await executeDockerCmd({ dockerId, command: `docker stop -t 0 ${id}` })
await executeDockerCmd({ dockerId, command: `docker rm ${id}` }) await executeDockerCmd({ dockerId, command: `docker rm ${id}` })

View File

@@ -428,7 +428,7 @@ export async function deployApplication(request: FastifyRequest<DeployApplicatio
try { try {
const { id } = request.params const { id } = request.params
const teamId = request.user?.teamId; const teamId = request.user?.teamId;
const { pullmergeRequestId = null, branch } = request.body const { pullmergeRequestId = null, branch, forceRebuild } = request.body
const buildId = cuid(); const buildId = cuid();
const application = await getApplicationFromDB(id, teamId); const application = await getApplicationFromDB(id, teamId);
if (application) { if (application) {
@@ -467,13 +467,15 @@ export async function deployApplication(request: FastifyRequest<DeployApplicatio
type: 'manual', type: 'manual',
...application, ...application,
sourceBranch: branch, sourceBranch: branch,
pullmergeRequestId pullmergeRequestId,
forceRebuild
}); });
} else { } else {
scheduler.workers.get('deployApplication').postMessage({ scheduler.workers.get('deployApplication').postMessage({
build_id: buildId, build_id: buildId,
type: 'manual', type: 'manual',
...application ...application,
forceRebuild
}); });
} }

View File

@@ -44,7 +44,7 @@ export interface CheckDNS extends OnlyId {
} }
export interface DeployApplication { export interface DeployApplication {
Querystring: { domain: string } Querystring: { domain: string }
Body: { pullmergeRequestId: string | null, branch: string } Body: { pullmergeRequestId: string | null, branch: string, forceRebuild?: boolean }
} }
export interface GetImages { export interface GetImages {
Body: { buildPack: string, deploymentType: string } Body: { buildPack: string, deploymentType: string }
@@ -115,7 +115,8 @@ export interface CancelDeployment {
export interface DeployApplication extends OnlyId { export interface DeployApplication extends OnlyId {
Body: { Body: {
pullmergeRequestId: string | null, pullmergeRequestId: string | null,
branch: string branch: string,
forceRebuild?: boolean
} }
} }

View File

@@ -77,9 +77,9 @@
const { id } = $page.params; const { id } = $page.params;
async function handleDeploySubmit() { async function handleDeploySubmit(forceRebuild = false) {
try { try {
const { buildId } = await post(`/applications/${id}/deploy`, { ...application }); const { buildId } = await post(`/applications/${id}/deploy`, { ...application, forceRebuild });
addToast({ addToast({
message: $t('application.deployment_queued'), message: $t('application.deployment_queued'),
type: 'success' type: 'success'
@@ -141,8 +141,7 @@
if ( if (
application.gitSourceId && application.gitSourceId &&
application.destinationDockerId && application.destinationDockerId &&
(application.fqdn || (application.fqdn || application.settings.isBot)
application.settings.isBot)
) { ) {
await getStatus(); await getStatus();
statusInterval = setInterval(async () => { statusInterval = setInterval(async () => {
@@ -256,7 +255,7 @@
<rect x="14" y="5" width="4" height="14" rx="1" /> <rect x="14" y="5" width="4" height="14" rx="1" />
</svg> </svg>
</button> </button>
<form on:submit|preventDefault={handleDeploySubmit}> <form on:submit|preventDefault={() => handleDeploySubmit(true)}>
<button <button
type="submit" type="submit"
disabled={$disabledButton || !isQueueActive} disabled={$disabledButton || !isQueueActive}
@@ -264,7 +263,7 @@
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm flex items-center space-x-2" class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm flex items-center space-x-2"
data-tip={$appSession.isAdmin data-tip={$appSession.isAdmin
? isQueueActive ? isQueueActive
? 'Rebuild Application' ? 'Force Rebuild Application'
: 'Autoupdate inprogress. Cannot rebuild application.' : 'Autoupdate inprogress. Cannot rebuild application.'
: 'You do not have permission to rebuild application.'} : 'You do not have permission to rebuild application.'}
> >

View File

@@ -26,7 +26,7 @@
delete tempBuildPack.color; delete tempBuildPack.color;
delete tempBuildPack.hoverColor; delete tempBuildPack.hoverColor;
if (foundConfig.buildPack !== name) { if (foundConfig?.buildPack !== name) {
await post(`/applications/${id}`, { ...tempBuildPack, buildPack: name }); await post(`/applications/${id}`, { ...tempBuildPack, buildPack: name });
} }
await post(`/applications/${id}/configuration/buildpack`, { buildPack: name }); await post(`/applications/${id}/configuration/buildpack`, { buildPack: name });

View File

@@ -10,7 +10,7 @@
const { id } = $page.params; const { id } = $page.params;
let publicRepositoryLink: string = 'https://github.com/zekth/fastify-typescript-example'; let publicRepositoryLink: string = 'https://gitlab.com/aleveha/fastify-example';
let projectId: number; let projectId: number;
let repositoryName: string; let repositoryName: string;
let branchName: string; let branchName: string;
@@ -21,43 +21,85 @@
branches: false branches: false
}; };
async function loadBranches() { async function loadBranches() {
try {
loading.branches = true;
const protocol = publicRepositoryLink.split(':')[0]; const protocol = publicRepositoryLink.split(':')[0];
const gitUrl = publicRepositoryLink.replace('http://', '').replace('https://', ''); const gitUrl = publicRepositoryLink.replace('http://', '').replace('https://', '');
let [host, ...path] = gitUrl.split('/'); let [host, ...path] = gitUrl.split('/');
const [owner, repository, ...branch] = path; const [owner, repository, ...branch] = path;
ownerName = owner; ownerName = owner;
repositoryName = repository; repositoryName = repository;
if (branch[0] === 'tree') {
branchName = branch[1];
await saveRepository();
return;
}
if (host === 'github.com') { if (host === 'github.com') {
host = 'api.github.com'; host = 'api.github.com';
type = 'github'; type = 'github';
if (branch[0] === 'tree' && branch[1]) {
branchName = branch[1];
}
} }
if (host === 'gitlab.com') { if (host === 'gitlab.com') {
host = 'gitlab.com/api/v4'; host = 'gitlab.com/api/v4';
type = 'gitlab'; type = 'gitlab';
if (branch[1] === 'tree' && branch[2]) {
branchName = branch[2];
}
} }
const apiUrl = `${protocol}://${host}`; const apiUrl = `${protocol}://${host}`;
if (type === 'github') {
const repositoryDetails = await get(`${apiUrl}/repos/${ownerName}/${repositoryName}`); const repositoryDetails = await get(`${apiUrl}/repos/${ownerName}/${repositoryName}`);
projectId = repositoryDetails.id.toString(); projectId = repositoryDetails.id.toString();
}
if (type === 'gitlab') {
const repositoryDetails = await get(`${apiUrl}/projects/${ownerName}%2F${repositoryName}`);
projectId = repositoryDetails.id.toString();
}
if (type === 'github' && branchName) {
try {
await get(`${apiUrl}/repos/${ownerName}/${repositoryName}/branches/${branchName}`);
await saveRepository();
loading.branches = false;
return;
} catch (error) {
errorNotification(error);
}
}
if (type === 'gitlab' && branchName) {
try {
await get(
`${apiUrl}/projects/${ownerName}%2F${repositoryName}/repository/branches/${branchName}`
);
await saveRepository();
loading.branches = false;
return;
} catch (error) {
errorNotification(error);
}
}
let branches: any[] = []; let branches: any[] = [];
let page = 1; let page = 1;
let branchCount = 0; let branchCount = 0;
loading.branches = true; const loadedBranches = await loadBranchesByPage(
const loadedBranches = await loadBranchesByPage(apiUrl, ownerName, repositoryName, page); apiUrl,
ownerName,
repositoryName,
page,
type
);
branches = branches.concat(loadedBranches); branches = branches.concat(loadedBranches);
branchCount = branches.length; branchCount = branches.length;
if (branchCount === 100) { if (branchCount === 100) {
while (branchCount === 100) { while (branchCount === 100) {
page = page + 1; page = page + 1;
const nextBranches = await loadBranchesByPage(apiUrl, ownerName, repositoryName, page); const nextBranches = await loadBranchesByPage(
apiUrl,
ownerName,
repositoryName,
page,
type
);
branches = branches.concat(nextBranches); branches = branches.concat(nextBranches);
branchCount = nextBranches.length; branchCount = nextBranches.length;
} }
@@ -67,10 +109,28 @@
value: branch.name, value: branch.name,
label: branch.name label: branch.name
})); }));
} catch (error) {
return errorNotification(error);
} finally {
loading.branches = false;
} }
async function loadBranchesByPage(apiUrl: string, owner: string, repository: string, page = 1) { }
async function loadBranchesByPage(
apiUrl: string,
owner: string,
repository: string,
page = 1,
type: string
) {
if (type === 'github') {
return await get(`${apiUrl}/repos/${owner}/${repository}/branches?per_page=100&page=${page}`); return await get(`${apiUrl}/repos/${owner}/${repository}/branches?per_page=100&page=${page}`);
} }
if (type === 'gitlab') {
return await get(
`${apiUrl}/projects/${ownerName}%2F${repositoryName}/repository/branches?page=${page}`
);
}
}
async function saveRepository(event?: any) { async function saveRepository(event?: any) {
try { try {
if (event?.detail?.value) { if (event?.detail?.value) {
@@ -89,6 +149,7 @@
webhookToken: null, webhookToken: null,
isPublicRepository: true isPublicRepository: true
}); });
return await goto(`/applications/${id}/configuration/destination`); return await goto(`/applications/${id}/configuration/destination`);
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
@@ -96,11 +157,21 @@
} }
</script> </script>
<div class="title">Public repository link</div> <div class="mx-auto max-w-7xl">
<Explainer text="Only works with Github.com and Gitlab.com" /> <div class="grid grid-flow-row gap-2 px-10">
<div> <div class="flex">
<input bind:value={publicRepositoryLink} /> <form class="flex" on:submit|preventDefault={loadBranches}>
<button on:click={loadBranches}>Load</button> <div class="flex-col">
<label for="fqdn" class="pt-2 w-40 text-base font-bold text-stone-100"
>Public Git HTTP Url</label
>
<Explainer
text="Only works with Github.com and Gitlab.com.<br><br><span class='text-green-500 font-bold'>https://github.com/zekth/fastify-typescript-example</span><br>or<br><span class='text-green-500 font-bold'>https://github.com/zekth/fastify-typescript-example/tree/main</span> to import a specific branch <br>or<br>https://gitlab.com/aleveha/fastify-example <br>or<br>"
/>
</div>
<div class="space-y-4">
<input class="w-[32rem]" bind:value={publicRepositoryLink} />
{#if branchSelectOptions.length > 0} {#if branchSelectOptions.length > 0}
<div class="custom-select-wrapper"> <div class="custom-select-wrapper">
<Select <Select
@@ -120,3 +191,11 @@
</div> </div>
{/if} {/if}
</div> </div>
<button class="btn mx-4 bg-green-600" class:loading={loading.branches} type="submit"
>Load Repository</button
>
</form>
</div>
</div>
</div>

View File

@@ -249,7 +249,6 @@
if (!isPublicRepository) { if (!isPublicRepository) {
await scanRepository(); await scanRepository();
} else { } else {
foundConfig = findBuildPack('node', packageManager);
scanning = false; scanning = false;
} }
}); });

View File

@@ -32,6 +32,7 @@
import { errorNotification } from '$lib/common'; import { errorNotification } from '$lib/common';
import { appSession } from '$lib/store'; import { appSession } from '$lib/store';
import PublicRepository from './_PublicRepository.svelte'; import PublicRepository from './_PublicRepository.svelte';
import Explainer from '$lib/components/Explainer.svelte';
const { id } = $page.params; const { id } = $page.params;
const from = $page.url.searchParams.get('from'); const from = $page.url.searchParams.get('from');
@@ -72,7 +73,9 @@
{$t('application.configuration.select_a_git_source')} {$t('application.configuration.select_a_git_source')}
</div> </div>
</div> </div>
<div class="flex flex-col justify-center"> <div class="max-w-7xl mx-auto ">
<div class="title pb-8">Git App</div>
<div class="flex flex-wrap justify-center">
{#if !filteredSources || ownSources.length === 0} {#if !filteredSources || ownSources.length === 0}
<div class="flex-col"> <div class="flex-col">
<div class="pb-2 text-center font-bold"> <div class="pb-2 text-center font-bold">
@@ -189,7 +192,9 @@
</div> </div>
{/if} {/if}
</div> </div>
<div class="title">Public Repository</div>
<div class="flex flex-wrap justify-center pt-10 items-center"> <div class="flex flex-wrap justify-center items-center pt-4">
<PublicRepository /> <PublicRepository />
</div> </div>
</div>

View File

@@ -620,7 +620,7 @@
</div> </div>
{/if} {/if}
{/if} {/if}
{#if !staticDeployments.includes(application.buildPack) && !isBot} {#if !staticDeployments.includes(application.buildPack)}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="port" class="text-base font-bold text-stone-100">{$t('forms.port')}</label> <label for="port" class="text-base font-bold text-stone-100">{$t('forms.port')}</label>
<input <input
@@ -631,6 +631,9 @@
bind:value={application.port} bind:value={application.port}
placeholder="{$t('forms.default')}: 'python' ? '8000' : '3000'" placeholder="{$t('forms.default')}: 'python' ? '8000' : '3000'"
/> />
<Explainer
text={'The port your application listens on.'}
/>
</div> </div>
{/if} {/if}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">