vps-health-api/.forgejo/workflows/ci.yml
le king fu 4e7879da6c
All checks were successful
CI / verification (pull_request) Successful in 21s
CI / verification (push) Successful in 19s
ci: add a Forgejo Actions workflow with a boot-from-COPY check (#24)
Nothing verified this repository until now. The workflow runs on every pull
request (no branches filter, so intermediate stack links get a status) and on
pushes to main, in node:22-alpine, the Dockerfile's own base: npm ci, npm test,
the socket-level pass, then scripts/boot-from-copy.sh.

The script stands in for a docker build, which would need the Docker socket in
the instance-scoped runner and so root on the production VPS for every
workflow. It starts the CMD from the COPY sources alone and fails on the
MODULE_NOT_FOUND that #11 had to fix by hand. __tests__/ci.test.js pins the
workflow and what the script assumes of the Dockerfile.

Refs #24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 20:22:48 -04:00

67 lines
2.7 KiB
YAML

name: CI
# Until issue #24 nothing verified this repository: every stack was checked by
# hand, by whoever remembered to run the right command. Modelled on
# `roadtrip/.forgejo/workflows/ci.yml` and `simpl-sante/.forgejo/workflows/ci.yml`,
# the workflows known to run on this runner (Forgejo 8.0.3, runner v12.7.0).
# Two forms are avoided because the runner rejects the whole job before its
# first command, the error being readable only in the Forgejo database on the VPS:
#
# - `working-directory` on a `uses:` step (allowed on `run:` only)
# - `defaults:` at job level
#
# No `concurrency:` key: it is not inert on this instance, and a second push
# cancels the first run — whose missing status then reads like a runner failure.
#
# See `la-compagnie-maximus/docs/forgejo-ops.md` and the `diag-forgejo-ci` skill.
on:
# No `branches:` filter, on purpose. In a stacked run each PR targets the
# previous link's branch and only the root one targets `main`: with
# `branches: [main]` every intermediate link would get no status at all,
# indistinguishable from a runner that never saw the commit.
pull_request:
# Merges land as fast-forwards pushed to `main`: a PR trigger alone would miss
# what actually reaches production.
push:
branches: [main]
jobs:
verification:
runs-on: ubuntu
# The Dockerfile's own base image (a vitest pin keeps the two aligned): the
# tests, the socket pass and the boot check all see the musl libc and busybox
# tools production runs on. The job runs as root in this container, unlike
# the image (`USER node`) — a future test relying on an unreadable file
# would be weakened here without failing.
container: node:22-alpine
steps:
- name: Tooling
# Before any `uses:` step: checkout needs git, test-curl.sh needs bash
# and curl. The image already carries node, which runs checkout@v4.
run: |
apk add --no-cache git bash curl
node --version
npm --version
- name: Checkout
uses: https://github.com/actions/checkout@v4
- name: Dependencies
run: npm ci
- name: Unit tests
run: npm test
- name: Socket-level pass
# Boots its own servers on 3099 and 3098, no outside service needed.
run: bash test-curl.sh
- name: Boot from the COPY file set
# Stands in for a `docker build`: a real build would need the Docker
# socket inside the job, which on this instance-scoped runner makes every
# workflow of every repository root on the production VPS. The script
# starts the CMD from the COPY sources alone and catches the
# MODULE_NOT_FOUND that #11 had to fix by hand.
run: sh scripts/boot-from-copy.sh