scripts/new-post.mjs writes schema-valid posts from flags or a JSON event (the IaC publish seam). Gitea Actions workflow: ci check, audit-ci gate, build, dist scan, CycloneDX SBOM, buildah build+push, and a least-privilege digest-bump PR to home-ops (never auto-merged). Renovate + audit allowlist.
This commit is contained in:
@@ -46,8 +46,46 @@ Dockerfile Debian build stage → nginx-unprivileged runtime
|
||||
- Fill the `TODO(Jonathon)` markers in `src/data/experience.ts`, `projects.ts`, `socials.ts`
|
||||
(employer names, dates, GitHub/LinkedIn handles).
|
||||
|
||||
## Publishing a post
|
||||
|
||||
A post is just a Markdown file in `src/content/blog/`. Write one by hand, or generate
|
||||
a schema-valid one with the publish helper (this is the seam an IaC/CI step calls):
|
||||
|
||||
```bash
|
||||
# from flags
|
||||
node scripts/new-post.mjs --title "My post" --summary "One line" \
|
||||
--tags "kubernetes,gpu" [--draft] [--bodyFile notes.md]
|
||||
|
||||
# from a JSON event (e.g. an Ansible/AWX deploy summary)
|
||||
echo '{"title":"...","summary":"...","tags":["x"],"body":"## Hi\n..."}' \
|
||||
| node scripts/new-post.mjs --stdin
|
||||
```
|
||||
|
||||
Commit the file to `main` → CI rebuilds and ships. A malformed post **fails the build**
|
||||
(frontmatter is zod-validated), so a bad pipeline event never reaches production.
|
||||
|
||||
## CI/CD
|
||||
|
||||
`.gitea/workflows/deploy.yml` runs on a self-hosted runner (a dedicated unprivileged
|
||||
user on the bastion):
|
||||
|
||||
```
|
||||
npm ci → astro check → audit-ci (high/critical gate) → build → scan dist →
|
||||
SBOM (CycloneDX) → buildah build+push → open a digest-bump PR to home-ops
|
||||
```
|
||||
|
||||
The PR is **never auto-merged** — `home-ops` `main` is branch-protected; merging it is
|
||||
what triggers the ArgoCD rollout. The runner holds only least-privilege creds (a
|
||||
`home-ops`-scoped deploy key + a PR token + a registry push token).
|
||||
|
||||
- `npm run scan` — build-time gate: no secrets, no inline scripts, no third-party origins.
|
||||
- `.audit-ci.json` — fails on high/critical advisories. One allowlisted: `GHSA-gv7w-rqvm-qjhr`
|
||||
(esbuild install-integrity; build-time only, mitigated by the committed lockfile + trusted registry).
|
||||
- `renovate.json` — keeps npm deps and the digest-pinned base images current.
|
||||
|
||||
## Deploy
|
||||
|
||||
Built into a container image, served by nginx-unprivileged on a homelab Kubernetes
|
||||
cluster, exposed via Cloudflare Tunnel. The image is pinned by digest in the private
|
||||
`home-ops` repo and rolled out by ArgoCD. See `scripts/build-image.sh`.
|
||||
`home-ops` repo and rolled out by ArgoCD. Manual/bootstrap build: `scripts/build-image.sh push`.
|
||||
See `SECURITY.md` for the full security posture.
|
||||
|
||||
Reference in New Issue
Block a user