fix: rebuild hook

This commit is contained in:
2025-02-06 04:47:42 +06:00
parent f297c5b18f
commit a7bf23222f
4 changed files with 123 additions and 88 deletions

View File

@@ -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

80
manifests/ayaume.yaml Normal file
View File

@@ -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

View File

@@ -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",

View File

@@ -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,14 +20,16 @@ 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));
};
const updateRepo = async (repoUrl) => {
fastify.post(
"/webhook/rebuild",
{ preHandler: authMiddleware },
async (request, reply) => {
try {
const {
ref,
repository: { clone_url: repoUrl },
} = request.body;
const { code } = await execAsync("git rev-parse --git-dir")
.then(() => ({ code: 0 }))
.catch((error) => ({ code: error.code }));
@@ -32,30 +39,19 @@ const updateRepo = async (repoUrl) => {
await execAsync(`git remote add origin ${repoUrl}`);
}
await execAsync(`git remote set-url origin ${repoUrl}`);
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);
// 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");
}
});
}
);
fastify.listen({ port: 3000, host: "0.0.0.0" }, (err) => {
if (err) {