Skip to content

Commit 6350033

Browse files
committed
ci fix:
- frontend without docker call, directly npm test - backend with setup ci compose
1 parent 578efc3 commit 6350033

File tree

7 files changed

+288
-427
lines changed

7 files changed

+288
-427
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Setup CI Compose
2+
description: Creates docker-compose.ci.yaml with CI-specific modifications
3+
4+
inputs:
5+
kubeconfig-path:
6+
description: Path to kubeconfig file for cert-generator mount
7+
required: true
8+
9+
runs:
10+
using: composite
11+
steps:
12+
- name: Install yq
13+
shell: bash
14+
run: |
15+
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
16+
sudo chmod +x /usr/local/bin/yq
17+
18+
- name: Create CI compose configuration
19+
shell: bash
20+
env:
21+
KUBECONFIG_PATH: ${{ inputs.kubeconfig-path }}
22+
run: |
23+
cp docker-compose.yaml docker-compose.ci.yaml
24+
25+
# Backend environment variables
26+
yq eval '.services.backend.environment += ["TESTING=true"]' -i docker-compose.ci.yaml
27+
yq eval '.services.backend.environment += ["MONGO_ROOT_USER=root"]' -i docker-compose.ci.yaml
28+
yq eval '.services.backend.environment += ["MONGO_ROOT_PASSWORD=rootpassword"]' -i docker-compose.ci.yaml
29+
yq eval '.services.backend.environment += ["OTEL_SDK_DISABLED=true"]' -i docker-compose.ci.yaml
30+
31+
# Remove hot-reload volume mounts (causes permission issues in CI)
32+
yq eval '.services.backend.volumes = [.services.backend.volumes[] | select(. != "./backend:/app")]' -i docker-compose.ci.yaml
33+
yq eval '.services."k8s-worker".volumes = [.services."k8s-worker".volumes[] | select(. != "./backend:/app:ro")]' -i docker-compose.ci.yaml
34+
yq eval '.services."pod-monitor".volumes = [.services."pod-monitor".volumes[] | select(. != "./backend:/app:ro")]' -i docker-compose.ci.yaml
35+
yq eval '.services."result-processor".volumes = [.services."result-processor".volumes[] | select(. != "./backend:/app:ro")]' -i docker-compose.ci.yaml
36+
37+
# Disable Kafka SASL authentication for CI
38+
yq eval 'del(.services.kafka.environment.KAFKA_OPTS)' -i docker-compose.ci.yaml
39+
yq eval 'del(.services.zookeeper.environment.KAFKA_OPTS)' -i docker-compose.ci.yaml
40+
yq eval 'del(.services.zookeeper.environment.ZOOKEEPER_AUTH_PROVIDER_1)' -i docker-compose.ci.yaml
41+
yq eval '.services.kafka.volumes = [.services.kafka.volumes[] | select(. | contains("jaas.conf") | not)]' -i docker-compose.ci.yaml
42+
yq eval '.services.zookeeper.volumes = [.services.zookeeper.volumes[] | select(. | contains("/etc/kafka") | not)]' -i docker-compose.ci.yaml
43+
44+
# Simplify Zookeeper for CI
45+
yq eval '.services.zookeeper.environment.ZOOKEEPER_4LW_COMMANDS_WHITELIST = "ruok,srvr"' -i docker-compose.ci.yaml
46+
yq eval 'del(.services.zookeeper.healthcheck)' -i docker-compose.ci.yaml
47+
yq eval '.services.kafka.depends_on.zookeeper.condition = "service_started"' -i docker-compose.ci.yaml
48+
49+
# Cert-generator CI configuration
50+
yq eval 'select(.services."cert-generator".extra_hosts == null).services."cert-generator".extra_hosts = []' -i docker-compose.ci.yaml
51+
yq eval '.services."cert-generator".extra_hosts += ["host.docker.internal:host-gateway"]' -i docker-compose.ci.yaml
52+
yq eval '.services."cert-generator".environment += ["CI=true"]' -i docker-compose.ci.yaml
53+
yq eval ".services.\"cert-generator\".volumes += [\"${KUBECONFIG_PATH}:/root/.kube/config:ro\"]" -i docker-compose.ci.yaml
54+
55+
echo "Created docker-compose.ci.yaml"

.github/workflows/ci.yml

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, dev]
6+
pull_request:
7+
branches: [main, dev]
8+
workflow_dispatch:
9+
10+
jobs:
11+
test:
12+
name: Tests
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v6
16+
17+
# ============================================================
18+
# Frontend Unit Tests (no docker needed)
19+
# ============================================================
20+
- name: Setup Node.js
21+
uses: actions/setup-node@v4
22+
with:
23+
node-version: '22'
24+
cache: 'npm'
25+
cache-dependency-path: frontend/package-lock.json
26+
27+
- name: Install frontend dependencies
28+
working-directory: frontend
29+
run: npm ci
30+
31+
- name: Run frontend unit tests
32+
working-directory: frontend
33+
run: npm test
34+
35+
- name: Run frontend tests with coverage
36+
working-directory: frontend
37+
run: npm run test:coverage
38+
39+
- name: Upload frontend coverage
40+
uses: actions/upload-artifact@v6
41+
if: always()
42+
with:
43+
name: frontend-coverage
44+
path: frontend/coverage/
45+
46+
# ============================================================
47+
# Infrastructure Setup (for backend + E2E tests)
48+
# ============================================================
49+
- name: Setup Docker Buildx
50+
uses: docker/setup-buildx-action@v3
51+
52+
- name: Setup Kubernetes (k3s)
53+
run: |
54+
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik --tls-san host.docker.internal" sh -
55+
mkdir -p $HOME/.kube
56+
sudo k3s kubectl config view --raw > $HOME/.kube/config
57+
sudo chmod 600 $HOME/.kube/config
58+
timeout 90 bash -c 'until sudo k3s kubectl cluster-info; do sleep 5; done'
59+
kubectl version
60+
kubectl get nodes
61+
62+
- name: Create kubeconfig for CI
63+
run: |
64+
cat > backend/kubeconfig.yaml <<EOF
65+
apiVersion: v1
66+
kind: Config
67+
clusters:
68+
- name: ci-cluster
69+
cluster:
70+
server: https://host.docker.internal:6443
71+
insecure-skip-tls-verify: true
72+
users:
73+
- name: ci-user
74+
user:
75+
token: "ci-token"
76+
contexts:
77+
- name: ci
78+
context:
79+
cluster: ci-cluster
80+
user: ci-user
81+
current-context: ci
82+
EOF
83+
84+
- name: Setup CI Compose
85+
uses: ./.github/actions/setup-ci-compose
86+
with:
87+
kubeconfig-path: ${{ env.HOME }}/.kube/config
88+
89+
- name: Pre-pull base images
90+
run: |
91+
docker pull python:3.12-slim &
92+
docker pull ghcr.io/astral-sh/uv:0.9.18 &
93+
docker pull node:22-alpine &
94+
docker pull alpine:latest &
95+
docker pull confluentinc/cp-kafka:7.5.0 &
96+
docker pull confluentinc/cp-zookeeper:7.5.0 &
97+
docker pull confluentinc/cp-schema-registry:7.5.0 &
98+
docker pull mongo:8.0 &
99+
docker pull redis:7-alpine &
100+
docker pull grafana/grafana:latest &
101+
docker pull jaegertracing/all-in-one:1.52 &
102+
docker pull victoriametrics/victoria-metrics:v1.96.0 &
103+
docker pull otel/opentelemetry-collector-contrib:0.91.0 &
104+
docker pull obsidiandynamics/kafdrop:3.31.0 &
105+
docker pull danielqsj/kafka-exporter:latest &
106+
wait
107+
108+
- name: Build services
109+
uses: docker/bake-action@v6
110+
with:
111+
source: .
112+
files: docker-compose.ci.yaml
113+
load: true
114+
set: |
115+
*.cache-from=type=gha,scope=buildkit-${{ github.repository }}-${{ github.ref_name }}
116+
*.cache-from=type=gha,scope=buildkit-${{ github.repository }}-main
117+
*.cache-to=type=gha,mode=max,scope=buildkit-${{ github.repository }}-${{ github.ref_name }}
118+
*.pull=true
119+
env:
120+
BUILDKIT_PROGRESS: plain
121+
122+
- name: Start services
123+
run: |
124+
docker compose -f docker-compose.ci.yaml up -d --remove-orphans
125+
docker compose -f docker-compose.ci.yaml ps
126+
127+
- name: Wait for backend
128+
run: |
129+
curl --retry 60 --retry-delay 5 --retry-all-errors -ksf https://127.0.0.1:443/api/v1/health/live
130+
docker compose -f docker-compose.ci.yaml ps
131+
132+
- name: Wait for frontend
133+
run: |
134+
curl --retry 30 --retry-delay 5 --retry-all-errors -ksf https://127.0.0.1:5001/ || true
135+
136+
- name: Check K8s status
137+
run: |
138+
kubectl get pods -A -o wide
139+
kubectl get services -A -o wide
140+
141+
# ============================================================
142+
# Backend Tests
143+
# ============================================================
144+
- name: Set up uv
145+
uses: astral-sh/setup-uv@v7
146+
with:
147+
enable-cache: true
148+
cache-dependency-glob: "backend/uv.lock"
149+
150+
- name: Install Python dependencies
151+
run: |
152+
cd backend
153+
uv python install 3.12
154+
uv sync --frozen
155+
156+
- name: Run backend tests
157+
id: backend-tests
158+
timeout-minutes: 5
159+
env:
160+
BACKEND_BASE_URL: https://127.0.0.1:443
161+
MONGO_ROOT_USER: root
162+
MONGO_ROOT_PASSWORD: rootpassword
163+
MONGODB_HOST: 127.0.0.1
164+
MONGODB_PORT: 27017
165+
MONGODB_URL: mongodb://root:[email protected]:27017/?authSource=admin
166+
SCHEMA_SUBJECT_PREFIX: "ci.${{ github.run_id }}."
167+
run: |
168+
cd backend
169+
uv run pytest tests/integration tests/unit -v --cov=app --cov-branch --cov-report=xml --cov-report=term --cov-report=term-missing
170+
171+
- name: Upload backend coverage to Codecov
172+
uses: codecov/codecov-action@v5
173+
if: always()
174+
with:
175+
token: ${{ secrets.CODECOV_TOKEN }}
176+
file: backend/coverage.xml
177+
flags: backend
178+
name: backend-coverage
179+
slug: HardMax71/Integr8sCode
180+
fail_ci_if_error: false
181+
182+
# ============================================================
183+
# E2E Tests
184+
# ============================================================
185+
- name: Install Playwright browsers
186+
if: success() || failure()
187+
working-directory: frontend
188+
run: npx playwright install chromium
189+
190+
- name: Run E2E tests
191+
id: e2e-tests
192+
if: success() || failure()
193+
working-directory: frontend
194+
env:
195+
CI: true
196+
run: npx playwright test --reporter=html
197+
198+
- name: Upload Playwright report
199+
uses: actions/upload-artifact@v6
200+
if: always()
201+
with:
202+
name: playwright-report
203+
path: frontend/playwright-report/
204+
205+
# ============================================================
206+
# Cleanup & Logs
207+
# ============================================================
208+
- name: Collect logs
209+
if: always()
210+
run: |
211+
mkdir -p logs
212+
docker compose -f docker-compose.ci.yaml logs > logs/docker-compose.log
213+
docker compose -f docker-compose.ci.yaml logs cert-generator > logs/cert-generator.log
214+
docker compose -f docker-compose.ci.yaml logs backend > logs/backend.log
215+
docker compose -f docker-compose.ci.yaml logs frontend > logs/frontend.log
216+
docker compose -f docker-compose.ci.yaml logs mongo > logs/mongo.log
217+
kubectl get events --sort-by='.metadata.creationTimestamp' > logs/k8s-events.log 2>&1 || true
218+
kubectl get pods -A -o wide > logs/k8s-pods-final.log 2>&1 || true
219+
kubectl describe pods -A > logs/k8s-describe-pods-final.log 2>&1 || true
220+
221+
- name: Upload logs
222+
if: always()
223+
uses: actions/upload-artifact@v6
224+
with:
225+
name: ci-logs
226+
path: logs/

0 commit comments

Comments
 (0)