feat: Webhooks inititate all applications with the correct branch

This commit is contained in:
Andras Bacsai
2022-03-11 21:18:12 +01:00
parent 16ea9a3e07
commit c5c9f84503
7 changed files with 256 additions and 231 deletions

View File

@@ -20,7 +20,6 @@ export const options: RequestHandler = async () => {
export const post: RequestHandler = async (event) => {
try {
const buildId = cuid();
const allowedGithubEvents = ['push', 'pull_request'];
const allowedActions = ['opened', 'reopened', 'synchronize', 'closed'];
const githubEvent = event.request.headers.get('x-github-event')?.toLowerCase();
@@ -45,137 +44,147 @@ export const post: RequestHandler = async (event) => {
branch = body.pull_request.head.ref.split('/')[2];
}
const applicationFound = await db.getApplicationWebhook({ projectId, branch });
if (applicationFound) {
const webhookSecret = applicationFound.gitSource.githubApp.webhookSecret;
const hmac = crypto.createHmac('sha256', webhookSecret);
const digest = Buffer.from(
'sha256=' + hmac.update(JSON.stringify(body)).digest('hex'),
'utf8'
);
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?'
}
};
}
}
const applications = await db.getApplicationWebhook({ projectId, branch });
if (applications.length > 0) {
for (const application of applications) {
const buildId = cuid();
if (githubEvent === 'push') {
if (!applicationFound.configHash) {
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!'
const webhookSecret = application.gitSource.githubApp.webhookSecret;
const hmac = crypto.createHmac('sha256', webhookSecret);
const digest = Buffer.from(
'sha256=' + hmac.update(JSON.stringify(body)).digest('hex'),
'utf8'
);
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?'
}
};
}
};
} 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) {
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.updateMany({
where: { branch, projectId },
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 {
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 (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: 500,
status: 200,
body: {
message: 'Application not running.'
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!'
}
};
}
}
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
});
} else {
return {
status: 200,
status: 500,
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!'
message: 'Pull request previews are not enabled.'
}
};
}
} else {
return {
status: 500,
body: {
message: 'Pull request previews are not enabled.'
}
};
}
}
return {
status: 500,
body: {
message: 'Not handled event.'
}
};
}
return {
status: 500,
body: {
message: 'Not handled event.'
message: 'No applications configured in Coolify.'
}
};
} catch (err) {