feat(lab-03): Redis advanced — 6-node cluster (3 primary + 3 replica)… #9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main, develop, 'feature/**', 'bugfix/**'] | |
| pull_request: | |
| branches: [main, develop] | |
| permissions: | |
| contents: read | |
| security-events: write | |
| jobs: | |
| validate: | |
| name: Validate Configuration | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Validate Docker Compose files | |
| run: | | |
| echo "Validating: docker/docker-compose.standalone.yml" | |
| docker compose -f docker/docker-compose.standalone.yml config -q | |
| echo "OK: docker/docker-compose.standalone.yml" | |
| echo "Validating: docker/docker-compose.lan.yml" | |
| docker compose -f docker/docker-compose.lan.yml config -q | |
| echo "OK: docker/docker-compose.lan.yml" | |
| for f in docker/docker-compose.advanced.yml \ | |
| docker/docker-compose.sso.yml docker/docker-compose.integration.yml \ | |
| docker/docker-compose.production.yml; do | |
| echo "Checking scaffold: $f" | |
| docker compose -f "$f" config --no-interpolate -q 2>&1 && echo "OK: $f" \ | |
| || echo "WARN: $f has placeholder variables (scaffold — not yet built out)" | |
| done | |
| - name: ShellCheck — lab test scripts | |
| run: | | |
| sudo apt-get install -y shellcheck -qq | |
| shellcheck tests/labs/*.sh | |
| - name: Validate module manifest | |
| run: | | |
| python3 -c " | |
| import sys, re | |
| with open('it-stack-redis.yml') as f: | |
| content = f.read() | |
| required = ['module:', 'version:', 'phase:', 'category:', 'ports:'] | |
| missing = [k for k in required if k not in content] | |
| if missing: | |
| print('Missing fields:', missing); sys.exit(1) | |
| print('Manifest valid') | |
| " | |
| security-scan: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| needs: validate | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Trivy — scan Dockerfile | |
| uses: aquasecurity/trivy-action@0.28.0 | |
| with: | |
| scan-type: config | |
| scan-ref: . | |
| exit-code: '0' | |
| severity: CRITICAL,HIGH | |
| - name: Trivy — SARIF output | |
| uses: aquasecurity/trivy-action@0.28.0 | |
| with: | |
| scan-type: config | |
| scan-ref: . | |
| format: sarif | |
| output: trivy-results.sarif | |
| - name: Upload SARIF to GitHub Security | |
| uses: github/codeql-action/upload-sarif@v3 | |
| if: always() | |
| with: | |
| sarif_file: trivy-results.sarif | |
| lab-01-smoke: | |
| name: Lab 01 — Smoke Test | |
| runs-on: ubuntu-latest | |
| needs: validate | |
| continue-on-error: true # scaffold stubs; full lab runs on real VMs | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Redis client tools | |
| run: sudo apt-get install -y redis-tools netcat-openbsd | |
| - name: Start standalone stack | |
| run: docker compose -f docker/docker-compose.standalone.yml up -d | |
| - name: Wait for Redis to be ready | |
| run: | | |
| echo "Waiting for Redis..." | |
| timeout 60 bash -c ' | |
| until redis-cli -h localhost -p 6379 -a "Lab01Password!" --no-auth-warning PING 2>/dev/null | grep -q PONG; do | |
| sleep 2 | |
| done' | |
| echo "Redis is ready" | |
| docker compose -f docker/docker-compose.standalone.yml ps | |
| - name: Run Lab 04-01 test script | |
| run: bash tests/labs/test-lab-04-01.sh | |
| - name: Collect logs on failure | |
| if: failure() | |
| run: docker compose -f docker/docker-compose.standalone.yml logs | |
| - name: Cleanup | |
| if: always() | |
| run: docker compose -f docker/docker-compose.standalone.yml down -v | |
| lab-02-smoke: | |
| name: Lab 02 — Sentinel HA | |
| runs-on: ubuntu-latest | |
| needs: validate | |
| continue-on-error: true | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Redis client tools | |
| run: sudo apt-get install -y redis-tools netcat-openbsd | |
| - name: Start LAN stack (master + 2 replicas + 3 sentinels) | |
| run: docker compose -f docker/docker-compose.lan.yml up -d | |
| - name: Wait for Redis master | |
| run: | | |
| timeout 90 bash -c ' | |
| until redis-cli -h localhost -p 6379 -a "Lab02Password!" --no-auth-warning PING 2>/dev/null | grep -q PONG; do | |
| sleep 3 | |
| done' | |
| echo "Master is ready" | |
| - name: Wait for sentinels to stabilise | |
| run: sleep 30 | |
| - name: Run Lab 04-02 test script | |
| env: | |
| REDIS_PASS: "Lab02Password!" | |
| run: bash tests/labs/test-lab-04-02.sh | |
| - name: Collect logs on failure | |
| if: failure() | |
| run: docker compose -f docker/docker-compose.lan.yml logs | |
| - name: Cleanup | |
| if: always() | |
| run: docker compose -f docker/docker-compose.lan.yml down -v | |
| lab-03-smoke: | |
| name: Lab 03 — Redis Cluster (6 nodes) | |
| runs-on: ubuntu-latest | |
| needs: validate | |
| continue-on-error: true | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Redis client tools | |
| run: sudo apt-get install -y redis-tools netcat-openbsd | |
| - name: Start advanced stack (6-node cluster) | |
| run: docker compose -f docker/docker-compose.advanced.yml up -d | |
| - name: Wait for all 6 nodes | |
| run: | | |
| for port in 7001 7002 7003 7004 7005 7006; do | |
| timeout 60 bash -c "until redis-cli -p $port -a 'Lab03Password!' --no-auth-warning PING 2>/dev/null | grep -q PONG; do sleep 2; done" | |
| echo "Node :$port ready" | |
| done | |
| - name: Wait for cluster init to complete | |
| run: sleep 20 | |
| - name: Run Lab 04-03 test script | |
| env: | |
| REDIS_PASS: "Lab03Password!" | |
| run: bash tests/labs/test-lab-04-03.sh | |
| - name: Collect logs on failure | |
| if: failure() | |
| run: docker compose -f docker/docker-compose.advanced.yml logs | |
| - name: Cleanup | |
| if: always() | |
| run: docker compose -f docker/docker-compose.advanced.yml down -v |