# 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:@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