Revert double build

This commit is contained in:
Andras Bacsai 2022-03-11 22:48:55 +01:00
parent fa6cf068c7
commit c6b4d04e26
4 changed files with 237 additions and 264 deletions

View File

@ -70,7 +70,7 @@ export async function removeApplication({ id, teamId }) {
export async function getApplicationWebhook({ projectId, branch }) { export async function getApplicationWebhook({ projectId, branch }) {
try { try {
let applications = await prisma.application.findMany({ let application = await prisma.application.findFirst({
where: { projectId, branch, settings: { autodeploy: true } }, where: { projectId, branch, settings: { autodeploy: true } },
include: { include: {
destinationDocker: true, destinationDocker: true,
@ -79,40 +79,38 @@ export async function getApplicationWebhook({ projectId, branch }) {
secrets: true secrets: true
} }
}); });
for (const application of applications) { if (application.gitSource?.githubApp?.clientSecret) {
if (application.gitSource?.githubApp?.clientSecret) { application.gitSource.githubApp.clientSecret = decrypt(
application.gitSource.githubApp.clientSecret = decrypt( application.gitSource.githubApp.clientSecret
application.gitSource.githubApp.clientSecret );
);
}
if (application.gitSource?.githubApp?.webhookSecret) {
application.gitSource.githubApp.webhookSecret = decrypt(
application.gitSource.githubApp.webhookSecret
);
}
if (application.gitSource?.githubApp?.privateKey) {
application.gitSource.githubApp.privateKey = decrypt(
application.gitSource.githubApp.privateKey
);
}
if (application?.gitSource?.gitlabApp?.appSecret) {
application.gitSource.gitlabApp.appSecret = decrypt(
application.gitSource.gitlabApp.appSecret
);
}
if (application?.gitSource?.gitlabApp?.webhookToken) {
application.gitSource.gitlabApp.webhookToken = decrypt(
application.gitSource.gitlabApp.webhookToken
);
}
if (application?.secrets.length > 0) {
application.secrets = application.secrets.map((s) => {
s.value = decrypt(s.value);
return s;
});
}
} }
return [...applications]; if (application.gitSource?.githubApp?.webhookSecret) {
application.gitSource.githubApp.webhookSecret = decrypt(
application.gitSource.githubApp.webhookSecret
);
}
if (application.gitSource?.githubApp?.privateKey) {
application.gitSource.githubApp.privateKey = decrypt(
application.gitSource.githubApp.privateKey
);
}
if (application?.gitSource?.gitlabApp?.appSecret) {
application.gitSource.gitlabApp.appSecret = decrypt(
application.gitSource.gitlabApp.appSecret
);
}
if (application?.gitSource?.gitlabApp?.webhookToken) {
application.gitSource.gitlabApp.webhookToken = decrypt(
application.gitSource.gitlabApp.webhookToken
);
}
if (application?.secrets.length > 0) {
application.secrets = application.secrets.map((s) => {
s.value = decrypt(s.value);
return s;
});
}
return { ...application };
} catch (e) { } catch (e) {
throw { status: 404, body: { message: e.message } }; throw { status: 404, body: { message: e.message } };
} }

View File

@ -108,11 +108,9 @@
try { try {
loading = true; loading = true;
await post(`/applications/${id}/stop.json`, {}); await post(`/applications/${id}/stop.json`, {});
isRunning = false; return window.location.reload();
} catch ({ error }) { } catch ({ error }) {
return errorNotification(error); return errorNotification(error);
} finally {
loading = false;
} }
} }
</script> </script>

View File

@ -20,6 +20,7 @@ export const options: RequestHandler = async () => {
export const post: RequestHandler = async (event) => { export const post: RequestHandler = async (event) => {
try { try {
const buildId = cuid();
const allowedGithubEvents = ['push', 'pull_request']; const allowedGithubEvents = ['push', 'pull_request'];
const allowedActions = ['opened', 'reopened', 'synchronize', 'closed']; const allowedActions = ['opened', 'reopened', 'synchronize', 'closed'];
const githubEvent = event.request.headers.get('x-github-event')?.toLowerCase(); const githubEvent = event.request.headers.get('x-github-event')?.toLowerCase();
@ -44,147 +45,137 @@ export const post: RequestHandler = async (event) => {
branch = body.pull_request.head.ref.split('/')[2]; branch = body.pull_request.head.ref.split('/')[2];
} }
const applications = await db.getApplicationWebhook({ projectId, branch }); const applicationFound = await db.getApplicationWebhook({ projectId, branch });
if (applications.length > 0) { if (applicationFound) {
for (const application of applications) { const webhookSecret = applicationFound.gitSource.githubApp.webhookSecret;
const buildId = cuid(); const hmac = crypto.createHmac('sha256', webhookSecret);
const digest = Buffer.from(
const webhookSecret = application.gitSource.githubApp.webhookSecret; 'sha256=' + hmac.update(JSON.stringify(body)).digest('hex'),
const hmac = crypto.createHmac('sha256', webhookSecret); 'utf8'
const digest = Buffer.from( );
'sha256=' + hmac.update(JSON.stringify(body)).digest('hex'), const checksum = Buffer.from(githubSignature, 'utf8');
'utf8' if (!dev) {
); if (checksum.length !== digest.length || !crypto.timingSafeEqual(digest, checksum)) {
const checksum = Buffer.from(githubSignature, 'utf8');
if (!dev) {
if (checksum.length !== digest.length || !crypto.timingSafeEqual(digest, checksum)) {
return {
status: 500,
body: {
message: 'SHA256 checksum failed. Are you doing something fishy?'
}
};
}
}
if (githubEvent === 'push') {
if (!application.configHash) {
const configHash = crypto
.createHash('sha256')
.update(
JSON.stringify({
buildPack: application.buildPack,
port: application.port,
installCommand: application.installCommand,
buildCommand: application.buildCommand,
startCommand: application.startCommand
})
)
.digest('hex');
await db.prisma.application.update({
where: { id: application.id },
data: { configHash }
});
}
await db.prisma.application.update({
where: { id: application.id },
data: { updatedAt: new Date() }
});
await buildQueue.add(buildId, {
build_id: buildId,
type: 'webhook_commit',
...application
});
return { return {
status: 200, status: 500,
body: { body: {
message: 'Queued. Thank you!' message: 'SHA256 checksum failed. Are you doing something fishy?'
} }
}; };
} else if (githubEvent === 'pull_request') {
const pullmergeRequestId = body.number;
const pullmergeRequestAction = body.action;
const sourceBranch = body.pull_request.head.ref;
if (!allowedActions.includes(pullmergeRequestAction)) {
return {
status: 500,
body: {
message: 'Action not allowed.'
}
};
}
if (application.settings.previews) {
if (application.destinationDockerId) {
const isRunning = await checkContainer(
application.destinationDocker.engine,
application.id
);
if (!isRunning) {
return {
status: 500,
body: {
message: 'Application not running.'
}
};
}
}
if (
pullmergeRequestAction === 'opened' ||
pullmergeRequestAction === 'reopened' ||
pullmergeRequestAction === 'synchronize'
) {
await db.prisma.application.update({
where: { id: application.id },
data: { updatedAt: new Date() }
});
await buildQueue.add(buildId, {
build_id: buildId,
type: 'webhook_pr',
...application,
sourceBranch,
pullmergeRequestId
});
return {
status: 200,
body: {
message: 'Queued. Thank you!'
}
};
} else if (pullmergeRequestAction === 'closed') {
if (application.destinationDockerId) {
const id = `${application.id}-${pullmergeRequestId}`;
const engine = application.destinationDocker.engine;
await removeDestinationDocker({ id, engine });
}
return {
status: 200,
body: {
message: 'Removed preview. Thank you!'
}
};
}
} else {
return {
status: 500,
body: {
message: 'Pull request previews are not enabled.'
}
};
}
} }
} }
return {
status: 500, if (githubEvent === 'push') {
body: { if (!applicationFound.configHash) {
message: 'Not handled event.' const configHash = crypto
.createHash('sha256')
.update(
JSON.stringify({
buildPack: applicationFound.buildPack,
port: applicationFound.port,
installCommand: applicationFound.installCommand,
buildCommand: applicationFound.buildCommand,
startCommand: applicationFound.startCommand
})
)
.digest('hex');
await db.prisma.application.updateMany({
where: { branch, projectId },
data: { configHash }
});
} }
}; await db.prisma.application.update({
where: { id: applicationFound.id },
data: { updatedAt: new Date() }
});
await buildQueue.add(buildId, {
build_id: buildId,
type: 'webhook_commit',
...applicationFound
});
return {
status: 200,
body: {
message: 'Queued. Thank you!'
}
};
} else if (githubEvent === 'pull_request') {
const pullmergeRequestId = body.number;
const pullmergeRequestAction = body.action;
const sourceBranch = body.pull_request.head.ref;
if (!allowedActions.includes(pullmergeRequestAction)) {
return {
status: 500,
body: {
message: 'Action not allowed.'
}
};
}
if (applicationFound.settings.previews) {
if (applicationFound.destinationDockerId) {
const isRunning = await checkContainer(
applicationFound.destinationDocker.engine,
applicationFound.id
);
if (!isRunning) {
return {
status: 500,
body: {
message: 'Application not running.'
}
};
}
}
if (
pullmergeRequestAction === 'opened' ||
pullmergeRequestAction === 'reopened' ||
pullmergeRequestAction === 'synchronize'
) {
await db.prisma.application.update({
where: { id: applicationFound.id },
data: { updatedAt: new Date() }
});
await buildQueue.add(buildId, {
build_id: buildId,
type: 'webhook_pr',
...applicationFound,
sourceBranch,
pullmergeRequestId
});
return {
status: 200,
body: {
message: 'Queued. Thank you!'
}
};
} else if (pullmergeRequestAction === 'closed') {
if (applicationFound.destinationDockerId) {
const id = `${applicationFound.id}-${pullmergeRequestId}`;
const engine = applicationFound.destinationDocker.engine;
await removeDestinationDocker({ id, engine });
}
return {
status: 200,
body: {
message: 'Removed preview. Thank you!'
}
};
}
} else {
return {
status: 500,
body: {
message: 'Pull request previews are not enabled.'
}
};
}
}
} }
return { return {
status: 500, status: 500,
body: { body: {
message: 'No applications configured in Coolify.' message: 'Not handled event.'
} }
}; };
} catch (err) { } catch (err) {

View File

@ -21,46 +21,42 @@ export const options: RequestHandler = async () => {
export const post: RequestHandler = async (event) => { export const post: RequestHandler = async (event) => {
const allowedActions = ['opened', 'reopen', 'close', 'open', 'update']; const allowedActions = ['opened', 'reopen', 'close', 'open', 'update'];
const body = await event.request.json(); const body = await event.request.json();
const buildId = cuid();
try { try {
const { object_kind: objectKind } = body; const { object_kind: objectKind } = body;
if (objectKind === 'push') { if (objectKind === 'push') {
const { ref } = body; const { ref } = body;
const projectId = Number(body['project_id']); const projectId = Number(body['project_id']);
const branch = ref.split('/')[2]; const branch = ref.split('/')[2];
const applications = await db.getApplicationWebhook({ projectId, branch }); const applicationFound = await db.getApplicationWebhook({ projectId, branch });
if (applications.length > 0) { if (applicationFound) {
for (const application of applications) { if (!applicationFound.configHash) {
const buildId = cuid(); const configHash = crypto
if (!application.configHash) { .createHash('sha256')
const configHash = crypto .update(
.createHash('sha256') JSON.stringify({
.update( buildPack: applicationFound.buildPack,
JSON.stringify({ port: applicationFound.port,
buildPack: application.buildPack, installCommand: applicationFound.installCommand,
port: application.port, buildCommand: applicationFound.buildCommand,
installCommand: application.installCommand, startCommand: applicationFound.startCommand
buildCommand: application.buildCommand, })
startCommand: application.startCommand )
}) .digest('hex');
) await db.prisma.application.updateMany({
.digest('hex'); where: { branch, projectId },
await db.prisma.application.update({ data: { configHash }
where: { id: application.id },
data: { configHash }
});
}
await db.prisma.application.update({
where: { id: application.id },
data: { updatedAt: new Date() }
});
await buildQueue.add(buildId, {
build_id: buildId,
type: 'webhook_commit',
...application
}); });
} }
await db.prisma.application.update({
where: { id: applicationFound.id },
data: { updatedAt: new Date() }
});
await buildQueue.add(buildId, {
build_id: buildId,
type: 'webhook_commit',
...applicationFound
});
return { return {
status: 200, status: 200,
body: { body: {
@ -68,12 +64,6 @@ export const post: RequestHandler = async (event) => {
} }
}; };
} }
return {
status: 500,
body: {
message: 'No applications configured in Coolify.'
}
};
} else if (objectKind === 'merge_request') { } else if (objectKind === 'merge_request') {
const webhookToken = event.request.headers.get('x-gitlab-token'); const webhookToken = event.request.headers.get('x-gitlab-token');
if (!webhookToken) { if (!webhookToken) {
@ -108,73 +98,69 @@ export const post: RequestHandler = async (event) => {
}; };
} }
const applications = await db.getApplicationWebhook({ projectId, branch: targetBranch }); const applicationFound = await db.getApplicationWebhook({ projectId, branch: targetBranch });
if (applications.length > 0) { if (applicationFound) {
for (const application of applications) { if (applicationFound.settings.previews) {
const buildId = cuid(); if (applicationFound.destinationDockerId) {
if (application.settings.previews) { const isRunning = await checkContainer(
if (application.destinationDockerId) { applicationFound.destinationDocker.engine,
const isRunning = await checkContainer( applicationFound.id
application.destinationDocker.engine, );
application.id if (!isRunning) {
);
if (!isRunning) {
return {
status: 500,
body: {
message: 'Application not running.'
}
};
}
}
if (!dev && application.gitSource.gitlabApp.webhookToken !== webhookToken) {
return { return {
status: 500, status: 500,
body: { body: {
message: 'Ooops, something is not okay, are you okay?' message: 'Application not running.'
}
};
}
if (
action === 'opened' ||
action === 'reopen' ||
action === 'open' ||
action === 'update'
) {
await db.prisma.application.update({
where: { id: application.id },
data: { updatedAt: new Date() }
});
await buildQueue.add(buildId, {
build_id: buildId,
type: 'webhook_mr',
...application,
sourceBranch,
pullmergeRequestId
});
return {
status: 200,
body: {
message: 'Queued. Thank you!'
}
};
} else if (action === 'close') {
if (application.destinationDockerId) {
const id = `${application.id}-${pullmergeRequestId}`;
const engine = application.destinationDocker.engine;
await removeDestinationDocker({ id, engine });
}
return {
status: 200,
body: {
message: 'Removed preview. Thank you!'
} }
}; };
} }
} }
} if (!dev && applicationFound.gitSource.gitlabApp.webhookToken !== webhookToken) {
return {
status: 500,
body: {
message: 'Ooops, something is not okay, are you okay?'
}
};
}
if (
action === 'opened' ||
action === 'reopen' ||
action === 'open' ||
action === 'update'
) {
await db.prisma.application.update({
where: { id: applicationFound.id },
data: { updatedAt: new Date() }
});
await buildQueue.add(buildId, {
build_id: buildId,
type: 'webhook_mr',
...applicationFound,
sourceBranch,
pullmergeRequestId
});
return {
status: 200,
body: {
message: 'Queued. Thank you!'
}
};
} else if (action === 'close') {
if (applicationFound.destinationDockerId) {
const id = `${applicationFound.id}-${pullmergeRequestId}`;
const engine = applicationFound.destinationDocker.engine;
await removeDestinationDocker({ id, engine });
}
return {
status: 200,
body: {
message: 'Removed preview. Thank you!'
}
};
}
}
return { return {
status: 500, status: 500,
body: { body: {