166 lines
6.9 KiB
YAML
166 lines
6.9 KiB
YAML
name: CI (SIAX Cloud)
|
|
|
|
# Self-hosted CI on SIAX Cloud (Gitea Actions, runners siax-runner-1/2).
|
|
# Blocking quality/security + real-dependency gates for the 0pt capability layer.
|
|
on:
|
|
push:
|
|
branches: ["**"]
|
|
pull_request:
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
quality:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22"
|
|
- name: Enable corepack + pin pnpm@9 (pnpm-lock.yaml is lockfileVersion 9.0)
|
|
run: |
|
|
corepack enable
|
|
corepack prepare pnpm@9 --activate
|
|
- name: Install (frozen lockfile)
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Typecheck (tsc over src/ + tests/ -- blocking)
|
|
run: pnpm run typecheck
|
|
- name: Test (vitest -- blocking)
|
|
run: pnpm run test
|
|
- name: Lint (eslint -- advisory until legacy findings are separately burned down)
|
|
continue-on-error: true
|
|
run: pnpm run lint
|
|
- name: Build (next build -- blocking quality gate)
|
|
run: pnpm run build
|
|
|
|
integration:
|
|
runs-on: ubuntu-latest
|
|
services:
|
|
opt-ci-opensearch:
|
|
image: opensearchproject/opensearch:2.11.1
|
|
env:
|
|
discovery.type: single-node
|
|
DISABLE_SECURITY_PLUGIN: "true"
|
|
OPENSEARCH_JAVA_OPTS: "-Xms512m -Xmx512m"
|
|
cluster.name: opt_ci_${{ github.run_id }}_${{ github.run_attempt }}
|
|
options: >-
|
|
--workdir /usr/share/opensearch
|
|
--health-cmd "curl -fsS http://localhost:9200/_cluster/health || exit 1"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 60
|
|
opt-ci-clickhouse:
|
|
image: clickhouse/clickhouse-server:24.8
|
|
env:
|
|
CLICKHOUSE_USER: opt_ci
|
|
CLICKHOUSE_PASSWORD: ci_${{ github.run_id }}_${{ github.run_attempt }}
|
|
CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: "1"
|
|
options: >-
|
|
--health-cmd "wget -qO- http://localhost:8123/ping || exit 1"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 60
|
|
opt-ci-postgres:
|
|
image: postgres:16-alpine
|
|
env:
|
|
POSTGRES_USER: opt_ci
|
|
POSTGRES_PASSWORD: ci_${{ github.run_id }}_${{ github.run_attempt }}
|
|
POSTGRES_DB: opt_ci
|
|
options: >-
|
|
--health-cmd "pg_isready -U opt_ci -d opt_ci || exit 1"
|
|
--health-interval 5s
|
|
--health-timeout 5s
|
|
--health-retries 30
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22"
|
|
- name: Enable corepack + pin pnpm@9
|
|
run: |
|
|
corepack enable
|
|
corepack prepare pnpm@9 --activate
|
|
- name: Install (frozen lockfile)
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Select THIS run's OpenSearch by identity
|
|
run: |
|
|
set -eu
|
|
WANT="opt_ci_${{ github.run_id }}_${{ github.run_attempt }}"
|
|
FOUND=""
|
|
for ip in $(getent ahostsv4 opt-ci-opensearch | awk '{print $1}' | sort -u); do
|
|
NAME=$(curl -fsS --max-time 5 "http://$ip:9200/" | sed -n 's/.*"cluster_name" *: *"\([^"]*\)".*/\1/p' || true)
|
|
echo "candidate $ip cluster_name=${NAME:-<none>}"
|
|
if [ "$NAME" = "$WANT" ]; then FOUND="$ip"; fi
|
|
done
|
|
[ -n "$FOUND" ] || { echo "FATAL: no OpenSearch behind the alias identifies as $WANT"; exit 1; }
|
|
echo "OPENSEARCH_URL=http://$FOUND:9200" >> "$GITHUB_ENV"
|
|
- name: Select THIS run's ClickHouse by identity
|
|
run: |
|
|
set -eu
|
|
PASS="ci_${{ github.run_id }}_${{ github.run_attempt }}"
|
|
FOUND=""
|
|
for ip in $(getent ahostsv4 opt-ci-clickhouse | awk '{print $1}' | sort -u); do
|
|
OK=$(curl -fsS --max-time 5 -u "opt_ci:$PASS" "http://$ip:8123/?query=SELECT%201" || true)
|
|
echo "candidate $ip auth_select=${OK:-<denied>}"
|
|
if [ "$OK" = "1" ]; then FOUND="$ip"; fi
|
|
done
|
|
[ -n "$FOUND" ] || { echo "FATAL: no ClickHouse behind the alias accepts this run's credentials"; exit 1; }
|
|
echo "CLICKHOUSE_URL=http://$FOUND:8123" >> "$GITHUB_ENV"
|
|
echo "CLICKHOUSE_AUTH=opt_ci:$PASS" >> "$GITHUB_ENV"
|
|
- name: Select THIS run's Postgres by run-unique credentials
|
|
run: |
|
|
set -eu
|
|
PASS="ci_${{ github.run_id }}_${{ github.run_attempt }}"
|
|
FOUND=""
|
|
for ip in $(getent ahostsv4 opt-ci-postgres | awk '{print $1}' | sort -u); do
|
|
if PG_CANDIDATE="postgres://opt_ci:$PASS@$ip:5432/opt_ci" node --input-type=module - <<'NODE'
|
|
import postgres from 'postgres';
|
|
const sql = postgres(process.env.PG_CANDIDATE, { max: 1, connect_timeout: 3, onnotice: () => undefined });
|
|
try {
|
|
const rows = await sql`SELECT current_user AS u, current_database() AS d`;
|
|
if (rows[0]?.u !== 'opt_ci' || rows[0]?.d !== 'opt_ci') process.exitCode = 2;
|
|
} catch {
|
|
process.exitCode = 1;
|
|
} finally {
|
|
await sql.end({ timeout: 1 }).catch(() => undefined);
|
|
}
|
|
NODE
|
|
then
|
|
FOUND="$ip"
|
|
break
|
|
fi
|
|
done
|
|
[ -n "$FOUND" ] || { echo "FATAL: no Postgres behind the alias accepts this run's credentials"; exit 1; }
|
|
URL="postgres://opt_ci:$PASS@$FOUND:5432/opt_ci"
|
|
echo "TEST_DATABASE_URL=$URL" >> "$GITHUB_ENV"
|
|
echo "DATASET_TEST_DATABASE_URL=$URL" >> "$GITHUB_ENV"
|
|
echo "SEARCH_DEFINITION_TEST_DATABASE_URL=$URL" >> "$GITHUB_ENV"
|
|
- name: Integration tests against LIVE OpenSearch + ClickHouse + Postgres (blocking)
|
|
run: |
|
|
set -eu
|
|
[ -n "${OPENSEARCH_URL:-}" ] && [ -n "${CLICKHOUSE_URL:-}" ] && [ -n "${SEARCH_DEFINITION_TEST_DATABASE_URL:-}" ]
|
|
pnpm vitest run tests/integration 2>&1 | tee /tmp/itest.log
|
|
if grep -qE "skipped" /tmp/itest.log && ! grep -qE "Tests [0-9]+ passed" /tmp/itest.log; then
|
|
echo "FATAL: integration suites skipped instead of running"; exit 1
|
|
fi
|
|
- name: Durable AUD0 outbox against LIVE Postgres (blocking)
|
|
run: |
|
|
set -eu
|
|
[ -n "${TEST_DATABASE_URL:-}" ]
|
|
pnpm vitest run tests/p0/aud0-outbox-postgres.realinfra.test.ts
|
|
- name: Dataset registry + versions against LIVE Postgres (blocking)
|
|
run: |
|
|
set -eu
|
|
[ -n "${DATASET_TEST_DATABASE_URL:-}" ]
|
|
pnpm vitest run tests/p0/dataset-postgres.realinfra.test.ts
|
|
|
|
security:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install Trivy
|
|
run: |
|
|
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
|
|
- name: Trivy scan (vulnerability + secret; HIGH/CRITICAL blocking)
|
|
run: |
|
|
trivy fs --scanners vuln,secret --severity HIGH,CRITICAL --exit-code 1 .
|