diff --git a/.github/workflows/coverage_comment.yml b/.github/workflows/coverage_comment.yml index c826b8a7257b..da94d0d81f8c 100644 --- a/.github/workflows/coverage_comment.yml +++ b/.github/workflows/coverage_comment.yml @@ -1,7 +1,10 @@ name: Coverage Comment on: - workflow_run: + # The so-called dangerous workflow_run trigger is necessary for letting forks + # gain workflow-scoped pull-requests: write permission. The only + # user-controlled content is the content of diff-cover-report.md. + workflow_run: # zizmor: ignore[dangerous-triggers] workflows: ["Coverage Tests"] types: - completed @@ -27,15 +30,7 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} run-id: ${{ github.event.workflow_run.id }} - - name: Read PR number - id: pr - run: | - pr_number=$(cat pr_number.txt) - echo "number=$pr_number" >> $GITHUB_OUTPUT - - name: Post/update PR comment - env: - PR_NUMBER: ${{ steps.pr.outputs.number }} uses: actions/github-script@v9 with: script: | @@ -54,16 +49,23 @@ jobs: '**Note:** Missing lines are warnings only. Some database-specific lines may not be measured. [More information](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.'); + const headSha = context.payload.workflow_run.head_sha; + const { data: prs } = + await github.rest.repos.listPullRequestsAssociatedWithCommit({ + owner: context.repo.owner, + repo: context.repo.repo, + commit_sha: headSha, + }); + const pr = prs.find((p) => p.head.sha === headSha); + if (!pr) { + core.setFailed(`No PR found for commit ${headSha}.`); return; } const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, - issue_number: prNumber, + issue_number: pr.number, }); for (const c of comments) { @@ -79,6 +81,6 @@ jobs: await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, - issue_number: prNumber, + issue_number: pr.number, body: commentBody, }); diff --git a/.github/workflows/coverage_tests.yml b/.github/workflows/coverage_tests.yml index 4ac6751e5da8..0020694597f3 100644 --- a/.github/workflows/coverage_tests.yml +++ b/.github/workflows/coverage_tests.yml @@ -87,16 +87,10 @@ jobs: echo "No coverage data available." > diff-cover-report.md fi - - name: Save PR number - if: success() - run: echo "${{ github.event.pull_request.number }}" > pr_number.txt - - name: Upload artifacts if: success() uses: actions/upload-artifact@v7 with: name: coverage-artifacts - path: | - diff-cover-report.md - pr_number.txt + path: diff-cover-report.md retention-days: 1 diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py index 34f53a4df2c2..38aa98b6bdb6 100644 --- a/django/contrib/admin/utils.py +++ b/django/contrib/admin/utils.py @@ -372,7 +372,7 @@ def label_for_field(name, model, model_admin=None, return_attr=False, form=None) except FieldDoesNotExist: if name == "__str__": label = str(model._meta.verbose_name) - attr = str + attr = model.__str__ else: if callable(name): attr = name diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 0ceaf5f7a5c4..1bfe48082933 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -359,7 +359,7 @@ def get_ordering_field(self, field_name): # that allows sorting. if callable(field_name): attr = field_name - elif hasattr(self.model_admin, field_name): + elif hasattr(self.model_admin, field_name) and field_name != "__str__": attr = getattr(self.model_admin, field_name) else: try: diff --git a/docs/ref/forms/widgets.txt b/docs/ref/forms/widgets.txt index 25f6079a0aeb..edb6d8c783af 100644 --- a/docs/ref/forms/widgets.txt +++ b/docs/ref/forms/widgets.txt @@ -79,39 +79,6 @@ widget on the field. In the following example, the See the :ref:`built-in widgets` for more information about which widgets are available and which arguments they accept. -Widgets inheriting from the ``Select`` widget -============================================= - -Widgets inheriting from the :class:`Select` widget deal with choices. They -present the user with a list of options to choose from. The different widgets -present this choice differently; the :class:`Select` widget itself uses a -``