Replace placeholder pages with ToolEmbed component that embeds LangGraph, LangFlow, and Langfuse in iframes when configured, or shows "Not Configured" placeholders when URLs are empty. Add ServiceUrlsContext for passing service URLs through Dioxus context. Add docker-compose services for local development: LangFlow, LangGraph (trial), Langfuse with full dependency stack (Postgres, ClickHouse, Redis, MinIO). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
272 lines
9.3 KiB
YAML
272 lines
9.3 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- "**"
|
|
pull_request:
|
|
branches:
|
|
- main
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
RUSTFLAGS: "-D warnings"
|
|
# sccache caches compilation artifacts within a job so that compiling
|
|
# both --features server and --features web shares common crate work.
|
|
RUSTC_WRAPPER: /usr/local/bin/sccache
|
|
SCCACHE_DIR: /tmp/sccache
|
|
|
|
# Cancel in-progress runs for the same branch/PR
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
# ---------------------------------------------------------------------------
|
|
# Stage 1: Code quality checks (run in parallel)
|
|
# ---------------------------------------------------------------------------
|
|
fmt:
|
|
name: Format
|
|
runs-on: docker
|
|
container:
|
|
image: rust:1.89-bookworm
|
|
steps:
|
|
- name: Checkout
|
|
run: |
|
|
git init
|
|
git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git"
|
|
git fetch --depth=1 origin "${GITHUB_SHA}"
|
|
git checkout FETCH_HEAD
|
|
- run: rustup component add rustfmt
|
|
# Format check does not compile, so sccache is not needed here.
|
|
- run: cargo fmt --check
|
|
env:
|
|
RUSTC_WRAPPER: ""
|
|
|
|
clippy:
|
|
name: Clippy
|
|
runs-on: docker
|
|
container:
|
|
image: rust:1.89-bookworm
|
|
steps:
|
|
- name: Checkout
|
|
run: |
|
|
git init
|
|
git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git"
|
|
git fetch --depth=1 origin "${GITHUB_SHA}"
|
|
git checkout FETCH_HEAD
|
|
- name: Install sccache
|
|
run: |
|
|
curl -fsSL https://github.com/mozilla/sccache/releases/download/v0.9.1/sccache-v0.9.1-x86_64-unknown-linux-musl.tar.gz \
|
|
| tar xz --strip-components=1 -C /usr/local/bin/ sccache-v0.9.1-x86_64-unknown-linux-musl/sccache
|
|
chmod +x /usr/local/bin/sccache
|
|
- run: rustup component add clippy
|
|
# Lint both feature sets independently.
|
|
# sccache deduplicates shared crates between the two compilations.
|
|
- name: Clippy (server)
|
|
run: cargo clippy --features server --no-default-features -- -D warnings
|
|
- name: Clippy (web)
|
|
run: cargo clippy --features web --no-default-features -- -D warnings
|
|
- name: Show sccache stats
|
|
run: sccache --show-stats
|
|
if: always()
|
|
|
|
audit:
|
|
name: Security Audit
|
|
runs-on: docker
|
|
if: github.ref == 'refs/heads/main'
|
|
container:
|
|
image: rust:1.89-bookworm
|
|
steps:
|
|
- name: Checkout
|
|
run: |
|
|
git init
|
|
git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git"
|
|
git fetch --depth=1 origin "${GITHUB_SHA}"
|
|
git checkout FETCH_HEAD
|
|
- run: cargo install cargo-audit
|
|
env:
|
|
RUSTC_WRAPPER: ""
|
|
- run: cargo audit
|
|
env:
|
|
RUSTC_WRAPPER: ""
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Stage 2: Tests (only after all quality checks pass)
|
|
# ---------------------------------------------------------------------------
|
|
test:
|
|
name: Tests
|
|
runs-on: docker
|
|
needs: [fmt, clippy, audit]
|
|
container:
|
|
image: rust:1.89-bookworm
|
|
steps:
|
|
- name: Checkout
|
|
run: |
|
|
git init
|
|
git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git"
|
|
git fetch --depth=1 origin "${GITHUB_SHA}"
|
|
git checkout FETCH_HEAD
|
|
- name: Install sccache
|
|
run: |
|
|
curl -fsSL https://github.com/mozilla/sccache/releases/download/v0.9.1/sccache-v0.9.1-x86_64-unknown-linux-musl.tar.gz \
|
|
| tar xz --strip-components=1 -C /usr/local/bin/ sccache-v0.9.1-x86_64-unknown-linux-musl/sccache
|
|
chmod +x /usr/local/bin/sccache
|
|
- name: Run tests (server)
|
|
run: cargo test --features server --no-default-features
|
|
- name: Run tests (web)
|
|
run: cargo test --features web --no-default-features
|
|
- name: Show sccache stats
|
|
run: sccache --show-stats
|
|
if: always()
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Stage 2b: E2E tests (only on main / PRs to main, after quality checks)
|
|
# ---------------------------------------------------------------------------
|
|
e2e:
|
|
name: E2E Tests
|
|
runs-on: docker
|
|
needs: [fmt, clippy, audit]
|
|
if: github.ref == 'refs/heads/main' || github.event_name == 'pull_request'
|
|
container:
|
|
image: rust:1.89-bookworm
|
|
# MongoDB and SearXNG can start immediately (no repo files needed).
|
|
# Keycloak requires realm-export.json from the repo, so it is started
|
|
# manually after checkout via docker CLI.
|
|
services:
|
|
mongo:
|
|
image: mongo:latest
|
|
env:
|
|
MONGO_INITDB_ROOT_USERNAME: root
|
|
MONGO_INITDB_ROOT_PASSWORD: example
|
|
ports:
|
|
- 27017:27017
|
|
searxng:
|
|
image: searxng/searxng:latest
|
|
env:
|
|
SEARXNG_BASE_URL: http://localhost:8888
|
|
ports:
|
|
- 8888:8080
|
|
env:
|
|
KEYCLOAK_URL: http://localhost:8080
|
|
KEYCLOAK_REALM: certifai
|
|
KEYCLOAK_CLIENT_ID: certifai-dashboard
|
|
MONGODB_URI: mongodb://root:example@mongo:27017
|
|
MONGODB_DATABASE: certifai
|
|
SEARXNG_URL: http://searxng:8080
|
|
LANGGRAPH_URL: ""
|
|
LANGFLOW_URL: ""
|
|
LANGFUSE_URL: ""
|
|
steps:
|
|
- name: Checkout
|
|
run: |
|
|
git init
|
|
git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git"
|
|
git fetch --depth=1 origin "${GITHUB_SHA}"
|
|
git checkout FETCH_HEAD
|
|
- name: Install system dependencies
|
|
run: |
|
|
apt-get update -qq
|
|
apt-get install -y -qq --no-install-recommends \
|
|
unzip curl docker.io \
|
|
libglib2.0-0 libnss3 libnspr4 libdbus-1-3 libatk1.0-0 \
|
|
libatk-bridge2.0-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 \
|
|
libxdamage1 libxfixes3 libxrandr2 libgbm1 libpango-1.0-0 \
|
|
libcairo2 libasound2 libatspi2.0-0 libxshmfence1
|
|
- name: Start Keycloak
|
|
run: |
|
|
docker run -d --name ci-keycloak --network host \
|
|
-e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
|
|
-e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
|
|
-e KC_DB=dev-mem \
|
|
-e KC_HEALTH_ENABLED=true \
|
|
-v "$PWD/keycloak/realm-export.json:/opt/keycloak/data/import/realm-export.json:ro" \
|
|
-v "$PWD/keycloak/themes/certifai:/opt/keycloak/themes/certifai:ro" \
|
|
quay.io/keycloak/keycloak:26.0 start-dev --import-realm
|
|
|
|
echo "Waiting for Keycloak..."
|
|
for i in $(seq 1 60); do
|
|
if curl -sf http://localhost:8080/realms/certifai > /dev/null 2>&1; then
|
|
echo "Keycloak is ready"
|
|
break
|
|
fi
|
|
if [ "$i" -eq 60 ]; then
|
|
echo "Keycloak failed to start within 60s"
|
|
docker logs ci-keycloak
|
|
exit 1
|
|
fi
|
|
sleep 2
|
|
done
|
|
- name: Install sccache
|
|
run: |
|
|
curl -fsSL https://github.com/mozilla/sccache/releases/download/v0.9.1/sccache-v0.9.1-x86_64-unknown-linux-musl.tar.gz \
|
|
| tar xz --strip-components=1 -C /usr/local/bin/ sccache-v0.9.1-x86_64-unknown-linux-musl/sccache
|
|
chmod +x /usr/local/bin/sccache
|
|
- name: Install dioxus-cli
|
|
run: cargo install dioxus-cli --locked
|
|
- name: Install bun
|
|
run: |
|
|
curl -fsSL https://bun.sh/install | bash
|
|
echo "$HOME/.bun/bin" >> "$GITHUB_PATH"
|
|
- name: Install Playwright
|
|
run: |
|
|
export PATH="$HOME/.bun/bin:$PATH"
|
|
bun install
|
|
bunx playwright install chromium
|
|
- name: Build app
|
|
run: dx build --release
|
|
- name: Start app and run E2E tests
|
|
run: |
|
|
export PATH="$HOME/.bun/bin:$PATH"
|
|
# Start the app in the background
|
|
dx serve --release --port 8000 &
|
|
APP_PID=$!
|
|
|
|
# Wait for the app to be ready
|
|
echo "Waiting for app to start..."
|
|
for i in $(seq 1 60); do
|
|
if curl -sf http://localhost:8000 > /dev/null 2>&1; then
|
|
echo "App is ready"
|
|
break
|
|
fi
|
|
if [ "$i" -eq 60 ]; then
|
|
echo "App failed to start within 60s"
|
|
exit 1
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
BASE_URL=http://localhost:8000 bunx playwright test --reporter=list
|
|
|
|
kill "$APP_PID" 2>/dev/null || true
|
|
- name: Upload test report
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: playwright-report
|
|
path: playwright-report/
|
|
retention-days: 7
|
|
- name: Cleanup Keycloak
|
|
if: always()
|
|
run: docker rm -f ci-keycloak 2>/dev/null || true
|
|
- name: Show sccache stats
|
|
run: sccache --show-stats
|
|
if: always()
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Stage 3: Deploy (only after tests pass, only on main)
|
|
# ---------------------------------------------------------------------------
|
|
deploy:
|
|
name: Deploy
|
|
runs-on: docker
|
|
needs: [test, e2e]
|
|
if: github.ref == 'refs/heads/main'
|
|
container:
|
|
image: alpine:latest
|
|
steps:
|
|
- name: Trigger Coolify deploy
|
|
run: |
|
|
apk add --no-cache curl
|
|
curl -sf "${{ secrets.COOLIFY_WEBHOOK }}" \
|
|
-H "Authorization: Bearer ${{ secrets.COOLIFY_TOKEN }}"
|