Conversation
The lint workflow uses pull_request_target which can't fetch fork branches by ref name. Switch to checking out by SHA with the fork's repository, which works for both forks and same-repo PRs. Skip the auto-push step for fork PRs since we can't push to external repos.
Use env var instead of direct expression interpolation for head.ref in run blocks to prevent potential code injection via attacker-controlled branch names.
There was a problem hiding this comment.
Pull request overview
Updates the lint GitHub Actions workflow to run successfully on fork-based pull requests by checking out the PR’s exact commit and avoiding push attempts to forks, while preserving the auto-fix-and-push behavior for same-repo PRs.
Changes:
- Switch
actions/checkoutto usepull_request.head.shaandpull_request.head.repo.full_name(with fallbacks) so fork PRs can be fetched. - Gate the “commit and push” step to only run for same-repo PRs.
- Explicitly create/check out the PR branch name before pushing, and push to
origin <branch>.
Comments suppressed due to low confidence (2)
.github/workflows/lint.yml:29
- For fork PRs the workflow now checks out and runs
rubocop -A, but the commit/push step is skipped. That means RuboCop can auto-correct locally and still exit successfully, so the check may pass even though the contributor’s branch remains non-compliant. Consider either (a) running RuboCop in check-only mode for forks (no-A) or (b) explicitly failing the job whenenv.changes == 'true'on forks with a message instructing the contributor to run RuboCop locally.
ref: ${{ github.event.pull_request.head.sha || github.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
- name: Setup Ruby
uses: ruby/setup-ruby@v1.299.0
with:
bundler-cache: true
- name: Run RuboCop with auto-correct
run: |
bundle exec rubocop -A
.github/workflows/lint.yml:47
- The branch name from
github.event.pull_request.head.refis interpolated into shell commands unquoted. While uncommon, branch names can contain characters that break the shell invocation. Quote the ref (and consider using--where applicable) to avoid unexpected parsing and to ensure the push targets the intended ref.
HEAD_REF: ${{ github.event.pull_request.head.ref }}
run: |
git checkout -b "$HEAD_REF"
git add .
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - uses: actions/checkout@v6.0.2 | ||
| with: | ||
| ref: ${{ github.event.pull_request.head.ref || github.ref }} | ||
| ref: ${{ github.event.pull_request.head.sha || github.ref }} | ||
| repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} | ||
|
|
There was a problem hiding this comment.
Using pull_request_target while checking out github.event.pull_request.head.sha from head.repo.full_name means the job will execute untrusted fork code with the base repo’s GITHUB_TOKEN permissions (contents: write at the workflow level). This is a known security footgun: a malicious fork PR can run arbitrary code (e.g., via Bundler/RuboCop) and use the write-scoped token to modify the base repository. Consider splitting into two jobs/workflows: a fork-safe lint job (triggered by pull_request or with job-level permissions: contents: read and no pushing) and a same-repo auto-correct job (only when head.repo.full_name == github.repository) that has write permissions and does the commit/push.
This issue also appears in the following locations of the same file:
- line 18
- line 44
Separate the lint workflow into: - lint: read-only job that checks out fork code safely with contents: read permission, runs rubocop without auto-correct - autocorrect: write job that only runs for same-repo PRs, checks out by branch ref, and pushes auto-corrections This prevents fork PRs from executing untrusted code with write-scoped GITHUB_TOKEN.
Fix lint workflow failing on fork PRs
CodeQL flags cache poisoning risk when pull_request_target checks out untrusted code with bundler-cache enabled. A malicious fork could poison the cache via a crafted Gemfile.lock. Disable caching for the lint job (which runs fork code) and use a plain bundle install instead. The autocorrect job (same-repo only) retains bundler-cache.
Problem
The lint workflow fails on all fork PRs (e.g. #5075) with:
The workflow uses
pull_request_targetand checks outgithub.event.pull_request.head.ref, which is just the branch name (e.g.,askpt/add-openfeature). For fork PRs, that branch does not exist ingithub/explore— it only exists in the contributor's fork — so the fetch fails.Fix
head.shawithhead.repo.full_nameworks for both forks and same-repo branches.head.repo.full_name == github.repository.