Files
Crussell/.gitea/workflows/ci.yaml
T
popertots e896591098
CI / Docker compose check (push) Successful in 14s
CI / Env docs check (push) Successful in 15s
CI / Nginx config check (push) Successful in 18s
CI / Frontend deps check (push) Successful in 27s
CI / Frontend major deps (push) Failing after 27s
CI / Go build (push) Successful in 35s
CI / Secrets scan (push) Successful in 41s
CI / Frontend build (push) Successful in 43s
CI / Knip (push) Successful in 28s
CI / Frontend a11y check (push) Successful in 1m35s
CI / Go vet (prod) (push) Successful in 2m11s
CI / go mod tidy (push) Successful in 42s
CI / Go vet (dev) (push) Successful in 2m18s
CI / Frontend QC (audit) (push) Successful in 48s
CI / Staticcheck (prod) (push) Successful in 2m57s
CI / Staticcheck (dev) (push) Successful in 3m1s
CI / Go vulnerabilities (push) Successful in 1m27s
CI / golangci-lint (push) Successful in 3m41s
CI / Frontend QC (typecheck) (push) Successful in 1m35s
CI / Frontend QC (lint) (push) Successful in 1m51s
CI / Security scan (prod) (push) Successful in 4m29s
CI / Security scan (dev) (push) Successful in 4m44s
CI / Svelte strict check (push) Successful in 1m49s
CI / Tests (prod) (push) Successful in 3m30s
CI / Tests (dev) (push) Successful in 3m57s
CI / Race (prod) (push) Successful in 7m14s
CI / Race (dev) (push) Successful in 7m25s
chore: upgrade npm deps — vite 8, prettier plugins, @types/node, @eslint/compat
Upgrades applied:
  @types/node: 22.20.1 → 26.1.1
  @eslint/compat: 1.4.1 → 2.1.0
  prettier-plugin-tailwindcss: 0.7.4 → 0.8.0
  prettier-plugin-svelte: 3.5.2 → 4.1.1 (formatted textarea.svelte)
  vite: 7.3.6 → 8.1.4
  @sveltejs/vite-plugin-svelte: 6.2.4 → 7.2.0

Left at current (blocked by deps chain):
  eslint / @eslint/js — typescript-eslint needs eslint 10 support
  typescript — typescript-eslint needs TS 7 support

Added CI TODO note for when vite-plugin-svelte-inspector catches up.
2026-07-10 20:03:41 +01:00

923 lines
27 KiB
YAML

name: CI
description: Runs Go tests, race detection, vulnerability scanning, and frontend quality checks.
on:
push:
branches:
- main
- develop
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
POSTGRES_DB: mydb
jobs:
secrets-scan:
name: Secrets scan
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- uses: actions/setup-go@v5
with:
go-version: "1.26"
cache: false
- name: Install git (required by gitleaks)
run: apk add --no-cache git
- name: Install gitleaks
run: go install github.com/zricethezav/gitleaks/v8@latest
- name: Detect secrets
run: gitleaks detect --source . --verbose --no-banner
env-docs-check:
name: Env docs check
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- name: Install python3
run: apk add --no-cache python3
- name: Check env var documentation
run: python3 scripts/check-env-docs.py
go-build:
name: Go build
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26"
cache: false
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-build
restore-keys: |
${{ runner.os }}-go-
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Build
run: go build ./...
working-directory: backend
go-vet-dev:
name: Go vet (dev)
needs: [go-build]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26"
cache: false
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-vet-dev
restore-keys: |
${{ runner.os }}-go-
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Vet (dev tags)
run: go vet -tags "test,dev" ./...
working-directory: backend
go-vet-prod:
name: Go vet (prod)
needs: [go-build]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26"
cache: false
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-vet-prod
restore-keys: |
${{ runner.os }}-go-
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Vet (prod tags)
run: go vet -tags "test,!dev" ./...
working-directory: backend
go-lint:
name: golangci-lint
needs: [go-build]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26"
cache: false
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-lint
restore-keys: |
${{ runner.os }}-go-
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: golangci-lint
run: |
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
golangci-lint run ./... --timeout 5m
working-directory: backend
go-staticcheck-dev:
name: Staticcheck (dev)
needs: [go-build]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26"
cache: false
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-staticcheck-dev
restore-keys: |
${{ runner.os }}-go-
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Staticcheck (dev tags)
run: |
go install honnef.co/go/tools/cmd/staticcheck@latest
staticcheck -tags "test,dev" ./...
working-directory: backend
go-staticcheck-prod:
name: Staticcheck (prod)
needs: [go-build]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26"
cache: false
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-staticcheck-prod
restore-keys: |
${{ runner.os }}-go-
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Staticcheck (prod tags)
run: |
go install honnef.co/go/tools/cmd/staticcheck@latest
staticcheck -tags "test,!dev" ./...
working-directory: backend
go-gosec-dev:
name: Security scan (dev)
needs: [go-build]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26"
cache: false
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-gosec-dev
restore-keys: |
${{ runner.os }}-go-
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: gosec (dev tags)
run: |
go install github.com/securego/gosec/v2/cmd/gosec@latest
gosec -severity medium -tags "test,dev" ./...
working-directory: backend
go-gosec-prod:
name: Security scan (prod)
needs: [go-build]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26"
cache: false
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-gosec-prod
restore-keys: |
${{ runner.os }}-go-
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: gosec (prod tags)
run: |
go install github.com/securego/gosec/v2/cmd/gosec@latest
gosec -severity medium -tags "test,!dev" ./...
working-directory: backend
go-mod-tidy:
name: go mod tidy
needs: [go-build]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26"
cache: false
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-tidy
restore-keys: |
${{ runner.os }}-go-
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: go mod tidy check
run: |
cp go.sum go.sum.bak
cp go.mod go.mod.bak
go mod tidy
diff -q go.sum go.sum.bak && diff -q go.mod go.mod.bak && echo "go.mod and go.sum up to date" || { echo "go.mod or go.sum out of date — run 'go mod tidy' and commit"; exit 1; }
rm -f go.sum.bak go.mod.bak
working-directory: backend
test:
name: Tests (${{ matrix.label }})
needs: [go-vet-dev, go-vet-prod, go-lint, go-staticcheck-dev, go-staticcheck-prod, go-gosec-dev, go-gosec-prod, go-mod-tidy, vulns]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
POSTGRES_DB: mydb
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
strategy:
matrix:
include:
- label: dev
gotags: test,dev
verbose: -v
coverflags: -coverprofile=coverage.out -covermode=atomic
- label: prod
gotags: test,!dev
verbose: ""
coverflags: -coverprofile=coverage.out -covermode=atomic
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26"
cache: false
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-test-${{ matrix.label }}
restore-keys: |
${{ runner.os }}-go-
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Install psql client
run: apk add --no-cache postgresql-client
- name: Wait for Postgres
run: |
for i in $(seq 1 30); do
pg_isready -h postgres -U myuser && break
sleep 1
done
- name: Create test database
run: PGPASSWORD=mypassword psql -h postgres -U myuser -d mydb -c "CREATE DATABASE crussell_test_db;" 2>/dev/null || true
- name: Run tests
working-directory: backend
run: go test -tags "${{ matrix.gotags }}" -count=1 ${{ matrix.verbose }} ${{ matrix.coverflags }} ./...
env:
GO_TESTING: "1"
POSTGRES_HOST: postgres
TEST_DB_HOST: postgres
- name: Report coverage
working-directory: backend
run: |
if [ -f coverage.out ]; then
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
echo "Total coverage: $COVERAGE%"
go tool cover -func=coverage.out | grep -E "total|handler"
else
echo "No coverage file generated"
fi
race:
name: Race (${{ matrix.label }})
needs: [go-vet-dev, go-vet-prod, go-lint, go-staticcheck-dev, go-staticcheck-prod, go-gosec-dev, go-gosec-prod, go-mod-tidy, vulns]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
POSTGRES_DB: mydb
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
strategy:
matrix:
include:
- label: dev
gotags: test,dev
- label: prod
gotags: test,!dev
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26"
cache: false
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-race-${{ matrix.label }}
restore-keys: |
${{ runner.os }}-go-
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Install psql + build-base
run: apk add --no-cache postgresql-client build-base
- name: Wait for Postgres
run: |
for i in $(seq 1 30); do
pg_isready -h postgres -U myuser && break
sleep 1
done
- name: Create test database
run: PGPASSWORD=mypassword psql -h postgres -U myuser -d mydb -c "CREATE DATABASE crussell_test_db;" 2>/dev/null || true
- name: Run race detector
working-directory: backend
run: go test -tags "${{ matrix.gotags }}" -race -count=1 ./...
env:
POSTGRES_HOST: postgres
TEST_DB_HOST: postgres
CGO_ENABLED: "1"
vulns:
name: Go vulnerabilities
needs: [go-build]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26"
cache: false
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-vulns
restore-keys: |
${{ runner.os }}-go-
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Go vulnerability scan
working-directory: backend
run: |
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
frontend-deps:
name: Frontend deps check
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Cache npm dependencies
uses: actions/cache@v4
with:
path: |
~/.npm
frontend/node_modules
key: ${{ runner.os }}-npm-${{ hashFiles('frontend/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
- name: Install dependencies
run: cd frontend && npm ci
- name: Check for in-range dependency updates
run: |
cd frontend && npm outdated --json 2>&1 | node -e "
const chunks = [];
process.stdin.on('data', c => chunks.push(c));
process.stdin.on('end', () => {
const raw = Buffer.concat(chunks).toString().trim();
if (!raw) { console.log('No dependencies to check'); process.exit(0); }
const data = JSON.parse(raw);
const updates = Object.entries(data).filter(([_, v]) => v.current !== v.wanted);
if (updates.length) {
console.log('In-range updates available — run \"npm update\" locally and commit:');
updates.forEach(([k, v]) => console.log(' ' + k + ': ' + v.current + ' -> ' + v.wanted));
process.exit(1);
}
console.log('All dependencies up to date within semver range');
});
"
- name: Check for stale overrides
run: |
cd frontend && node -e "
const { execSync } = require('child_process');
const pkg = JSON.parse(require('fs').readFileSync('package.json', 'utf8'));
const overrides = pkg.overrides || {};
const keys = Object.keys(overrides);
if (!keys.length) { console.log('No overrides configured'); process.exit(0); }
function parseMin(range) {
const v = range.replace(/^[\^~>=<]*/, '').split('.').map(Number);
return { major: v[0]||0, minor: v[1]||0, patch: v[2]||0 };
}
function gte(a, b) {
if (a.major !== b.major) return a.major > b.major;
if (a.minor !== b.minor) return a.minor > b.minor;
return a.patch >= b.patch;
}
let stale = [];
for (const key of keys) {
const explain = execSync('npm explain ' + key + ' 2>/dev/null || true').toString();
const was = explain.match(/\(was \"([^\"]+)\"\)/);
if (!was) {
const found = explain.includes('node_modules/' + key);
console.log(key + ': ' + (found ? 'override active' : 'not in tree'));
continue;
}
const parentRange = was[1];
const overrideTarget = overrides[key];
if (gte(parseMin(parentRange), parseMin(overrideTarget))) {
stale.push(key + ' (parent requires ' + parentRange + ', override is ' + overrideTarget + ')');
}
}
if (stale.length) {
console.log('Stale overrides detected — remove from package.json:');
stale.forEach(s => console.log(' ' + s));
process.exit(1);
}
console.log('All overrides appear necessary');
"
frontend-deps-major:
name: Frontend major deps
continue-on-error: true
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Restore npm dependencies
uses: actions/cache@v4
with:
path: |
~/.npm
frontend/node_modules
key: ${{ runner.os }}-npm-${{ hashFiles('frontend/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
- name: Install dependencies
run: cd frontend && npm ci
- name: Check for major updates (non-blocking)
run: |
cd frontend && npm outdated --json 2>&1 | node -e "
const chunks = [];
process.stdin.on('data', c => chunks.push(c));
process.stdin.on('end', () => {
const raw = Buffer.concat(chunks).toString().trim();
if (!raw) { console.log('No dependencies to check'); process.exit(0); }
const data = JSON.parse(raw);
const major = Object.entries(data).filter(([_, v]) => v.wanted !== v.latest);
if (major.length) {
console.log('Major (out-of-range) updates available — review carefully:');
major.forEach(([k, v]) => console.log(' ' + k + ': ' + v.current + ' (wanted: ' + v.wanted + ') -> latest: ' + v.latest));
// TODO: vite 8 + svelte-vite 7 now install clean via npm ci.
// Remove --legacy-peer-deps from local npm install workflow once
// @sveltejs/vite-plugin-svelte-inspector catches up.
process.exit(1);
} else {
console.log('All dependencies within semver range, no major updates');
process.exit(0);
}
});
"
knip:
name: Knip
needs: [frontend-deps]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Restore npm dependencies
uses: actions/cache@v4
with:
path: |
~/.npm
frontend/node_modules
key: ${{ runner.os }}-npm-${{ hashFiles('frontend/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
- name: Install dependencies
run: cd frontend && npm ci
- name: Run knip
run: cd frontend && npx knip
frontend-a11y:
name: Frontend a11y check
needs: [frontend-deps]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Restore npm dependencies
uses: actions/cache@v4
with:
path: |
~/.npm
frontend/node_modules
key: ${{ runner.os }}-npm-${{ hashFiles('frontend/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
- name: Install dependencies
run: cd frontend && npm ci
- name: Check a11y
run: cd frontend && npm run lint:a11y
frontend-build:
name: Frontend build
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Cache npm dependencies
uses: actions/cache@v4
with:
path: |
~/.npm
frontend/node_modules
key: ${{ runner.os }}-npm-${{ hashFiles('frontend/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
- name: Install dependencies
run: cd frontend && npm ci
- name: Build
run: cd frontend && npm run build
frontend-svelte-strict:
name: Svelte strict check
needs: [frontend-qc]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Restore npm dependencies
uses: actions/cache@v4
with:
path: |
~/.npm
frontend/node_modules
key: ${{ runner.os }}-npm-${{ hashFiles('frontend/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
- name: Install dependencies
run: cd frontend && npm ci
- name: svelte-kit sync
run: cd frontend && npx svelte-kit sync
- name: svelte-check (fail on warnings)
run: cd frontend && npx svelte-check --tsconfig ./tsconfig.json --fail-on-warnings
frontend-qc:
name: Frontend QC (${{ matrix.task }})
needs: [frontend-build, knip]
runs-on: ubuntu-latest
defaults:
run:
shell: sh
strategy:
matrix:
include:
- task: typecheck
cmd: npm run check
- task: lint
cmd: npm run lint
- task: audit
cmd: npm audit --audit-level=info
steps:
- uses: actions/checkout@v4
- name: Fix node toolcache path for Post-step cleanup
run: |
mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin
ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node
- name: Restore npm dependencies
uses: actions/cache@v4
with:
path: |
~/.npm
frontend/node_modules
key: ${{ runner.os }}-npm-${{ hashFiles('frontend/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
- name: Install dependencies
run: cd frontend && npm ci
- name: Run QC task
run: cd frontend && ${{ matrix.cmd }}
docker-compose-check:
name: Docker compose check
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- name: Install docker CLI
run: apk add --no-cache docker-cli docker-compose
- name: Create env file for compose validation
run: cp .env.example backend/.env
- name: Validate compose.yml
run: docker compose -f compose.yml config --quiet
nginx-check:
name: Nginx config check
runs-on: ubuntu-latest
defaults:
run:
shell: sh
steps:
- uses: actions/checkout@v4
- name: Install nginx
run: apk add --no-cache nginx
- name: Validate nginx config
run: |
apk add --no-cache openssl
mkdir -p /etc/nginx/http.d /etc/nginx/certs
cp $(pwd)/nginx/conf.d/default.conf /etc/nginx/http.d/default.conf
# Create dummy TLS certs so nginx -t can resolve ssl_certificate paths
openssl req -x509 -nodes -days 1 -newkey rsa:2048 -keyout /etc/nginx/certs/privkey.pem -out /etc/nginx/certs/fullchain.pem -subj "/CN=localhost" 2>/dev/null
# Add compose service names so nginx -t can resolve upstreams
echo "127.0.0.1 backend sabredav" >> /etc/hosts
nginx -t