Jesús Pérez 09a97ac8f5
chore: update platform submodule to monorepo crates structure
Platform restructured into crates/, added AI service and detector,
       migrated control-center-ui to Leptos 0.8
2026-01-08 21:32:59 +00:00

413 lines
13 KiB
YAML

name: CI/CD Pipeline - RAG Service
on:
push:
branches:
- main
- develop
paths:
- 'provisioning/platform/rag/**'
- '.github/workflows/ci-cd.yml'
pull_request:
branches:
- main
paths:
- 'provisioning/platform/rag/**'
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}/provisioning-rag
RUST_VERSION: 1.80.1
jobs:
# ============================================================================
# LINTING AND FORMATTING
# ============================================================================
lint:
name: Lint and Format Check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.RUST_VERSION }}
components: rustfmt, clippy
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
workspaces: provisioning/platform/rag
- name: Run Clippy
run: |
cd provisioning/platform/rag
cargo clippy --all-targets --all-features -- -D warnings
- name: Check formatting
run: |
cd provisioning/platform/rag
cargo fmt -- --check
# ============================================================================
# UNIT TESTS
# ============================================================================
test:
name: Unit Tests
runs-on: ubuntu-latest
needs: lint
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.RUST_VERSION }}
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
workspaces: provisioning/platform/rag
- name: Run tests
run: |
cd provisioning/platform/rag
cargo test --lib --doc
- name: Run integration tests
run: |
cd provisioning/platform/rag
cargo test --test integration_tests
- name: Upload test results
if: always()
uses: actions/upload-artifact@v3
with:
name: test-results
path: provisioning/platform/rag/target/debug/deps/
# ============================================================================
# BENCHMARKING
# ============================================================================
benchmark:
name: Performance Benchmarks
runs-on: ubuntu-latest
needs: test
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.RUST_VERSION }}
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
workspaces: provisioning/platform/rag
- name: Run benchmarks
run: |
cd provisioning/platform/rag
cargo bench --no-run
cargo bench -- --output-format bencher | tee output.txt
- name: Store benchmark results
uses: benchmark-action/github-action-benchmark@v1
with:
name: Provisioning RAG Benchmarks
tool: 'cargo'
output-file-path: provisioning/platform/rag/output.txt
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: true
- name: Upload benchmark results
if: always()
uses: actions/upload-artifact@v3
with:
name: benchmark-results
path: provisioning/platform/rag/target/criterion/
# ============================================================================
# SECURITY SCANNING
# ============================================================================
security:
name: Security Scanning
runs-on: ubuntu-latest
needs: lint
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.RUST_VERSION }}
- name: Install cargo-audit
run: cargo install cargo-audit
- name: Audit dependencies
run: |
cd provisioning/platform/rag
cargo audit
- name: Run cargo-deny
uses: EmbarkStudios/cargo-deny-action@v1
with:
log-level: warn
command: check advisories
# ============================================================================
# BUILD DOCKER IMAGE
# ============================================================================
build:
name: Build Docker Image
runs-on: ubuntu-latest
needs: [test, benchmark, security]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
permissions:
contents: read
packages: write
outputs:
image-tag: ${{ steps.meta.outputs.tags }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log in to Container Registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
file: provisioning/platform/rag/docker/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# ============================================================================
# DEPLOY TO STAGING
# ============================================================================
deploy-staging:
name: Deploy to Staging
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
environment:
name: staging
url: https://rag-staging.example.com
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up kubectl
uses: azure/setup-kubectl@v3
with:
version: v1.27.0
- name: Configure kubectl
run: |
mkdir -p $HOME/.kube
echo "${{ secrets.KUBECONFIG_STAGING }}" | base64 -d > $HOME/.kube/config
chmod 600 $HOME/.kube/config
- name: Deploy to Kubernetes
run: |
cd provisioning/platform/rag/k8s
kubectl apply -f 00-namespace.yaml
kubectl apply -f 01-configmap.yaml
kubectl apply -f 02-secrets.yaml
kubectl apply -f 03-storage.yaml
kubectl apply -f 04-deployment.yaml
kubectl apply -f 05-service.yaml
kubectl apply -f 06-hpa-ingress.yaml
kubectl apply -f 07-rbac.yaml
kubectl rollout status deployment/provisioning-rag -n provisioning-rag --timeout=5m
- name: Verify deployment health
run: |
for i in {1..30}; do
if curl -f https://rag-staging.example.com/health; then
echo "✓ Deployment healthy"
exit 0
fi
echo "Waiting for service to be healthy... ($i/30)"
sleep 10
done
echo "✗ Service failed to become healthy"
exit 1
- name: Run smoke tests
run: |
cd provisioning/platform/rag
curl -f https://rag-staging.example.com/health
curl -f https://rag-staging.example.com/tasks
echo "✓ Smoke tests passed"
# ============================================================================
# DEPLOY TO PRODUCTION
# ============================================================================
deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
needs: deploy-staging
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
environment:
name: production
url: https://rag.example.com
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up kubectl
uses: azure/setup-kubectl@v3
with:
version: v1.27.0
- name: Configure kubectl
run: |
mkdir -p $HOME/.kube
echo "${{ secrets.KUBECONFIG_PRODUCTION }}" | base64 -d > $HOME/.kube/config
chmod 600 $HOME/.kube/config
- name: Create backup of current state
run: |
cd provisioning/platform/rag/k8s
kubectl get deployment provisioning-rag -n provisioning-rag -o yaml > /tmp/deployment-backup.yaml
echo "Backup saved for rollback if needed"
- name: Deploy to Kubernetes
run: |
cd provisioning/platform/rag/k8s
kubectl apply -f 00-namespace.yaml
kubectl apply -f 01-configmap.yaml
kubectl apply -f 02-secrets.yaml
kubectl apply -f 03-storage.yaml
kubectl apply -f 04-deployment.yaml
kubectl apply -f 05-service.yaml
kubectl apply -f 06-hpa-ingress.yaml
kubectl apply -f 07-rbac.yaml
kubectl rollout status deployment/provisioning-rag -n provisioning-rag --timeout=10m
- name: Verify production health
run: |
for i in {1..30}; do
if curl -f https://rag.example.com/health; then
echo "✓ Production deployment healthy"
exit 0
fi
echo "Waiting for service to be healthy... ($i/30)"
sleep 10
done
echo "✗ Service failed to become healthy"
exit 1
- name: Run comprehensive tests
run: |
cd provisioning/platform/rag
curl -f https://rag.example.com/health
curl -f https://rag.example.com/tasks
curl -f https://rag.example.com/metrics
echo "✓ Comprehensive tests passed"
- name: Notify deployment
if: success()
run: |
echo "✓ Production deployment successful"
echo "Service URL: https://rag.example.com"
echo "Metrics: https://rag.example.com/metrics"
# ============================================================================
# ROLLBACK (Manual trigger)
# ============================================================================
rollback:
name: Rollback Production
runs-on: ubuntu-latest
if: failure() && github.event_name == 'workflow_dispatch'
environment:
name: production
steps:
- name: Set up kubectl
uses: azure/setup-kubectl@v3
- name: Configure kubectl
run: |
mkdir -p $HOME/.kube
echo "${{ secrets.KUBECONFIG_PRODUCTION }}" | base64 -d > $HOME/.kube/config
chmod 600 $HOME/.kube/config
- name: Rollback to previous version
run: |
kubectl rollout undo deployment/provisioning-rag -n provisioning-rag
kubectl rollout status deployment/provisioning-rag -n provisioning-rag --timeout=5m
- name: Verify rollback
run: |
curl -f https://rag.example.com/health
echo "✓ Rollback successful"
# ============================================================================
# NOTIFICATION
# ============================================================================
notify:
name: Notification
runs-on: ubuntu-latest
if: always()
needs: [lint, test, benchmark, security, build, deploy-staging, deploy-production]
steps:
- name: Determine status
id: status
run: |
if [ "${{ job.status }}" == "success" ]; then
echo "status=✓ Success" >> $GITHUB_OUTPUT
echo "color=0x28a745" >> $GITHUB_OUTPUT
else
echo "status=✗ Failed" >> $GITHUB_OUTPUT
echo "color=0xdc3545" >> $GITHUB_OUTPUT
fi
- name: Slack Notification
uses: slackapi/slack-github-action@v1
with:
webhook-url: ${{ secrets.SLACK_WEBHOOK }}
payload: |
{
"text": "RAG Service CI/CD Pipeline ${{ steps.status.outputs.status }}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "RAG Service CI/CD Pipeline\n*Status:* ${{ steps.status.outputs.status }}\n*Commit:* ${{ github.sha }}\n*Branch:* ${{ github.ref_name }}"
}
}
]
}