From 41bdfdf78fef3701930a67a3128901f060dc207c Mon Sep 17 00:00:00 2001 From: Paulo Santana <30875229+hikinine@users.noreply.github.com> Date: Sat, 25 May 2024 09:43:49 -0300 Subject: [PATCH 1/3] feat: (#107) webhook listener filter docker events based on image tag. Fixes #107 --- pages/api/deploy/[refreshToken].ts | 49 +++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/pages/api/deploy/[refreshToken].ts b/pages/api/deploy/[refreshToken].ts index 5f88decdc..47cdbda7d 100644 --- a/pages/api/deploy/[refreshToken].ts +++ b/pages/api/deploy/[refreshToken].ts @@ -35,7 +35,20 @@ export default async function handler( const deploymentTitle = extractCommitMessage(req.headers, req.body); const sourceType = application.sourceType; - if (sourceType === "github") { + + if (sourceType === "docker") { + const applicationDockerTag = extractImageTagFromApplication(application.dockerImage); + if (applicationDockerTag) { + const webhookDockerTag = extractImageTagFromRequestEventPayload(req.headers, req.body); + if (webhookDockerTag && (webhookDockerTag !== applicationDockerTag)) { + res.status(301).json({ + message: `Application Image Tag(${applicationDockerTag}) doesn't match request event payload Image Tag(${webhookDockerTag}).` + }); + return; + } + } + } + else if (sourceType === "github") { const branchName = extractBranchName(req.headers, req.body); if (!branchName || branchName !== application.branch) { res.status(301).json({ message: "Branch Not Match" }); @@ -79,6 +92,40 @@ export default async function handler( res.status(400).json({ message: "Error To Deploy Application", error }); } } + +/** + * Return the last part of the image name, which is the tag + * Example: "my-image" => null + * Example: "my-image:latest" => "latest" + * Example: "my-image:1.0.0" => "1.0.0" + * Example: "myregistryhost:5000/fedora/httpd:version1.0" => "version1.0" + * @link https://docs.docker.com/reference/cli/docker/image/tag/ + */ +function extractImageTagFromApplication(dockerImage: string | null) { + if (!dockerImage || typeof dockerImage !== "string") { + return null; + } + + const partsOfDockerImageName = dockerImage.split(':') + if (partsOfDockerImageName.length === 1) { + return null; + } + + return partsOfDockerImageName[partsOfDockerImageName.length - 1]; +} + +/** + * @link https://docs.docker.com/docker-hub/webhooks/#example-webhook-payload + */ +function extractImageTagFromRequestEventPayload(headers: any, body: any) { + if (headers["user-agent"]?.includes("Go-http-client")) { + if (body.push_data && body.repository) { + return body.push_data.tag; + } + } + return null; +} + function extractCommitMessage(headers: any, body: any) { // GitHub if (headers["x-github-event"]) { From eef0bf6ff7da8ddbf04c6147712dab414e853c33 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 25 May 2024 16:13:40 -0600 Subject: [PATCH 2/3] refactor: simplify comparison docker tags --- pages/api/deploy/[refreshToken].ts | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/pages/api/deploy/[refreshToken].ts b/pages/api/deploy/[refreshToken].ts index 47cdbda7d..0552bf17c 100644 --- a/pages/api/deploy/[refreshToken].ts +++ b/pages/api/deploy/[refreshToken].ts @@ -37,15 +37,19 @@ export default async function handler( const sourceType = application.sourceType; if (sourceType === "docker") { - const applicationDockerTag = extractImageTagFromApplication(application.dockerImage); - if (applicationDockerTag) { - const webhookDockerTag = extractImageTagFromRequestEventPayload(req.headers, req.body); - if (webhookDockerTag && (webhookDockerTag !== applicationDockerTag)) { - res.status(301).json({ - message: `Application Image Tag(${applicationDockerTag}) doesn't match request event payload Image Tag(${webhookDockerTag}).` - }); - return; - } + const applicationDockerTag = extractImageTag(application.dockerImage); + const webhookDockerTag = extractImageTagFromRequest( + req.headers, + req.body, + ); + if ( + applicationDockerTag && + webhookDockerTag && + webhookDockerTag !== applicationDockerTag + ) { + return res.status(301).json({ + message: `Application Image Tag (${applicationDockerTag}) doesn't match request event payload Image Tag (${webhookDockerTag}).`, + }); } } else if (sourceType === "github") { @@ -101,23 +105,19 @@ export default async function handler( * Example: "myregistryhost:5000/fedora/httpd:version1.0" => "version1.0" * @link https://docs.docker.com/reference/cli/docker/image/tag/ */ -function extractImageTagFromApplication(dockerImage: string | null) { +function extractImageTag(dockerImage: string | null) { if (!dockerImage || typeof dockerImage !== "string") { return null; } - const partsOfDockerImageName = dockerImage.split(':') - if (partsOfDockerImageName.length === 1) { - return null; - } - - return partsOfDockerImageName[partsOfDockerImageName.length - 1]; + const tag = dockerImage.split(":").pop(); + return tag === dockerImage ? "latest" : tag; } /** * @link https://docs.docker.com/docker-hub/webhooks/#example-webhook-payload */ -function extractImageTagFromRequestEventPayload(headers: any, body: any) { +function extractImageTagFromRequest(headers: any, body: any): string | null { if (headers["user-agent"]?.includes("Go-http-client")) { if (body.push_data && body.repository) { return body.push_data.tag; From e17410137703a44d14e5f7cade10329d594bc19d Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sat, 25 May 2024 16:17:34 -0600 Subject: [PATCH 3/3] refactor: remove return in res status --- pages/api/deploy/[refreshToken].ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pages/api/deploy/[refreshToken].ts b/pages/api/deploy/[refreshToken].ts index 0552bf17c..24def5a4b 100644 --- a/pages/api/deploy/[refreshToken].ts +++ b/pages/api/deploy/[refreshToken].ts @@ -47,9 +47,10 @@ export default async function handler( webhookDockerTag && webhookDockerTag !== applicationDockerTag ) { - return res.status(301).json({ + res.status(301).json({ message: `Application Image Tag (${applicationDockerTag}) doesn't match request event payload Image Tag (${webhookDockerTag}).`, }); + return; } } else if (sourceType === "github") {