name: Build & Push Docker Images run-name: ${{ gitea.actor }} - ${{ gitea.ref }} on: push: branches: - main jobs: detect-changes: name: Detect Changes runs-on: ubuntu-latest outputs: backend: ${{ steps.filter.outputs.backend }} frontend: ${{ steps.filter.outputs.frontend }} parapharmacy-api: ${{ steps.filter.outputs.parapharmacy-api }} pip-platform: ${{ steps.filter.outputs.pip-platform }} steps: - uses: actions/checkout@v4 - uses: dorny/paths-filter@v3 id: filter with: filters: | backend: - 'apps/backend/**' - 'packages/**' frontend: - 'apps/frontend/**' - 'packages/**' parapharmacy-api: - 'apps/parapharmacy-api/**' - 'packages/**' pip-platform: - 'apps/pip-platform/**' test-backend: name: Backend Tests needs: detect-changes if: needs.detect-changes.outputs.backend == 'true' runs-on: ubuntu-latest timeout-minutes: 15 steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' - name: Install dependencies run: npm ci --ignore-scripts - name: Install backend native deps run: npm rebuild sqlite3 bcrypt --workspace=farma-clic-backend - name: Run tests run: npm test --workspace=farma-clic-backend test-parapharmacy-api: name: Parapharmacy API Tests needs: detect-changes if: needs.detect-changes.outputs.parapharmacy-api == 'true' runs-on: ubuntu-latest timeout-minutes: 15 services: mongodb: image: mongo:7 ports: - 27017:27017 steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' - name: Install dependencies run: npm ci --ignore-scripts - name: Run Parapharmacy API Tests run: npm test --workspace=farmafinder-parapharmacy-api test-pip-platform: name: Pip Platform Tests needs: detect-changes if: false && needs.detect-changes.outputs.pip-platform == 'true' runs-on: ubuntu-latest timeout-minutes: 15 services: postgres: image: postgres:16-alpine env: POSTGRES_DB: pip_test POSTGRES_USER: pip POSTGRES_PASSWORD: pip_test ports: - 5432:5432 options: >- --health-cmd="pg_isready -U pip" --health-interval=10s --health-timeout=5s --health-retries=5 redis: image: redis:alpine ports: - 6379:6379 options: >- --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=5 steps: - uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.13' - name: Install uv run: pip install uv - name: Install dependencies working-directory: apps/pip-platform run: uv sync --extra dev - name: Run Tests working-directory: apps/pip-platform run: uv run pytest test-frontend: name: Frontend Tests needs: detect-changes if: needs.detect-changes.outputs.frontend == 'true' runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm' - name: Install dependencies run: npm ci --ignore-scripts - name: Run tests run: npm test --workspace=farma-clic-frontend -- --run --reporter=basic build-backend: name: Build Backend needs: [ detect-changes, test-backend ] if: | always() && needs.detect-changes.outputs.backend == 'true' && (needs.test-backend.result == 'success' || needs.test-backend.result == 'skipped') runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Log in to Gitea registry uses: docker/login-action@v3 with: registry: git.hacecalor.net username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push backend image uses: docker/build-push-action@v5 with: context: . file: ./apps/backend/Dockerfile push: true tags: | git.hacecalor.net/ichitux/farmafinder-backend:latest git.hacecalor.net/ichitux/farmafinder-backend:${{ gitea.sha }} build-parapharmacy-api: name: Build Parapharmacy API needs: [ detect-changes, test-parapharmacy-api ] if: | always() && needs.detect-changes.outputs.parapharmacy-api == 'true' && (needs.test-parapharmacy-api.result == 'success' || needs.test-parapharmacy-api.result == 'skipped') runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Log in to Gitea registry uses: docker/login-action@v3 with: registry: git.hacecalor.net username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push parapharmacy-api image uses: docker/build-push-action@v5 with: context: . file: ./apps/parapharmacy-api/Dockerfile push: true tags: | git.hacecalor.net/ichitux/farmafinder-parapharmacy-api:latest git.hacecalor.net/ichitux/farmafinder-parapharmacy-api:${{ gitea.sha }} build-pip-platform: name: Build Pip Platform needs: [ detect-changes, test-pip-platform ] if: | always() && needs.detect-changes.outputs.pip-platform == 'true' && (needs.test-pip-platform.result == 'success' || needs.test-pip-platform.result == 'skipped') runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Log in to Gitea registry uses: docker/login-action@v3 with: registry: git.hacecalor.net username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push pip-platform image uses: docker/build-push-action@v5 with: context: . file: ./apps/pip-platform/Dockerfile push: true tags: | git.hacecalor.net/ichitux/farmafinder-pip-platform:latest git.hacecalor.net/ichitux/farmafinder-pip-platform:${{ gitea.sha }} build-frontend: name: Build Frontend needs: [ detect-changes, test-frontend ] if: | always() && needs.detect-changes.outputs.frontend == 'true' && (needs.test-frontend.result == 'success' || needs.test-frontend.result == 'skipped') runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Log in to Gitea registry uses: docker/login-action@v3 with: registry: git.hacecalor.net username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push frontend image uses: docker/build-push-action@v5 with: context: ./apps/frontend push: true tags: | git.hacecalor.net/ichitux/farmafinder-frontend:latest git.hacecalor.net/ichitux/farmafinder-frontend:${{ gitea.sha }} deploy: name: Deploy needs: [ detect-changes, build-backend, build-frontend, build-parapharmacy-api, build-pip-platform ] if: | always() && (needs.build-backend.result == 'success' || needs.build-backend.result == 'skipped') && (needs.build-frontend.result == 'success' || needs.build-frontend.result == 'skipped') && (needs.build-parapharmacy-api.result == 'success' || needs.build-parapharmacy-api.result == 'skipped') && (needs.build-pip-platform.result == 'success' || needs.build-pip-platform.result == 'skipped') && (needs.detect-changes.outputs.backend == 'true' || needs.detect-changes.outputs.frontend == 'true') runs-on: self-hosted steps: - name: Pull latest code working-directory: /docker/FarmaFinder run: | set -euo pipefail git pull - name: Sync .env files from .env.example working-directory: /docker/FarmaFinder run: | set -euo pipefail while IFS= read -r env_example; do dir=$(dirname "$env_example") env_file="$dir/.env" if [ ! -f "$env_file" ]; then cp "$env_example" "$env_file" echo "[env-sync] Created $env_file from $env_example" else while IFS= read -r line || [ -n "$line" ]; do case "$line" in ''|\#*) continue ;; esac key=$(echo "$line" | cut -d'=' -f1) if ! grep -qF "$key=" "$env_file"; then echo "$line" >> "$env_file" echo "[env-sync] Added missing key '$key' to $env_file" fi done < "$env_example" fi done < <(find apps -name ".env.example" -type f) - name: Deploy containers working-directory: /docker/FarmaFinder run: | set -euo pipefail docker compose pull docker compose down --remove-orphans docker compose up -d