Skip to content

feat(proxy): route cyber-flagged work to authorized accounts #1999

feat(proxy): route cyber-flagged work to authorized accounts

feat(proxy): route cyber-flagged work to authorized accounts #1999

Workflow file for this run

name: CI
on:
push:
branches: ["main"]
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
frontend-lint:
name: Frontend lint (eslint)
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Set up Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.10"
- name: Install frontend dependencies
run: cd frontend && bun install --frozen-lockfile
- name: Run frontend lint
run: cd frontend && bun run lint
frontend-typecheck:
name: Frontend type check (tsc)
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Set up Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.10"
- name: Install frontend dependencies
run: cd frontend && bun install --frozen-lockfile
- name: Run frontend type check
run: cd frontend && bun run typecheck
frontend-test:
name: Frontend tests (vitest + coverage)
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Set up Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.10"
- name: Install frontend dependencies
run: cd frontend && bun install --frozen-lockfile
- name: Run frontend tests with coverage
run: cd frontend && bun run test:coverage
frontend-build:
name: Frontend build (vite)
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Set up Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.10"
- name: Install frontend dependencies
run: cd frontend && bun install --frozen-lockfile
- name: Build frontend
run: cd frontend && bun run build
lint:
name: Lint (ruff)
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Set up uv
uses: astral-sh/setup-uv@v8.0.0
with:
python-version: "3.13"
enable-cache: true
- name: Ruff check
run: uvx ruff check .
- name: Ruff format (check)
run: uvx ruff format --check .
typecheck:
name: Type check (ty)
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Set up uv
uses: astral-sh/setup-uv@v8.0.0
with:
python-version: "3.13"
enable-cache: true
- name: Install dependencies
run: uv sync --dev --frozen
- name: Ty check
run: uv run ty check
test:
name: Tests (pytest, ${{ matrix.slice.name }})
runs-on: ubuntu-24.04
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
slice:
- name: unit
paths: "tests/unit tests/test_request_logs_options_api.py"
- name: integration-core
paths: "tests/integration --ignore=tests/integration/test_http_responses_bridge.py --ignore=tests/integration/test_proxy_websocket_responses.py"
extra_args: ""
- name: integration-bridge
paths: "tests/integration/test_http_responses_bridge.py tests/integration/test_proxy_websocket_responses.py"
extra_args: "-vv"
- name: e2e
paths: "tests/e2e"
extra_args: ""
env:
PYTHONFAULTHANDLER: "1"
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Set up Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.10"
- name: Install frontend dependencies
run: cd frontend && bun install --frozen-lockfile
- name: Build frontend assets
run: cd frontend && bun run build
- name: Set up uv
uses: astral-sh/setup-uv@v8.0.0
with:
python-version: "3.13"
enable-cache: true
- name: Install dependencies
run: uv sync --dev --frozen
- name: Run tests
run: uv run pytest -q -ra ${{ matrix.slice.extra_args }} -o faulthandler_timeout=300 -o faulthandler_exit_on_timeout=true --timeout=180 --timeout-method=thread --durations=20 ${{ matrix.slice.paths }}
test-postgres:
name: Tests (pytest, PostgreSQL)
runs-on: ubuntu-24.04
timeout-minutes: 20
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: codex_lb
POSTGRES_PASSWORD: codex_lb
POSTGRES_DB: codex_lb
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U codex_lb -d codex_lb"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
CODEX_LB_TEST_DATABASE_URL: postgresql+asyncpg://codex_lb:codex_lb@127.0.0.1:5432/codex_lb
PYTHONFAULTHANDLER: "1"
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Set up Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.10"
- name: Install frontend dependencies
run: cd frontend && bun install --frozen-lockfile
- name: Build frontend assets
run: cd frontend && bun run build
- name: Set up uv
uses: astral-sh/setup-uv@v8.0.0
with:
python-version: "3.13"
enable-cache: true
- name: Install dependencies
run: uv sync --dev --frozen
- name: Run tests
run: uv run pytest -q -ra -o faulthandler_timeout=300 -o faulthandler_exit_on_timeout=true --timeout=180 --timeout-method=thread --durations=20
migration-check:
name: Migration check (alembic)
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Set up uv
uses: astral-sh/setup-uv@v8.0.0
with:
python-version: "3.13"
enable-cache: true
- name: Install dependencies
run: uv sync --dev --frozen
- name: Validate migration policy and drift
shell: bash
run: |
set -euo pipefail
TMP_DB="$(mktemp -u /tmp/codex-lb-ci-migrate-XXXXXX.db)"
DB_URL="sqlite+aiosqlite:///${TMP_DB}"
uv run codex-lb-db --db-url "${DB_URL}" upgrade head
uv run codex-lb-db --db-url "${DB_URL}" check
migration-check-postgres:
name: Migration check (alembic, PostgreSQL)
runs-on: ubuntu-24.04
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: codex_lb
POSTGRES_PASSWORD: codex_lb
POSTGRES_DB: codex_lb
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U codex_lb -d codex_lb"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Set up uv
uses: astral-sh/setup-uv@v8.0.0
with:
python-version: "3.13"
enable-cache: true
- name: Install dependencies
run: uv sync --dev --frozen
- name: Validate migration policy and drift on PostgreSQL
shell: bash
run: |
set -euo pipefail
DB_URL="postgresql+asyncpg://codex_lb:codex_lb@127.0.0.1:5432/codex_lb"
uv run codex-lb-db --db-url "${DB_URL}" upgrade head
uv run codex-lb-db --db-url "${DB_URL}" check
package:
name: Package (build)
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Set up Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.10"
- name: Install frontend dependencies
run: cd frontend && bun install --frozen-lockfile
- name: Build frontend assets
run: cd frontend && bun run build
- name: Set up uv
uses: astral-sh/setup-uv@v8.0.0
with:
python-version: "3.13"
enable-cache: true
- name: Install package (runtime deps)
run: uv sync --frozen --no-dev
- name: Import check
run: uv run python -c "import app; import app.main; print('import ok')"
- name: Build sdist + wheel
run: uvx --from build python -m build
- name: Verify wheel contains frontend assets
shell: bash
run: |
python - <<'PY'
import glob
import zipfile
wheels = glob.glob("dist/*.whl")
if not wheels:
raise SystemExit("no wheel found in dist/")
wheel = wheels[0]
with zipfile.ZipFile(wheel) as zf:
names = set(zf.namelist())
has_index = "app/static/index.html" in names
has_js = any(name.startswith("app/static/assets/") and name.endswith(".js") for name in names)
has_css = any(name.startswith("app/static/assets/") and name.endswith(".css") for name in names)
if not (has_index and has_js and has_css):
raise SystemExit(
f"frontend assets missing in wheel: index={has_index} js={has_js} css={has_css}"
)
print(f"frontend assets verified in wheel: {wheel}")
PY
docker:
name: Docker build
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Build Docker image
uses: docker/build-push-action@v7
with:
context: .
file: Dockerfile
push: false
load: true
tags: codex-lb:ci
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Scan Docker image with Trivy
uses: aquasecurity/trivy-action@0.35.0
with:
image-ref: codex-lb:ci
format: table
exit-code: 1
severity: CRITICAL
ignore-unfixed: true
helm-lint:
name: Helm lint + template + kubeconform
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Set up Helm
uses: azure/setup-helm@v5
- name: Build Helm dependencies
run: helm dependency build deploy/helm/codex-lb/
- name: Helm lint (base values)
run: |
helm lint --strict deploy/helm/codex-lb/ \
--set postgresql.auth.password=test-password
- name: Helm lint (dev overlay)
run: |
helm lint --strict deploy/helm/codex-lb/ \
-f deploy/helm/codex-lb/values-dev.yaml \
--set postgresql.auth.password=test-password
- name: Helm lint (bundled mode)
run: |
helm lint --strict deploy/helm/codex-lb/ \
-f deploy/helm/codex-lb/values-bundled.yaml \
--set postgresql.auth.password=test-password
- name: Helm lint (external DB mode)
run: |
helm lint --strict deploy/helm/codex-lb/ \
-f deploy/helm/codex-lb/values-external-db.yaml \
--set externalDatabase.url=postgresql+asyncpg://test:test@localhost/test
- name: Helm lint (external secrets mode)
run: |
helm lint --strict deploy/helm/codex-lb/ \
-f deploy/helm/codex-lb/values-external-secrets.yaml \
--set externalSecrets.secretStoreRef.name=test-store
- name: Helm lint (staging overlay)
run: |
helm lint --strict deploy/helm/codex-lb/ \
-f deploy/helm/codex-lb/values-staging.yaml \
--set externalDatabase.url=postgresql+asyncpg://test:test@localhost/test
- name: Helm lint (prod overlay)
run: |
helm lint --strict deploy/helm/codex-lb/ \
-f deploy/helm/codex-lb/values-prod.yaml \
--set externalSecrets.secretStoreRef.name=test-store
- name: Helm template (base values)
run: |
helm template codex-lb deploy/helm/codex-lb/ \
--set postgresql.auth.password=test-password \
> /dev/null
- name: Helm template (dev overlay)
run: |
helm template codex-lb deploy/helm/codex-lb/ \
-f deploy/helm/codex-lb/values-dev.yaml \
--set postgresql.auth.password=test-password \
> /dev/null
- name: Helm template (bundled mode)
run: |
helm template codex-lb deploy/helm/codex-lb/ \
-f deploy/helm/codex-lb/values-bundled.yaml \
--set postgresql.auth.password=test-password \
> /dev/null
- name: Helm template (external DB mode)
run: |
helm template codex-lb deploy/helm/codex-lb/ \
-f deploy/helm/codex-lb/values-external-db.yaml \
--set externalDatabase.url=postgresql+asyncpg://test:test@localhost/test \
> /dev/null
- name: Helm template (external secrets mode)
run: |
helm template codex-lb deploy/helm/codex-lb/ \
-f deploy/helm/codex-lb/values-external-secrets.yaml \
--set externalSecrets.secretStoreRef.name=test-store \
> /dev/null
- name: Helm template (staging overlay)
run: |
helm template codex-lb deploy/helm/codex-lb/ \
-f deploy/helm/codex-lb/values-staging.yaml \
--set externalDatabase.url=postgresql+asyncpg://test:test@localhost/test \
> /dev/null
- name: Helm template (prod overlay)
run: |
helm template codex-lb deploy/helm/codex-lb/ \
-f deploy/helm/codex-lb/values-prod.yaml \
--set externalSecrets.secretStoreRef.name=test-store \
> /dev/null
- name: Install kubeconform
run: |
KUBECONFORM_VERSION="0.7.0"
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
if [ "$ARCH" = "x86_64" ]; then ARCH="amd64"; fi
curl -sSL "https://github.com/yannh/kubeconform/releases/download/v${KUBECONFORM_VERSION}/kubeconform-${OS}-${ARCH}.tar.gz" \
| tar xz -C /tmp
sudo mv /tmp/kubeconform /usr/local/bin/kubeconform
- name: kubeconform (K8s 1.32.0)
run: |
helm template codex-lb deploy/helm/codex-lb/ \
-f deploy/helm/codex-lb/values-prod.yaml \
--set externalSecrets.secretStoreRef.name=test \
--set externalSecrets.secretStoreRef.kind=SecretStore \
--set gatewayApi.enabled=true \
--set "gatewayApi.parentRefs[0].name=test-gw" \
--set "gatewayApi.hostnames[0]=test.example.com" \
| kubeconform \
-strict \
-kubernetes-version 1.32.0 \
-schema-location default \
-schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
-summary
- name: kubeconform (K8s 1.35.0)
run: |
helm template codex-lb deploy/helm/codex-lb/ \
-f deploy/helm/codex-lb/values-prod.yaml \
--set externalSecrets.secretStoreRef.name=test \
--set externalSecrets.secretStoreRef.kind=SecretStore \
--set gatewayApi.enabled=true \
--set "gatewayApi.parentRefs[0].name=test-gw" \
--set "gatewayApi.hostnames[0]=test.example.com" \
| kubeconform \
-strict \
-kubernetes-version 1.35.0 \
-schema-location default \
-schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
-summary
helm-smoke-kind:
name: Helm smoke install (kind)
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.2
- name: Set up Helm
uses: azure/setup-helm@v5
- name: Install kind
run: |
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.30.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
- name: Create kind cluster
run: kind create cluster --name codex-lb-smoke --image kindest/node:v1.35.0 --wait 120s
- name: Build Docker image
run: docker build -t ghcr.io/soju06/codex-lb:ci .
- name: Load image into kind
run: kind load docker-image ghcr.io/soju06/codex-lb:ci --name codex-lb-smoke
- name: Smoke install (bundled mode)
env:
KUBE_CONTEXT: kind-codex-lb-smoke
IMAGE_REGISTRY: ghcr.io
IMAGE_REPOSITORY: soju06/codex-lb
IMAGE_TAG: ci
run: ./scripts/helm-kind-smoke.sh bundled
- name: Smoke install (external DB mode)
env:
KUBE_CONTEXT: kind-codex-lb-smoke
IMAGE_REGISTRY: ghcr.io
IMAGE_REPOSITORY: soju06/codex-lb
IMAGE_TAG: ci
run: ./scripts/helm-kind-smoke.sh external-db