.github/workflows/backend_tests.yml

Summary

Maintainability
Test Coverage
name: Backend tests
on:
  merge_group:
    types: [checks_requested]
  push:
    branches:
      - develop
      - release-*
  pull_request:
    branches:
      - develop
      - release-*

jobs:
  run_tests:
    name: Run backend tests
    runs-on:  ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-22.04]
        shard: [1, 2, 3, 4, 5]
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: '3.8.15'
          architecture: 'x64'
      - name: Cache node modules and third_party/static
        uses: actions/cache@v3
        env:
          cache-name: cache-node-modules
        with:
          path: |
            /home/runner/work/oppia/yarn_cache
            /home/runner/work/oppia/oppia/third_party/static
          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('yarn.lock', 'dependencies.json') }}
          restore-keys: |
            ${{ runner.os }}-build-${{ env.cache-name }}-
            ${{ runner.os }}-build-
            ${{ runner.os }}-
      - uses: ./.github/actions/install-oppia-dependencies
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
      - name: Install packages for optimized coverage
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
        run: sudo apt-get install -y python-dev-is-python3 gcc
      - name: Install coverage and configparser
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
        run: pip install coverage configparser
      - name: Run backend test shard
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
        run: PYTHONIOENCODING=utf-8 python -m scripts.run_backend_tests --generate_coverage_report --ignore_coverage --exclude_load_tests --test_shard ${{ matrix.shard }}
      - name: Report failure if failed on oppia/oppia develop branch
        if: ${{ failure() && github.event_name == 'push' && github.repository == 'oppia/oppia' && github.ref == 'refs/heads/develop'}}
        uses: ./.github/actions/send-webhook-notification
        with:
          message: "A backend test failed on the upstream develop branch."
          webhook-url: ${{ secrets.BUILD_FAILURE_ROOM_WEBHOOK_URL }}
      - name: Upload coverage report
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
        uses: actions/upload-artifact@v3
        with:
          name: ${{ format('backend_test_coverage_shard_{0}', matrix.shard) }}
          path: .coverage
          retention-days: 1
  check_combined_coverage:
    name: Check combined backend test coverage
    needs: run_tests
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: '3.8.15'
          architecture: 'x64'
      - name: Cache node modules
        uses: actions/cache@v3
        env:
          cache-name: cache-node-modules
        with:
          path: /home/runner/work/oppia/yarn_cache
          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-build-${{ env.cache-name }}-
            ${{ runner.os }}-build-
            ${{ runner.os }}-
      # We need this so that we can check coverage of autogenerated code
      - uses: ./.github/actions/install-oppia-dependencies
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
      - name: Install coverage
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
        run: pip install coverage
      - name: Download coverage report for shard 1
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
        uses: actions/download-artifact@v3
        with:
          name: backend_test_coverage_shard_1
          path: coverage/coverage_1
      - name: Download coverage report for shard 2
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
        uses: actions/download-artifact@v3
        with:
          name: backend_test_coverage_shard_2
          path: coverage/coverage_2
      - name: Download coverage report for shard 3
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
        uses: actions/download-artifact@v3
        with:
          name: backend_test_coverage_shard_3
          path: coverage/coverage_3
      - name: Download coverage report for shard 4
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
        uses: actions/download-artifact@v3
        with:
          name: backend_test_coverage_shard_4
          path: coverage/coverage_4
      - name: Download coverage report for shard 5
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
        uses: actions/download-artifact@v3
        with:
          name: backend_test_coverage_shard_5
          path: coverage/coverage_5
      - name: Move coverage reports from artifact folders to coverage folder
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
        shell: bash
        run: |
          for i in {1..5}; do cp coverage/coverage_$i/.coverage coverage/.coverage.$i; done
      - name: Combine coverage reports
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
        shell: bash
        run: coverage combine coverage/.coverage.*
      - name: Check coverage
        if: startsWith(github.head_ref, 'update-changelog-for-release') == false
        shell: bash
        run: PYTHONIOENCODING=utf-8 python -m scripts.check_overall_backend_test_coverage
      - name: Report failure if failed on oppia/oppia develop branch
        if: ${{ failure() && github.event_name == 'push' && github.repository == 'oppia/oppia' && github.ref == 'refs/heads/develop'}}
        uses: ./.github/actions/send-webhook-notification
        with:
          message: "Backend coverage checks failed on the upstream develop branch."
          webhook-url: ${{ secrets.BUILD_FAILURE_ROOM_WEBHOOK_URL }}