Files
reflector/.github/workflows/integration_tests.yml
Juan Diego García 9a2f973a2e test: full integration tests (#916)
* test: full integration tests

* fix: add env vars as secrets in CI
2026-03-18 15:29:21 -05:00

140 lines
5.1 KiB
YAML

name: Integration Tests
on:
workflow_dispatch:
inputs:
llm_model:
description: "LLM model name (overrides LLM_MODEL secret)"
required: false
default: ""
type: string
jobs:
integration:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- name: Start infrastructure services
working-directory: server/tests
env:
LLM_URL: ${{ secrets.LLM_URL }}
LLM_MODEL: ${{ inputs.llm_model || secrets.LLM_MODEL }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
HF_TOKEN: ${{ secrets.HF_TOKEN }}
run: |
docker compose -f docker-compose.integration.yml up -d --build postgres redis garage hatchet mock-daily
- name: Set up Garage bucket and keys
working-directory: server/tests
run: |
GARAGE="docker compose -f docker-compose.integration.yml exec -T garage /garage"
GARAGE_KEY_ID="GK0123456789abcdef01234567" # gitleaks:allow
GARAGE_KEY_SECRET="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" # gitleaks:allow
echo "Waiting for Garage to be healthy..."
for i in $(seq 1 60); do
if $GARAGE stats &>/dev/null; then break; fi
sleep 2
done
echo "Setting up Garage..."
NODE_ID=$($GARAGE node id -q 2>&1 | tr -d '[:space:]')
LAYOUT_STATUS=$($GARAGE layout show 2>&1 || true)
if echo "$LAYOUT_STATUS" | grep -q "No nodes"; then
$GARAGE layout assign "$NODE_ID" -c 1G -z dc1
$GARAGE layout apply --version 1
fi
$GARAGE bucket info reflector-media &>/dev/null || $GARAGE bucket create reflector-media
if ! $GARAGE key info reflector-test &>/dev/null; then
$GARAGE key import --yes "$GARAGE_KEY_ID" "$GARAGE_KEY_SECRET"
$GARAGE key rename "$GARAGE_KEY_ID" reflector-test
fi
$GARAGE bucket allow reflector-media --read --write --key reflector-test
- name: Wait for Hatchet and generate API token
working-directory: server/tests
run: |
echo "Waiting for Hatchet to be healthy..."
for i in $(seq 1 90); do
if docker compose -f docker-compose.integration.yml exec -T hatchet curl -sf http://localhost:8888/api/live &>/dev/null; then
echo "Hatchet is ready."
break
fi
sleep 2
done
echo "Generating Hatchet API token..."
HATCHET_OUTPUT=$(docker compose -f docker-compose.integration.yml exec -T hatchet \
/hatchet-admin token create --config /config --name integration-test 2>&1)
HATCHET_TOKEN=$(echo "$HATCHET_OUTPUT" | grep -o 'eyJ[A-Za-z0-9_.\-]*')
if [ -z "$HATCHET_TOKEN" ]; then
echo "ERROR: Failed to extract Hatchet JWT token"
exit 1
fi
echo "HATCHET_CLIENT_TOKEN=${HATCHET_TOKEN}" >> $GITHUB_ENV
- name: Start backend services
working-directory: server/tests
env:
LLM_URL: ${{ secrets.LLM_URL }}
LLM_MODEL: ${{ inputs.llm_model || secrets.LLM_MODEL }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
HF_TOKEN: ${{ secrets.HF_TOKEN }}
run: |
# Export garage and hatchet credentials for backend services
export GARAGE_KEY_ID="${{ env.GARAGE_KEY_ID }}"
export GARAGE_KEY_SECRET="${{ env.GARAGE_KEY_SECRET }}"
export HATCHET_CLIENT_TOKEN="${{ env.HATCHET_CLIENT_TOKEN }}"
docker compose -f docker-compose.integration.yml up -d \
server worker hatchet-worker-cpu hatchet-worker-llm test-runner
- name: Wait for server health check
working-directory: server/tests
run: |
echo "Waiting for server to be healthy..."
for i in $(seq 1 60); do
if docker compose -f docker-compose.integration.yml exec -T test-runner \
curl -sf http://server:1250/health &>/dev/null; then
echo "Server is ready."
break
fi
sleep 3
done
- name: Run DB migrations
working-directory: server/tests
run: |
docker compose -f docker-compose.integration.yml exec -T server \
uv run alembic upgrade head
- name: Run integration tests
working-directory: server/tests
run: |
docker compose -f docker-compose.integration.yml exec -T test-runner \
uv run pytest tests/integration/ -v -x
- name: Collect logs on failure
if: failure()
working-directory: server/tests
run: |
docker compose -f docker-compose.integration.yml logs --tail=500 > integration-logs.txt 2>&1
- name: Upload logs artifact
if: failure()
uses: actions/upload-artifact@v4
with:
name: integration-logs
path: server/tests/integration-logs.txt
retention-days: 7
- name: Teardown
if: always()
working-directory: server/tests
run: |
docker compose -f docker-compose.integration.yml down -v --remove-orphans