Django Testing CI #2337
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
| # Github Actions workflow that runs the test suite on the master branch | |
| # every night, as well as tests new pull requests. | |
| name: Django Testing CI | |
| on: | |
| schedule: # Run every night at 3 AM | |
| - cron: '0 10 * * *' # 10 AM UTC = 3 AM PST | |
| push: # Run when pushes are made on the master and develop branch | |
| branches: [ "master", "develop" ] | |
| pull_request: # Runs when pull request to develop or master is opened, | |
| # reopened, or updated with a new commit. | |
| branches: [ "master", "develop" ] | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| jobs: | |
| # ─── Coverage strategy ─────────────────────────────────────────────────────── | |
| # | |
| # Each test job writes its coverage data to a unique coverage-<shard> file, | |
| # then uploads it as an artifact. The `report` job downloads all five files, | |
| # runs `coverage combine`, and generates the combined HTML + XML report. | |
| # | |
| # Shared setup (checkout, Python, venv, settings) lives in the composite | |
| # action at .github/actions/coldfront-setup. Each job still declares its | |
| # own Postgres service because services cannot be defined in composite actions. | |
| # | |
| # Coverage is written to the default .coverage file (no --data-file flag), | |
| # then renamed to coverage-<shard> (no leading dot) immediately after the run. | |
| # Each job runs on an isolated runner so there is no cross-job collision. | |
| # | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| test-pytest: | |
| runs-on: ubuntu-22.04 | |
| permissions: | |
| contents: read | |
| services: | |
| postgres: | |
| image: postgres:15.2-alpine3.17 | |
| env: | |
| POSTGRES_DB: cf_brc_db | |
| POSTGRES_PASSWORD: test | |
| POSTGRES_PORT: 5432 | |
| POSTGRES_USER: test | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 2s | |
| --health-timeout 3s | |
| --health-retries 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/coldfront-setup | |
| - name: Run pytest unit tests | |
| run: | | |
| source ~/venv/bin/activate | |
| export django_secret_key=`openssl rand -base64 64` | |
| coverage run -m pytest coldfront/ -m unit | |
| - name: Run pytest component tests | |
| run: | | |
| source ~/venv/bin/activate | |
| export django_secret_key=`openssl rand -base64 64` | |
| coverage run --append -m pytest coldfront/ -m component | |
| - name: Rename coverage data | |
| if: always() | |
| run: mv .coverage coverage-pytest || true | |
| - name: Upload pytest coverage data | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-data-pytest | |
| path: coverage-pytest | |
| if: always() | |
| # ─── Django: core.project views ────────────────────────────────────────────── | |
| # ~143 test methods — view tests only. | |
| test-django-project-views: | |
| runs-on: ubuntu-22.04 | |
| permissions: | |
| contents: read | |
| services: | |
| postgres: | |
| image: postgres:15.2-alpine3.17 | |
| env: | |
| POSTGRES_DB: cf_brc_db | |
| POSTGRES_PASSWORD: test | |
| POSTGRES_PORT: 5432 | |
| POSTGRES_USER: test | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 2s | |
| --health-timeout 3s | |
| --health-retries 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/coldfront-setup | |
| - name: Run Django tests (core.project - views) | |
| run: | | |
| source ~/venv/bin/activate | |
| export django_secret_key=`openssl rand -base64 64` | |
| python manage.py migrate | |
| coverage run manage.py test \ | |
| --timing \ | |
| --testrunner=coldfront.tests.timing_runner.TimingTestRunner \ | |
| coldfront.core.project.tests.test_views | |
| - name: Rename coverage data | |
| if: always() | |
| run: mv .coverage coverage-django-project-views || true | |
| - name: Upload Django project views coverage data | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-data-django-project-views | |
| path: coverage-django-project-views | |
| if: always() | |
| # ─── Django: core.project non-views ────────────────────────────────────────── | |
| # ~151 test methods — commands, forms, and utils. | |
| test-django-project-other: | |
| runs-on: ubuntu-22.04 | |
| permissions: | |
| contents: read | |
| services: | |
| postgres: | |
| image: postgres:15.2-alpine3.17 | |
| env: | |
| POSTGRES_DB: cf_brc_db | |
| POSTGRES_PASSWORD: test | |
| POSTGRES_PORT: 5432 | |
| POSTGRES_USER: test | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 2s | |
| --health-timeout 3s | |
| --health-retries 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/coldfront-setup | |
| - name: Run Django tests (core.project - commands, forms, utils) | |
| run: | | |
| source ~/venv/bin/activate | |
| export django_secret_key=`openssl rand -base64 64` | |
| python manage.py migrate | |
| coverage run manage.py test \ | |
| --timing \ | |
| --testrunner=coldfront.tests.timing_runner.TimingTestRunner \ | |
| coldfront.core.project.tests.test_commands \ | |
| coldfront.core.project.tests.test_forms \ | |
| coldfront.core.project.tests.test_utils | |
| - name: Rename coverage data | |
| if: always() | |
| run: mv .coverage coverage-django-project-other || true | |
| - name: Upload Django project other coverage data | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-data-django-project-other | |
| path: coverage-django-project-other | |
| if: always() | |
| # ─── Django: api.* ─────────────────────────────────────────────────────────── | |
| # ~229 test methods across allocation, billing, project, statistics, user apps. | |
| test-django-api: | |
| runs-on: ubuntu-22.04 | |
| permissions: | |
| contents: read | |
| services: | |
| postgres: | |
| image: postgres:15.2-alpine3.17 | |
| env: | |
| POSTGRES_DB: cf_brc_db | |
| POSTGRES_PASSWORD: test | |
| POSTGRES_PORT: 5432 | |
| POSTGRES_USER: test | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 2s | |
| --health-timeout 3s | |
| --health-retries 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/coldfront-setup | |
| - name: Run Django tests (api) | |
| run: | | |
| source ~/venv/bin/activate | |
| export django_secret_key=`openssl rand -base64 64` | |
| python manage.py migrate | |
| coverage run manage.py test \ | |
| --timing \ | |
| --testrunner=coldfront.tests.timing_runner.TimingTestRunner \ | |
| coldfront.api | |
| - name: Rename coverage data | |
| if: always() | |
| run: mv .coverage coverage-django-api || true | |
| - name: Upload Django API coverage data | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-data-django-api | |
| path: coverage-django-api | |
| if: always() | |
| # ─── Django: remaining core.* + plugins.* ──────────────────────────────────── | |
| # ~284 test methods: core.allocation, billing, user, utils, statistics, | |
| # account, socialaccount, research_output, publication, and plugins. | |
| test-django-core: | |
| runs-on: ubuntu-22.04 | |
| permissions: | |
| contents: read | |
| services: | |
| postgres: | |
| image: postgres:15.2-alpine3.17 | |
| env: | |
| POSTGRES_DB: cf_brc_db | |
| POSTGRES_PASSWORD: test | |
| POSTGRES_PORT: 5432 | |
| POSTGRES_USER: test | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 2s | |
| --health-timeout 3s | |
| --health-retries 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/coldfront-setup | |
| - name: Run Django tests (core except project, plugins) | |
| run: | | |
| source ~/venv/bin/activate | |
| export django_secret_key=`openssl rand -base64 64` | |
| python manage.py migrate | |
| coverage run manage.py test \ | |
| --timing \ | |
| --testrunner=coldfront.tests.timing_runner.TimingTestRunner \ | |
| coldfront.core.account \ | |
| coldfront.core.allocation \ | |
| coldfront.core.billing \ | |
| coldfront.core.publication \ | |
| coldfront.core.research_output \ | |
| coldfront.core.socialaccount \ | |
| coldfront.core.statistics \ | |
| coldfront.core.user \ | |
| coldfront.core.utils \ | |
| coldfront.plugins | |
| - name: Rename coverage data | |
| if: always() | |
| run: mv .coverage coverage-django-core || true | |
| - name: Upload Django core coverage data | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-data-django-core | |
| path: coverage-django-core | |
| if: always() | |
| # ─── Report ────────────────────────────────────────────────────────────────── | |
| # Runs after all five test jobs (even if one fails) to combine coverage data, | |
| # post the PR comment, and upload the combined report artifact. | |
| report: | |
| needs: [test-pytest, test-django-project-views, test-django-project-other, test-django-api, test-django-core] | |
| if: always() | |
| runs-on: ubuntu-22.04 | |
| permissions: | |
| contents: write # required to push python-coverage-comment-action-data branch | |
| pull-requests: write # required to post coverage comment | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/coldfront-setup | |
| - name: Download all coverage data | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: coverage-data-* | |
| merge-multiple: true | |
| path: coverage-data | |
| - name: Generate combined coverage report | |
| run: | | |
| source ~/venv/bin/activate | |
| coverage combine coverage-data/coverage-* | |
| coverage html | |
| coverage xml -o coverage-combined.xml | |
| coverage report --fail-under=50 | |
| - name: Post coverage comment on PR | |
| uses: py-cov-action/python-coverage-comment-action@v3 | |
| with: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| - name: Upload coverage reports | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-reports | |
| path: | | |
| coverage-*.xml | |
| htmlcov/ | |
| retention-days: 7 | |
| if: always() |