Repository navigation
chore(deps-dev): bump @playwright/test from 1.62.1 to 1.63.0 in /tests in the e2e group across 1 directory #752
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] | |
| pull_request: | |
| branches: [main, develop] | |
| workflow_dispatch: | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| REGISTRY: ghcr.io | |
| NIX_CONFIG: "experimental-features = nix-command flakes" | |
| jobs: | |
| backend-lint: | |
| name: Lint backend | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: DeterminateSystems/nix-installer-action@v22 | |
| - uses: DeterminateSystems/magic-nix-cache-action@v14 | |
| - name: Run ruff | |
| run: nix shell --inputs-from . nixpkgs#ruff -c ruff check backend --output-format=concise --exclude database/migrations | |
| simulator-lint: | |
| name: Lint simulator | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: DeterminateSystems/nix-installer-action@v22 | |
| - uses: DeterminateSystems/magic-nix-cache-action@v14 | |
| - name: Run ruff | |
| run: nix shell --inputs-from . nixpkgs#ruff -c ruff check simulator --output-format=concise | |
| frontend-lint: | |
| name: Lint frontend | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-node@v7 | |
| with: | |
| node-version: "22" | |
| cache: "npm" | |
| cache-dependency-path: web/package-lock.json | |
| - name: Install dependencies | |
| working-directory: web | |
| run: npm ci | |
| - name: Lint | |
| working-directory: web | |
| run: npm run lint | |
| - name: Check translation keys | |
| working-directory: web | |
| run: npm run check-translations | |
| dockerfile-lint: | |
| name: Lint Dockerfiles | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: hadolint/hadolint-action@v3.5.0 | |
| with: | |
| dockerfile: backend/Dockerfile | |
| failure-threshold: warning | |
| - uses: hadolint/hadolint-action@v3.5.0 | |
| with: | |
| dockerfile: web/Dockerfile | |
| failure-threshold: warning | |
| - uses: hadolint/hadolint-action@v3.5.0 | |
| with: | |
| dockerfile: simulator/Dockerfile | |
| failure-threshold: warning | |
| - uses: hadolint/hadolint-action@v3.5.0 | |
| with: | |
| dockerfile: proxy/Dockerfile | |
| failure-threshold: warning | |
| nix-fmt: | |
| name: Format nix | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: DeterminateSystems/nix-installer-action@v22 | |
| - uses: DeterminateSystems/magic-nix-cache-action@v14 | |
| - name: Check nix formatting | |
| run: | | |
| mapfile -t files < <(find . -name '*.nix' -not -path './result*') | |
| nix shell --inputs-from . nixpkgs#nixfmt -c nixfmt --check "${files[@]}" | |
| lint: | |
| name: Lint | |
| needs: [backend-lint, simulator-lint, frontend-lint, dockerfile-lint, nix-fmt] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - run: echo "All lint jobs passed." | |
| nix: | |
| name: Nix build | |
| needs: [lint] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: DeterminateSystems/nix-installer-action@v22 | |
| - uses: DeterminateSystems/magic-nix-cache-action@v14 | |
| - name: Build packages | |
| run: | | |
| nix build .#backend .#web .#simulator .#proxy .#default -L | |
| - name: Build scratch image streams | |
| run: | | |
| nix build .#backend-docker .#web-docker .#proxy-docker .#simulator-docker -L | |
| - name: Build rootfs derivations | |
| run: | | |
| nix build .#backend-rootfs .#web-rootfs .#proxy-rootfs .#simulator-rootfs -L | |
| - name: Flake check | |
| run: nix flake check --no-build | |
| docker: | |
| name: Docker ${{ matrix.component }} | |
| needs: [nix] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - component: backend | |
| flake_attr: backend-docker | |
| image_name: helpwave-tasks-backend | |
| ghcr_image: ${{ github.repository }}-backend | |
| - component: web | |
| flake_attr: web-docker | |
| image_name: helpwave-tasks-web | |
| ghcr_image: ${{ github.repository }}-web | |
| - component: proxy | |
| flake_attr: proxy-docker | |
| image_name: helpwave-tasks-proxy | |
| ghcr_image: ${{ github.repository }}-proxy | |
| - component: simulator | |
| flake_attr: simulator-docker | |
| image_name: helpwave-tasks-simulator | |
| ghcr_image: ${{ github.repository }}-simulator | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: DeterminateSystems/nix-installer-action@v22 | |
| - uses: DeterminateSystems/magic-nix-cache-action@v14 | |
| - uses: docker/setup-buildx-action@v4 | |
| - name: Log in to GHCR | |
| if: github.event_name != 'pull_request' | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build nix image stream and load | |
| run: | | |
| nix build ".#${{ matrix.flake_attr }}" -o "./result-${{ matrix.component }}" -L | |
| "./result-${{ matrix.component }}" | docker load | |
| docker tag "${{ matrix.image_name }}:latest" "local/tasks-${{ matrix.component }}:ci" | |
| - name: Push to GHCR | |
| if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' | |
| run: | | |
| docker tag "${{ matrix.image_name }}:latest" "${{ env.REGISTRY }}/${{ matrix.ghcr_image }}:latest" | |
| docker push "${{ env.REGISTRY }}/${{ matrix.ghcr_image }}:latest" | |
| - name: Save image artifact for tests | |
| run: | | |
| docker save "local/tasks-${{ matrix.component }}:ci" | gzip > "/tmp/tasks-${{ matrix.component }}.tar.gz" | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: image-${{ matrix.component }} | |
| path: /tmp/tasks-${{ matrix.component }}.tar.gz | |
| retention-days: 1 | |
| backend-tests: | |
| name: Backend tests | |
| needs: [docker] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ["3.11", "3.12", "3.13"] | |
| services: | |
| postgres: | |
| image: postgres:15 | |
| env: | |
| POSTGRES_USER: test | |
| POSTGRES_PASSWORD: test | |
| POSTGRES_DB: test | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 5432:5432 | |
| redis: | |
| image: redis:7-alpine | |
| options: >- | |
| --health-cmd "redis-cli ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 6379:6379 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-python@v7 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - uses: actions/cache@v6 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-${{ hashFiles('backend/requirements.txt') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip- | |
| - name: Install dependencies | |
| working-directory: backend | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| - name: Unit tests | |
| working-directory: backend | |
| run: pytest tests/unit -v --cov=api --cov=database --cov-report=xml --cov-report=term | |
| - name: Integration tests | |
| working-directory: backend | |
| run: pytest tests/integration -v | |
| - name: Upload coverage | |
| if: matrix.python-version == '3.13' | |
| uses: codecov/codecov-action@v7 | |
| with: | |
| file: ./backend/coverage.xml | |
| flags: backend | |
| name: backend-coverage | |
| frontend-tests: | |
| name: Frontend unit tests | |
| needs: [docker] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-node@v7 | |
| with: | |
| node-version: "22" | |
| cache: "npm" | |
| cache-dependency-path: web/package-lock.json | |
| - name: Install dependencies | |
| working-directory: web | |
| run: npm ci | |
| - name: Unit tests | |
| working-directory: web | |
| run: npm run test | |
| e2e-proxy: | |
| name: E2E (proxy stack) | |
| needs: [docker] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Download backend image | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: image-backend | |
| path: /tmp/images | |
| - name: Download web image | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: image-web | |
| path: /tmp/images | |
| - name: Download proxy image | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: image-proxy | |
| path: /tmp/images | |
| - name: Load images | |
| run: | | |
| gunzip -c /tmp/images/tasks-backend.tar.gz | docker load | |
| gunzip -c /tmp/images/tasks-web.tar.gz | docker load | |
| gunzip -c /tmp/images/tasks-proxy.tar.gz | docker load | |
| docker tag local/tasks-backend:ci local/tasks-backend:e2e | |
| docker tag local/tasks-web:ci local/tasks-web:e2e | |
| docker tag local/tasks-proxy:ci local/tasks-proxy:e2e | |
| - name: Start the stack | |
| env: | |
| BACKEND_IMAGE: local/tasks-backend:e2e | |
| WEB_IMAGE: local/tasks-web:e2e | |
| PROXY_IMAGE: local/tasks-proxy:e2e | |
| run: docker compose -f docker-compose.e2e.yml up -d | |
| - name: Wait for the stack | |
| run: | | |
| set -uo pipefail | |
| dump_logs() { | |
| echo "===== docker compose ps =====" | |
| docker compose -f docker-compose.e2e.yml ps -a || true | |
| echo "===== docker compose logs =====" | |
| docker compose -f docker-compose.e2e.yml logs --no-color || true | |
| } | |
| wait_http() { | |
| local name="$1" | |
| local url="$2" | |
| local ready=0 | |
| echo "Waiting for ${name}..." | |
| for _ in $(seq 1 60); do | |
| if curl -fs --connect-timeout 2 "$url" > /dev/null; then | |
| ready=1 | |
| break | |
| fi | |
| sleep 3 | |
| done | |
| if [ "$ready" -ne 1 ]; then | |
| echo "${name} never became ready at ${url}" | |
| dump_logs | |
| exit 1 | |
| fi | |
| } | |
| wait_proxy_port() { | |
| local ready=0 | |
| echo "Waiting for proxy to accept connections..." | |
| for _ in $(seq 1 60); do | |
| code=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 2 http://localhost/ || echo 000) | |
| if [ "$code" != "000" ]; then | |
| ready=1 | |
| break | |
| fi | |
| sleep 3 | |
| done | |
| if [ "$ready" -ne 1 ]; then | |
| echo "Proxy never became reachable on :80" | |
| dump_logs | |
| exit 1 | |
| fi | |
| } | |
| wait_graphql() { | |
| local ready=0 | |
| echo "Waiting for the backend..." | |
| for _ in $(seq 1 60); do | |
| code=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 2 -X POST \ | |
| -H 'content-type: application/json' \ | |
| -d '{"query":"{ __typename }"}' \ | |
| http://localhost/graphql || echo 000) | |
| if [ "$code" != "000" ] && [ "$code" -lt 500 ]; then | |
| ready=1 | |
| break | |
| fi | |
| sleep 3 | |
| done | |
| if [ "$ready" -ne 1 ]; then | |
| echo "Backend GraphQL never became ready" | |
| dump_logs | |
| exit 1 | |
| fi | |
| } | |
| wait_proxy_port | |
| wait_http "keycloak" "http://localhost/keycloak/realms/tasks/.well-known/openid-configuration" | |
| wait_graphql | |
| wait_http "frontend" "http://localhost/" | |
| - uses: actions/setup-node@v7 | |
| with: | |
| node-version: "22" | |
| cache: "npm" | |
| cache-dependency-path: tests/package-lock.json | |
| - name: Install E2E dependencies | |
| working-directory: tests | |
| run: npm ci | |
| - name: Install Playwright browsers | |
| working-directory: tests | |
| run: npx playwright install --with-deps chromium | |
| - name: Run proxied E2E tests | |
| working-directory: tests | |
| env: | |
| CI: true | |
| E2E_PROXY_TARGET: "1" | |
| E2E_BASE_URL: http://localhost | |
| run: npx playwright test e2e/proxy-fullstack.spec.ts | |
| - name: Dump stack logs | |
| if: failure() | |
| run: docker compose -f docker-compose.e2e.yml logs --no-color > /tmp/stack.log 2>&1 || true | |
| - uses: actions/upload-artifact@v7 | |
| if: always() | |
| with: | |
| name: playwright-report-proxy | |
| path: tests/playwright-report/ | |
| retention-days: 30 | |
| - uses: actions/upload-artifact@v7 | |
| if: failure() | |
| with: | |
| name: proxy-stack-logs | |
| path: /tmp/stack.log | |
| retention-days: 7 | |
| ci: | |
| name: CI | |
| needs: [backend-tests, frontend-tests, e2e-proxy, nix, docker] | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check required jobs | |
| run: | | |
| if [[ "${{ needs.backend-tests.result }}" != "success" ]] \ | |
| || [[ "${{ needs.frontend-tests.result }}" != "success" ]] \ | |
| || [[ "${{ needs.e2e-proxy.result }}" != "success" ]] \ | |
| || [[ "${{ needs.nix.result }}" != "success" ]] \ | |
| || [[ "${{ needs.docker.result }}" != "success" ]]; then | |
| echo "One or more required jobs failed or were skipped." | |
| exit 1 | |
| fi |