Skip to content

CI: cppcheck workflow fails on all fork PRs — actions/checkout now refuses pull_request_target fork checkout #13729

Description

@svan71

The cppcheck workflow used across linuxdeepin repos fails on every PR from an external fork before cppcheck ever runs. The job dies in ~5s at the actions/checkout step:

##[error]Refusing to check out fork pull request code from a 'pull_request_target' workflow. This workflow runs with the base repository's GITHUB_TOKEN, secrets, default-branch cache scope, and runner access. Fetching and executing a fork's code in that trusted context commonly leads to "pwn request" vulnerabilities. To opt in, review the risks at https://gh.io/securely-using-pull_request_target and set 'allow-unsafe-pr-checkout: true' on the actions/checkout step.

Cause: the workflow triggers on pull_request_target and checks out github.event.pull_request.head.sha. A recent actions/checkout release (the workflows float on @v3/@v4 major tags) added a guard that refuses fork-head checkout in that trusted context unless the step sets allow-unsafe-pr-checkout: true. No repo code or workflow change caused this — e.g. in deepin-screen-recorder the same PR branch passed cppcheck on 2026-07-17 (run 29561313565) and started failing 2026-07-21 (runs 29862562257, 30045419160) with the workflow file untouched since 2023.

Impact: every external-contributor PR touching cppcheck-relevant paths now shows a red ✗. Examples: dde-tray-loader#478 (run 30027755691), deepin-screen-recorder#877 (run 30045419160), deepin-screen-recorder#879 (run 30045750551). Same-repo branch PRs are unaffected, so maintainers may not notice. Since the workflow has paths-ignore: .github/workflows/** and runs the base-branch workflow anyway, contributors cannot fix or work around this from the PR side.

Possible fixes (maintainer decision, in rough order of effort):

  1. Add allow-unsafe-pr-checkout: true to the checkout step. This restores the exact pre-guard behavior. The step already sets persist-credentials: false, and linuxdeepin/action-cppcheck only runs static analysis over the tree (it never executes checked-out code — no build, no scripts), so the practical added risk versus last month is nil; but it is the org's call to accept the now-explicit risk.
  2. Split the job per GitHub's recommended pattern: a plain pull_request workflow runs cppcheck on the untrusted code without secrets and uploads the report as an artifact; a workflow_run job with the token posts the annotations/comment.

Whichever way you go, it presumably belongs in whatever template propagates .github/workflows/cppcheck.yml org-wide (dde-tray-loader's copy last synced 2026-07-09), since all repos using this workflow shape are affected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions