Skip to content

Instantly share code, notes, and snippets.

@maietta
Created January 12, 2025 06:20
Show Gist options
  • Save maietta/3decaf7310e1b3116ecbbbb77ed8381b to your computer and use it in GitHub Desktop.
Save maietta/3decaf7310e1b3116ecbbbb77ed8381b to your computer and use it in GitHub Desktop.
Proxies webhook payloads from Gitea and triggers a deploy for a matching repo and branch.
import { serve } from "bun";
import fs from "fs";
// Extract the repository name and branch from the payload
function extractRepoInfo(payload: { repository: { full_name: string }; ref: string }) {
const repoName = payload?.repository?.full_name; // Repository name is in 'full_name'
const branch = payload?.ref?.split("/").pop(); // Branch name is after 'refs/heads/'
return { repoName, branch };
}
const apiUrl = `${process.env.COOLIFY_API_URL}/api/v1`;
const token = `Bearer ${process.env.COOLIFY_API_KEY}`;
// Function to fetch the API list
async function getApiList() {
const url = `${apiUrl}/applications`; // Adjust to your actual API endpoint for the list
try {
const response = await fetch(url, {
headers: {
Authorization: token,
},
});
if (!response.ok) {
throw new Error(
`HTTP error! status: ${response.status} - ${response.statusText}`
);
}
const data = await response.json();
// Write the API list to a file
fs.writeFileSync("applications_list.json", JSON.stringify(data, null, 2));
console.log("Application list saved to 'applications_list.json'.");
return data; // Assuming the API returns a JSON list
} catch (error: any) {
console.error("Error fetching API list:", error.message);
throw error;
}
}
// Function to trigger a Coolify webhook
async function triggerWebhook(uuid: string, force: boolean): Promise<any> {
const url = `${apiUrl}/deploy?uuid=${uuid}&force=${force}`;
try {
const response = await fetch(url, {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
});
if (!response.ok) {
throw new Error(
`HTTP error! status: ${response.status} - ${response.statusText}`
);
}
return await response.json();
} catch (error: any) {
console.error("Error triggering the webhook:", error.message);
throw error;
}
}
// Handle the request
serve({
port: 3000,
fetch(req) {
if (req.method === "POST") {
return req
.json()
.then(async (payload) => {
const { repoName, branch } = extractRepoInfo(payload);
if (!repoName || !branch) {
return new Response(
JSON.stringify({ error: "Missing repository name or branch" }),
{ status: 400 }
);
}
// Log the extracted information
console.log(`Repository from Payload: ${repoName}`);
console.log(`Branch from Payload: ${branch}`);
try {
const apiList = await getApiList();
// Log the entire API list item to inspect the structure
const matchedRepo = apiList.find(
(item: {
git_repository: string;
branch: string;
uuid: string;
}) => {
// Log the item object to see its structure
console.log("API list item:", item);
// Extract repo names from both payload and API list
const trimmedRepoName = repoName.trim().toLowerCase();
const trimmedApiRepo = item.git_repository
?.trim()
.toLowerCase();
// Log the repository names being compared
console.log(
`Checking match for repository: Payload Repo: '${trimmedRepoName}', API Repo: '${trimmedApiRepo}'`
);
// Return true if the names match
return trimmedRepoName === trimmedApiRepo;
}
);
if (matchedRepo) {
console.log(`Repository match found! API Repository: ${matchedRepo.git_repository}`);
console.log(`Matching UUID: ${matchedRepo.uuid}`);
// Log the entire matchedRepo to inspect its structure
// console.log("Matched Repo Data:", matchedRepo);
// Now, check for branch information inside the git_repository field
if (matchedRepo.git_repository && matchedRepo.git_repository.branch) {
const apiBranch = matchedRepo.git_repository.branch;
// Check if the branch matches with a case-insensitive comparison
if (apiBranch.toLowerCase() === branch.toLowerCase()) {
console.log(`Branch matches: ${apiBranch}`);
// await triggerWebhook(matchedRepo.uuid, false); // Trigger the webhook
} else {
console.log(`Branch does not match. Payload Branch: ${branch}, API Branch: ${apiBranch}`);
}
} else {
console.log("No branch field found in the git_repository data.");
}
} else {
console.log("No matching repository found in the API list.");
}
} catch (error: any) {
console.error("Error processing API list:", error.message);
return new Response(
JSON.stringify({ error: "Error processing API list" }),
{ status: 500 }
);
}
return new Response(
JSON.stringify({
message: "Payload received successfully",
repository: repoName,
branch: branch,
}),
{
status: 200,
headers: { "Content-Type": "application/json" },
}
);
})
.catch((err) => {
console.error("Error parsing JSON:", err);
return new Response(JSON.stringify({ error: "Invalid JSON" }), {
status: 400,
});
});
}
return new Response("Not Found", { status: 404 });
},
});
console.log("Server running at http://localhost:3000/");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment