diff --git a/.github/workflows/coverage_comment.yml b/.github/workflows/coverage_comment.yml new file mode 100644 index 0000000000..d63e6f4a75 --- /dev/null +++ b/.github/workflows/coverage_comment.yml @@ -0,0 +1,72 @@ +name: Coverage Comment + +on: + workflow_run: + workflows: ["Coverage Tests"] + types: + - completed + +permissions: + contents: read + pull-requests: write + +jobs: + comment: + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' && + github.repository == 'django/django' && + github.event.workflow_run.pull_requests[0] != null + name: Post Coverage Comment + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - name: Download diff coverage report + uses: actions/download-artifact@v4 + with: + name: diff-coverage-report-${{ github.event.workflow_run.pull_requests[0].number }} + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + + - name: Post/update PR comment + env: + PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }} + uses: actions/github-script@v8 + with: + script: | + const fs = require('fs'); + const reportPath = 'diff-cover-report.md'; + let body = 'No coverage data available.'; + if (fs.existsSync(reportPath)) { + body = fs.readFileSync(reportPath, 'utf8'); + } + const commentBody = '### 📊 Coverage Report for Changed Files\n\n```\n' + body + '\n```\n\n**Note:** Missing lines are warnings only. Some lines may not be covered by SQLite tests as they are database-specific.\n\nFor more information about code coverage on pull requests, see the [contributing documentation](https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/unit-tests/#code-coverage-on-pull-requests).'; + + const prNumber = parseInt(process.env.PR_NUMBER); + if (isNaN(prNumber)) { + core.setFailed('PR number is not available or invalid.'); + return; + } + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + }); + + for (const c of comments) { + if ((c.body || '').includes('📊 Coverage Report for Changed Files')) { + await github.rest.issues.deleteComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: c.id, + }); + } + } + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: commentBody, + }); diff --git a/.github/workflows/coverage_tests.yml b/.github/workflows/coverage_tests.yml new file mode 100644 index 0000000000..af463bb295 --- /dev/null +++ b/.github/workflows/coverage_tests.yml @@ -0,0 +1,75 @@ +name: Coverage Tests + +on: + pull_request: + paths-ignore: + - 'docs/**' + - '**/*.md' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + coverage: + if: github.repository == 'django/django' + name: Coverage Tests (Windows) + runs-on: windows-latest + timeout-minutes: 60 + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: '3.14' + cache: 'pip' + cache-dependency-path: 'tests/requirements/py3.txt' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip wheel + python -m pip install -r tests/requirements/py3.txt -e . + python -m pip install 'coverage[toml]' diff-cover + + - name: Run tests with coverage + env: + PYTHONPATH: ${{ github.workspace }}/tests + COVERAGE_PROCESS_START: ${{ github.workspace }}/tests/.coveragerc + RUNTESTS_DIR: ${{ github.workspace }}/tests + run: | + python -Wall tests/runtests.py -v2 + + - name: Generate coverage report + if: success() + env: + COVERAGE_RCFILE: ${{ github.workspace }}/tests/.coveragerc + RUNTESTS_DIR: ${{ github.workspace }}/tests + run: | + python -m coverage combine + python -m coverage report --show-missing + python -m coverage xml -o tests/coverage.xml + + - name: Generate diff coverage report + if: success() + run: | + if (Test-Path 'tests/coverage.xml') { + diff-cover tests/coverage.xml --compare-branch=origin/main --fail-under=0 > diff-cover-report.md + } else { + Set-Content -Path diff-cover-report.md -Value 'No coverage data available.' + } + + - name: Upload diff coverage report + if: success() + uses: actions/upload-artifact@v4 + with: + name: diff-coverage-report-${{ github.event.pull_request.number }} + path: diff-cover-report.md + retention-days: 1 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b709ed5145..079fae6328 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -19,6 +19,7 @@ permissions: jobs: windows: + if: github.event_name == 'push' runs-on: windows-latest strategy: matrix: diff --git a/zizmor.yml b/zizmor.yml index 76e53f73cc..23630337b4 100644 --- a/zizmor.yml +++ b/zizmor.yml @@ -1,6 +1,7 @@ rules: dangerous-triggers: ignore: + - coverage_comment.yml - labels.yml - new_contributor_pr.yml unpinned-uses: