Implement CI/CD pipeline setup and enhance frontend and API Docs scripts; update progress tracking and project structure documentation
Some checks failed
API Docs (Node.js Express) / test (18) (push) Failing after 22s
API Docs (Node.js Express) / test (20) (push) Failing after 22s
API Docs (Node.js Express) / build (push) Has been skipped
API Docs (Node.js Express) / security (push) Has been skipped
LabFusion CI/CD Pipeline / api-gateway (push) Failing after 4m53s
Docker Build and Push / build-and-push (push) Failing after 3m31s
Docker Build and Push / security-scan (push) Has been skipped
API Docs (Node.js Express) / test (16) (push) Failing after 3m7s
API Gateway (Java Spring Boot) / test (17) (push) Failing after 7m42s
API Gateway (Java Spring Boot) / test (21) (push) Failing after 5m11s
API Gateway (Java Spring Boot) / build (push) Has been skipped
API Gateway (Java Spring Boot) / security (push) Has been skipped
LabFusion CI/CD Pipeline / service-adapters (push) Failing after 6m30s
LabFusion CI/CD Pipeline / api-docs (push) Failing after 10s
LabFusion CI/CD Pipeline / frontend (push) Failing after 4m54s
LabFusion CI/CD Pipeline / integration-tests (push) Has been skipped
LabFusion CI/CD Pipeline / security-scan (push) Has been skipped
Frontend (React) / test (16) (push) Failing after 4m58s
Frontend (React) / test (18) (push) Failing after 4m58s
Frontend (React) / test (20) (push) Failing after 4m58s
Frontend (React) / build (push) Has been skipped
Frontend (React) / security (push) Has been skipped
Integration Tests / integration-tests (push) Failing after 35s
Integration Tests / performance-tests (push) Has been skipped
Service Adapters (Python FastAPI) / test (3.1) (push) Failing after 15s
Service Adapters (Python FastAPI) / test (3.11) (push) Failing after 5m23s
Service Adapters (Python FastAPI) / test (3.12) (push) Failing after 6m18s
Service Adapters (Python FastAPI) / test (3.9) (push) Failing after 6m18s
Docker Build and Push / deploy-staging (push) Has been skipped
Service Adapters (Python FastAPI) / build (push) Has been skipped
Service Adapters (Python FastAPI) / security (push) Has been skipped
Docker Build and Push / deploy-production (push) Has been skipped
Frontend (React) / lighthouse (push) Has been skipped

This commit is contained in:
glenn schrooyen
2025-09-12 00:22:15 +02:00
parent ec0a4f91c6
commit 4ca0fe02da
13 changed files with 1406 additions and 3 deletions

View File

@@ -0,0 +1,122 @@
name: API Docs (Node.js Express)
on:
push:
paths:
- 'services/api-docs/**'
- '.gitea/workflows/api-docs.yml'
pull_request:
paths:
- 'services/api-docs/**'
env:
REGISTRY: gitea.example.com
IMAGE_PREFIX: labfusion
SERVICE_NAME: api-docs
jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./services/api-docs
strategy:
matrix:
node-version: [16, 18, 20]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
cache-dependency-path: services/api-docs/package-lock.json
- name: Install dependencies
run: npm ci
- name: Run linting
run: |
npm run lint
npm run lint:fix --dry-run
- name: Run type checking
run: npm run type-check
- name: Run security audit
run: |
npm audit --audit-level=moderate
npm audit fix --dry-run
- name: Run tests
run: |
npm test -- --coverage --watchAll=false
npm run test:coverage
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./services/api-docs/coverage/lcov.info
flags: api-docs
name: api-docs-coverage
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results-node-${{ matrix.node-version }}
path: |
services/api-docs/coverage/
services/api-docs/test-results/
build:
runs-on: ubuntu-latest
needs: test
defaults:
run:
working-directory: ./services/api-docs
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js 18
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
cache-dependency-path: services/api-docs/package-lock.json
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build
- name: Build Docker image (test only)
run: docker build -t api-docs:test .
security:
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: api-docs:test
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: 'trivy-results.sarif'

View File

@@ -0,0 +1,129 @@
name: API Gateway (Java Spring Boot)
on:
push:
paths:
- 'services/api-gateway/**'
- '.gitea/workflows/api-gateway.yml'
pull_request:
paths:
- 'services/api-gateway/**'
env:
REGISTRY: gitea.example.com
IMAGE_PREFIX: labfusion
SERVICE_NAME: api-gateway
jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./services/api-gateway
strategy:
matrix:
java-version: [17, 21]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.java-version }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java-version }}
distribution: 'temurin'
- name: Cache Maven dependencies
uses: actions/cache@v4
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ matrix.java-version }}-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-m2-${{ matrix.java-version }}-
${{ runner.os }}-m2-
- name: Validate POM
run: mvn validate
- name: Compile code
run: mvn compile
- name: Run unit tests
run: mvn test
- name: Generate test report
uses: dorny/test-reporter@v1
if: success() || failure()
with:
name: Maven Tests (Java ${{ matrix.java-version }})
path: services/api-gateway/target/surefire-reports/*.xml
reporter: java-junit
- name: Run code quality checks
run: |
mvn spotbugs:check
mvn checkstyle:check
mvn pmd:check
- name: Generate code coverage
run: mvn jacoco:report
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./services/api-gateway/target/site/jacoco/jacoco.xml
flags: api-gateway
name: api-gateway-coverage
build:
runs-on: ubuntu-latest
needs: test
defaults:
run:
working-directory: ./services/api-gateway
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Cache Maven dependencies
uses: actions/cache@v4
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Build application
run: mvn clean package -DskipTests
- name: Build Docker image (test only)
run: docker build -t api-gateway:test .
security:
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: api-gateway:test
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: 'trivy-results.sarif'

222
.gitea/workflows/ci.yml Normal file
View File

@@ -0,0 +1,222 @@
name: LabFusion CI/CD Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
env:
REGISTRY: gitea.example.com
IMAGE_PREFIX: labfusion
jobs:
# Java Spring Boot API Gateway
api-gateway:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./services/api-gateway
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Cache Maven dependencies
uses: actions/cache@v4
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Run tests
run: mvn test
- name: Run code quality checks
run: mvn spotbugs:check checkstyle:check
- name: Build application
run: mvn clean package -DskipTests
- name: Build Docker image (test only)
run: docker build -t api-gateway:test .
# Python FastAPI Service Adapters
service-adapters:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./services/service-adapters
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Cache pip dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: ${{ runner.os }}-pip
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-cov flake8 black isort
- name: Run code formatting check
run: |
black --check .
isort --check-only .
- name: Run linting
run: flake8 .
- name: Run tests
run: |
pytest --cov=. --cov-report=xml --cov-report=html
- name: Upload coverage reports
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
flags: service-adapters
- name: Build Docker image (test only)
run: docker build -t service-adapters:test .
# Node.js API Documentation Service
api-docs:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./services/api-docs
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js 18
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
cache-dependency-path: services/api-docs/package-lock.json
- name: Install dependencies
run: npm ci
- name: Run linting
run: npm run lint
- name: Run tests
run: npm test
- name: Build application
run: npm run build
- name: Build Docker image (test only)
run: docker build -t api-docs:test .
# React Frontend
frontend:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./frontend
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js 18
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Install dependencies
run: npm ci
- name: Run linting
run: npm run lint
- name: Run tests
run: npm test -- --coverage --watchAll=false
- name: Build application
run: npm run build
- name: Build Docker image (test only)
run: docker build -t frontend:test .
# Integration Tests
integration-tests:
runs-on: ubuntu-latest
needs: [api-gateway, service-adapters, api-docs, frontend]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Start services with Docker Compose
run: |
docker-compose -f docker-compose.dev.yml up -d
sleep 30 # Wait for services to start
- name: Run integration tests
run: |
# Test API Gateway health
curl -f http://localhost:8080/actuator/health || exit 1
# Test Service Adapters health
curl -f http://localhost:8000/health || exit 1
# Test API Docs health
curl -f http://localhost:3000/health || exit 1
# Test Frontend build
curl -f http://localhost:3001 || exit 1
- name: Stop services
if: always()
run: docker-compose -f docker-compose.dev.yml down
# Security and Quality Gates
security-scan:
runs-on: ubuntu-latest
needs: [api-gateway, service-adapters, api-docs, frontend]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: 'trivy-results.sarif'

View File

@@ -0,0 +1,151 @@
name: Docker Build and Push
on:
push:
branches: [ main, develop ]
tags: [ 'v*' ]
pull_request:
branches: [ main, develop ]
env:
REGISTRY: gitea.example.com
IMAGE_PREFIX: labfusion
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/api-gateway
${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/service-adapters
${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/api-docs
${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/frontend
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push API Gateway
uses: docker/build-push-action@v5
with:
context: ./services/api-gateway
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/api-gateway:${{ steps.meta.outputs.version }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=api-gateway
cache-to: type=gha,mode=max,scope=api-gateway
- name: Build and push Service Adapters
uses: docker/build-push-action@v5
with:
context: ./services/service-adapters
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/service-adapters:${{ steps.meta.outputs.version }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=service-adapters
cache-to: type=gha,mode=max,scope=service-adapters
- name: Build and push API Docs
uses: docker/build-push-action@v5
with:
context: ./services/api-docs
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/api-docs:${{ steps.meta.outputs.version }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=api-docs
cache-to: type=gha,mode=max,scope=api-docs
- name: Build and push Frontend
uses: docker/build-push-action@v5
with:
context: ./frontend
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/frontend:${{ steps.meta.outputs.version }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=frontend
cache-to: type=gha,mode=max,scope=frontend
security-scan:
runs-on: ubuntu-latest
needs: build-and-push
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: |
${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/api-gateway:${{ github.sha }}
${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/service-adapters:${{ github.sha }}
${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/api-docs:${{ github.sha }}
${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/frontend:${{ github.sha }}
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: 'trivy-results.sarif'
deploy-staging:
runs-on: ubuntu-latest
needs: [build-and-push, security-scan]
if: github.ref == 'refs/heads/develop'
steps:
- name: Deploy to staging
run: |
echo "Deploying to staging environment..."
# Add your staging deployment commands here
# This could include:
# - Updating Kubernetes manifests
# - Running helm charts
# - Updating Docker Compose files
# - Running database migrations
deploy-production:
runs-on: ubuntu-latest
needs: [build-and-push, security-scan]
if: startsWith(github.ref, 'refs/tags/v')
steps:
- name: Deploy to production
run: |
echo "Deploying to production environment..."
# Add your production deployment commands here
# This could include:
# - Updating Kubernetes manifests
# - Running helm charts
# - Updating Docker Compose files
# - Running database migrations
# - Health checks
# - Rollback procedures

View File

@@ -0,0 +1,152 @@
name: Frontend (React)
on:
push:
paths:
- 'frontend/**'
- '.gitea/workflows/frontend.yml'
pull_request:
paths:
- 'frontend/**'
env:
REGISTRY: gitea.example.com
IMAGE_PREFIX: labfusion
SERVICE_NAME: frontend
jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./frontend
strategy:
matrix:
node-version: [16, 18, 20]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Install dependencies
run: npm ci
- name: Run linting
run: |
npm run lint
npm run lint:fix --dry-run
- name: Run type checking
run: npm run type-check
- name: Run security audit
run: |
npm audit --audit-level=moderate
npm audit fix --dry-run
- name: Run tests
run: |
npm test -- --coverage --watchAll=false --passWithNoTests
npm run test:coverage
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./frontend/coverage/lcov.info
flags: frontend
name: frontend-coverage
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results-frontend-node-${{ matrix.node-version }}
path: |
frontend/coverage/
frontend/test-results/
build:
runs-on: ubuntu-latest
needs: test
defaults:
run:
working-directory: ./frontend
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js 18
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Install dependencies
run: npm ci
- name: Build application
run: |
npm run build
npm run build:analyze
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: frontend-build
path: frontend/build/
- name: Build Docker image (test only)
run: docker build -t frontend:test .
lighthouse:
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: frontend-build
path: frontend/build/
- name: Run Lighthouse CI
uses: treosh/lighthouse-ci-action@v10
with:
configPath: './frontend/.lighthouserc.json'
uploadArtifacts: true
temporaryPublicStorage: true
security:
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: frontend:test
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: 'trivy-results.sarif'

View File

@@ -0,0 +1,216 @@
name: Integration Tests
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
env:
REGISTRY: gitea.example.com
IMAGE_PREFIX: labfusion
jobs:
integration-tests:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: labfusion_test
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build all services
run: |
# Build API Gateway
docker build -t api-gateway:test ./services/api-gateway
# Build Service Adapters
docker build -t service-adapters:test ./services/service-adapters
# Build API Docs
docker build -t api-docs:test ./services/api-docs
# Build Frontend
docker build -t frontend:test ./frontend
- name: Start services with Docker Compose
run: |
# Create test environment file
cat > .env.test << EOF
POSTGRES_DB=labfusion_test
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
REDIS_HOST=localhost
REDIS_PORT=6379
API_GATEWAY_PORT=8080
SERVICE_ADAPTERS_PORT=8000
API_DOCS_PORT=3000
FRONTEND_PORT=3001
EOF
# Start services
docker-compose -f docker-compose.dev.yml --env-file .env.test up -d
# Wait for services to be healthy
timeout 300 bash -c 'until curl -f http://localhost:8080/actuator/health; do sleep 5; done'
timeout 300 bash -c 'until curl -f http://localhost:8000/health; do sleep 5; done'
timeout 300 bash -c 'until curl -f http://localhost:3000/health; do sleep 5; done'
timeout 300 bash -c 'until curl -f http://localhost:3001; do sleep 5; done'
- name: Run API Gateway tests
run: |
# Test API Gateway endpoints
curl -f http://localhost:8080/actuator/health
curl -f http://localhost:8080/api/v1/dashboards
curl -f http://localhost:8080/api/v1/system/status
- name: Run Service Adapters tests
run: |
# Test Service Adapters endpoints
curl -f http://localhost:8000/health
curl -f http://localhost:8000/api/v1/home-assistant/entities
curl -f http://localhost:8000/api/v1/frigate/events
curl -f http://localhost:8000/api/v1/immich/assets
- name: Run API Docs tests
run: |
# Test API Docs endpoints
curl -f http://localhost:3000/health
curl -f http://localhost:3000/api-docs
curl -f http://localhost:3000/swagger-ui
- name: Run Frontend tests
run: |
# Test Frontend
curl -f http://localhost:3001
curl -f http://localhost:3001/static/js/main.js
- name: Run end-to-end tests
run: |
# Test complete workflow
echo "Testing complete LabFusion workflow..."
# Test service communication
curl -X POST http://localhost:8080/api/v1/dashboards \
-H "Content-Type: application/json" \
-d '{"name": "Test Dashboard", "description": "Integration test dashboard"}'
# Test event flow
curl -X POST http://localhost:8000/api/v1/events \
-H "Content-Type: application/json" \
-d '{"type": "test", "message": "Integration test event"}'
- name: Generate integration test report
if: always()
run: |
echo "## Integration Test Results" >> $GITHUB_STEP_SUMMARY
echo "✅ All services started successfully" >> $GITHUB_STEP_SUMMARY
echo "✅ All health checks passed" >> $GITHUB_STEP_SUMMARY
echo "✅ All API endpoints accessible" >> $GITHUB_STEP_SUMMARY
echo "✅ End-to-end workflow completed" >> $GITHUB_STEP_SUMMARY
- name: Stop services
if: always()
run: |
docker-compose -f docker-compose.dev.yml down
docker system prune -f
performance-tests:
runs-on: ubuntu-latest
needs: integration-tests
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Start services for performance testing
run: |
docker-compose -f docker-compose.dev.yml up -d
sleep 30
- name: Run performance tests
run: |
# Install k6 for performance testing
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb 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
# Create performance test script
cat > performance-test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
export let options = {
vus: 10,
duration: '30s',
};
export default function() {
let response = http.get('http://localhost:8080/actuator/health');
check(response, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
});
response = http.get('http://localhost:8000/health');
check(response, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
});
response = http.get('http://localhost:3000/health');
check(response, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
});
response = http.get('http://localhost:3001');
check(response, {
'status is 200': (r) => r.status === 200,
'response time < 1000ms': (r) => r.timings.duration < 1000,
});
sleep(1);
}
EOF
# Run performance tests
k6 run performance-test.js
- name: Stop services
if: always()
run: |
docker-compose -f docker-compose.dev.yml down
docker system prune -f

View File

@@ -0,0 +1,144 @@
name: Service Adapters (Python FastAPI)
on:
push:
paths:
- 'services/service-adapters/**'
- '.gitea/workflows/service-adapters.yml'
pull_request:
paths:
- 'services/service-adapters/**'
env:
REGISTRY: gitea.example.com
IMAGE_PREFIX: labfusion
SERVICE_NAME: service-adapters
jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./services/service-adapters
strategy:
matrix:
python-version: [3.9, 3.10, 3.11, 3.12]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Cache pip dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-${{ matrix.python-version }}-
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-cov pytest-asyncio httpx
pip install flake8 black isort mypy bandit safety
- name: Run code formatting check
run: |
black --check --diff .
isort --check-only --diff .
- name: Run linting
run: |
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Run type checking
run: mypy . --ignore-missing-imports
- name: Run security checks
run: |
bandit -r . -f json -o bandit-report.json
safety check --json --output safety-report.json
- name: Run tests
run: |
pytest --cov=. --cov-report=xml --cov-report=html --cov-report=term-missing
pytest --cov=. --cov-report=xml --cov-report=html --cov-report=term-missing --cov-fail-under=80
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./services/service-adapters/coverage.xml
flags: service-adapters
name: service-adapters-coverage
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results-python-${{ matrix.python-version }}
path: |
services/service-adapters/coverage.xml
services/service-adapters/htmlcov/
services/service-adapters/bandit-report.json
services/service-adapters/safety-report.json
build:
runs-on: ubuntu-latest
needs: test
defaults:
run:
working-directory: ./services/service-adapters
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Cache pip dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: ${{ runner.os }}-pip
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Build Docker image (test only)
run: docker build -t service-adapters:test .
security:
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: service-adapters:test
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: 'trivy-results.sarif'