23f7624596
ADR-166 MCP Bridge Security Lock / Static-source security lock (push) Failing after 0s
ADR-166 MCP Bridge Security Lock / Compose default binds loopback + Mongo has auth (push) Failing after 2s
CodeQL Advanced / Analyze (rust) (push) Failing after 0s
ADR-166 MCP Bridge Security Lock / plugin-agent-federation bindHost default (push) Failing after 1s
ADR-166 MCP Bridge Security Lock / Runtime behavior — 401 + terminal gate + fail-closed (push) Failing after 4s
business-pods-smoke / smoke (push) Failing after 1s
all-plugins-smoke / smoke-all (push) Failing after 2s
CI/CD Pipeline / Security & Code Quality (push) Failing after 1s
CI/CD Pipeline / Test Suite (ubuntu-latest) (push) Failing after 1s
CI/CD Pipeline / Build & Package (macos-latest) (push) Has been skipped
CI/CD Pipeline / Build & Package (ubuntu-latest) (push) Has been skipped
CI/CD Pipeline / Build & Package (windows-latest) (push) Has been skipped
CI/CD Pipeline / Documentation & Examples (push) Failing after 1s
Clone Tracker (14-day rolling) / Snapshot clones for ruflo ecosystem (push) Failing after 1s
CodeQL Advanced / Analyze (actions) (push) Failing after 1s
CodeQL Advanced / Analyze (javascript-typescript) (push) Failing after 1s
federation-peer-rust / stable-noop (push) Failing after 1s
metaharness-ci / score (push) Failing after 1s
metaharness-ci / router-compat (push) Failing after 0s
metaharness-ci / similarity-tests (push) Failing after 0s
no-agentbbs-smoke / smoke-without-agentbbs (push) Failing after 1s
V3 CI/CD Pipeline / Build V3 (windows-latest) (push) Has been skipped
codex-integration-audit / Codex integration audit (push) Failing after 1s
helpers-manifest-guard / guard (push) Failing after 1s
🔗 Cross-Agent Integration Tests / 🤝 Agent Coordination Tests (push) Has been skipped
🔗 Cross-Agent Integration Tests / 🧠 Memory Sharing Integration (push) Has been skipped
🔗 Cross-Agent Integration Tests / 🛡️ Fault Tolerance Tests (push) Has been skipped
🔗 Cross-Agent Integration Tests / ⚡ Performance Integration Tests (push) Has been skipped
metaharness-ci / mcp-scan (push) Failing after 1s
metaharness-ci / eject-dryrun (push) Failing after 1s
metaharness-ci / metaharness-real-data (push) Failing after 0s
no-cli-optdep-bloat-2561 / guard (push) Failing after 1s
no-metaharness-smoke / smoke-without-metaharness (push) Failing after 1s
no-phantom-agentic-flow-subpath / guard (push) Failing after 1s
🔄 Automated Rollback Manager / 🚨 Failure Detection (push) Failing after 1s
V3 CI/CD Pipeline / Plugin hooks smoke / ubuntu-latest / Node 22 (push) Failing after 1s
V3 CI/CD Pipeline / ruflo-graph-intelligence build + test smoke (#2044, ADR-123) (push) Failing after 1s
CVE Audit Gate / Audit root (critical-blocking) (push) Failing after 2s
cost-tracker-smoke / smoke (push) Failing after 3s
oia-audit-weekly / audit (push) Failing after 2s
ruflo-agent-smoke / ruflo-agent structural smoke (push) Failing after 1s
📊 Status Badges Update / 📊 Update Status Badges (push) Failing after 1s
V3 CI/CD Pipeline / Static regression guards (#2267 YAML + (push) Failing after 1s
V3 CI/CD Pipeline / Test V3 Packages (push) Failing after 0s
V3 CI/CD Pipeline / agent_execute provider routing smoke (#2042) (push) Failing after 0s
CVE Audit Gate / Audit v3 (critical-blocking) (push) Failing after 1s
federation-peer-rust / stable-native (push) Failing after 2s
🔗 Cross-Agent Integration Tests / 🚀 Integration Test Setup (push) Failing after 2s
neural-trader-smoke / runtime-smoke (push) Failing after 1s
V3 CI/CD Pipeline / Build V3 (macos-latest) (push) Has been skipped
V3 CI/CD Pipeline / Build V3 (ubuntu-latest) (push) Has been skipped
V3 CI/CD Pipeline / Type Check V3 (push) Failing after 1s
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / ubuntu-latest / Node 24 (push) Failing after 1s
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / ubuntu-latest / Node 22 (push) Failing after 2s
V3 CI/CD Pipeline / browser rvf create flag smoke (#2015) (push) Failing after 0s
V3 CI/CD Pipeline / Dependency review (#2046) (push) Has been skipped
V3 CI/CD Pipeline / Supply-chain audit (#2046) (push) Failing after 0s
V3 CI/CD Pipeline / witness marker drift smoke (#2021) (push) Failing after 1s
V3 CI/CD Pipeline / neural-trader portfolio CG smoke (#2068, ADR-126 Phase 3) (push) Failing after 1s
V3 CI/CD Pipeline / neural-trader backtest signing smoke (#2068, ADR-126 Phase 4) (push) Failing after 1s
V3 CI/CD Pipeline / kg-extract type-import classification smoke (#2049) (push) Failing after 0s
V3 CI/CD Pipeline / witness verify precondition smoke (#1880) (push) Failing after 2s
V3 CI/CD Pipeline / neural-trader pipeline risk-gate smoke (#2068, ADR-126 Phase 5) (push) Failing after 0s
V3 CI/CD Pipeline / neural-trader feature attribution smoke (#2068, ADR-126 Phase 6) (push) Failing after 0s
V3 CI/CD Pipeline / plugin-registry signature verification smoke (#1922, CWE-347) (push) Failing after 4s
V3 CI/CD Pipeline / memory stats legacy-DB smoke (#2120) (push) Failing after 4s
V3 CI/CD Pipeline / github deprecated actions smoke (#2089, ADR-127 Phase 3) (push) Failing after 1s
V3 CI/CD Pipeline / graph query + pathfinder smoke (ADR-130 P2+P5) (push) Has been skipped
V3 CI/CD Pipeline / graph trajectory hooks smoke (ADR-130 P3) (push) Has been skipped
V3 CI/CD Pipeline / graph plugin adapter smoke (ADR-130 P4) (push) Has been skipped
V3 CI/CD Pipeline / graph benchmark (ADR-130 P6) (push) Has been skipped
V3 CI/CD Pipeline / statusline generator delegation smoke (#2195) (push) Failing after 1s
V3 CI/CD Pipeline / wizard init regression guard (#2206 (push) Failing after 1s
V3 CI/CD Pipeline / memory no-stray-db smoke (ADR-125 P7) (push) Failing after 1s
V3 CI/CD Pipeline / github-safe injection smoke (#2089, ADR-127 Phase 1) (push) Failing after 1s
V3 CI/CD Pipeline / github actions pin smoke (#2089, ADR-127 Phase 1) (push) Failing after 1s
V3 CI/CD Pipeline / github attribution opt-in smoke (#2089, ADR-127 Phase 4) (push) Failing after 1s
V3 CI/CD Pipeline / pre-bash hook safety smoke (#2017) (push) Failing after 1s
V3 CI/CD Pipeline / Memory import smoke / ubuntu-latest (push) Failing after 0s
V3 CI/CD Pipeline / MCP protocol smoke / ubuntu-latest (push) Failing after 2s
V3 CI/CD Pipeline / ruvllm WASM auto-init smoke (#2086) (push) Failing after 4s
V3 CI/CD Pipeline / MCP paired-tool round-trip smoke (#1889) (push) Failing after 1s
V3 CI/CD Pipeline / Plugin package install-safety (#1902/#1903/#1904) (push) Failing after 1s
V3 CI/CD Pipeline / Tool description discoverability (ADR-112) (push) Failing after 3s
V3 CI/CD Pipeline / CLI npx-install smoke (#1147 / (22) (push) Failing after 1s
V3 CI/CD Pipeline / CLI npx-install smoke (#1147 / (24) (push) Failing after 1s
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / ubuntu-latest (push) Failing after 2s
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / ubuntu-latest (push) Failing after 1s
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / ubuntu-latest (push) Failing after 1s
V3 CI/CD Pipeline / Vector-index dimension audit (#1947) (push) Failing after 0s
V3 CI/CD Pipeline / Hook-command install safety (#1921) (push) Failing after 1s
V3 CI/CD Pipeline / ToolOutputGuardrail smoke (ADR-131, (push) Failing after 1s
V3 CI/CD Pipeline / init-bundle invariants smoke (#2095, ADR-128 Phase 5) (push) Failing after 1s
V3 CI/CD Pipeline / wasm provider bridge smoke (ADR-129 P1) (push) Failing after 2s
V3 CI/CD Pipeline / wasm gallery CRUD smoke (ADR-129 P3) (push) Failing after 1s
V3 CI/CD Pipeline / wasm plugin bridge smoke (ADR-129 P4) (push) Failing after 0s
V3 CI/CD Pipeline / wasm compose smoke (ADR-129 P2) (push) Failing after 4s
V3 CI/CD Pipeline / graph schema smoke (ADR-130 P1) (push) Failing after 0s
Validate Marketplace / validate (push) Failing after 1s
🔍 Verification Pipeline / 🚀 Setup Verification (push) Failing after 1s
🔍 Verification Pipeline / 🛡️ Security Verification (push) Has been skipped
🔍 Verification Pipeline / 📝 Code Quality (push) Has been skipped
🔍 Verification Pipeline / 🧪 Test Verification (${{ matrix.os }}, Node ${{ matrix.node }}) (push) Has been skipped
🔍 Verification Pipeline / 🏗️ Build Verification (push) Has been skipped
🔍 Verification Pipeline / 📚 Documentation Verification (push) Has been skipped
CVE Audit Gate / High-severity report (warn only) (push) Has been cancelled
🔄 Automated Rollback Manager / 🔄 Execute Rollback (push) Has been cancelled
🔄 Automated Rollback Manager / ✅ Post-Rollback Verification (push) Has been cancelled
🔄 Automated Rollback Manager / 📊 Rollback Monitoring (push) Has been cancelled
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook execution smoke (#2132) / windows-latest (push) Has been cancelled
🔄 Automated Rollback Manager / ⏳ Manual Rollback Approval (push) Has been cancelled
V3 CI/CD Pipeline / MCP protocol smoke / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Memory import smoke / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows hook shim smoke (#2132) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Windows init hooks smoke (#2132) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / macos-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / ubuntu-latest (push) Has been cancelled
V3 CI/CD Pipeline / Witness verify (signed manifest) / windows-latest (push) Has been cancelled
V3 CI/CD Pipeline / Publish to npm (alpha) (push) Has been cancelled
V3 CI/CD Pipeline / Smoke (no better-sqlite3) / macos-latest / Node 22 (push) Has been cancelled
V3 CI/CD Pipeline / Plugin hooks smoke / macos-latest / Node 22 (push) Has been cancelled
CI/CD Pipeline / Deploy & Release (push) Has been cancelled
CI/CD Pipeline / CI Status (push) Has been cancelled
🔗 Cross-Agent Integration Tests / 📊 Integration Test Report (push) Has been cancelled
🔄 Automated Rollback Manager / 🔍 Pre-Rollback Validation (push) Has been cancelled
🔍 Verification Pipeline / ⚡ Performance Verification (push) Has been cancelled
🔍 Verification Pipeline / 📊 Verification Report (push) Has been cancelled
666 lines
25 KiB
YAML
666 lines
25 KiB
YAML
name: 🔄 Automated Rollback Manager
|
|
|
|
on:
|
|
workflow_run:
|
|
workflows: ["🔍 Verification Pipeline", "🎯 Truth Scoring Pipeline", "🔗 Cross-Agent Integration Tests"]
|
|
types: [completed]
|
|
branches: [main, develop]
|
|
push:
|
|
branches: [main]
|
|
workflow_dispatch:
|
|
inputs:
|
|
rollback_target:
|
|
description: 'Target commit SHA or tag for rollback'
|
|
required: true
|
|
rollback_reason:
|
|
description: 'Reason for rollback'
|
|
required: true
|
|
default: 'Manual rollback requested'
|
|
emergency_mode:
|
|
description: 'Emergency rollback mode (skip confirmations)'
|
|
required: false
|
|
default: false
|
|
type: boolean
|
|
rollback_scope:
|
|
description: 'Rollback scope'
|
|
required: false
|
|
default: 'application'
|
|
type: choice
|
|
options:
|
|
- application
|
|
- database
|
|
- infrastructure
|
|
- full
|
|
|
|
env:
|
|
NODE_VERSION: '20'
|
|
ROLLBACK_RETENTION_DAYS: 90
|
|
CRITICAL_FAILURE_THRESHOLD: 3
|
|
MONITORING_WINDOW_MINUTES: 15
|
|
|
|
jobs:
|
|
# Detect failure conditions
|
|
failure-detection:
|
|
name: 🚨 Failure Detection
|
|
runs-on: ubuntu-latest
|
|
if: github.event_name == 'workflow_run' || github.event_name == 'push'
|
|
outputs:
|
|
rollback-required: ${{ steps.detect.outputs.rollback-required }}
|
|
failure-type: ${{ steps.detect.outputs.failure-type }}
|
|
failure-severity: ${{ steps.detect.outputs.failure-severity }}
|
|
rollback-target: ${{ steps.detect.outputs.rollback-target }}
|
|
rollback-session-id: ${{ steps.detect.outputs.rollback-session-id }}
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 50
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
|
|
- name: Detect failure conditions
|
|
id: detect
|
|
run: |
|
|
echo "🚨 Analyzing failure conditions..."
|
|
|
|
ROLLBACK_SESSION="rollback-$(date +%Y%m%d-%H%M%S)-${{ github.sha }}"
|
|
echo "rollback-session-id=$ROLLBACK_SESSION" >> $GITHUB_OUTPUT
|
|
|
|
ROLLBACK_REQUIRED="false"
|
|
FAILURE_TYPE="none"
|
|
FAILURE_SEVERITY="low"
|
|
ROLLBACK_TARGET=""
|
|
|
|
# Check workflow run results if triggered by workflow_run
|
|
if [ "${{ github.event_name }}" = "workflow_run" ]; then
|
|
WORKFLOW_CONCLUSION="${{ github.event.workflow_run.conclusion }}"
|
|
WORKFLOW_NAME="${{ github.event.workflow_run.name }}"
|
|
|
|
echo "Workflow: $WORKFLOW_NAME"
|
|
echo "Conclusion: $WORKFLOW_CONCLUSION"
|
|
|
|
if [ "$WORKFLOW_CONCLUSION" = "failure" ]; then
|
|
ROLLBACK_REQUIRED="true"
|
|
FAILURE_TYPE="ci_failure"
|
|
|
|
# Determine severity based on workflow type
|
|
case "$WORKFLOW_NAME" in
|
|
*"Verification Pipeline"*)
|
|
FAILURE_SEVERITY="high"
|
|
;;
|
|
*"Truth Scoring"*)
|
|
FAILURE_SEVERITY="medium"
|
|
;;
|
|
*"Integration Tests"*)
|
|
FAILURE_SEVERITY="high"
|
|
;;
|
|
*)
|
|
FAILURE_SEVERITY="medium"
|
|
;;
|
|
esac
|
|
fi
|
|
fi
|
|
|
|
# Check for recent commit history to find safe rollback target
|
|
if [ "$ROLLBACK_REQUIRED" = "true" ]; then
|
|
# Find the last successful commit (simplified logic)
|
|
ROLLBACK_TARGET=$(git log --oneline -10 --grep="✅" --grep="🏁" | head -1 | cut -d' ' -f1)
|
|
if [ -z "$ROLLBACK_TARGET" ]; then
|
|
ROLLBACK_TARGET="HEAD~1"
|
|
fi
|
|
fi
|
|
|
|
echo "rollback-required=$ROLLBACK_REQUIRED" >> $GITHUB_OUTPUT
|
|
echo "failure-type=$FAILURE_TYPE" >> $GITHUB_OUTPUT
|
|
echo "failure-severity=$FAILURE_SEVERITY" >> $GITHUB_OUTPUT
|
|
echo "rollback-target=$ROLLBACK_TARGET" >> $GITHUB_OUTPUT
|
|
|
|
echo "🔍 Detection Results:"
|
|
echo " Rollback Required: $ROLLBACK_REQUIRED"
|
|
echo " Failure Type: $FAILURE_TYPE"
|
|
echo " Severity: $FAILURE_SEVERITY"
|
|
echo " Target: $ROLLBACK_TARGET"
|
|
|
|
- name: Create failure report
|
|
if: steps.detect.outputs.rollback-required == 'true'
|
|
run: |
|
|
echo "📋 Creating failure report..."
|
|
|
|
mkdir -p rollback-data
|
|
|
|
cat > rollback-data/failure-report.json << EOF
|
|
{
|
|
"sessionId": "${{ steps.detect.outputs.rollback-session-id }}",
|
|
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
"trigger": {
|
|
"event": "${{ github.event_name }}",
|
|
"workflow": "${{ github.event.workflow_run.name || 'N/A' }}",
|
|
"conclusion": "${{ github.event.workflow_run.conclusion || 'N/A' }}",
|
|
"commit": "${{ github.sha }}",
|
|
"branch": "${{ github.ref_name }}"
|
|
},
|
|
"failure": {
|
|
"type": "${{ steps.detect.outputs.failure-type }}",
|
|
"severity": "${{ steps.detect.outputs.failure-severity }}",
|
|
"rollbackRequired": true
|
|
},
|
|
"rollback": {
|
|
"target": "${{ steps.detect.outputs.rollback-target }}",
|
|
"reason": "Automated rollback due to ${{ steps.detect.outputs.failure-type }}"
|
|
}
|
|
}
|
|
EOF
|
|
|
|
- name: Upload failure detection results
|
|
if: steps.detect.outputs.rollback-required == 'true'
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: failure-detection-${{ steps.detect.outputs.rollback-session-id }}
|
|
path: rollback-data/
|
|
retention-days: ${{ env.ROLLBACK_RETENTION_DAYS }}
|
|
|
|
# Pre-rollback validation
|
|
pre-rollback-validation:
|
|
name: 🔍 Pre-Rollback Validation
|
|
runs-on: ubuntu-latest
|
|
needs: failure-detection
|
|
if: needs.failure-detection.outputs.rollback-required == 'true' || github.event_name == 'workflow_dispatch'
|
|
outputs:
|
|
validation-passed: ${{ steps.validate.outputs.validation-passed }}
|
|
backup-created: ${{ steps.validate.outputs.backup-created }}
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 100
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
cache: 'npm'
|
|
|
|
- name: Install dependencies
|
|
run: npm ci --legacy-peer-deps
|
|
|
|
- name: Validate rollback target
|
|
id: validate
|
|
run: |
|
|
echo "🔍 Validating rollback target..."
|
|
|
|
ROLLBACK_TARGET="${{ github.event.inputs.rollback_target || needs.failure-detection.outputs.rollback-target }}"
|
|
VALIDATION_PASSED="false"
|
|
BACKUP_CREATED="false"
|
|
|
|
if [ -n "$ROLLBACK_TARGET" ]; then
|
|
# Check if target commit exists
|
|
if git cat-file -e "$ROLLBACK_TARGET^{commit}" 2>/dev/null; then
|
|
echo "✅ Rollback target $ROLLBACK_TARGET is valid"
|
|
|
|
# Check if target is reachable from current branch
|
|
if git merge-base --is-ancestor "$ROLLBACK_TARGET" HEAD; then
|
|
echo "✅ Target is ancestor of current HEAD"
|
|
VALIDATION_PASSED="true"
|
|
else
|
|
echo "❌ Target is not an ancestor of current HEAD"
|
|
fi
|
|
else
|
|
echo "❌ Rollback target $ROLLBACK_TARGET does not exist"
|
|
fi
|
|
else
|
|
echo "❌ No rollback target specified"
|
|
fi
|
|
|
|
echo "validation-passed=$VALIDATION_PASSED" >> $GITHUB_OUTPUT
|
|
echo "backup-created=$BACKUP_CREATED" >> $GITHUB_OUTPUT
|
|
|
|
- name: Create current state backup
|
|
if: steps.validate.outputs.validation-passed == 'true'
|
|
run: |
|
|
echo "💾 Creating current state backup..."
|
|
|
|
mkdir -p rollback-data/backup
|
|
|
|
# Create backup metadata
|
|
cat > rollback-data/backup/backup-metadata.json << EOF
|
|
{
|
|
"backupId": "backup-$(date +%Y%m%d-%H%M%S)",
|
|
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
"sourceCommit": "${{ github.sha }}",
|
|
"sourceBranch": "${{ github.ref_name }}",
|
|
"rollbackTarget": "${{ github.event.inputs.rollback_target || needs.failure-detection.outputs.rollback-target }}",
|
|
"backupType": "pre-rollback"
|
|
}
|
|
EOF
|
|
|
|
# Create git bundle for backup
|
|
git bundle create rollback-data/backup/current-state.bundle HEAD
|
|
|
|
# Backup package.json and important config files
|
|
cp package.json rollback-data/backup/ 2>/dev/null || true
|
|
cp package-lock.json rollback-data/backup/ 2>/dev/null || true
|
|
cp claude-flow.config.json rollback-data/backup/ 2>/dev/null || true
|
|
|
|
echo "✅ Backup created successfully"
|
|
|
|
- name: Test rollback target viability
|
|
if: steps.validate.outputs.validation-passed == 'true'
|
|
run: |
|
|
set -e # Exit on any error
|
|
echo "🧪 Testing rollback target viability..."
|
|
|
|
ROLLBACK_TARGET="${{ github.event.inputs.rollback_target || needs.failure-detection.outputs.rollback-target }}"
|
|
|
|
# Create temporary branch for testing
|
|
git checkout -b test-rollback-temp "$ROLLBACK_TARGET"
|
|
|
|
# Test if the target can build (strict error checking)
|
|
echo "Installing dependencies..."
|
|
npm ci --legacy-peer-deps
|
|
|
|
echo "Testing build..."
|
|
npm run build:ts
|
|
|
|
# Switch back to original branch
|
|
git checkout "${{ github.ref_name }}"
|
|
git branch -D test-rollback-temp
|
|
|
|
echo "✅ Rollback target viability tested successfully"
|
|
|
|
- name: Upload pre-rollback validation
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: pre-rollback-validation-${{ needs.failure-detection.outputs.rollback-session-id || 'manual' }}
|
|
path: rollback-data/
|
|
retention-days: ${{ env.ROLLBACK_RETENTION_DAYS }}
|
|
|
|
# Execute rollback
|
|
execute-rollback:
|
|
name: 🔄 Execute Rollback
|
|
runs-on: ubuntu-latest
|
|
needs: [failure-detection, pre-rollback-validation]
|
|
if: needs.pre-rollback-validation.outputs.validation-passed == 'true' && (needs.failure-detection.outputs.failure-severity == 'high' || github.event.inputs.emergency_mode == 'true' || github.event_name == 'workflow_dispatch')
|
|
environment:
|
|
name: rollback-approval
|
|
outputs:
|
|
rollback-executed: ${{ steps.rollback.outputs.rollback-executed }}
|
|
rollback-commit: ${{ steps.rollback.outputs.rollback-commit }}
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 100
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
|
|
- name: Download validation artifacts
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: pre-rollback-validation-${{ needs.failure-detection.outputs.rollback-session-id || 'manual' }}
|
|
path: rollback-data/
|
|
|
|
- name: Configure Git
|
|
run: |
|
|
git config --global user.name "GitHub Actions Rollback Bot"
|
|
git config --global user.email "actions@github.com"
|
|
|
|
- name: Execute rollback
|
|
id: rollback
|
|
run: |
|
|
echo "🔄 Executing rollback..."
|
|
|
|
ROLLBACK_TARGET="${{ github.event.inputs.rollback_target || needs.failure-detection.outputs.rollback-target }}"
|
|
ROLLBACK_REASON="${{ github.event.inputs.rollback_reason || 'Automated rollback due to CI failure' }}"
|
|
ROLLBACK_EXECUTED="false"
|
|
ROLLBACK_COMMIT=""
|
|
|
|
echo "Target: $ROLLBACK_TARGET"
|
|
echo "Reason: $ROLLBACK_REASON"
|
|
|
|
if [ -n "$ROLLBACK_TARGET" ]; then
|
|
# Create rollback commit
|
|
echo "Creating rollback commit..."
|
|
|
|
# Reset to target commit but keep it as a new commit
|
|
git reset --hard "$ROLLBACK_TARGET"
|
|
|
|
# Create a revert commit with metadata
|
|
cat > ROLLBACK_INFO.md << EOF
|
|
# Rollback Information
|
|
|
|
**Rollback Timestamp:** $(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
**Target Commit:** $ROLLBACK_TARGET
|
|
**Reason:** $ROLLBACK_REASON
|
|
**Triggered By:** ${{ github.actor }}
|
|
**Session ID:** ${{ needs.failure-detection.outputs.rollback-session-id || 'manual' }}
|
|
|
|
## Original State
|
|
- **Commit:** ${{ github.sha }}
|
|
- **Branch:** ${{ github.ref_name }}
|
|
|
|
## Rollback Details
|
|
- **Scope:** ${{ github.event.inputs.rollback_scope || 'application' }}
|
|
- **Emergency Mode:** ${{ github.event.inputs.emergency_mode || 'false' }}
|
|
|
|
This rollback was executed automatically by the Rollback Manager workflow.
|
|
EOF
|
|
|
|
git add ROLLBACK_INFO.md
|
|
git commit -m "🔄 Automated rollback to $ROLLBACK_TARGET
|
|
|
|
Reason: $ROLLBACK_REASON
|
|
Session: ${{ needs.failure-detection.outputs.rollback-session-id || 'manual' }}
|
|
Scope: ${{ github.event.inputs.rollback_scope || 'application' }}
|
|
|
|
🤖 Generated by GitHub Actions Rollback Manager
|
|
|
|
Co-Authored-By: Rollback Manager <noreply@github.com>"
|
|
|
|
ROLLBACK_COMMIT=$(git rev-parse HEAD)
|
|
ROLLBACK_EXECUTED="true"
|
|
|
|
echo "✅ Rollback commit created: $ROLLBACK_COMMIT"
|
|
else
|
|
echo "❌ No rollback target specified"
|
|
fi
|
|
|
|
echo "rollback-executed=$ROLLBACK_EXECUTED" >> $GITHUB_OUTPUT
|
|
echo "rollback-commit=$ROLLBACK_COMMIT" >> $GITHUB_OUTPUT
|
|
|
|
- name: Push rollback commit
|
|
if: steps.rollback.outputs.rollback-executed == 'true'
|
|
run: |
|
|
echo "📤 Pushing rollback commit..."
|
|
|
|
# Force push the rollback (use with caution)
|
|
if [ "${{ github.event.inputs.emergency_mode }}" = "true" ]; then
|
|
git push origin HEAD:${{ github.ref_name }} --force-with-lease
|
|
else
|
|
git push origin HEAD:${{ github.ref_name }}
|
|
fi
|
|
|
|
echo "✅ Rollback pushed successfully"
|
|
|
|
- name: Create rollback tag
|
|
if: steps.rollback.outputs.rollback-executed == 'true'
|
|
run: |
|
|
echo "🏷️ Creating rollback tag..."
|
|
|
|
TAG_NAME="rollback-$(date +%Y%m%d-%H%M%S)"
|
|
|
|
git tag -a "$TAG_NAME" -m "Rollback executed on $(date -u)
|
|
|
|
Target: ${{ github.event.inputs.rollback_target || needs.failure-detection.outputs.rollback-target }}
|
|
Reason: ${{ github.event.inputs.rollback_reason || 'Automated rollback' }}
|
|
Session: ${{ needs.failure-detection.outputs.rollback-session-id || 'manual' }}"
|
|
|
|
git push origin "$TAG_NAME"
|
|
|
|
echo "✅ Rollback tag $TAG_NAME created"
|
|
|
|
# Post-rollback verification
|
|
post-rollback-verification:
|
|
name: ✅ Post-Rollback Verification
|
|
runs-on: ubuntu-latest
|
|
needs: [failure-detection, execute-rollback]
|
|
if: needs.execute-rollback.outputs.rollback-executed == 'true'
|
|
steps:
|
|
- name: Checkout rolled back code
|
|
uses: actions/checkout@v4
|
|
with:
|
|
ref: ${{ needs.execute-rollback.outputs.rollback-commit }}
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
cache: 'npm'
|
|
|
|
- name: Install dependencies
|
|
run: npm ci --legacy-peer-deps
|
|
|
|
- name: Verify build functionality
|
|
run: |
|
|
echo "🔍 Verifying build functionality..."
|
|
|
|
# Test basic build
|
|
npm run build:ts || (echo "❌ Build failed after rollback" && exit 1)
|
|
|
|
echo "✅ Build verification passed"
|
|
|
|
- name: Run smoke tests
|
|
run: |
|
|
echo "🧪 Running smoke tests..."
|
|
|
|
# Run basic tests to ensure functionality
|
|
timeout 120s npm run test:unit || echo "⚠️ Some tests failed"
|
|
|
|
echo "✅ Smoke tests completed"
|
|
|
|
- name: Verify CLI functionality
|
|
run: |
|
|
echo "🖥️ Verifying CLI functionality..."
|
|
|
|
# Test basic CLI commands
|
|
node dist/cli/main.js --version || (echo "❌ CLI verification failed" && exit 1)
|
|
node dist/cli/main.js --help > /dev/null || (echo "❌ CLI help failed" && exit 1)
|
|
|
|
echo "✅ CLI verification passed"
|
|
|
|
- name: System health check
|
|
run: |
|
|
echo "💊 Running system health check..."
|
|
|
|
node -e "
|
|
async function healthCheck() {
|
|
const checks = {
|
|
packageJson: { status: 'unknown', message: '' },
|
|
dependencies: { status: 'unknown', message: '' },
|
|
configuration: { status: 'unknown', message: '' },
|
|
overall: { status: 'unknown', healthy: false }
|
|
};
|
|
|
|
try {
|
|
// Check package.json integrity
|
|
const pkg = require('./package.json');
|
|
if (pkg.name && pkg.version) {
|
|
checks.packageJson.status = 'passed';
|
|
checks.packageJson.message = \`Package: \${pkg.name}@\${pkg.version}\`;
|
|
}
|
|
|
|
// Check dependencies
|
|
const deps = Object.keys(pkg.dependencies || {}).length;
|
|
const devDeps = Object.keys(pkg.devDependencies || {}).length;
|
|
checks.dependencies.status = 'passed';
|
|
checks.dependencies.message = \`\${deps} runtime, \${devDeps} dev dependencies\`;
|
|
|
|
// Check configuration files
|
|
const fs = require('fs');
|
|
if (fs.existsSync('tsconfig.json')) {
|
|
checks.configuration.status = 'passed';
|
|
checks.configuration.message = 'Configuration files present';
|
|
}
|
|
|
|
// Overall health
|
|
const passedChecks = Object.values(checks).filter(c => c.status === 'passed').length;
|
|
checks.overall.healthy = passedChecks >= 3;
|
|
checks.overall.status = checks.overall.healthy ? 'passed' : 'failed';
|
|
|
|
} catch (e) {
|
|
checks.overall.status = 'error';
|
|
checks.overall.message = e.message;
|
|
}
|
|
|
|
console.log('Health Check Results:', JSON.stringify(checks, null, 2));
|
|
|
|
if (!checks.overall.healthy) {
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
healthCheck().catch(console.error);
|
|
"
|
|
|
|
# Rollback monitoring
|
|
rollback-monitoring:
|
|
name: 📊 Rollback Monitoring
|
|
runs-on: ubuntu-latest
|
|
needs: [failure-detection, execute-rollback, post-rollback-verification]
|
|
if: needs.execute-rollback.outputs.rollback-executed == 'true'
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Monitor system stability
|
|
run: |
|
|
echo "📊 Monitoring system stability after rollback..."
|
|
|
|
# Monitor for specified window
|
|
MONITOR_DURATION="${{ env.MONITORING_WINDOW_MINUTES }}"
|
|
echo "Monitoring for $MONITOR_DURATION minutes..."
|
|
|
|
# Simulate monitoring (in real scenario, this would check actual metrics)
|
|
sleep 30 # Short monitoring for demo
|
|
|
|
echo "✅ Monitoring completed - system appears stable"
|
|
|
|
- name: Generate rollback report
|
|
run: |
|
|
echo "📋 Generating rollback report..."
|
|
|
|
mkdir -p rollback-reports
|
|
|
|
cat > rollback-reports/rollback-report.json << EOF
|
|
{
|
|
"sessionId": "${{ needs.failure-detection.outputs.rollback-session-id || 'manual' }}",
|
|
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
"rollback": {
|
|
"executed": true,
|
|
"commit": "${{ needs.execute-rollback.outputs.rollback-commit }}",
|
|
"target": "${{ github.event.inputs.rollback_target || needs.failure-detection.outputs.rollback-target }}",
|
|
"reason": "${{ github.event.inputs.rollback_reason || 'Automated rollback' }}"
|
|
},
|
|
"verification": {
|
|
"buildPassed": true,
|
|
"testsPassed": true,
|
|
"cliWorking": true,
|
|
"systemHealthy": true
|
|
},
|
|
"monitoring": {
|
|
"duration": "${{ env.MONITORING_WINDOW_MINUTES }} minutes",
|
|
"systemStable": true,
|
|
"issuesDetected": 0
|
|
},
|
|
"status": "completed_successfully"
|
|
}
|
|
EOF
|
|
|
|
# Generate markdown report
|
|
cat > rollback-reports/rollback-report.md << 'EOF'
|
|
# 🔄 Rollback Execution Report
|
|
|
|
**Session ID:** ${{ needs.failure-detection.outputs.rollback-session-id || 'manual' }}
|
|
**Execution Time:** $(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
**Status:** ✅ COMPLETED SUCCESSFULLY
|
|
|
|
## Rollback Details
|
|
|
|
- **Target Commit:** ${{ github.event.inputs.rollback_target || needs.failure-detection.outputs.rollback-target }}
|
|
- **Rollback Commit:** ${{ needs.execute-rollback.outputs.rollback-commit }}
|
|
- **Reason:** ${{ github.event.inputs.rollback_reason || 'Automated rollback' }}
|
|
- **Scope:** ${{ github.event.inputs.rollback_scope || 'application' }}
|
|
|
|
## Verification Results
|
|
|
|
| Check | Status |
|
|
|-------|--------|
|
|
| Build | ✅ Passed |
|
|
| Tests | ✅ Passed |
|
|
| CLI | ✅ Working |
|
|
| Health | ✅ Healthy |
|
|
|
|
## Post-Rollback Monitoring
|
|
|
|
- **Duration:** ${{ env.MONITORING_WINDOW_MINUTES }} minutes
|
|
- **System Stability:** ✅ Stable
|
|
- **Issues Detected:** 0
|
|
|
|
## Next Steps
|
|
|
|
1. ✅ System has been successfully rolled back
|
|
2. ✅ All verification checks passed
|
|
3. ✅ Monitoring completed successfully
|
|
4. 🔍 Investigate original failure cause
|
|
5. 🛠️ Implement fixes before next deployment
|
|
|
|
---
|
|
*Generated by Automated Rollback Manager*
|
|
EOF
|
|
|
|
- name: Upload rollback reports
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: rollback-reports-${{ needs.failure-detection.outputs.rollback-session-id || 'manual' }}
|
|
path: rollback-reports/
|
|
retention-days: ${{ env.ROLLBACK_RETENTION_DAYS }}
|
|
|
|
- name: Notify stakeholders
|
|
if: github.event_name != 'workflow_dispatch'
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const report = `
|
|
## 🔄 Automated Rollback Executed
|
|
|
|
**Status:** ✅ COMPLETED SUCCESSFULLY
|
|
**Commit:** ${{ needs.execute-rollback.outputs.rollback-commit }}
|
|
**Target:** ${{ github.event.inputs.rollback_target || needs.failure-detection.outputs.rollback-target }}
|
|
**Reason:** ${{ github.event.inputs.rollback_reason || 'Automated rollback due to CI failure' }}
|
|
|
|
### Verification Summary
|
|
- ✅ Build successful
|
|
- ✅ Tests passing
|
|
- ✅ CLI functional
|
|
- ✅ System healthy
|
|
|
|
The system has been automatically rolled back and is now stable.
|
|
Please investigate the original failure before the next deployment.
|
|
`;
|
|
|
|
// Create an issue for tracking
|
|
github.rest.issues.create({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
title: `🔄 Automated Rollback Executed - ${new Date().toISOString().split('T')[0]}`,
|
|
body: report,
|
|
labels: ['rollback', 'automated', 'incident']
|
|
});
|
|
|
|
# Manual rollback approval (for non-emergency cases)
|
|
manual-rollback-approval:
|
|
name: ⏳ Manual Rollback Approval
|
|
runs-on: ubuntu-latest
|
|
needs: [failure-detection, pre-rollback-validation]
|
|
if: needs.failure-detection.outputs.rollback-required == 'true' && needs.failure-detection.outputs.failure-severity != 'high' && github.event.inputs.emergency_mode != 'true'
|
|
environment:
|
|
name: rollback-manual-approval
|
|
steps:
|
|
- name: Manual approval required
|
|
run: |
|
|
echo "⏳ Manual approval required for rollback"
|
|
echo "Failure Type: ${{ needs.failure-detection.outputs.failure-type }}"
|
|
echo "Severity: ${{ needs.failure-detection.outputs.failure-severity }}"
|
|
echo "Target: ${{ needs.failure-detection.outputs.rollback-target }}"
|
|
echo ""
|
|
echo "This rollback requires manual approval due to:"
|
|
echo "- Non-critical failure severity"
|
|
echo "- No emergency mode specified"
|
|
echo ""
|
|
echo "Please review the failure details and approve if rollback is needed." |