Skip to content

ci: standardize shellcheck --severity=error across all lab scripts #12

ci: standardize shellcheck --severity=error across all lab scripts

ci: standardize shellcheck --severity=error across all lab scripts #12

Workflow file for this run

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: |
for f in docker/docker-compose.*.yml; do
echo "Validating: $f"
docker compose -f "$f" config --no-interpolate -q
done
- name: ShellCheck — lab test scripts
run: |
sudo apt-get install -y shellcheck -qq
shellcheck --severity=error tests/labs/*.sh
- name: Validate module manifest
run: |
python3 -c "
import sys, re
with open('it-stack-jitsi.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 — Jitsi standalone (web, prosody, jicofo, jvb, TLS)
runs-on: ubuntu-latest
needs: validate
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: Install tools
run: sudo apt-get install -y curl openssl
- name: Validate standalone compose
run: |
docker compose -f docker/docker-compose.standalone.yml config -q
echo "Standalone compose valid"
- name: Start standalone stack
run: docker compose -f docker/docker-compose.standalone.yml up -d
- name: Wait for Jitsi web (TLS on :8443)
run: timeout 120 bash -c 'until curl -sk https://localhost:8443/ -o /dev/null -w "%{http_code}" | grep -E "^(200|301|302)"; do sleep 5; done'
- name: Run Lab 08-01 test script
run: bash tests/labs/test-lab-08-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 — Jitsi LAN (coturn TURN/STUN, web, TLS, config.js)
runs-on: ubuntu-latest
needs: validate
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: Install tools
run: sudo apt-get install -y curl openssl
- name: Validate LAN compose
run: docker compose -f docker/docker-compose.lan.yml config -q && echo "LAN compose valid"
- name: Start LAN stack
run: docker compose -f docker/docker-compose.lan.yml up -d
- name: Wait for coturn TURN server
run: timeout 30 bash -c 'until timeout 3 bash -c "echo > /dev/tcp/localhost/3478" 2>/dev/null; do sleep 2; done'
- name: Wait for Jitsi web
run: timeout 120 bash -c 'until curl -sk https://localhost:8443/ -o /dev/null -w "%{http_code}" | grep -E "^(200|301|302)"; do sleep 5; done'
- name: Run Lab 08-02 test script
run: bash tests/labs/test-lab-08-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 - Jitsi Advanced (JWT auth, resource limits, coturn)
runs-on: ubuntu-latest
needs: validate
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: Install tools
run: sudo apt-get install -y curl openssl
- name: Validate advanced compose
run: docker compose -f docker/docker-compose.advanced.yml config -q && echo "Advanced compose valid"
- name: Start advanced stack
run: docker compose -f docker/docker-compose.advanced.yml up -d
- name: Wait for TURN server
run: timeout 30 bash -c 'until timeout 3 bash -c "echo > /dev/tcp/localhost/3478" 2>/dev/null; do sleep 2; done'
- name: Wait for Jitsi web
run: timeout 120 bash -c 'until curl -sk https://localhost:8443/ -o /dev/null -w "%{http_code}" | grep -qE "^(200|301|302)"; do sleep 5; done'
- name: Run Lab 08-03 test script
run: bash tests/labs/test-lab-08-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
lab-04-smoke:
name: Lab 04 — Jitsi SSO Integration (Keycloak JWT authority)
runs-on: ubuntu-latest
needs: validate
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: Install tools
run: sudo apt-get install -y curl openssl
- name: Validate SSO compose
run: docker compose -f docker/docker-compose.sso.yml config -q && echo "SSO compose valid"
- name: Start SSO stack
run: docker compose -f docker/docker-compose.sso.yml up -d
- name: Wait for Keycloak
run: timeout 120 bash -c 'until curl -sf http://localhost:8086/health/ready | grep -q UP; do sleep 5; done'
- name: Wait for Jitsi web
run: timeout 120 bash -c 'until curl -sk https://localhost:8443/ -o /dev/null -w "%{http_code}" | grep -E "^(200|301|302)"; do sleep 5; done'
- name: Run Lab 08-04 test script
run: bash tests/labs/test-lab-08-04.sh
- name: Collect logs on failure
if: failure()
run: docker compose -f docker/docker-compose.sso.yml logs
- name: Cleanup
if: always()
run: docker compose -f docker/docker-compose.sso.yml down -v
lab-05-smoke:
name: Lab 05 -- Jitsi Advanced Integration (Traefik + Keycloak JWT)
runs-on: ubuntu-latest
needs: validate
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: Install tools
run: sudo apt-get install -y curl
- name: Validate integration compose
run: docker compose -f docker/docker-compose.integration.yml config -q && echo "Integration compose valid"
- name: Start integration stack
run: docker compose -f docker/docker-compose.integration.yml up -d
- name: Wait for Keycloak
run: timeout 180 bash -c 'until curl -sf http://localhost:8107/health/ready | grep -q UP; do sleep 5; done'
- name: Wait for Traefik
run: timeout 60 bash -c 'until curl -sf http://localhost:8109/api/rawdata > /dev/null 2>&1; do sleep 5; done'
- name: Wait for Jitsi Web
run: timeout 180 bash -c 'until curl -sf http://localhost:8150/ | grep -qi "jitsi\|html"; do sleep 10; done'
- name: Run Lab 08-05 test script
run: bash tests/labs/test-lab-08-05.sh --no-cleanup
- name: Collect logs on failure
if: failure()
run: docker compose -f docker/docker-compose.integration.yml logs
- name: Cleanup
if: always()
run: docker compose -f docker/docker-compose.integration.yml down -v
lab-06-smoke:
name: Lab 06 -- Jitsi Production Deployment (resource limits + JWT + metrics)
runs-on: ubuntu-latest
needs: validate
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: Install tools
run: sudo apt-get install -y curl
- name: Validate production compose
run: docker compose -f docker/docker-compose.production.yml config -q && echo "Production compose valid"
- name: Start production stack
run: docker compose -f docker/docker-compose.production.yml up -d
- name: Wait for Keycloak
run: timeout 240 bash -c 'until curl -sf http://localhost:8207/health/ready | grep -q UP; do sleep 5; done'
- name: Wait for Prosody
run: timeout 180 bash -c 'until docker inspect jitsi-prod-prosody --format "{{.State.Health.Status}}" | grep -q healthy; do sleep 5; done'
- name: Wait for Jitsi web
run: timeout 300 bash -c 'until curl -sf http://localhost:8250/; do sleep 10; done'
- name: Run Lab 08-06 test script
run: bash tests/labs/test-lab-08-06.sh --no-cleanup
- name: Collect logs on failure
if: failure()
run: docker compose -f docker/docker-compose.production.yml logs
- name: Cleanup
if: always()
run: docker compose -f docker/docker-compose.production.yml down -v