M5: publish seam + CI/CD pipeline
build-and-deploy / build (push) Failing after 15m10s

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:
2026-06-17 17:20:54 +10:00
parent c1db5cec86
commit 83edaf5975
10 changed files with 2503 additions and 4 deletions
+65
View File
@@ -0,0 +1,65 @@
# CI: lint → typecheck → audit gate → build → scan → SBOM → image → digest-bump PR.
# Runs on a self-hosted act_runner (dedicated unprivileged user on the bastion;
# host mode, has node 22 + buildah + git). Registered against git.bztmon.com.
#
# Required repo secrets (set at go-live):
# REGISTRY_USER / REGISTRY_TOKEN - push to git.bztmon.com/jwright/bztmon-site (package:write)
# HOME_OPS_SSH_KEY - deploy key, write to home-ops ONLY
# GITEA_TOKEN - open a PR on the private instance
name: build-and-deploy
on:
push:
branches: [main]
paths:
- "src/**"
- "public/**"
- "astro.config.mjs"
- "package.json"
- "package-lock.json"
- "Dockerfile"
- "nginx/**"
workflow_dispatch: {}
jobs:
build:
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install (from lockfile)
run: npm ci
- name: Type-check
run: npm run check
- name: Dependency audit gate (high/critical)
run: npx audit-ci --config .audit-ci.json
- name: Build
run: npm run build
- name: Security scan (dist)
run: npm run scan
- name: SBOM (CycloneDX)
run: npx @cyclonedx/cyclonedx-npm --output-file sbom.json
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.json
- name: Registry login
run: echo "${{ secrets.REGISTRY_TOKEN }}" | buildah login -u "${{ secrets.REGISTRY_USER }}" --password-stdin git.bztmon.com
- name: Build & push image
run: scripts/build-image.sh push
- name: Open digest-bump PR to home-ops
env:
HOME_OPS_SSH_KEY: ${{ secrets.HOME_OPS_SSH_KEY }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: scripts/bump-digest.sh