Add support for direct-commit prek fixes for dependabot (#8084)

Suggested edits don't work well for dependabot, and this is a case where
it's especially useful to have the fixes automatically applied. So this
creates a dependabot-specific flow that directly commits the fixes
rather than merely attaching them as suggested edits.

Because this directly commits the fixes, it also adds some restrictive
filtering to only apply fixes that are edits to existing non-binary
files, and files outside of `.github/`. The intent here is to minimize
the risk, as the changes suggested are from a just-updated `prek` run.

Also adds some extra safety to the `tests` action by omitting a secret
there -- it isn't needed anyways. And it pins an additional version.

Assisted-by: Antigravity with Opus
This commit is contained in:
Chandler Carruth authored and GitHub committed 2026-11-04 21:35:07 +00:00
1 parent 5ae3dcaa92
commit 9f2f906b85
3 files changed
+121 -8

No files matched your search

+4 -4
View File
@@ -66,10 +66,10 @@ jobs:
# We want to automatically create github suggestions for prek file
# changes for a pull request. But `pull_request` actions never have write
# permissions to the repository, so we create the suggestions in a separate
# privileged `workflow_run` action in prek_suggestions.yaml. Here,
# we upload the diffs and event configuration to an artifact for use by
# that action.
# permissions to the repository, so we create the suggestions (or, for
# Dependabot PRs, commit the fixes) in a separate privileged `workflow_run`
# action in prek_suggestions.yaml. Here, we upload the diffs and event
# configuration to an artifact for use by that action.
- name: Collect prek output
if: failure()
run: |
+112 -3
View File
@@ -11,9 +11,18 @@ name: 'Add prek suggestions'
# we use a separate privileged `workflow_run` action here to pick up its results
# and convert them into suggestion comments.
#
# For Dependabot PRs, prek's fixes usually come from an updated hook and are in
# files outside the PR's diff, where GitHub doesn't allow suggestions. So
# instead, we commit the fixes directly to Dependabot's branch.
#
# A privileged `workflow_run` action is inherently risky, because it could be
# tricked into running untrusted code from a PR. So neither job here runs
# anything from the PR, and both treat prek's output as untrusted.
#
# This action is only run from the workflow file on the trunk branch. Changes to
# this file will not take effect until they are merged to trunk.
on:
# zizmor: ignore[dangerous-triggers] - {necessary to act on prek's results}
workflow_run:
workflows: [prek]
types:
@@ -25,10 +34,12 @@ permissions:
jobs:
pull-request-suggestions:
# Only generate suggestions if prek for a PR failed.
# Only generate suggestions if prek for a PR failed. Dependabot's PRs are
# handled by `dependabot-fixes` below.
if: |
github.event.workflow_run.conclusion == 'failure' &&
github.event.workflow_run.event == 'pull_request'
github.event.workflow_run.event == 'pull_request' &&
!startsWith(github.event.workflow_run.head_branch, 'dependabot/')
runs-on: ubuntu-latest
steps:
- name: Harden Runner
@@ -46,7 +57,7 @@ jobs:
- uses: reviewdog/action-setup@d8a7baabd7f3e8544ee4dbde3ee41d0011c3a93f # v1.5.0
with:
reviewdog_version: latest
reviewdog_version: v0.21.2
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
@@ -69,3 +80,101 @@ jobs:
cat ./diff | \
GITHUB_EVENT_PATH=./event \
reviewdog -f=diff -f.diff.strip=1 -reporter=github-pr-review
dependabot-fixes:
# Only handle prek failures from Dependabot's own pushes to its branches in
# this repository. This also keeps us from reacting to our own fix commits.
if: |
github.event.workflow_run.conclusion == 'failure' &&
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.actor.login == 'dependabot[bot]' &&
github.event.workflow_run.head_repository.full_name == github.repository &&
startsWith(github.event.workflow_run.head_branch, 'dependabot/')
runs-on: ubuntu-latest
permissions:
actions: read # To download the artifact from the prek run.
contents: read # For actions/checkout.
pull-requests: read # To check the PR before pushing to it.
steps:
- name: Harden Runner
uses: step-security/harden-runner@46b06cea07f9e64621fdf066ba77ac6915163d43 # v2.22.3
with:
disable-sudo: true
egress-policy: block
# prettier-ignore
allowed-endpoints: >
api.github.com:443
github.com:443
- name: Download prek output
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: prek output
path: ${{ runner.temp }}/prek-output
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event.workflow_run.head_sha }}
persist-credentials: false
# The diff comes from running newly updated hooks, so treat it as
# untrusted: never run anything from it, and only accept edits to existing
# files outside of `.github`.
- name: Commit prek's fixes
env:
BRANCH: ${{ github.event.workflow_run.head_branch }}
DIFF: ${{ runner.temp }}/prek-output/diff
GH_TOKEN: ${{ github.token }}
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }}
# A CarbonInfraBot token that can push to this repository. A push with
# `GITHUB_TOKEN` wouldn't trigger CI for the new commit.
PUSH_TOKEN: ${{ secrets.CARBON_INFRA_BOT_DEPENDABOT_FIXES }}
run: |
# Check the PR itself, rather than trusting the artifact.
if [[ -z "$PR_NUMBER" ]]; then
echo "No PR is associated with this run, so skipping."
exit 0
fi
pr="$(gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" \
--jq '[.user.login, .head.ref, .head.sha] | join(" ")')"
if [[ "$pr" != "dependabot[bot] $BRANCH $HEAD_SHA" ]]; then
echo "PR #$PR_NUMBER isn't Dependabot's or has moved on; skipping."
exit 0
fi
if [[ ! -s "$DIFF" ]]; then
echo "prek didn't change any files, so there's nothing to commit."
exit 0
fi
# Have git describe the diff: `--numstat` gives a tab-separated line
# per file with its added and removed line counts ("-" for binary
# files), and `--summary` adds a line for anything that isn't an edit,
# such as creating, deleting, or renaming a file. Only accept text
# edits to files outside of `.github`.
changes="$(git apply --numstat --summary "$DIFF")"
rejected="$(awk -F'\t' '
!($1 ~ /^[0-9]+$/ && $2 ~ /^[0-9]+$/ && $3 !~ /^\.github\//)
' <<<"$changes")"
if [[ -n "$rejected" ]]; then
echo "::error::Not applying prek's diff because of:"
echo "$rejected"
exit 1
fi
if ! git apply "$DIFF"; then
echo "::error::prek's diff doesn't apply; run prek on the branch."
exit 1
fi
if [[ -z "$PUSH_TOKEN" ]]; then
echo "::error::CARBON_INFRA_BOT_DEPENDABOT_FIXES isn't available."
exit 1
fi
git -c user.name=CarbonInfraBot \
-c user.email=64870956+CarbonInfraBot@users.noreply.github.com \
commit --all --quiet --message='Apply fixes from updated prek hooks'
remote="https://x-access-token:${PUSH_TOKEN}@github.com"
git push "$remote/$GITHUB_REPOSITORY.git" "HEAD:refs/heads/$BRANCH"
+5 -1
View File
@@ -95,7 +95,11 @@ jobs:
${{ github.event_name == 'pull_request' &&
github.event.pull_request.base.sha ||
github.event.merge_group.base_sha }}
remote_cache_key: ${{ secrets.CARBON_BUILDS_GITHUB }}
# The remote cache key is only used outside of PRs, so only make it
# available on those events. PRs get an empty string.
remote_cache_key:
${{ (github.event_name != 'pull_request' &&
secrets.CARBON_BUILDS_GITHUB) || '' }}
targets_file: ${{ runner.temp }}/targets
# Build and run just the tests impacted by the PR or merge group.