Skip to content

Add integration and stability tests #33

Add integration and stability tests

Add integration and stability tests #33

Workflow file for this run

name: CI
on:
pull_request:
branches: [main]
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
# Database URLs for CI
DATABASE_URL: postgres://agentauth:agentauth_dev@localhost:5434/agentauth
DATABASE_REPLICA_URL: postgres://agentauth:agentauth_dev@localhost:5435/agentauth
# Redis URL for CI
REDIS_URL: redis://localhost:6379
jobs:
# Step 1-5: Rust checks (no external dependencies needed)
rust-checks:
name: Rust Checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
cache-all-crates: true
- name: Cache cargo binaries
uses: actions/cache@v4
with:
path: ~/.cargo/bin
key: ${{ runner.os }}-cargo-bin-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: |
${{ runner.os }}-cargo-bin-
- name: Install cargo tools
run: |
# Only install if not already cached
command -v cargo-nextest >/dev/null 2>&1 || cargo install cargo-nextest --locked
command -v cargo-audit >/dev/null 2>&1 || cargo install cargo-audit --locked
command -v cargo-deny >/dev/null 2>&1 || cargo install cargo-deny --locked
# Step 1: cargo check
- name: Check workspace
run: cargo check --workspace
# Step 2: cargo clippy
- name: Clippy
run: cargo clippy --workspace -- -D warnings
# Step 3: cargo audit
- name: Security audit
run: cargo audit
# Step 4-5: cargo deny
- name: License and dependency check
run: |
cargo deny check licenses || echo "::warning::License check not configured"
cargo deny check bans || echo "::warning::Ban check not configured"
# Step 6-11: Integration tests with services
integration-tests:
name: Integration Tests
runs-on: ubuntu-latest
needs: rust-checks
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: agentauth
POSTGRES_PASSWORD: agentauth_dev
POSTGRES_DB: agentauth
ports:
- 5434:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
cache-all-crates: true
- name: Cache cargo binaries
uses: actions/cache@v4
with:
path: ~/.cargo/bin
key: ${{ runner.os }}-cargo-bin-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: |
${{ runner.os }}-cargo-bin-
- name: Install cargo tools
run: |
# Only install if not already cached
command -v cargo-nextest >/dev/null 2>&1 || cargo install cargo-nextest --locked
command -v sqlx >/dev/null 2>&1 || cargo install sqlx-cli --locked --no-default-features --features postgres
# Step 7-8: Database migrations
- name: Run migrations
run: |
sqlx migrate run --source migrations/ || echo "::warning::No migrations found"
- name: Test migration rollback
run: |
sqlx migrate revert --source migrations/ || echo "::warning::No migrations to revert"
sqlx migrate run --source migrations/ || echo "::warning::No migrations found"
# Step 9: Run all tests
- name: Run tests
run: cargo nextest run --workspace
# Step 11: Compliance tests
- name: Run compliance tests
run: cargo nextest run --test compliance || echo "::warning::No compliance tests found"
# Step 12: Banned pattern checks
security-patterns:
name: Security Pattern Checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check for plaintext key backends in production code
run: |
# Check for InMemorySigningBackend outside of #[cfg(test)] blocks
# The struct and impl are properly gated with #[cfg(test)] in backend.rs
# We check that no service code uses it
if grep -rn "InMemorySigningBackend" services/ --include="*.rs" | grep -v "//"; then
echo "::error::Found InMemorySigningBackend in service code"
exit 1
fi
# Check for PlaintextKeyfile feature in production Dockerfiles and Helm charts
# PlaintextKeyfile is gated behind allow-plaintext-keys feature
if grep -rn "allow-plaintext-keys" Dockerfile* deploy/ --include="*.yml" --include="*.yaml" 2>/dev/null; then
echo "::error::Found allow-plaintext-keys feature in production configs"
exit 1
fi
echo "No plaintext key backends found in production code"
- name: Check for unwrap() in library crates
run: |
# Count unwraps in non-test code (warning only for now)
count=$(grep -rn "\.unwrap()" crates/ --include="*.rs" | grep -v "#\[cfg(test)\]\|//.*safe because\|test::" | wc -l)
if [ "$count" -gt 0 ]; then
echo "::warning::Found $count uses of unwrap() in library crates"
grep -rn "\.unwrap()" crates/ --include="*.rs" | grep -v "#\[cfg(test)\]\|//.*safe because\|test::" | head -20
fi
- name: Check for hardcoded secrets
run: |
if grep -rn "secret\|password\|private_key\|api_key" crates/ services/ --include="*.rs" | grep -v "//\|\"\"" | grep "= \"" | grep -v "test\|example\|placeholder"; then
echo "::error::Potential hardcoded secrets found"
exit 1
fi
echo "No hardcoded secrets found"
- name: Check for SQL string interpolation
run: |
if grep -rn "format!.*SELECT\|format!.*INSERT\|format!.*UPDATE\|format!.*DELETE" crates/ services/ --include="*.rs"; then
echo "::error::SQL string interpolation found - use parameterized queries"
exit 1
fi
echo "No SQL string interpolation found"
# Step 17: Documentation
docs:
name: Documentation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- name: Build documentation
run: cargo doc --no-deps --workspace
env:
RUSTDOCFLAGS: -D warnings
# Step 18: Load test baseline (only on main branch)
load-test:
name: Load Test Baseline
runs-on: ubuntu-latest
needs: integration-tests
if: github.ref == 'refs/heads/main'
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: agentauth
POSTGRES_PASSWORD: agentauth_dev
POSTGRES_DB: agentauth
ports:
- 5434:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- name: Install k6
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: Run load tests
run: |
if [ -f "load-tests/token-verify.js" ]; then
k6 run --vus 10 --duration 30s load-tests/token-verify.js
else
echo "::warning::No load tests found"
fi
# Summary job
ci-success:
name: CI Success
runs-on: ubuntu-latest
needs: [rust-checks, integration-tests, security-patterns, docs]
if: always()
steps:
- name: Check all jobs passed
run: |
if [ "${{ needs.rust-checks.result }}" != "success" ] || \
[ "${{ needs.integration-tests.result }}" != "success" ] || \
[ "${{ needs.security-patterns.result }}" != "success" ] || \
[ "${{ needs.docs.result }}" != "success" ]; then
echo "One or more jobs failed"
exit 1
fi
echo "All CI checks passed!"