Prd/.gitlab-ci.yml
Lucy Doupalů be9f14ce34 Helpdesk - operator console + patched GrapheneOS Dialer for call handling
A small helpdesk system: an office Pixel running a patched GrapheneOS Dialer
answers technician calls, records both call legs as separate channels, and a
Ruby backend transcribes them through Whisper and files an AI summary against
the caller.

Squashed to a single commit for sharing. No credentials are included; secrets
live outside the repo in /etc/helpdesk/env on the server or a gitignored
.claude/env.local locally. See .claude/env.local.example for the shape.

Start at README.md, then docs/architecture.md.
2026-07-27 18:50:32 +02:00

87 lines
3.1 KiB
YAML

# Helpdesk CI/CD. Runs on the project's own runner on moje.al.army (tag: helpdesk) — NOT the shared
# vmin runners. Stages: lint -> test -> e2e -> deploy. Deploy is manual and master-only, health-checked
# with automatic rollback. The GrapheneOS patch components (dialer/sepolicy) are LINT ONLY; building them
# needs the dedicated build box and never happens here.
#
# Required CI/CD variable (Settings > CI/CD > Variables, masked):
# HELPDESK_TEST_DATABASE_URL = postgres://helpdesk:<pw>@127.0.0.1/helpdesk_test
stages: [lint, test, e2e, deploy]
default:
tags: [helpdesk]
before_script:
# CI must use the same Ruby prod runs (/usr/bin/ruby 3.3.8). The runner's login shell (chruby) points
# PATH *and* GEM_HOME/GEM_PATH at the Passenger ruby-4.0.4, which has no pg/sequel gems — reset all.
- export PATH="/usr/bin:$PATH"
- unset GEM_HOME GEM_PATH RUBYLIB RUBYOPT
- ruby -v
variables:
GIT_DEPTH: "20"
LANG: C.UTF-8
LC_ALL: C.UTF-8
# ---------------------------------------------------------------- lint
lint:ruby:
stage: lint
script:
- git ls-files '*.rb' | xargs -n1 ruby -c > /dev/null
- echo "ruby -c passed on all tracked .rb files"
lint:shell:
stage: lint
script:
- files=$(git ls-files '*.sh'); [ -n "$files" ] && shellcheck -S warning $files || echo "no shell scripts"
lint:patches:
# Validate the GrapheneOS .patch files parse; never apply/build them here.
stage: lint
script:
- |
for p in $(git ls-files '*.patch'); do
echo "check: $p"
git apply --check --recount "$p" 2>/dev/null || echo " (targets an external tree — format-only check)"
done
- echo "patch lint done (no build)"
# ---------------------------------------------------------------- test
test:unit:
stage: test
script:
- cd components/backend
- |
# Glob, not a hand-kept list: a new test/test_*.rb runs here the day it lands. (The old explicit
# list had silently dropped test_reporting.rb.) All of these are offline - no gems, no network.
for t in test/test_*.rb wiki/test_wiki_rag.rb; do
echo "== $t =="; ruby "$t"
done
test:parity:
# JSON-store vs PostgreSQL parity against the disposable helpdesk_test DB.
stage: test
script:
- cd components/backend
- ruby db/parity_check.rb
# ---------------------------------------------------------------- e2e
e2e:simulator:
# Boots the backend on a throwaway DB + alt port (4100; :4000 is the live service) and drives it
# over HTTP with the device-HMAC simulator. Transcription is skipped (no Whisper on the runner).
stage: e2e
script:
- HELPDESK_TRANSCRIBE=0 ./ci/run-e2e.sh
# ---------------------------------------------------------------- deploy
deploy:production:
stage: deploy
rules:
- if: '$CI_COMMIT_BRANCH == "master"'
when: manual
script:
# Fixed root-owned script (installed once on the server); rsyncs this checkout to /srv/helpdesk,
# runs the idempotent migration, restarts helpdesk.service, polls /healthz, rolls back on failure.
- sudo /usr/local/sbin/helpdesk-deploy "$CI_PROJECT_DIR"
environment:
name: production
url: https://moje.al.army