This commit is contained in:
Andras Bacsai
2021-06-07 23:44:36 +02:00
committed by GitHub
parent 04a5b1bd4f
commit 9d14b03eb1
36 changed files with 2341 additions and 1169 deletions

View File

@@ -11,7 +11,7 @@ export async function deleteSameDeployments(configuration) {
const running = JSON.parse(s.Spec.Labels.configuration);
if (
running.repository.id === configuration.repository.id &&
running.repository.branch === configuration.repository.branch &&
running.repository.branch === configuration.repository.branch &&
running.publish.domain === configuration.publish.domain
) {
await execShellAsync(`docker stack rm ${s.Spec.Labels['com.docker.stack.namespace']}`);
@@ -55,7 +55,6 @@ export async function purgeImagesContainers(configuration, deleteAll = false) {
.split('\n');
if (IDsToDelete.length > 1) await execShellAsync(`docker rmi -f ${IDsToDelete.join(' ')}`);
}
} catch (error) {
console.log(error);
}

View File

@@ -39,7 +39,9 @@ export default async function (configuration) {
);
if (isPreviewDeploymentEnabled && pullRequest && pullRequest !== 0) {
await execShellAsync(`cd ${workdir} && git fetch origin pull/${pullRequest}/head:pull_${pullRequest} && git checkout pull_${pullRequest}`)
await execShellAsync(
`cd ${workdir} && git fetch origin pull/${pullRequest}/head:pull_${pullRequest} && git checkout pull_${pullRequest}`
);
}
configuration.build.container.tag = (
await execShellAsync(`cd ${workdir}/ && git rev-parse HEAD`)

View File

@@ -21,8 +21,11 @@ export function setDefaultConfiguration(configuration) {
configuration.general.deployId = deployId;
configuration.general.workdir = `/tmp/${deployId}`;
if (configuration.general.isPreviewDeploymentEnabled && configuration.general.pullRequest !== 0) {
configuration.build.container.name = `pr${configuration.general.pullRequest}-${sha256.slice(0, 8)}`
configuration.publish.domain = `pr${configuration.general.pullRequest}.${configuration.publish.domain}`
configuration.build.container.name = `pr${configuration.general.pullRequest}-${sha256.slice(
0,
8
)}`;
configuration.publish.domain = `pr${configuration.general.pullRequest}.${configuration.publish.domain}`;
}
if (!configuration.publish.path) configuration.publish.path = '/';
if (!configuration.publish.port) {
@@ -59,11 +62,13 @@ export function setDefaultConfiguration(configuration) {
configuration.build.pack === 'nextjs' ||
configuration.build.pack === 'nestjs'
) {
if (!configuration.build.command.start) configuration.build.command.start = 'yarn start'
if (!configuration.build.command.start) configuration.build.command.start = 'yarn start';
}
if (configuration.build.pack === 'python') {
if (!configuration.build.command.python.module) configuration.build.command.python.module = 'main'
if (!configuration.build.command.python.instance) configuration.build.command.python.instance = 'app'
if (!configuration.build.command.python.module)
configuration.build.command.python.module = 'main';
if (!configuration.build.command.python.instance)
configuration.build.command.python.instance = 'app';
}
configuration.build.container.baseSHA = crypto
@@ -77,7 +82,10 @@ export function setDefaultConfiguration(configuration) {
export async function precheckDeployment(configuration) {
const services = (await docker.engine.listServices()).filter(
(r) => r.Spec.Labels.managedBy === 'coolify' && r.Spec.Labels.type === 'application' && JSON.parse(r.Spec.Labels.configuration).publish.domain === configuration.publish.domain
(r) =>
r.Spec.Labels.managedBy === 'coolify' &&
r.Spec.Labels.type === 'application' &&
JSON.parse(r.Spec.Labels.configuration).publish.domain === configuration.publish.domain
);
let foundService = false;
let configChanged = false;
@@ -86,7 +94,6 @@ export async function precheckDeployment(configuration) {
for (const service of services) {
const running = JSON.parse(service.Spec.Labels.configuration);
if (running) {
if (
running.repository.id === configuration.repository.id &&
running.repository.branch === configuration.repository.branch
@@ -117,26 +124,27 @@ export async function precheckDeployment(configuration) {
const compareObjects = (a, b) => {
if (a === b) return true;
if (typeof a != 'object' || typeof b != 'object' || a == null || b == null) return false;
let keysA = Object.keys(a), keysB = Object.keys(b);
const keysA = Object.keys(a),
keysB = Object.keys(b);
if (keysA.length != keysB.length) return false;
for (let key of keysA) {
if (!keysB.includes(key)) return false;
if (typeof a[key] === 'function' || typeof b[key] === 'function') {
if (a[key].toString() != b[key].toString()) return false;
} else {
if (!compareObjects(a[key], b[key])) return false;
}
for (const key of keysA) {
if (!keysB.includes(key)) return false;
if (typeof a[key] === 'function' || typeof b[key] === 'function') {
if (a[key].toString() != b[key].toString()) return false;
} else {
if (!compareObjects(a[key], b[key])) return false;
}
}
return true;
}
};
const runningWithoutContainer = JSON.parse(JSON.stringify(running));
delete runningWithoutContainer.build.container;
@@ -145,19 +153,23 @@ export async function precheckDeployment(configuration) {
// If only the configuration changed
if (
!compareObjects(runningWithoutContainer.build,configurationWithoutContainer.build) ||
!compareObjects(runningWithoutContainer.publish,configurationWithoutContainer.publish) ||
!compareObjects(runningWithoutContainer.build, configurationWithoutContainer.build) ||
!compareObjects(runningWithoutContainer.publish, configurationWithoutContainer.publish) ||
runningWithoutContainer.general.isPreviewDeploymentEnabled !==
configurationWithoutContainer.general.isPreviewDeploymentEnabled
){
configurationWithoutContainer.general.isPreviewDeploymentEnabled
) {
configChanged = true;
}
// If only the image changed
if (running.build.container.tag !== configuration.build.container.tag) imageChanged = true;
// If build pack changed, forceUpdate the service
if (running.build.pack !== configuration.build.pack) forceUpdate = true;
if (configuration.general.isPreviewDeploymentEnabled && configuration.general.pullRequest !== 0) forceUpdate = true
if (
configuration.general.isPreviewDeploymentEnabled &&
configuration.general.pullRequest !== 0
)
forceUpdate = true;
}
}
}
@@ -174,5 +186,9 @@ export async function precheckDeployment(configuration) {
}
export async function updateServiceLabels(configuration) {
return await execShellAsync(`docker service update --label-add configuration='${JSON.stringify(configuration)}' ${configuration.build.container.name}_${configuration.build.container.name}`)
return await execShellAsync(
`docker service update --label-add configuration='${JSON.stringify(configuration)}' ${
configuration.build.container.name
}_${configuration.build.container.name}`
);
}

View File

@@ -42,12 +42,8 @@ export default async function (configuration, imageChanged) {
'`) && PathPrefix(`' +
configuration.publish.path +
'`)',
'traefik.http.routers.' +
containerName +
'.tls.certresolver=letsencrypt',
'traefik.http.routers.' +
containerName +
'.middlewares=global-compress'
'traefik.http.routers.' + containerName + '.tls.certresolver=letsencrypt',
'traefik.http.routers.' + containerName + '.middlewares=global-compress'
]
}
}
@@ -76,7 +72,7 @@ export default async function (configuration, imageChanged) {
await delay(10000);
await purgeImagesContainers(found, true);
}
purgeImagesAsync(configuration)
purgeImagesAsync(configuration);
await saveAppLog('### Published done!', configuration);
}

View File

@@ -4,7 +4,6 @@ import ApplicationLog from '$models/ApplicationLog';
import dayjs from 'dayjs';
import { version } from '../../../../package.json';
function generateTimestamp() {
return `${dayjs().format('YYYY-MM-DD HH:mm:ss.SSS')} `;
}

View File

@@ -15,10 +15,7 @@ const publishPython = (configuration) => {
};
export default async function (configuration) {
await fs.writeFile(
`${configuration.general.workdir}/Dockerfile`,
publishPython(configuration)
);
await fs.writeFile(`${configuration.general.workdir}/Dockerfile`, publishPython(configuration));
const stream = await docker.engine.buildImage(
{ src: ['.'], context: configuration.general.workdir },
{ t: `${configuration.build.container.name}:${configuration.build.container.tag}` }

View File

@@ -1,4 +1,3 @@
import Deployment from '$models/Deployment';
import dayjs from 'dayjs';
import buildContainer from './buildContainer';