fix: rebuild hook
This commit is contained in:
49
README.md
49
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
|
||||
|
||||
[](https://stackblitz.com/github/withastro/astro/tree/latest/examples/basics)
|
||||
[](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/basics)
|
||||
[](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!
|
||||
|
||||

|
||||
|
||||
## 🚀 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
80
manifests/ayaume.yaml
Normal 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
|
||||
@@ -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",
|
||||
|
||||
74
server.js
74
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) {
|
||||
|
||||
Reference in New Issue
Block a user