From a7bf23222f2a8f0f02b70fcf093bf7d24dcc4b42 Mon Sep 17 00:00:00 2001 From: kuwoyuki Date: Thu, 6 Feb 2025 04:47:42 +0600 Subject: [PATCH] fix: rebuild hook --- README.md | 49 +++----------------------- manifests/ayaume.yaml | 80 +++++++++++++++++++++++++++++++++++++++++++ package.json | 8 ++--- server.js | 74 +++++++++++++++++++-------------------- 4 files changed, 123 insertions(+), 88 deletions(-) create mode 100644 manifests/ayaume.yaml diff --git a/README.md b/README.md index ff19a3e..2f3dbb3 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,7 @@ -# Astro Starter Kit: Basics +# blog -```sh -npm create astro@latest -- --template basics -``` +`POST /webhook/rebuild` spawns npm run build and rebuilds -[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/basics) -[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/basics) -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/basics/devcontainer.json) +docker entrypoint is `node --watch server.js`, fastify serves `dist` as static content -> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! - -![just-the-basics](https://github.com/withastro/astro/assets/2244813/a0a5533c-a856-4198-8470-2d67b1d7c554) - -## 🚀 Project Structure - -Inside of your Astro project, you'll see the following folders and files: - -```text -/ -├── public/ -│ └── favicon.svg -├── src/ -│ ├── layouts/ -│ │ └── Layout.astro -│ └── pages/ -│ └── index.astro -└── package.json -``` - -To learn more about the folder structure of an Astro project, refer to [our guide on project structure](https://docs.astro.build/en/basics/project-structure/). - -## 🧞 Commands - -All commands are run from the root of the project, from a terminal: - -| Command | Action | -| :------------------------ | :----------------------------------------------- | -| `npm install` | Installs dependencies | -| `npm run dev` | Starts local dev server at `localhost:4321` | -| `npm run build` | Build your production site to `./dist/` | -| `npm run preview` | Preview your build locally, before deploying | -| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | -| `npm run astro -- --help` | Get help using the Astro CLI | - -## 👀 Want to learn more? - -Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat). +[manifests/ayaume.yaml](/manifests/ayaume.yaml) has k8s manifest examples diff --git a/manifests/ayaume.yaml b/manifests/ayaume.yaml new file mode 100644 index 0000000..809918e --- /dev/null +++ b/manifests/ayaume.yaml @@ -0,0 +1,80 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: ayaume +--- +apiVersion: v1 +kind: Secret +metadata: + name: blog-secrets + namespace: ayaume +type: Opaque +data: + webhook-secret: c2VjcmV0 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: blog + namespace: ayaume +spec: + replicas: 1 + selector: + matchLabels: + app: blog + template: + metadata: + labels: + app: blog + spec: + containers: + - name: blog + image: registry.ayau.me/blog:latest + ports: + - containerPort: 3000 + env: + - name: WEBHOOK_SECRET + valueFrom: + secretKeyRef: + name: blog-secrets + key: webhook-secret + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "256Mi" + cpu: "200m" +--- +apiVersion: v1 +kind: Service +metadata: + name: blog + namespace: ayaume +spec: + ports: + - port: 80 + targetPort: 3000 + selector: + app: blog +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: blog-ingress + namespace: ayaume + annotations: + spec.ingressClassName: traefik +spec: + rules: + - host: w.ayau.me + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: blog + port: + number: 80 diff --git a/package.json b/package.json index afdf028..2d65029 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,10 @@ "type": "module", "version": "0.0.1", "scripts": { - "dev": "astro dev", - "build": "astro build", - "preview": "astro preview", - "astro": "astro" + "dev": "ASTRO_TELEMETRY_DISABLED=1 astro dev", + "build": "ASTRO_TELEMETRY_DISABLED=1 astro build", + "preview": "ASTRO_TELEMETRY_DISABLED=1 astro preview", + "astro": "ASTRO_TELEMETRY_DISABLED=1 astro" }, "dependencies": { "@astrojs/mdx": "^4.0.8", diff --git a/server.js b/server.js index 260c758..b4f37aa 100644 --- a/server.js +++ b/server.js @@ -3,9 +3,14 @@ import fastifyStatic from "@fastify/static"; import { exec } from "node:child_process"; import { promisify } from "node:util"; import path from "node:path"; -import crypto from "node:crypto"; -const { WEBHOOK_SECRET } = process.env; +const { AUTH_TOKEN } = process.env; + +const authMiddleware = async (request, reply) => { + if (request.headers.authorization !== `Bearer ${AUTH_TOKEN}`) { + return reply.code(401).send("Unauthorized"); + } +}; const execAsync = promisify(exec); const fastify = Fastify({ logger: true }); @@ -15,47 +20,38 @@ fastify.register(fastifyStatic, { prefix: "/", }); -const verifySignature = (payload, signature) => { - const hmac = crypto.createHmac("sha256", WEBHOOK_SECRET); - const digest = "sha256=" + hmac.update(payload).digest("hex"); - return crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(signature)); -}; +fastify.post( + "/webhook/rebuild", + { preHandler: authMiddleware }, + async (request, reply) => { + try { + const { + ref, + repository: { clone_url: repoUrl }, + } = request.body; -const updateRepo = async (repoUrl) => { - try { - const { code } = await execAsync("git rev-parse --git-dir") - .then(() => ({ code: 0 })) - .catch((error) => ({ code: error.code })); + const { code } = await execAsync("git rev-parse --git-dir") + .then(() => ({ code: 0 })) + .catch((error) => ({ code: error.code })); - if (code !== 0) { - await execAsync("git init"); - await execAsync(`git remote add origin ${repoUrl}`); + if (code !== 0) { + await execAsync("git init"); + await execAsync(`git remote add origin ${repoUrl}`); + } + + await execAsync(`git remote set-url origin ${repoUrl}`); + await execAsync("git fetch origin"); + // we won't be able to reply later, so do it here + // this doesn't necessarily imply a successful build though + // TODO: healthcheck + reply.status(200).send("Updated successfully"); + await execAsync(`git reset --hard ${ref}`); + await execAsync("npm run build"); + } catch (error) { + reply.status(500).send("Update failed"); } - - await execAsync("git fetch origin"); - await execAsync("git reset --hard origin/main"); - await execAsync("npm run build"); - } catch (error) { - console.error("Failed to update repository:", error); - throw error; } -}; - -fastify.post("/webhook/rebuild", async (request, reply) => { - const signature = request.headers["x-gitea-signature"]; - - if (!signature || !verifySignature(JSON.stringify(request.body), signature)) { - return reply.status(401).send("Invalid signature"); - } - - try { - const repoUrl = request.body.repository.clone_url; - await updateRepo(repoUrl); - reply.status(200).send("Updated successfully"); - } catch (error) { - reply.status(500).send("Update failed"); - } -}); +); fastify.listen({ port: 3000, host: "0.0.0.0" }, (err) => { if (err) {