name: People Workflow

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

jobs:
  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@v2
        with:
            fetch-depth: 0
      - name: show
        run: git log
      - name: Enforce absence of print statements in code
        run: |
          ! git diff origin/${{ github.event.pull_request.base.ref }}..HEAD -- . ':(exclude)**/people.yml' | grep "print("
      - name: Check absence of fixup commits
        run: |
          ! git log | grep 'fixup!'
      - name: Install gitlint
        run: pip install --user requests gitlint
      - name: Lint commit messages added to main
        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@v2
        with:
            fetch-depth: 0
      - name: Check that the CHANGELOG has been modified in the current branch
        run: git whatchanged --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@v2
      - 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

  test-front:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: src/frontend/
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18.x'
          cache: 'yarn'
          cache-dependency-path: src/frontend/yarn.lock

      - name: Install dependencies
        run: yarn install --frozen-lockfile

      - name: Test App
        run: yarn app:test

  lint-front:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: src/frontend/
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18.x'
          cache: 'yarn'
          cache-dependency-path: src/frontend/yarn.lock

      - name: Install dependencies
        run: yarn install --frozen-lockfile
        
      - name: Check linting
        run: yarn lint

  test-e2e:
    runs-on: ubuntu-latest
    needs: build-mails
    timeout-minutes: 10
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
            
      - name: Set services env variables
        run: |
          make create-env-files
          cat env.d/development/common.e2e.dist >> env.d/development/common

      - name: Download mails' templates
        uses: actions/download-artifact@v4
        with:
          name: mails-templates
          path: src/backend/core/templates/mail
    
      - 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 run
        
      - name: Apply DRF migrations
        run: |
          make migrate

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

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18.x'
          cache: 'yarn'
          cache-dependency-path: src/frontend/yarn.lock

      - name: Install dependencies
        run: cd src/frontend/ && yarn install --frozen-lockfile

      - name: Install Playwright Browsers
        run: cd src/frontend/apps/e2e && yarn install

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

      - name: Run e2e tests
        run: cd src/frontend/ && yarn e2e:test

      - uses: actions/upload-artifact@v3
        if: always()
        with:
          name: playwright-report
          path: src/frontend/apps/e2e/report/
          retention-days: 7

  build-mails:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: src/mail
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
      - name: Install yarn
        run: npm install -g yarn
      - name: Install node dependencies
        run: yarn install --frozen-lockfile
      - name: Build mails
        run: yarn build
      - name: Persist mails' templates
        uses: actions/upload-artifact@v4
        with:
            name: mails-templates
            path: src/backend/core/templates/mail

  lint-back:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: src/backend
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
      - name: Install Python
        uses: actions/setup-python@v3
        with:
          python-version: '3.10'
      - name: Install development dependencies
        run: pip install --user .[dev]
      - name: Check code formatting with ruff
        run: ~/.local/bin/ruff format . --diff
      - name: Lint code with ruff
        run: ~/.local/bin/ruff check .
      - name: Lint code with pylint
        run: ~/.local/bin/pylint .

  test-back:
    runs-on: ubuntu-latest
    needs: build-mails
    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@v2
      - name: Create writable /data
        run: |
          sudo mkdir -p /data/media && \
          sudo mkdir -p /data/static
      - name: Download mails' templates
        uses: actions/download-artifact@v4
        with:
          name: mails-templates
          path: src/backend/core/templates/mail
      - name: Install Python
        uses: actions/setup-python@v3
        with:
          python-version: '3.10'
      - name: Install development dependencies
        run: pip install --user .[dev]
      - 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: python manage.py compilemessages
      - name: Run tests
        run: ~/.local/bin/pytest -n 2

  i18n-crowdin:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
        
      - name: Install gettext (required to make messages)
        run: |
          sudo apt-get update
          sudo apt-get install -y gettext
      
      - name: Install Python
        uses: actions/setup-python@v3
        with:
          python-version: '3.10'

      - name: Install development dependencies
        working-directory: src/backend
        run: pip install --user .[dev]

      - name: Generate the translation base file
        run: ~/.local/bin/django-admin makemessages --keep-pot --all
        
      - name: Load sops secrets
        uses: rouja/actions-sops@main
        with:
          secret-file: .github/workflows/secrets.enc.env
          age-key: ${{ secrets.SOPS_PRIVATE }}
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18.x'
          cache: 'yarn'
          cache-dependency-path: src/frontend/yarn.lock

      - name: Install dependencies
        run: cd src/frontend/ && yarn install --frozen-lockfile

      - name: Download sources from Crowdin to stay synchronized
        run: |
          docker run \
          --rm \
          -e CROWDIN_API_TOKEN=$CROWDIN_API_TOKEN \
          -e CROWDIN_PROJECT_ID=$CROWDIN_PROJECT_ID \
          -e CROWDIN_BASE_PATH=$CROWDIN_BASE_PATH \
          -v "${{ github.workspace }}:/app" \
          crowdin/cli:3.16.0 \
          crowdin download sources -c /app/crowdin/config.yml
      
      - name: Extract the frontend translation
        run: make frontend-i18n-extract
      
      - name: Upload files to Crowdin
        run: |
          docker run \
          --rm \
          -e CROWDIN_API_TOKEN=$CROWDIN_API_TOKEN \
          -e CROWDIN_PROJECT_ID=$CROWDIN_PROJECT_ID \
          -e CROWDIN_BASE_PATH=$CROWDIN_BASE_PATH \
          -v "${{ github.workspace }}:/app" \
          crowdin/cli:3.16.0 \
          crowdin upload sources -c /app/crowdin/config.yml
