mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-20 22:23:02 +03:00
The tracked frontend/public/mockServiceWorker.js is generated by msw and pinned at 2.14.7, while package-lock.json installs 2.15.0. msw rewrites the worker on postinstall, so npm ci leaves the tree dirty on a clean checkout and every contributor either commits an unrelated 30-line diff or discards it. Regenerate the worker for the locked version and add a check that compares it against the installed runtime, wired into make verify and CI so the pair cannot drift again.
209 lines
6.8 KiB
YAML
209 lines
6.8 KiB
YAML
name: CI
|
|
|
|
on:
|
|
pull_request:
|
|
paths:
|
|
- "**.go"
|
|
- "go.mod"
|
|
- "go.sum"
|
|
- "frontend/**"
|
|
- ".nvmrc"
|
|
- ".github/workflows/ci.yml"
|
|
push:
|
|
branches:
|
|
- main
|
|
paths:
|
|
- "**.go"
|
|
- "go.mod"
|
|
- "go.sum"
|
|
- "frontend/**"
|
|
- ".nvmrc"
|
|
- ".github/workflows/ci.yml"
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
go-test:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-go@v7
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: true
|
|
- name: Stub internal/web/dist for go:embed
|
|
run: mkdir -p internal/web/dist && touch internal/web/dist/.gitkeep
|
|
- name: Test
|
|
run: |
|
|
go list ./... | grep -v '/frontend/node_modules/' > /tmp/go-packages.txt
|
|
go test -shuffle=on -count=1 $(cat /tmp/go-packages.txt)
|
|
|
|
postgres-durable-first:
|
|
runs-on: ubuntu-latest
|
|
services:
|
|
postgres:
|
|
image: postgres:16
|
|
env:
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_PASSWORD: postgres
|
|
POSTGRES_DB: xui_durable
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd "pg_isready -U postgres -d xui_durable"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
env:
|
|
XUI_DB_TYPE: postgres
|
|
XUI_DB_DSN: "host=127.0.0.1 port=5432 user=postgres password=postgres dbname=xui_durable sslmode=disable"
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-go@v7
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: true
|
|
- name: Stub internal/web/dist for go:embed
|
|
run: mkdir -p internal/web/dist && touch internal/web/dist/.gitkeep
|
|
- name: PostgreSQL durable-first tests
|
|
run: |
|
|
set -o pipefail
|
|
go test ./internal/web/service -run 'PostgresCommitFailure' -count=1 -v | tee /tmp/postgres-durable-first.log
|
|
# Count passes rather than assert no SKIP: a renamed or deleted test
|
|
# prints "no tests to run" and exits 0, leaving the step green for nothing.
|
|
passed=$(grep -c -- '--- PASS' /tmp/postgres-durable-first.log || true)
|
|
if [ "$passed" -lt 1 ]; then
|
|
echo "expected at least 1 passing durable-first test, got $passed" >&2
|
|
exit 1
|
|
fi
|
|
|
|
- name: PostgreSQL schema and migration tests
|
|
run: |
|
|
set -o pipefail
|
|
go test ./internal/database -run '^(TestHostAutoMigrateCreatesColumns_Postgres|TestMigrate_Postgres)$' -count=1 -v | tee /tmp/postgres-schema.log
|
|
# Both must pass. Counting, not SKIP-matching: renaming either test would
|
|
# otherwise leave this step green while testing nothing.
|
|
passed=$(grep -c -- '--- PASS' /tmp/postgres-schema.log || true)
|
|
if [ "$passed" -lt 2 ]; then
|
|
echo "expected 2 passing PostgreSQL schema tests, got $passed" >&2
|
|
exit 1
|
|
fi
|
|
|
|
codegen:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-go@v7
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: true
|
|
- uses: actions/setup-node@v7
|
|
with:
|
|
node-version-file: .nvmrc
|
|
- name: Regenerate schemas, examples and OpenAPI
|
|
run: npm run gen
|
|
working-directory: frontend
|
|
- name: Fail if generated files are stale (run 'npm run gen' and commit)
|
|
run: git diff --exit-code -- frontend/src/generated frontend/public/openapi.json
|
|
|
|
govulncheck:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-go@v7
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: true
|
|
- name: Stub internal/web/dist for go:embed
|
|
run: mkdir -p internal/web/dist && touch internal/web/dist/.gitkeep
|
|
- name: Install govulncheck
|
|
run: go install golang.org/x/vuln/cmd/govulncheck@latest
|
|
- name: Run govulncheck
|
|
run: govulncheck ./...
|
|
|
|
# Race + shuffle hygiene gate: data races and order-dependent tests fail the build.
|
|
race:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-go@v7
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: true
|
|
- name: Stub internal/web/dist for go:embed
|
|
run: mkdir -p internal/web/dist && touch internal/web/dist/.gitkeep
|
|
- name: Race + shuffle
|
|
run: |
|
|
go list ./... | grep -v '/frontend/node_modules/' > /tmp/go-packages.txt
|
|
go test -race -shuffle=on -count=1 $(cat /tmp/go-packages.txt)
|
|
|
|
# Brief native-fuzz smoke on the security-/parser-critical decoders. Each runs the
|
|
# generated corpus plus 30s of exploration; a crash here is a real input-handling bug.
|
|
fuzz-smoke:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-go@v7
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: true
|
|
- name: Stub internal/web/dist for go:embed
|
|
run: mkdir -p internal/web/dist && touch internal/web/dist/.gitkeep
|
|
- name: Fuzz critical parsers (smoke)
|
|
run: |
|
|
go test -run '^$' -fuzz 'FuzzParseLink$' -fuzztime=30s ./internal/util/link/
|
|
go test -run '^$' -fuzz 'FuzzDecodeCertPin$' -fuzztime=30s ./internal/web/runtime/
|
|
|
|
golangci:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-go@v7
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: true
|
|
- name: Stub internal/web/dist for go:embed
|
|
run: mkdir -p internal/web/dist && touch internal/web/dist/.gitkeep
|
|
- name: golangci-lint
|
|
uses: golangci/golangci-lint-action@v9
|
|
with:
|
|
version: latest
|
|
|
|
frontend:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-node@v7
|
|
with:
|
|
node-version-file: .nvmrc
|
|
cache: npm
|
|
cache-dependency-path: frontend/package-lock.json
|
|
- name: Install
|
|
run: npm ci
|
|
working-directory: frontend
|
|
- name: Verify generated MSW worker is current
|
|
run: git diff --exit-code -- public/mockServiceWorker.js package-lock.json
|
|
working-directory: frontend
|
|
- name: Lint
|
|
run: npm run lint
|
|
working-directory: frontend
|
|
- name: Typecheck
|
|
run: npm run typecheck
|
|
working-directory: frontend
|
|
- name: Install Playwright Chromium (Storybook story tests)
|
|
run: npx playwright install --with-deps chromium
|
|
working-directory: frontend
|
|
- name: Test
|
|
run: npm test
|
|
working-directory: frontend
|
|
- name: Build
|
|
run: npm run build
|
|
working-directory: frontend
|
|
- name: Build Storybook
|
|
run: npm run build-storybook
|
|
working-directory: frontend
|
|
- name: Audit
|
|
run: npm audit --omit=dev --audit-level=high
|
|
working-directory: frontend
|