feat: github allow fual branches
This commit is contained in:
parent
4e2dad7720
commit
582170f26e
@ -183,7 +183,7 @@ export async function getApplicationFromDB(id: string, teamId: string) {
|
|||||||
}
|
}
|
||||||
export async function getApplicationFromDBWebhook(projectId: number, branch: string) {
|
export async function getApplicationFromDBWebhook(projectId: number, branch: string) {
|
||||||
try {
|
try {
|
||||||
let application = await prisma.application.findFirst({
|
let applications = await prisma.application.findMany({
|
||||||
where: { projectId, branch, settings: { autodeploy: true } },
|
where: { projectId, branch, settings: { autodeploy: true } },
|
||||||
include: {
|
include: {
|
||||||
destinationDocker: true,
|
destinationDocker: true,
|
||||||
@ -193,22 +193,28 @@ export async function getApplicationFromDBWebhook(projectId: number, branch: str
|
|||||||
persistentStorage: true
|
persistentStorage: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!application) {
|
if (applications.length === 0) {
|
||||||
throw { status: 500, message: 'Application not configured.' }
|
throw { status: 500, message: 'Application not configured.' }
|
||||||
}
|
}
|
||||||
application = decryptApplication(application);
|
applications = applications.map((application: any) => {
|
||||||
const { baseImage, baseBuildImage, baseBuildImages, baseImages } = setDefaultBaseImage(
|
application = decryptApplication(application);
|
||||||
application.buildPack
|
const { baseImage, baseBuildImage, baseBuildImages, baseImages } = setDefaultBaseImage(
|
||||||
);
|
application.buildPack
|
||||||
|
);
|
||||||
|
|
||||||
// Set default build images
|
// Set default build images
|
||||||
if (!application.baseImage) {
|
if (!application.baseImage) {
|
||||||
application.baseImage = baseImage;
|
application.baseImage = baseImage;
|
||||||
}
|
}
|
||||||
if (!application.baseBuildImage) {
|
if (!application.baseBuildImage) {
|
||||||
application.baseBuildImage = baseBuildImage;
|
application.baseBuildImage = baseBuildImage;
|
||||||
}
|
}
|
||||||
return { ...application, baseBuildImages, baseImages };
|
application.baseBuildImages = baseBuildImages;
|
||||||
|
application.baseImages = baseImages;
|
||||||
|
return application
|
||||||
|
})
|
||||||
|
|
||||||
|
return applications;
|
||||||
|
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
return errorHandler({ status, message })
|
return errorHandler({ status, message })
|
||||||
@ -284,11 +290,11 @@ export async function saveApplicationSettings(request: FastifyRequest<SaveApplic
|
|||||||
try {
|
try {
|
||||||
const { id } = request.params
|
const { id } = request.params
|
||||||
const { debug, previews, dualCerts, autodeploy, branch, projectId, isBot } = request.body
|
const { debug, previews, dualCerts, autodeploy, branch, projectId, isBot } = request.body
|
||||||
const isDouble = await checkDoubleBranch(branch, projectId);
|
// const isDouble = await checkDoubleBranch(branch, projectId);
|
||||||
if (isDouble && autodeploy) {
|
// if (isDouble && autodeploy) {
|
||||||
await prisma.applicationSettings.updateMany({ where: { application: { branch, projectId } }, data: { autodeploy: false } })
|
// await prisma.applicationSettings.updateMany({ where: { application: { branch, projectId } }, data: { autodeploy: false } })
|
||||||
throw { status: 500, message: 'Cannot activate automatic deployments until only one application is defined for this repository / branch.' }
|
// throw { status: 500, message: 'Cannot activate automatic deployments until only one application is defined for this repository / branch.' }
|
||||||
}
|
// }
|
||||||
await prisma.application.update({
|
await prisma.application.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
data: { fqdn: isBot ? null : undefined, settings: { update: { debug, previews, dualCerts, autodeploy, isBot } } },
|
data: { fqdn: isBot ? null : undefined, settings: { update: { debug, previews, dualCerts, autodeploy, isBot } } },
|
||||||
@ -672,12 +678,12 @@ export async function saveRepository(request, reply) {
|
|||||||
data: { repository, branch, projectId, settings: { update: { autodeploy, isPublicRepository } } }
|
data: { repository, branch, projectId, settings: { update: { autodeploy, isPublicRepository } } }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!isPublicRepository) {
|
// if (!isPublicRepository) {
|
||||||
const isDouble = await checkDoubleBranch(branch, projectId);
|
// const isDouble = await checkDoubleBranch(branch, projectId);
|
||||||
if (isDouble) {
|
// if (isDouble) {
|
||||||
await prisma.applicationSettings.updateMany({ where: { application: { branch, projectId } }, data: { autodeploy: false, isPublicRepository } })
|
// await prisma.applicationSettings.updateMany({ where: { application: { branch, projectId } }, data: { autodeploy: false, isPublicRepository } })
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return reply.code(201).send()
|
return reply.code(201).send()
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
return errorHandler({ status, message })
|
return errorHandler({ status, message })
|
||||||
@ -974,9 +980,12 @@ export async function getBuildIdLogs(request: FastifyRequest<GetBuildIdLogs>) {
|
|||||||
where: { buildId, time: { gt: sequence } },
|
where: { buildId, time: { gt: sequence } },
|
||||||
orderBy: { time: 'asc' }
|
orderBy: { time: 'asc' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = await prisma.build.findFirst({ where: { id: buildId } });
|
const data = await prisma.build.findFirst({ where: { id: buildId } });
|
||||||
|
const createdAt = day(data.createdAt).utc();
|
||||||
return {
|
return {
|
||||||
logs,
|
logs,
|
||||||
|
took: day().diff(createdAt) / 1000,
|
||||||
status: data?.status || 'queued'
|
status: data?.status || 'queued'
|
||||||
}
|
}
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
|
@ -67,7 +67,7 @@ export async function configureGitHubApp(request, reply) {
|
|||||||
}
|
}
|
||||||
export async function gitHubEvents(request: FastifyRequest<GitHubEvents>): Promise<any> {
|
export async function gitHubEvents(request: FastifyRequest<GitHubEvents>): Promise<any> {
|
||||||
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 = request.headers['x-github-event']?.toString().toLowerCase();
|
const githubEvent = request.headers['x-github-event']?.toString().toLowerCase();
|
||||||
@ -87,126 +87,124 @@ export async function gitHubEvents(request: FastifyRequest<GitHubEvents>): Promi
|
|||||||
if (!projectId || !branch) {
|
if (!projectId || !branch) {
|
||||||
throw { status: 500, message: 'Cannot parse projectId or branch from the webhook?!' }
|
throw { status: 500, message: 'Cannot parse projectId or branch from the webhook?!' }
|
||||||
}
|
}
|
||||||
const applicationFound = await getApplicationFromDBWebhook(projectId, branch);
|
const applicationsFound = await getApplicationFromDBWebhook(projectId, branch);
|
||||||
if (applicationFound) {
|
if (applicationsFound && applicationsFound.length > 0) {
|
||||||
const webhookSecret = applicationFound.gitSource.githubApp.webhookSecret || null;
|
for (const application of applicationsFound) {
|
||||||
//@ts-ignore
|
const buildId = cuid();
|
||||||
const hmac = crypto.createHmac('sha256', webhookSecret);
|
const webhookSecret = application.gitSource.githubApp.webhookSecret || null;
|
||||||
const digest = Buffer.from(
|
|
||||||
'sha256=' + hmac.update(JSON.stringify(body)).digest('hex'),
|
|
||||||
'utf8'
|
|
||||||
);
|
|
||||||
if (!isDev) {
|
|
||||||
const checksum = Buffer.from(githubSignature, 'utf8');
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
if (checksum.length !== digest.length || !crypto.timingSafeEqual(digest, checksum)) {
|
const hmac = crypto.createHmac('sha256', webhookSecret);
|
||||||
throw { status: 500, message: 'SHA256 checksum failed. Are you doing something fishy?' }
|
const digest = Buffer.from(
|
||||||
};
|
'sha256=' + hmac.update(JSON.stringify(body)).digest('hex'),
|
||||||
}
|
'utf8'
|
||||||
|
);
|
||||||
|
if (!isDev) {
|
||||||
if (githubEvent === 'push') {
|
const checksum = Buffer.from(githubSignature, 'utf8');
|
||||||
if (!applicationFound.configHash) {
|
//@ts-ignore
|
||||||
const configHash = crypto
|
if (checksum.length !== digest.length || !crypto.timingSafeEqual(digest, checksum)) {
|
||||||
//@ts-ignore
|
console.log('SHA256 checksum failed. Are you doing something fishy?')
|
||||||
.createHash('sha256')
|
// throw { status: 500, message: 'SHA256 checksum failed. Are you doing something fishy?'
|
||||||
.update(
|
};
|
||||||
JSON.stringify({
|
|
||||||
buildPack: applicationFound.buildPack,
|
|
||||||
port: applicationFound.port,
|
|
||||||
exposePort: applicationFound.exposePort,
|
|
||||||
installCommand: applicationFound.installCommand,
|
|
||||||
buildCommand: applicationFound.buildCommand,
|
|
||||||
startCommand: applicationFound.startCommand
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.digest('hex');
|
|
||||||
await prisma.application.updateMany({
|
|
||||||
where: { branch, projectId },
|
|
||||||
data: { configHash }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
await prisma.application.update({
|
|
||||||
where: { id: applicationFound.id },
|
|
||||||
data: { updatedAt: new Date() }
|
|
||||||
});
|
|
||||||
await prisma.build.create({
|
|
||||||
data: {
|
|
||||||
id: buildId,
|
|
||||||
applicationId: applicationFound.id,
|
|
||||||
destinationDockerId: applicationFound.destinationDocker.id,
|
|
||||||
gitSourceId: applicationFound.gitSource.id,
|
|
||||||
githubAppId: applicationFound.gitSource.githubApp?.id,
|
|
||||||
gitlabAppId: applicationFound.gitSource.gitlabApp?.id,
|
|
||||||
status: 'queued',
|
|
||||||
type: 'webhook_commit'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
message: 'Queued. Thank you!'
|
|
||||||
};
|
|
||||||
} else if (githubEvent === 'pull_request') {
|
|
||||||
const pullmergeRequestId = body.number.toString();
|
|
||||||
const pullmergeRequestAction = body.action;
|
|
||||||
const sourceBranch = body.pull_request.head.ref.includes('/') ? body.pull_request.head.ref.split('/')[2] : body.pull_request.head.ref;
|
|
||||||
if (!allowedActions.includes(pullmergeRequestAction)) {
|
|
||||||
throw { status: 500, message: 'Action not allowed.' }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applicationFound.settings.previews) {
|
if (githubEvent === 'push') {
|
||||||
if (applicationFound.destinationDockerId) {
|
if (!application.configHash) {
|
||||||
const isRunning = await checkContainer(
|
const configHash = crypto
|
||||||
{
|
//@ts-ignore
|
||||||
dockerId: applicationFound.destinationDocker.id,
|
.createHash('sha256')
|
||||||
container: applicationFound.id
|
.update(
|
||||||
}
|
JSON.stringify({
|
||||||
);
|
buildPack: application.buildPack,
|
||||||
if (!isRunning) {
|
port: application.port,
|
||||||
throw { status: 500, message: 'Application not running.' }
|
exposePort: application.exposePort,
|
||||||
}
|
installCommand: application.installCommand,
|
||||||
}
|
buildCommand: application.buildCommand,
|
||||||
if (
|
startCommand: application.startCommand
|
||||||
pullmergeRequestAction === 'opened' ||
|
})
|
||||||
pullmergeRequestAction === 'reopened' ||
|
)
|
||||||
pullmergeRequestAction === 'synchronize'
|
.digest('hex');
|
||||||
) {
|
|
||||||
await prisma.application.update({
|
await prisma.application.update({
|
||||||
where: { id: applicationFound.id },
|
where: { id: application.id },
|
||||||
data: { updatedAt: new Date() }
|
data: { configHash }
|
||||||
});
|
});
|
||||||
await prisma.build.create({
|
|
||||||
data: {
|
|
||||||
id: buildId,
|
|
||||||
pullmergeRequestId,
|
|
||||||
sourceBranch,
|
|
||||||
applicationId: applicationFound.id,
|
|
||||||
destinationDockerId: applicationFound.destinationDocker.id,
|
|
||||||
gitSourceId: applicationFound.gitSource.id,
|
|
||||||
githubAppId: applicationFound.gitSource.githubApp?.id,
|
|
||||||
gitlabAppId: applicationFound.gitSource.gitlabApp?.id,
|
|
||||||
status: 'queued',
|
|
||||||
type: 'webhook_pr'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
message: 'Queued. Thank you!'
|
|
||||||
};
|
|
||||||
} else if (pullmergeRequestAction === 'closed') {
|
|
||||||
if (applicationFound.destinationDockerId) {
|
|
||||||
const id = `${applicationFound.id}-${pullmergeRequestId}`;
|
|
||||||
await removeContainer({ id, dockerId: applicationFound.destinationDocker.id });
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
message: 'Removed preview. Thank you!'
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw { status: 500, message: 'Pull request previews are not enabled.' }
|
await prisma.application.update({
|
||||||
|
where: { id: application.id },
|
||||||
|
data: { updatedAt: new Date() }
|
||||||
|
});
|
||||||
|
console.log(application.id)
|
||||||
|
|
||||||
|
await prisma.build.create({
|
||||||
|
data: {
|
||||||
|
id: buildId,
|
||||||
|
applicationId: application.id,
|
||||||
|
destinationDockerId: application.destinationDocker.id,
|
||||||
|
gitSourceId: application.gitSource.id,
|
||||||
|
githubAppId: application.gitSource.githubApp?.id,
|
||||||
|
gitlabAppId: application.gitSource.gitlabApp?.id,
|
||||||
|
status: 'queued',
|
||||||
|
type: 'webhook_commit'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(`Webhook for ${application.name} queued.`)
|
||||||
|
|
||||||
|
} else if (githubEvent === 'pull_request') {
|
||||||
|
const pullmergeRequestId = body.number.toString();
|
||||||
|
const pullmergeRequestAction = body.action;
|
||||||
|
const sourceBranch = body.pull_request.head.ref.includes('/') ? body.pull_request.head.ref.split('/')[2] : body.pull_request.head.ref;
|
||||||
|
if (!allowedActions.includes(pullmergeRequestAction)) {
|
||||||
|
throw { status: 500, message: 'Action not allowed.' }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (application.settings.previews) {
|
||||||
|
if (application.destinationDockerId) {
|
||||||
|
const isRunning = await checkContainer(
|
||||||
|
{
|
||||||
|
dockerId: application.destinationDocker.id,
|
||||||
|
container: application.id
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (!isRunning) {
|
||||||
|
throw { status: 500, message: 'Application not running.' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
pullmergeRequestAction === 'opened' ||
|
||||||
|
pullmergeRequestAction === 'reopened' ||
|
||||||
|
pullmergeRequestAction === 'synchronize'
|
||||||
|
) {
|
||||||
|
await prisma.application.update({
|
||||||
|
where: { id: application.id },
|
||||||
|
data: { updatedAt: new Date() }
|
||||||
|
});
|
||||||
|
await prisma.build.create({
|
||||||
|
data: {
|
||||||
|
id: buildId,
|
||||||
|
pullmergeRequestId,
|
||||||
|
sourceBranch,
|
||||||
|
applicationId: application.id,
|
||||||
|
destinationDockerId: application.destinationDocker.id,
|
||||||
|
gitSourceId: application.gitSource.id,
|
||||||
|
githubAppId: application.gitSource.githubApp?.id,
|
||||||
|
gitlabAppId: application.gitSource.gitlabApp?.id,
|
||||||
|
status: 'queued',
|
||||||
|
type: 'webhook_pr'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
} else if (pullmergeRequestAction === 'closed') {
|
||||||
|
if (application.destinationDockerId) {
|
||||||
|
const id = `${application.id}-${pullmergeRequestId}`;
|
||||||
|
await removeContainer({ id, dockerId: application.destinationDocker.id });
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw { status: 500, message: 'Not handled event.' }
|
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
return errorHandler({ status, message })
|
return errorHandler({ status, message })
|
||||||
}
|
}
|
||||||
|
@ -95,19 +95,19 @@
|
|||||||
async function isBranchAlreadyUsed(event: any) {
|
async function isBranchAlreadyUsed(event: any) {
|
||||||
selected.branch = event.detail.value;
|
selected.branch = event.detail.value;
|
||||||
try {
|
try {
|
||||||
const data = await get(
|
// const data = await get(
|
||||||
`/applications/${id}/configuration/repository?repository=${selected.repository}&branch=${selected.branch}`
|
// `/applications/${id}/configuration/repository?repository=${selected.repository}&branch=${selected.branch}`
|
||||||
);
|
// );
|
||||||
if (data.used) {
|
// if (data.used) {
|
||||||
const sure = confirm($t('application.configuration.branch_already_in_use'));
|
// const sure = confirm($t('application.configuration.branch_already_in_use'));
|
||||||
if (sure) {
|
// if (sure) {
|
||||||
selected.autodeploy = false;
|
// selected.autodeploy = false;
|
||||||
showSave = true;
|
// showSave = true;
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
showSave = false;
|
// showSave = false;
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
showSave = true;
|
showSave = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showSave = false;
|
showSave = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user