Skip to content

feat: Phase 4 Lab 06 -- Production Deployment (restart policy, resour… #10

feat: Phase 4 Lab 06 -- Production Deployment (restart policy, resour…

feat: Phase 4 Lab 06 -- Production Deployment (restart policy, resour… #10

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 tests/labs/*.sh
- name: Validate module manifest
run: |
python3 -c "
import sys, re
with open('it-stack-taiga.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: Generate CI env file
run: |
# Copy example env and inject CI-safe defaults for any unset port vars
if [ -f .env.example ]; then cp .env.example .env; fi
# Set port placeholder vars used in scaffold compose files
echo "firstPort=389" >> .env
echo "secondPort=9090" >> .env
- name: Validate standalone compose can start
run: |
docker compose -f docker/docker-compose.standalone.yml config --no-interpolate -q
echo "Standalone compose structure is valid"
- name: Start standalone stack
run: docker compose -f docker/docker-compose.standalone.yml up -d
- name: Wait for health
run: |
echo "Waiting for services..."
sleep 30
docker compose -f docker/docker-compose.standalone.yml ps
- name: Run Lab 01 test script
run: bash tests/labs/test-lab-15-01.sh
- name: Collect logs on failure

Check failure on line 107 in .github/workflows/ci.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/ci.yml

Invalid workflow file

You have an error in your yaml syntax on line 107
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 -- Taiga External Dependencies (PostgreSQL + Redis + Mailhog)
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 postgresql-client -qq
- 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 PostgreSQL
run: timeout 120 bash -c 'until docker exec taiga-l02-db pg_isready -U taiga -d taiga; do sleep 5; done'
- name: Wait for Redis
run: timeout 60 bash -c 'until docker exec taiga-l02-redis redis-cli ping | grep -q PONG; do sleep 5; done'
- name: Wait for Mailhog
run: timeout 60 bash -c 'until curl -sf http://localhost:8710/api/v2/messages; do sleep 5; done'
- name: Wait for Taiga backend
run: timeout 180 bash -c 'until curl -o /dev/null -sw "%{http_code}" http://localhost:8011/api/v1/ | grep -q "^[234]"; do sleep 10; done'
- name: Run Lab 15-02 test script
run: bash tests/labs/test-lab-15-02.sh --no-cleanup
- 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 -- Taiga Advanced Features (Async events worker + Redis persistence)
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 postgresql-client redis-tools -qq
- 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 PostgreSQL
run: timeout 120 bash -c 'until docker exec taiga-a03-db pg_isready -U taiga -d taiga; do sleep 5; done'
- name: Wait for Redis
run: timeout 60 bash -c 'until docker exec taiga-a03-redis redis-cli ping | grep -q PONG; do sleep 5; done'
- name: Wait for Mailhog
run: timeout 60 bash -c 'until curl -sf http://localhost:8720/api/v2/messages; do sleep 5; done'
- name: Wait for Taiga backend
run: timeout 300 bash -c 'until curl -o /dev/null -sw "%{http_code}" http://localhost:8021/api/v1/ | grep -q "^[234]"; do sleep 10; done'
- name: Run Lab 15-03 test script
run: bash tests/labs/test-lab-15-03.sh --no-cleanup
- 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 -- Taiga SSO Integration (Keycloak OIDC + OpenLDAP)
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 postgresql-client netcat-openbsd ldap-utils redis-tools
- 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 PostgreSQL
run: timeout 120 bash -c 'until docker exec taiga-s04-db pg_isready -U taiga; do sleep 5; done'
- name: Wait for OpenLDAP
run: timeout 120 bash -c 'until docker exec taiga-s04-ldap ldapsearch -x -H ldap://localhost -b dc=lab,dc=local -D cn=admin,dc=lab,dc=local -w LdapLab04! cn=admin >/dev/null 2>&1; do sleep 5; done'
- name: Wait for Keycloak
run: timeout 300 bash -c 'until curl -sf http://localhost:8530/realms/master; do sleep 10; done'
- name: Wait for Mailhog
run: timeout 60 bash -c 'until curl -sf http://localhost:8730/api/v2/messages; do sleep 5; done'
- name: Wait for Taiga frontend
run: timeout 300 bash -c 'until curl -o /dev/null -sw "%{http_code}" http://localhost:8430/ | grep -q "^[234]"; do sleep 10; done'
- name: Run Lab 15-04 test script
run: bash tests/labs/test-lab-15-04.sh --no-cleanup
- 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 15-05 -- Taiga Advanced Integration (Mattermost Webhook)
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 postgresql-client netcat-openbsd ldap-utils
- 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 WireMock
run: timeout 90 bash -c 'until curl -sf http://localhost:8761/__admin/health; do sleep 5; done'
- name: Wait for PostgreSQL
run: timeout 120 bash -c 'until docker exec taiga-i05-db pg_isready -U taiga > /dev/null 2>&1; do sleep 5; done'
- name: Wait for Keycloak
run: timeout 300 bash -c 'until curl -sf http://localhost:8540/realms/master; do sleep 10; done'
- name: Wait for Taiga Back
run: timeout 300 bash -c 'until curl -sf http://localhost:8041/api/v1/ | grep -q version; do sleep 15; done'
- name: Run Lab 15-05 test script
run: bash tests/labs/test-lab-15-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 15-06 -- Taiga Production Deployment (restart policy, resource limits, Celery events worker)
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 postgresql-client netcat-openbsd ldap-utils
- 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 PostgreSQL
run: |
for i in $(seq 1 18); do
docker exec taiga-p06-db pg_isready -U taiga -d taiga > /dev/null 2>&1 && echo "DB ready" && break
echo "Waiting for DB... ($i/18)"; sleep 5
done
- name: Wait for Keycloak
run: |
for i in $(seq 1 24); do
curl -sf http://localhost:8560/realms/master | grep -q realm && echo "KC ready" && break
echo "Waiting for KC... ($i/24)"; sleep 5
done
- name: Wait for Mailhog
run: |
for i in $(seq 1 12); do
curl -sf http://localhost:8750/api/v2/messages > /dev/null && echo "MH ready" && break
echo "Waiting for MH... ($i/12)"; sleep 5
done
- name: Wait for Taiga frontend
run: |
for i in $(seq 1 24); do
curl -sf http://localhost:8460/ | grep -qi html && echo "Taiga ready" && break
echo "Waiting for Taiga... ($i/24)"; sleep 5
done
- name: Run Lab 15-06 test script
run: bash tests/labs/test-lab-15-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