From 7beda0284ce6dae687e9744d3fbe87372ee0634f Mon Sep 17 00:00:00 2001 From: Mohamed jameel alabasy Date: Tue, 24 Mar 2026 14:37:24 +0200 Subject: [PATCH 1/6] feat(pipeline): add devops main CI workflow --- .github/workflows/devops.yml | 235 +++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 .github/workflows/devops.yml diff --git a/.github/workflows/devops.yml b/.github/workflows/devops.yml new file mode 100644 index 0000000..265a2de --- /dev/null +++ b/.github/workflows/devops.yml @@ -0,0 +1,235 @@ +name: DevOps — Main Pipeline + +on: + pull_request: + branches: + - main + +jobs: + # JOB 1 — Validate repo structure + validate-structure: + name: Validate Repo Structure + runs-on: ubuntu-latest + + steps: + - name: Checkout DevOps repo + uses: actions/checkout@v4 + + - name: Check Docker Compose files exist + run: | + echo "Checking Docker Compose files..." + test -f docker/docker-compose.yml || { echo "MISSING: docker/docker-compose.yml"; exit 1; } + test -f docker/docker-compose.backend.yml || { echo "MISSING: docker/docker-compose.backend.yml"; exit 1; } + test -f docker/docker-compose.frontend.yml || { echo "MISSING: docker/docker-compose.frontend.yml"; exit 1; } + echo "All Docker Compose files present." + + - name: Check Dockerfiles exist + run: | + echo "Checking Dockerfiles..." + test -f docker/backend/Dockerfile || { echo "MISSING: docker/backend/Dockerfile"; exit 1; } + test -f docker/frontend/Dockerfile || { echo "MISSING: docker/frontend/Dockerfile"; exit 1; } + echo "All Dockerfiles present." + + - name: Check scripts exist + run: | + echo "Checking bash scripts..." + for script in build.sh clean.sh migrate.sh seed.sh start.sh stop.sh \ + start-infra.sh start-backend.sh start-frontend.sh; do + test -f scripts/$script || { echo "MISSING: scripts/$script"; exit 1; } + done + echo "All required scripts present." + + - name: Check scripts are executable or callable + run: | + echo "Checking script syntax..." + for script in scripts/*.sh; do + bash -n "$script" || { echo "SYNTAX ERROR in $script"; exit 1; } + done + echo "All scripts passed syntax check." + + - name: Check .env.example exists + run: | + test -f environments/.env.example || { echo "MISSING: environments/.env.example"; exit 1; } + echo ".env.example present." + + - name: Validate required keys in .env.example + run: | + echo "Validating required env keys in .env.example..." + required_keys=( + "NODE_ENV" + "PORT" + "DATABASE_URL" + "POSTGRES_USER" + "POSTGRES_PASSWORD" + "POSTGRES_DB" + "AZURE_STORAGE_CONNECTION_STRING" + "BLOB_CONTAINER_AUDIO" + "BLOB_CONTAINER_MEDIA" + "JWT_SECRET" + "JWT_ACCESS_EXPIRES_IN" + "JWT_REFRESH_EXPIRES_IN" + "GOOGLE_CLIENT_ID" + "GOOGLE_CLIENT_SECRET" + "GMAIL_USER" + "GMAIL_APP_PASSWORD" + "RECAPTCHA_SECRET" + "VITE_API_BASE_URL" + "VITE_GOOGLE_CLIENT_ID" + "VITE_RECAPTCHA_SITE_KEY" + ) + missing=0 + for key in "${required_keys[@]}"; do + grep -q "^${key}=" environments/.env.example || { + echo "MISSING KEY in .env.example: $key" + missing=1 + } + done + [ $missing -eq 0 ] || exit 1 + echo "All required keys present in .env.example." + + # JOB 2 — Full integration validation + integration: + name: Full Integration Validation + runs-on: ubuntu-latest + needs: validate-structure + + env: + NODE_ENV: development + PORT: 8080 + BASE_URL: http://localhost:8080 + CLIENT_URL: http://localhost:5173 + APP_URL: http://localhost:5173 + + POSTGRES_USER: dev + POSTGRES_PASSWORD: devpassword + POSTGRES_DB: rythmify_dev + DATABASE_URL: postgresql://dev:devpassword@localhost:5432/rythmify_dev + + PGADMIN_EMAIL: admin@admin.com + PGADMIN_PASSWORD: admin + + AZURE_STORAGE_CONNECTION_STRING: "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://localhost:10000/devstoreaccount1;" + BLOB_CONTAINER_AUDIO: audio + BLOB_CONTAINER_MEDIA: media + + JWT_SECRET: ${{ secrets.JWT_SECRET }} + JWT_ACCESS_EXPIRES_IN: 15m + JWT_REFRESH_EXPIRES_IN: 7d + GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }} + GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }} + GOOGLE_CALLBACK_URL: http://localhost:8080/api/v1/auth/google/callback + GMAIL_USER: ${{ secrets.GMAIL_USER }} + GMAIL_APP_PASSWORD: ${{ secrets.GMAIL_APP_PASSWORD }} + EMAIL_FROM: "Rythmify " + RECAPTCHA_SECRET: ${{ secrets.RECAPTCHA_SECRET }} + VITE_API_BASE_URL: http://localhost:8080/api/v1 + VITE_USE_MOCK: "false" + VITE_GOOGLE_CLIENT_ID: ${{ secrets.VITE_GOOGLE_CLIENT_ID }} + VITE_APP_URL: http://localhost:5173 + VITE_RECAPTCHA_SITE_KEY: ${{ secrets.VITE_RECAPTCHA_SITE_KEY }} + + steps: + - name: Checkout DevOps repo + uses: actions/checkout@v4 + + - name: Checkout Backend repo + uses: actions/checkout@v4 + with: + repository: ${{ github.repository_owner }}/backend + ref: development + path: backend + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Checkout Frontend repo + uses: actions/checkout@v4 + with: + repository: ${{ github.repository_owner }}/frontend + ref: development + path: frontend + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Write .env file for CI + run: | + cat > environments/.env << EOF + NODE_ENV=${NODE_ENV} + PORT=${PORT} + BASE_URL=${BASE_URL} + CLIENT_URL=${CLIENT_URL} + APP_URL=${APP_URL} + POSTGRES_USER=${POSTGRES_USER} + POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + POSTGRES_DB=${POSTGRES_DB} + DATABASE_URL=${DATABASE_URL} + PGADMIN_EMAIL=${PGADMIN_EMAIL} + PGADMIN_PASSWORD=${PGADMIN_PASSWORD} + AZURE_STORAGE_CONNECTION_STRING=${AZURE_STORAGE_CONNECTION_STRING} + BLOB_CONTAINER_AUDIO=${BLOB_CONTAINER_AUDIO} + BLOB_CONTAINER_MEDIA=${BLOB_CONTAINER_MEDIA} + JWT_SECRET=${JWT_SECRET} + JWT_ACCESS_EXPIRES_IN=${JWT_ACCESS_EXPIRES_IN} + JWT_REFRESH_EXPIRES_IN=${JWT_REFRESH_EXPIRES_IN} + GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID} + GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} + GOOGLE_CALLBACK_URL=${GOOGLE_CALLBACK_URL} + GMAIL_USER=${GMAIL_USER} + GMAIL_APP_PASSWORD=${GMAIL_APP_PASSWORD} + EMAIL_FROM=${EMAIL_FROM} + RECAPTCHA_SECRET=${RECAPTCHA_SECRET} + VITE_API_BASE_URL=${VITE_API_BASE_URL} + VITE_USE_MOCK=${VITE_USE_MOCK} + VITE_GOOGLE_CLIENT_ID=${VITE_GOOGLE_CLIENT_ID} + VITE_APP_URL=${VITE_APP_URL} + VITE_RECAPTCHA_SITE_KEY=${VITE_RECAPTCHA_SITE_KEY} + EOF + echo ".env written for CI." + + - name: Start infrastructure containers + run: bash scripts/start-infra.sh + + - name: Build backend and frontend images + run: bash scripts/build.sh + + - name: Start backend + run: bash scripts/start-backend.sh + + - name: Run migrations + run: bash scripts/migrate.sh + + - name: Run seeds + run: bash scripts/seed.sh + + - name: Run backend smoke check + run: | + echo "Running backend smoke check..." + for i in $(seq 1 30); do + curl -sf http://localhost:8080/health > /dev/null && \ + echo "Backend is healthy." && break + echo "Attempt $i — not ready yet, waiting 3s..." + sleep 3 + done + response=$(curl -sf http://localhost:8080/health) || \ + { echo "Backend health check failed."; exit 1; } + echo "Response: $response" + echo "$response" | grep -q '"status":"ok"' || \ + { echo "Smoke check failed — unexpected response."; exit 1; } + echo "Smoke check passed." + + - name: Collect Docker logs on failure + if: failure() + run: | + mkdir -p ci-logs + docker compose -f docker/docker-compose.yml --env-file environments/.env logs > ci-logs/infra.log 2>&1 || true + docker compose -f docker/docker-compose.backend.yml --env-file environments/.env logs > ci-logs/backend.log 2>&1 || true + docker compose -f docker/docker-compose.frontend.yml --env-file environments/.env logs > ci-logs/frontend.log 2>&1 || true + + - name: Upload logs as artifact + if: failure() + uses: actions/upload-artifact@v4 + with: + name: ci-failure-logs + path: ci-logs/ + retention-days: 7 + + - name: Tear down all containers + if: always() + run: bash scripts/stop.sh From 4c34eda347dd49a243ad29ed1876348e82b4392a Mon Sep 17 00:00:00 2001 From: Mohamed jameel alabasy Date: Tue, 24 Mar 2026 14:52:19 +0200 Subject: [PATCH 2/6] fix(pipeline): improve .env file generation and backend health check logic --- .github/workflows/devops.yml | 85 +++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/.github/workflows/devops.yml b/.github/workflows/devops.yml index 265a2de..4e723f1 100644 --- a/.github/workflows/devops.yml +++ b/.github/workflows/devops.yml @@ -150,38 +150,40 @@ jobs: - name: Write .env file for CI run: | - cat > environments/.env << EOF - NODE_ENV=${NODE_ENV} - PORT=${PORT} - BASE_URL=${BASE_URL} - CLIENT_URL=${CLIENT_URL} - APP_URL=${APP_URL} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_DB=${POSTGRES_DB} - DATABASE_URL=${DATABASE_URL} - PGADMIN_EMAIL=${PGADMIN_EMAIL} - PGADMIN_PASSWORD=${PGADMIN_PASSWORD} - AZURE_STORAGE_CONNECTION_STRING=${AZURE_STORAGE_CONNECTION_STRING} - BLOB_CONTAINER_AUDIO=${BLOB_CONTAINER_AUDIO} - BLOB_CONTAINER_MEDIA=${BLOB_CONTAINER_MEDIA} - JWT_SECRET=${JWT_SECRET} - JWT_ACCESS_EXPIRES_IN=${JWT_ACCESS_EXPIRES_IN} - JWT_REFRESH_EXPIRES_IN=${JWT_REFRESH_EXPIRES_IN} - GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID} - GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} - GOOGLE_CALLBACK_URL=${GOOGLE_CALLBACK_URL} - GMAIL_USER=${GMAIL_USER} - GMAIL_APP_PASSWORD=${GMAIL_APP_PASSWORD} - EMAIL_FROM=${EMAIL_FROM} - RECAPTCHA_SECRET=${RECAPTCHA_SECRET} - VITE_API_BASE_URL=${VITE_API_BASE_URL} - VITE_USE_MOCK=${VITE_USE_MOCK} - VITE_GOOGLE_CLIENT_ID=${VITE_GOOGLE_CLIENT_ID} - VITE_APP_URL=${VITE_APP_URL} - VITE_RECAPTCHA_SITE_KEY=${VITE_RECAPTCHA_SITE_KEY} - EOF + { + echo "NODE_ENV=${NODE_ENV}" + echo "PORT=${PORT}" + echo "BASE_URL=${BASE_URL}" + echo "CLIENT_URL=${CLIENT_URL}" + echo "APP_URL=${APP_URL}" + echo "POSTGRES_USER=${POSTGRES_USER}" + echo "POSTGRES_PASSWORD=${POSTGRES_PASSWORD}" + echo "POSTGRES_DB=${POSTGRES_DB}" + echo "DATABASE_URL=${DATABASE_URL}" + echo "PGADMIN_EMAIL=${PGADMIN_EMAIL}" + echo "PGADMIN_PASSWORD=${PGADMIN_PASSWORD}" + echo "AZURE_STORAGE_CONNECTION_STRING=${AZURE_STORAGE_CONNECTION_STRING}" + echo "BLOB_CONTAINER_AUDIO=${BLOB_CONTAINER_AUDIO}" + echo "BLOB_CONTAINER_MEDIA=${BLOB_CONTAINER_MEDIA}" + echo "JWT_SECRET=${JWT_SECRET}" + echo "JWT_ACCESS_EXPIRES_IN=${JWT_ACCESS_EXPIRES_IN}" + echo "JWT_REFRESH_EXPIRES_IN=${JWT_REFRESH_EXPIRES_IN}" + echo "GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}" + echo "GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}" + echo "GOOGLE_CALLBACK_URL=${GOOGLE_CALLBACK_URL}" + echo "GMAIL_USER=${GMAIL_USER}" + echo "GMAIL_APP_PASSWORD=${GMAIL_APP_PASSWORD}" + echo "EMAIL_FROM=${EMAIL_FROM}" + echo "RECAPTCHA_SECRET=${RECAPTCHA_SECRET}" + echo "VITE_API_BASE_URL=${VITE_API_BASE_URL}" + echo "VITE_USE_MOCK=${VITE_USE_MOCK}" + echo "VITE_GOOGLE_CLIENT_ID=${VITE_GOOGLE_CLIENT_ID}" + echo "VITE_APP_URL=${VITE_APP_URL}" + echo "VITE_RECAPTCHA_SITE_KEY=${VITE_RECAPTCHA_SITE_KEY}" + } > environments/.env echo ".env written for CI." + echo "--- Verifying .env (keys only) ---" + grep -o '^[^=]*' environments/.env - name: Start infrastructure containers run: bash scripts/start-infra.sh @@ -202,16 +204,21 @@ jobs: run: | echo "Running backend smoke check..." for i in $(seq 1 30); do - curl -sf http://localhost:8080/health > /dev/null && \ - echo "Backend is healthy." && break + if curl -sf http://localhost:${PORT}/health > /dev/null; then + echo "Backend is healthy." + break + fi echo "Attempt $i — not ready yet, waiting 3s..." + if [ "$i" -eq 30 ]; then + echo "Backend health check failed after 30 attempts (90s)." + exit 1 + fi sleep 3 done - response=$(curl -sf http://localhost:8080/health) || \ - { echo "Backend health check failed."; exit 1; } + response=$(curl -sf http://localhost:${PORT}/health) echo "Response: $response" echo "$response" | grep -q '"status":"ok"' || \ - { echo "Smoke check failed — unexpected response."; exit 1; } + { echo "Smoke check failed — unexpected response: $response"; exit 1; } echo "Smoke check passed." - name: Collect Docker logs on failure @@ -221,6 +228,12 @@ jobs: docker compose -f docker/docker-compose.yml --env-file environments/.env logs > ci-logs/infra.log 2>&1 || true docker compose -f docker/docker-compose.backend.yml --env-file environments/.env logs > ci-logs/backend.log 2>&1 || true docker compose -f docker/docker-compose.frontend.yml --env-file environments/.env logs > ci-logs/frontend.log 2>&1 || true + echo "--- All containers (docker ps -a) ---" >> ci-logs/infra.log + docker ps -a >> ci-logs/infra.log 2>&1 || true + echo "--- Backend container logs (fallback) ---" >> ci-logs/backend.log + docker logs rythmify_backend >> ci-logs/backend.log 2>&1 || true + echo "--- Frontend container logs (fallback) ---" >> ci-logs/frontend.log + docker logs rythmify_frontend >> ci-logs/frontend.log 2>&1 || true - name: Upload logs as artifact if: failure() From 68b5dd55460aca90b2605791679aff694a3de073 Mon Sep 17 00:00:00 2001 From: Mohamed jameel alabasy Date: Tue, 24 Mar 2026 14:58:33 +0200 Subject: [PATCH 3/6] fix(docker): use environment variables for build context in docker-compose files --- docker/docker-compose.backend.yml | 4 ++-- docker/docker-compose.frontend.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker/docker-compose.backend.yml b/docker/docker-compose.backend.yml index 5bac42f..8a75082 100644 --- a/docker/docker-compose.backend.yml +++ b/docker/docker-compose.backend.yml @@ -3,7 +3,7 @@ name: rythmify services: backend: build: - context: ../../backend + context: ${BACKEND_CONTEXT:-../../backend} dockerfile: Dockerfile container_name: rythmify_backend restart: unless-stopped @@ -14,7 +14,7 @@ services: networks: - rythmify_network volumes: - - ../../backend:/app + - ${BACKEND_CONTEXT:-../../backend}:/app - /app/node_modules networks: diff --git a/docker/docker-compose.frontend.yml b/docker/docker-compose.frontend.yml index e01cd73..1678c75 100644 --- a/docker/docker-compose.frontend.yml +++ b/docker/docker-compose.frontend.yml @@ -3,7 +3,7 @@ name: rythmify services: frontend: build: - context: ../../frontend + context: ${FRONTEND_CONTEXT:-../../frontend} dockerfile: Dockerfile container_name: rythmify_frontend restart: unless-stopped @@ -16,7 +16,7 @@ services: networks: - rythmify_network volumes: - - ../../frontend:/app + - ${FRONTEND_CONTEXT:-../../frontend}:/app - /app/node_modules networks: From 19f8990bbe22fa767b9f498de1e84ff560abe016 Mon Sep 17 00:00:00 2001 From: Mohamed jameel alabasy Date: Tue, 24 Mar 2026 15:05:56 +0200 Subject: [PATCH 4/6] fix(pipeline): update CI workflow to use docker compose commands for infrastructure and build processes --- .github/workflows/devops.yml | 41 +++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/.github/workflows/devops.yml b/.github/workflows/devops.yml index 4e723f1..4156ab2 100644 --- a/.github/workflows/devops.yml +++ b/.github/workflows/devops.yml @@ -186,19 +186,32 @@ jobs: grep -o '^[^=]*' environments/.env - name: Start infrastructure containers - run: bash scripts/start-infra.sh + run: | + docker compose -f docker/docker-compose.yml --env-file environments/.env up -d + echo "Infrastructure running." - name: Build backend and frontend images - run: bash scripts/build.sh + run: | + export BACKEND_CONTEXT=$GITHUB_WORKSPACE/backend + export FRONTEND_CONTEXT=$GITHUB_WORKSPACE/frontend + echo "Backend context: $BACKEND_CONTEXT" + echo "Frontend context: $FRONTEND_CONTEXT" + docker compose -f docker/docker-compose.yml --env-file environments/.env build --no-cache + docker compose -f docker/docker-compose.backend.yml --env-file environments/.env build --no-cache + docker compose -f docker/docker-compose.frontend.yml --env-file environments/.env build --no-cache + echo "Build complete." - name: Start backend - run: bash scripts/start-backend.sh + run: | + export BACKEND_CONTEXT=$GITHUB_WORKSPACE/backend + docker compose -f docker/docker-compose.backend.yml --env-file environments/.env up -d + echo "Backend running." - name: Run migrations - run: bash scripts/migrate.sh + run: docker exec rythmify_backend sh -c "npm run migrate" - name: Run seeds - run: bash scripts/seed.sh + run: docker exec rythmify_backend sh -c "npm run seed" - name: Run backend smoke check run: | @@ -228,12 +241,12 @@ jobs: docker compose -f docker/docker-compose.yml --env-file environments/.env logs > ci-logs/infra.log 2>&1 || true docker compose -f docker/docker-compose.backend.yml --env-file environments/.env logs > ci-logs/backend.log 2>&1 || true docker compose -f docker/docker-compose.frontend.yml --env-file environments/.env logs > ci-logs/frontend.log 2>&1 || true - echo "--- All containers (docker ps -a) ---" >> ci-logs/infra.log - docker ps -a >> ci-logs/infra.log 2>&1 || true - echo "--- Backend container logs (fallback) ---" >> ci-logs/backend.log - docker logs rythmify_backend >> ci-logs/backend.log 2>&1 || true - echo "--- Frontend container logs (fallback) ---" >> ci-logs/frontend.log - docker logs rythmify_frontend >> ci-logs/frontend.log 2>&1 || true + echo "--- All containers (docker ps -a) ---" >> ci-logs/infra.log + docker ps -a >> ci-logs/infra.log 2>&1 || true + echo "--- Backend container logs (fallback) ---" >> ci-logs/backend.log + docker logs rythmify_backend >> ci-logs/backend.log 2>&1 || true + echo "--- Frontend container logs (fallback) ---" >> ci-logs/frontend.log + docker logs rythmify_frontend >> ci-logs/frontend.log 2>&1 || true - name: Upload logs as artifact if: failure() @@ -245,4 +258,8 @@ jobs: - name: Tear down all containers if: always() - run: bash scripts/stop.sh + run: | + docker compose -f docker/docker-compose.frontend.yml --env-file environments/.env down 2>/dev/null || true + docker compose -f docker/docker-compose.backend.yml --env-file environments/.env down 2>/dev/null || true + docker compose -f docker/docker-compose.yml --env-file environments/.env down 2>/dev/null || true + echo "Stopped." From 59e875f4d0b6723c121082bf4fff943eca900bff Mon Sep 17 00:00:00 2001 From: Mohamed jameel alabasy Date: Tue, 24 Mar 2026 15:14:48 +0200 Subject: [PATCH 5/6] fix(pipeline): update migration and seeding commands in CI workflow --- .github/workflows/devops.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/devops.yml b/.github/workflows/devops.yml index 4156ab2..9a75081 100644 --- a/.github/workflows/devops.yml +++ b/.github/workflows/devops.yml @@ -207,11 +207,19 @@ jobs: docker compose -f docker/docker-compose.backend.yml --env-file environments/.env up -d echo "Backend running." + - name: Start frontend + run: | + export FRONTEND_CONTEXT=$GITHUB_WORKSPACE/frontend + docker compose -f docker/docker-compose.frontend.yml --env-file environments/.env up -d + echo "Frontend running." + - name: Run migrations - run: docker exec rythmify_backend sh -c "npm run migrate" + run: docker exec rythmify_backend sh -c "npm run migrate:up" - name: Run seeds - run: docker exec rythmify_backend sh -c "npm run seed" + run: | + docker cp $GITHUB_WORKSPACE/backend/seeds/seed.sql rythmify_db:/seed.sql + docker exec rythmify_db psql -U dev -d rythmify_dev -f /seed.sql - name: Run backend smoke check run: | From c74a5cfee692bbbda4a01272e5f33a9558926b21 Mon Sep 17 00:00:00 2001 From: Mohamed jameel alabasy Date: Tue, 24 Mar 2026 15:18:35 +0200 Subject: [PATCH 6/6] fix(pipeline): update DATABASE_URL for database connection and add wait step for database readiness --- .github/workflows/devops.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/devops.yml b/.github/workflows/devops.yml index 9a75081..23514cb 100644 --- a/.github/workflows/devops.yml +++ b/.github/workflows/devops.yml @@ -103,7 +103,7 @@ jobs: POSTGRES_USER: dev POSTGRES_PASSWORD: devpassword POSTGRES_DB: rythmify_dev - DATABASE_URL: postgresql://dev:devpassword@localhost:5432/rythmify_dev + DATABASE_URL: postgresql://dev:devpassword@rythmify_db:5432/rythmify_dev PGADMIN_EMAIL: admin@admin.com PGADMIN_PASSWORD: admin @@ -213,6 +213,13 @@ jobs: docker compose -f docker/docker-compose.frontend.yml --env-file environments/.env up -d echo "Frontend running." + - name: Wait for database + run: | + for i in $(seq 1 20); do + docker exec rythmify_db pg_isready -U dev -d rythmify_dev && break + echo "Attempt $i — DB not ready, waiting 3s..." + sleep 3 + done - name: Run migrations run: docker exec rythmify_backend sh -c "npm run migrate:up"