Some checks failed
Rust CI / Security Audit (push) Has been cancelled
Rust CI / Check + Test + Lint (nightly) (push) Has been cancelled
Rust CI / Check + Test + Lint (stable) (push) Has been cancelled
mdBook Build & Deploy / Build mdBook (push) Has been cancelled
Nickel Type Check / Nickel Type Checking (push) Has been cancelled
mdBook Build & Deploy / Documentation Quality Check (push) Has been cancelled
mdBook Build & Deploy / Deploy to GitHub Pages (push) Has been cancelled
mdBook Build & Deploy / Notification (push) Has been cancelled
332 lines
12 KiB
YAML
332 lines
12 KiB
YAML
name: Rollback Deployment
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
target:
|
|
description: 'Rollback target'
|
|
required: true
|
|
type: choice
|
|
options:
|
|
- kubernetes
|
|
- docker
|
|
environment:
|
|
description: 'Target environment'
|
|
required: true
|
|
type: choice
|
|
options:
|
|
- staging
|
|
- production
|
|
deployment:
|
|
description: 'Deployment to rollback (or "all")'
|
|
required: false
|
|
default: 'all'
|
|
type: string
|
|
revision:
|
|
description: 'Specific revision to rollback to (0 = previous)'
|
|
required: false
|
|
default: '0'
|
|
type: string
|
|
|
|
concurrency:
|
|
group: rollback-${{ github.ref }}-${{ inputs.environment }}
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
pre-rollback-checks:
|
|
name: Pre-Rollback Safety Checks
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Verify environment protection
|
|
run: |
|
|
echo "🔒 Verifying environment: ${{ inputs.environment }}"
|
|
echo "Target: ${{ inputs.target }}"
|
|
echo "Deployment: ${{ inputs.deployment }}"
|
|
echo ""
|
|
echo "⚠️ This action will rollback production systems!"
|
|
echo " Ensure this is intentional and approved."
|
|
|
|
- name: Create pre-rollback snapshot
|
|
run: |
|
|
mkdir -p rollback-data
|
|
echo "Rollback initiated at: $(date -u +'%Y-%m-%dT%H:%M:%SZ')" > rollback-data/rollback-snapshot.txt
|
|
echo "Target: ${{ inputs.target }}" >> rollback-data/rollback-snapshot.txt
|
|
echo "Environment: ${{ inputs.environment }}" >> rollback-data/rollback-snapshot.txt
|
|
echo "Deployment: ${{ inputs.deployment }}" >> rollback-data/rollback-snapshot.txt
|
|
echo "Requested By: ${{ github.actor }}" >> rollback-data/rollback-snapshot.txt
|
|
echo "Workflow Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> rollback-data/rollback-snapshot.txt
|
|
cat rollback-data/rollback-snapshot.txt
|
|
|
|
- name: Upload pre-rollback snapshot
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: rollback-snapshot-${{ github.run_id }}
|
|
path: rollback-data/
|
|
retention-days: 90
|
|
|
|
rollback-kubernetes:
|
|
name: Rollback Kubernetes
|
|
needs: pre-rollback-checks
|
|
runs-on: ubuntu-latest
|
|
environment: ${{ inputs.environment }}
|
|
if: ${{ inputs.target == 'kubernetes' }}
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Install Nushell
|
|
run: |
|
|
cargo install nu --locked
|
|
nu --version
|
|
|
|
- name: Install kubectl
|
|
uses: azure/setup-kubectl@v3
|
|
with:
|
|
version: 'latest'
|
|
|
|
- name: Configure kubeconfig (staging)
|
|
run: |
|
|
mkdir -p ~/.kube
|
|
echo "${{ secrets.KUBE_CONFIG_STAGING }}" | base64 -d > ~/.kube/config
|
|
chmod 600 ~/.kube/config
|
|
kubectl cluster-info
|
|
if: ${{ inputs.environment == 'staging' }}
|
|
|
|
- name: Configure kubeconfig (production)
|
|
run: |
|
|
mkdir -p ~/.kube
|
|
echo "${{ secrets.KUBE_CONFIG_PRODUCTION }}" | base64 -d > ~/.kube/config
|
|
chmod 600 ~/.kube/config
|
|
kubectl cluster-info
|
|
if: ${{ inputs.environment == 'production' }}
|
|
|
|
- name: Store deployment history
|
|
run: |
|
|
mkdir -p rollback-data
|
|
echo "=== Deployment History ===" > rollback-data/pre-rollback-status.txt
|
|
|
|
for deployment in vapora-backend vapora-agents vapora-llm-router; do
|
|
if [ "${{ inputs.deployment }}" == "all" ] || [ "${{ inputs.deployment }}" == "$deployment" ]; then
|
|
echo "Deployment: $deployment" >> rollback-data/pre-rollback-status.txt
|
|
kubectl rollout history deployment/$deployment -n vapora >> rollback-data/pre-rollback-status.txt 2>&1
|
|
kubectl get deployment $deployment -n vapora -o yaml >> rollback-data/pre-rollback-status.txt 2>&1
|
|
echo "---" >> rollback-data/pre-rollback-status.txt
|
|
fi
|
|
done
|
|
|
|
cat rollback-data/pre-rollback-status.txt
|
|
|
|
- name: Perform Kubernetes rollback
|
|
run: |
|
|
cd provisioning
|
|
nu scripts/rollback.nu \
|
|
--target kubernetes \
|
|
--deployment "${{ inputs.deployment }}" \
|
|
--revision ${{ inputs.revision }} \
|
|
2>&1 | tee ../rollback-data/rollback-output.log
|
|
|
|
- name: Verify rollback status
|
|
run: |
|
|
echo "=== Post-Rollback Status ===" > rollback-data/post-rollback-status.txt
|
|
|
|
for deployment in vapora-backend vapora-agents vapora-llm-router; do
|
|
if [ "${{ inputs.deployment }}" == "all" ] || [ "${{ inputs.deployment }}" == "$deployment" ]; then
|
|
echo "Deployment: $deployment" >> rollback-data/post-rollback-status.txt
|
|
kubectl get deployment $deployment -n vapora -o wide >> rollback-data/post-rollback-status.txt 2>&1
|
|
kubectl rollout status deployment/$deployment -n vapora --timeout=5m >> rollback-data/post-rollback-status.txt 2>&1 || true
|
|
echo "---" >> rollback-data/post-rollback-status.txt
|
|
fi
|
|
done
|
|
|
|
cat rollback-data/post-rollback-status.txt
|
|
|
|
- name: Check pod health after rollback
|
|
run: |
|
|
echo "Pod Status After Rollback:" >> rollback-data/post-rollback-status.txt
|
|
kubectl get pods -n vapora -o wide >> rollback-data/post-rollback-status.txt 2>&1
|
|
echo "" >> rollback-data/post-rollback-status.txt
|
|
echo "Recent Events:" >> rollback-data/post-rollback-status.txt
|
|
kubectl get events -n vapora --sort-by='.lastTimestamp' | tail -20 >> rollback-data/post-rollback-status.txt 2>&1
|
|
|
|
- name: Upload rollback logs
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: k8s-rollback-logs-${{ github.run_id }}
|
|
path: rollback-data/
|
|
retention-days: 90
|
|
|
|
rollback-docker:
|
|
name: Rollback Docker
|
|
needs: pre-rollback-checks
|
|
runs-on: ubuntu-latest
|
|
if: ${{ inputs.target == 'docker' }}
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Install Nushell
|
|
run: |
|
|
cargo install nu --locked
|
|
nu --version
|
|
|
|
- name: Show rollback options
|
|
run: |
|
|
mkdir -p rollback-data
|
|
|
|
cat > rollback-data/docker-rollback-guide.md << 'EOF'
|
|
# Docker Rollback Guide
|
|
|
|
Docker Compose rollback requires manual steps:
|
|
|
|
## Option 1: Revert to previous compose file
|
|
```bash
|
|
cd deploy/docker
|
|
docker compose down
|
|
# Restore previous docker-compose.yml
|
|
git checkout HEAD~1 docker-compose.yml
|
|
docker compose up -d
|
|
```
|
|
|
|
## Option 2: Stop and restart with older images
|
|
```bash
|
|
docker compose -f docker-compose.yml.backup up -d
|
|
```
|
|
|
|
## Option 3: Remove containers and redeploy
|
|
```bash
|
|
docker compose down
|
|
docker system prune -f
|
|
docker compose up -d
|
|
```
|
|
|
|
## Verification
|
|
```bash
|
|
docker compose ps
|
|
docker compose logs -f backend
|
|
curl http://localhost:8001/health
|
|
```
|
|
|
|
EOF
|
|
|
|
cat rollback-data/docker-rollback-guide.md
|
|
|
|
- name: Store Docker compose file
|
|
run: |
|
|
mkdir -p rollback-data
|
|
if [ -f "deploy/docker/docker-compose.yml" ]; then
|
|
cp deploy/docker/docker-compose.yml rollback-data/current-docker-compose.yml
|
|
echo "Current docker-compose.yml backed up"
|
|
fi
|
|
|
|
- name: List available backups
|
|
run: |
|
|
echo "Looking for docker-compose backups..." >> rollback-data/available-backups.txt
|
|
find . -name "docker-compose*.yml*" -type f 2>/dev/null | head -20 >> rollback-data/available-backups.txt 2>&1 || echo "No backups found"
|
|
cat rollback-data/available-backups.txt
|
|
|
|
- name: Upload rollback guide
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: docker-rollback-guide-${{ github.run_id }}
|
|
path: rollback-data/
|
|
retention-days: 90
|
|
|
|
post-rollback-verification:
|
|
name: Post-Rollback Verification
|
|
needs: [pre-rollback-checks]
|
|
runs-on: ubuntu-latest
|
|
if: always()
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Create rollback report
|
|
run: |
|
|
mkdir -p rollback-reports
|
|
|
|
cat > rollback-reports/ROLLBACK_REPORT.md << 'EOF'
|
|
# Rollback Execution Report
|
|
|
|
**Rollback Time**: $(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
|
**Target**: ${{ inputs.target }}
|
|
**Environment**: ${{ inputs.environment }}
|
|
**Deployment**: ${{ inputs.deployment }}
|
|
**Revision**: ${{ inputs.revision }}
|
|
**Initiated By**: ${{ github.actor }}
|
|
**Workflow Run**: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
|
|
## Status
|
|
|
|
- **Pre-rollback Checks**: ✅ Passed
|
|
- **Rollback Execution**: ${{ job.status == 'success' && '✅' || '⚠️' }}
|
|
|
|
## Artifacts
|
|
|
|
Check the following artifacts for detailed information:
|
|
- `rollback-snapshot-${{ github.run_id }}` - Initial snapshot
|
|
- `k8s-rollback-logs-${{ github.run_id }}` - Kubernetes rollback logs (if K8s)
|
|
- `docker-rollback-guide-${{ github.run_id }}` - Docker rollback guide (if Docker)
|
|
|
|
## Next Steps
|
|
|
|
1. Verify service health
|
|
2. Review application logs
|
|
3. Monitor metrics
|
|
4. Investigate root cause of previous deployment
|
|
5. Plan corrected deployment
|
|
|
|
## Rollback Verification
|
|
|
|
### For Kubernetes
|
|
```bash
|
|
kubectl get deployments -n vapora
|
|
kubectl logs -f deployment/vapora-backend -n vapora
|
|
kubectl rollout history deployment/vapora-backend -n vapora
|
|
```
|
|
|
|
### For Docker
|
|
```bash
|
|
docker compose ps
|
|
docker compose logs -f
|
|
```
|
|
|
|
EOF
|
|
cat rollback-reports/ROLLBACK_REPORT.md
|
|
|
|
- name: Upload rollback report
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: rollback-report-${{ github.run_id }}
|
|
path: rollback-reports/
|
|
retention-days: 90
|
|
|
|
- name: Post rollback notification
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
github.rest.issues.create({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
title: `🔙 Deployment Rollback Executed - ${{ inputs.environment }}`,
|
|
body: `**Rollback Summary**\n\n- **Target**: ${{ inputs.target }}\n- **Environment**: ${{ inputs.environment }}\n- **Deployment**: ${{ inputs.deployment }}\n- **Revision**: ${{ inputs.revision }}\n- **Executed By**: ${{ github.actor }}\n- **Time**: ${new Date().toISOString()}\n\n**Artifacts**:\n- rollback-snapshot-${{ github.run_id }}\n- rollback-report-${{ github.run_id }}\n\n**Action Required**: Verify service health and investigate root cause.`,
|
|
labels: ['deployment', 'rollback', 'incident']
|
|
});
|
|
|
|
- name: Notify Slack - Rollback
|
|
uses: 8398a7/action-slack@v3
|
|
with:
|
|
status: ${{ job.status }}
|
|
text: |
|
|
🔙 VAPORA Rollback Executed
|
|
Target: ${{ inputs.target }}
|
|
Environment: ${{ inputs.environment }}
|
|
Deployment: ${{ inputs.deployment }}
|
|
Executed By: ${{ github.actor }}
|
|
webhook_url: ${{ secrets.SLACK_WEBHOOK_ALERTS }}
|
|
fields: repo,message,commit,author
|
|
continue-on-error: true
|