name: People Workflow

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - '*'

jobs:
  # Call the reusable workflow to install dependencies
  dependencies:
    uses: ./.github/workflows/dependencies.yml
    with:
      node_version: '22.x'
      with-front-dependencies-installation: true
      with-build_mails: true

  lint-git:
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request' # Makes sense only for pull requests
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - name: show
        run: git log
      - name: Enforce absence of print statements in code
        if: always()
        run: |
          ! git diff origin/${{ github.event.pull_request.base.ref }}..HEAD -- . ':(exclude)**/people.yml' | grep -E "(\bprint\(|\bpprint\()"
      - name: Check absence of fixup commits
        if: always()
        run: |
          ! git log | grep 'fixup!'
      - name: Install gitlint
        if: always()
        run: pip install --user requests gitlint
      - name: Lint commit messages added to main
        if: always()
        run: ~/.local/bin/gitlint --commits origin/${{ github.event.pull_request.base.ref }}..HEAD

  check-changelog:
    runs-on: ubuntu-latest
    if: |
      contains(github.event.pull_request.labels.*.name, 'noChangeLog') == false &&
      github.event_name == 'pull_request'
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - name: Check that the CHANGELOG has been modified in the current branch
        run: git log --name-only --pretty="" origin/${{ github.event.pull_request.base.ref }}..HEAD | grep CHANGELOG

  lint-changelog:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
      - name: Check CHANGELOG max line length
        run: |
          max_line_length=$(cat CHANGELOG.md | grep -Ev "^\[.*\]: https://github.com" | wc -L)
          if [ $max_line_length -ge 80 ]; then
            echo "ERROR: CHANGELOG has lines longer than 80 characters."
            exit 1
          fi

  build-front:
    runs-on: ubuntu-latest
    needs: dependencies
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Restore the frontend cache
        uses: actions/cache@v5
        id: front-node_modules
        with:
          path: 'src/frontend/**/node_modules'
          key: front-node_modules-${{ hashFiles('src/frontend/**/yarn.lock') }}

      - name: Build CI App
        run: cd src/frontend/ && yarn ci:build

      - name: Cache build frontend
        uses: actions/cache@v5
        with:
          path: src/frontend/apps/desk/out/
          key: build-front-${{ github.run_id }}

  test-front:
    runs-on: ubuntu-latest
    needs: dependencies
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Restore the frontend cache
        uses: actions/cache@v5
        id: front-node_modules
        with:
          path: 'src/frontend/**/node_modules'
          key: front-node_modules-${{ hashFiles('src/frontend/**/yarn.lock') }}

      - name: Test App
        run: cd src/frontend/ && yarn app:test

  lint-front:
    runs-on: ubuntu-latest
    needs: dependencies
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Restore the frontend cache
        uses: actions/cache@v5
        id: front-node_modules
        with:
          path: 'src/frontend/**/node_modules'
          key: front-node_modules-${{ hashFiles('src/frontend/**/yarn.lock') }}

      - name: Check linting
        run: cd src/frontend/ && yarn lint

  test-e2e:
    runs-on: ubuntu-latest
    needs: [dependencies, build-front]
    timeout-minutes: 10
    strategy:
      fail-fast: false
      matrix:
        shardIndex: [1, 2, 3, 4]
        shardTotal: [4]
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Set services env variables
        run: |
          make create-env-files
          cat env.d/development/common.e2e.dist >> env.d/development/common

      - name: Restore the mail templates
        uses: actions/cache@v5
        id: mail-templates
        with:
          path: "src/backend/core/templates/mail"
          key: mail-templates-${{ hashFiles('src/mail/mjml') }}
          fail-on-cache-miss: true  

      - name: Restore the frontend cache
        uses: actions/cache@v5
        id: front-node_modules
        with:
          path: 'src/frontend/**/node_modules'
          key: front-node_modules-${{ hashFiles('src/frontend/**/yarn.lock') }}

      - name: Restore the build cache
        uses: actions/cache@v5
        id: cache-build
        with:
          path: src/frontend/apps/desk/out/
          key: build-front-${{ github.run_id }}

      - name: Build and Start Docker Servers
        env:
          DOCKER_BUILDKIT: 1
          COMPOSE_DOCKER_CLI_BUILD: 1
        run: |
          docker compose build --pull --build-arg BUILDKIT_INLINE_CACHE=1
          make update-keycloak-realm-app
          make add-dev-rsa-private-key-to-env
          make run

      - name: Apply DRF migrations
        run: |
          make migrate

      - name: Add dummy data
        run: |
          make demo FLUSH_ARGS='--no-input'

      - name: Run e2e tests
        run: cd src/frontend/ && yarn e2e:test --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}

      - name: Save logs
        if: always()
        run: docker compose logs > src/frontend/apps/e2e/report/logs.txt

      - name: Save Dimail logs
        if: always()
        run: docker compose logs dimail > src/frontend/apps/e2e/report/dimail-logs.txt

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report-${{ matrix.shardIndex }}
          path: src/frontend/apps/e2e/report/
          retention-days: 7

  tests-e2e-feedback:
    runs-on: ubuntu-latest
    needs: [test-e2e]
    if: always()
    steps:
      - name: All tests ok
        if: ${{ !(contains(needs.*.result, 'failure')) }}
        run: exit 0
      - name: Some tests failed
        if: ${{ contains(needs.*.result, 'failure') }}
        run: exit 1

  lint-back:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: src/backend
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version-file: "src/backend/pyproject.toml"
      - name: Install uv
        uses: astral-sh/setup-uv@v6
      - name: Install the project
        run: uv sync --locked --all-extras

      - name: Check code formatting with ruff
        run: uv run ruff format . --diff
      - name: Lint code with ruff
        run: uv run ruff check .
      - name: Lint code with pylint
        run: uv run pylint .

  test-back:
    runs-on: ubuntu-latest
    needs: dependencies
    defaults:
      run:
        working-directory: src/backend

    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_DB: people
          POSTGRES_USER: dinum
          POSTGRES_PASSWORD: pass
        ports:
          - 5432:5432
        # needed because the postgres container does not provide a healthcheck
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

    env:
      DJANGO_CONFIGURATION: Test
      DJANGO_SETTINGS_MODULE: people.settings
      DJANGO_SECRET_KEY: ThisIsAnExampleKeyForTestPurposeOnly
      OIDC_OP_JWKS_ENDPOINT: /endpoint-for-test-purpose-only
      DB_HOST: localhost
      DB_NAME: people
      DB_USER: dinum
      DB_PASSWORD: pass
      DB_PORT: 5432

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
      - name: Create writable /data
        run: |
          sudo mkdir -p /data/media && \
          sudo mkdir -p /data/static
      - name: Restore the mail templates
        uses: actions/cache@v5
        id: mail-templates
        with:
          path: "src/backend/core/templates/mail"
          key: mail-templates-${{ hashFiles('src/mail/mjml') }}
          fail-on-cache-miss: true  

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version-file: "src/backend/pyproject.toml"
      - name: Install uv
        uses: astral-sh/setup-uv@v6
      - name: Install the dependencies
        run: uv sync --locked --all-extras

      - name: Install gettext (required to compile messages)
        run: |
          sudo apt-get update
          sudo apt-get install -y gettext

      - name: Generate a MO file from strings extracted from the project
        run: uv run python manage.py compilemessages

      - name: Run tests
        run: uv run pytest -n 2
