veza/veza-stream-server/.github/workflows/production-deploy.yml
senke 40db0b4c43 fix(ci): upgrade deprecated actions, fix Go version
production-deploy.yml:
- Replace actions-rs/toolchain@v1 with dtolnay/rust-toolchain@stable
- Upgrade actions/cache@v3 -> @v4
- Upgrade github/codeql-action/upload-sarif@v2 -> @v3
- Upgrade actions/upload-artifact@v3 -> @v4

backend-ci.yml:
- Upgrade Go 1.22 -> 1.23 to match go.mod (1.23.8)

Addresses audit findings A08: deprecated actions and outdated Go version.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 23:14:50 +01:00

228 lines
6 KiB
YAML

# === CI/CD PIPELINE PRODUCTION ===
name: Production Deployment
on:
push:
branches: [main]
tags: ['v*']
pull_request:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: veza/stream-server
jobs:
# === TESTS ===
test:
name: Tests & Quality
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Run tests
run: |
cargo test --verbose --all-features
cargo test --release --verbose
- name: Lint code
run: |
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
- name: Security audit
run: |
cargo install cargo-audit
cargo audit
- name: Check performance benchmarks
run: |
cargo bench --no-run
# === BUILD & PUSH IMAGE ===
build:
name: Build & Push Image
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'push'
outputs:
image-digest: ${{ steps.build.outputs.digest }}
image-url: ${{ steps.build.outputs.image-url }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push image
id: build
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile.production
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# === SECURITY SCAN ===
security-scan:
name: Security Scan
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'push'
steps:
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ needs.build.outputs.image-url }}
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
# === DEPLOY TO STAGING ===
deploy-staging:
name: Deploy to Staging
runs-on: ubuntu-latest
needs: [build, security-scan]
if: github.ref == 'refs/heads/main'
environment: staging
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup kubectl
uses: azure/setup-kubectl@v3
with:
version: 'v1.28.0'
- name: Configure kubectl
run: |
echo "${{ secrets.KUBECONFIG_STAGING }}" | base64 -d > kubeconfig
export KUBECONFIG=kubeconfig
- name: Deploy to staging
run: |
envsubst < k8s/staging/stream-server-deployment.yaml | kubectl apply -f -
kubectl rollout status deployment/veza-stream-server -n veza-staging
- name: Run integration tests
run: |
./scripts/test_integration_staging.sh
# === DEPLOY TO PRODUCTION ===
deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
needs: [deploy-staging]
if: startsWith(github.ref, 'refs/tags/v')
environment: production
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup kubectl
uses: azure/setup-kubectl@v3
with:
version: 'v1.28.0'
- name: Configure kubectl
run: |
echo "${{ secrets.KUBECONFIG_PRODUCTION }}" | base64 -d > kubeconfig
export KUBECONFIG=kubeconfig
- name: Pre-deployment checks
run: |
kubectl get pods -n veza-production
kubectl top nodes
- name: Deploy to production
run: |
envsubst < k8s/production/stream-server-deployment.yaml | kubectl apply -f -
kubectl rollout status deployment/veza-stream-server -n veza-production --timeout=600s
- name: Verify deployment
run: |
./scripts/test_production_health.sh
kubectl get pods -n veza-production -l app=veza-stream-server
- name: Slack notification
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: "🚀 Veza Stream Server v${{ github.ref_name }} deployed to production!"
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
# === PERFORMANCE TESTING ===
load-test:
name: Load Testing
runs-on: ubuntu-latest
needs: deploy-staging
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup K6
run: |
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
- name: Run load tests
run: |
k6 run --out json=load-test-results.json tests/load/stream-test.js
k6 run --out json=websocket-test-results.json tests/load/websocket-test.js
- name: Upload test results
uses: actions/upload-artifact@v4
with:
name: load-test-results
path: "*-test-results.json"
- name: Performance regression check
run: |
./scripts/check_performance_regression.sh