Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 28 additions & 23 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,36 +1,41 @@
name: CI

# Botsmann is deployed self-hosted on the Hetzner box "bitbaum" behind Caddy.
# Deployment runs from the local `.husky/pre-push` hook (build -> rsync -> systemd
# restart) when main is pushed. This workflow only validates build/lint/tests.
# The verification that used to live inside the Vercel deploy workflow. It
# belongs in its own file: prod is self-hosted on bitbaum, so the deploy
# workflow is now a shim over the shared pipeline — and that pipeline refuses
# to ship a commit whose CI is not green. Without this file there would be no
# CI to be green, and every deploy would sail through unverified.

on:
push:
branches: [main]
pull_request:
branches: [main]

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
build-and-test:
verify:
name: Format, lint, test, build
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'

- name: Install dependencies
run: npm ci

# Single SSOT gate: format:check + lint + test + build.
# Runs verbatim what developers run locally via `npm run verify`.
# No --if-present: a missing/renamed gate script fails loudly.
- name: Verify (format + lint + test + build)
run: npm run verify
env:
NEXT_PUBLIC_DEPLOY_TIME: ${{ github.event.head_commit.timestamp }}
cache: npm

- run: npm ci

- name: Format check
run: npm run format:check --if-present

- name: Lint
run: npm run lint --if-present

- name: Test
run: npm run test --if-present

- name: Build
run: npm run build
22 changes: 22 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Deploy

# Push to main → deploy botsmann.orangecat.ch to bitbaum. All the logic lives in
# one place: maonakamoto/fleetcrown/.github/workflows/selfhost-deploy.yml (docs:
# docs/infrastructure/self-host-cd.md there). It waits for this commit's own CI
# to go green before anything reaches the box.
#
# Replaces a Vercel deploy workflow: this app has been served from bitbaum
# behind Caddy for months, so those deploys were shipping to somewhere nobody
# looks while the real production build only ever changed by hand.

on:
push:
branches: [main]

jobs:
deploy:
uses: maonakamoto/fleetcrown/.github/workflows/selfhost-deploy.yml@main
with:
app: botsmann
node-version: '22'
secrets: inherit
22 changes: 18 additions & 4 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
#!/usr/bin/env sh
# >>> fleetcrown push-deploy >>>
# Pushing main deploys to the Hetzner box (background; see /tmp/push-deploy-botsmann.log)
if git symbolic-ref --short HEAD 2>/dev/null | grep -qx main; then
( sleep 5 && env -u CI -u VERCEL bash /home/g/dev/fleetcrown/scripts/hetzner/deploy.sh botsmann ) >> /tmp/push-deploy-botsmann.log 2>&1 & disown 2>/dev/null || true
echo "[push-deploy] botsmann: deploy started in background → /tmp/push-deploy-botsmann.log"
# Pushing the repo's default branch deploys to the Hetzner box
# (background; see /tmp/push-deploy-botsmann.log). Repos differ: some use
# 'main', some still use 'master' — match either so push-to-deploy fires
# regardless of the repo's branch convention.
# CI GATE: the background deploy first waits for GitHub CI on the pushed
# commit and is BLOCKED on a red — prod only receives what CI verified
# (ci-gate.sh; repos without CI pass after a short grace window).
if git symbolic-ref --short HEAD 2>/dev/null | grep -qxE 'main|master'; then
( sleep 5
_sha=$(git rev-parse HEAD)
_nwo=$(git remote get-url origin 2>/dev/null | sed -E 's#(git@github.com:|https://github.com/)##; s#\.git$##')
if [ -n "$_nwo" ] && ! bash "/home/g/dev/fleetcrown/scripts/hetzner/ci-gate.sh" "$_nwo" "$_sha"; then
echo "[push-deploy] botsmann: BLOCKED by CI gate for ${_sha} — fix CI, then re-push or deploy manually"
else
env -u CI bash /home/g/dev/fleetcrown/scripts/hetzner/deploy.sh botsmann
fi
) >> /tmp/push-deploy-botsmann.log 2>&1 & disown 2>/dev/null || true
echo "[push-deploy] botsmann: CI-gated deploy started in background → /tmp/push-deploy-botsmann.log"
fi
# <<< fleetcrown push-deploy <<<
Loading