Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions .github/workflows/pre-commit-push-fixes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Push pre-commit auto-fixes
on:
workflow_run:
workflows: [ "Halide Presubmit Checks" ]
types: [ completed ]

permissions:
contents: read
actions: read

jobs:
push-fixes:
name: Push auto-fixes to PR branch
runs-on: ubuntu-slim
if: github.event.workflow_run.conclusion == 'failure'
steps:
- name: Download auto-fix artifacts
id: download
uses: actions/download-artifact@v4
with:
name: pre-commit-fixes
path: /tmp/pre-commit-fixes
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
continue-on-error: true

- name: Read PR metadata
if: steps.download.outcome == 'success'
id: pr
run: |
{
echo "number=$(jq -r '.number' /tmp/pre-commit-fixes/pr-metadata.json)"
echo "head-repo=$(jq -r '.head_repo' /tmp/pre-commit-fixes/pr-metadata.json)"
echo "head-ref=$(jq -r '.head_ref' /tmp/pre-commit-fixes/pr-metadata.json)"
echo "maintainer-can-modify=$(jq -r '.maintainer_can_modify' /tmp/pre-commit-fixes/pr-metadata.json)"
} >> "$GITHUB_OUTPUT"

- name: Abort if maintainer edits not allowed
if: >-
steps.download.outcome == 'success'
&& steps.pr.outputs.head-repo != github.repository
&& steps.pr.outputs.maintainer-can-modify != 'true'
run: |
echo "::warning::PR #${{ steps.pr.outputs.number }} does not allow maintainer edits. Cannot push auto-fixes to fork."
echo "skip=true" >> "$GITHUB_ENV"

- uses: actions/create-github-app-token@v2
if: steps.download.outcome == 'success' && env.skip != 'true'
id: app-token
with:
app-id: ${{ secrets.LLVM_UPDATER_ID }}
private-key: ${{ secrets.LLVM_UPDATER_PRIVATE_KEY }}

- name: Get GitHub App user ID
if: steps.download.outcome == 'success' && env.skip != 'true'
id: get-user-id
run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}

- uses: actions/checkout@v4
if: steps.download.outcome == 'success' && env.skip != 'true'
with:
repository: ${{ steps.pr.outputs.head-repo }}
ref: ${{ steps.pr.outputs.head-ref }}
token: ${{ steps.app-token.outputs.token }}

- name: Apply and push fixes
if: steps.download.outcome == 'success' && env.skip != 'true'
run: |
git config user.name "${{ steps.app-token.outputs.app-slug }}[bot]"
git config user.email "${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com"

if [ "$(git log -1 --format='%ae')" = "$(git config user.email)" ]; then
echo "::error::pre-commit auto-fixes were not idempotent. Please fix manually."
exit 1
fi

git apply /tmp/pre-commit-fixes/pre-commit-fixes.patch
git add -A
git commit -m "Apply pre-commit auto-fixes"
git push
56 changes: 30 additions & 26 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,9 @@ jobs:
name: Run pre-commit checks
runs-on: ubuntu-slim
steps:
- uses: actions/create-github-app-token@v2
id: app-token
with:
app-id: ${{ secrets.LLVM_UPDATER_ID }}
private-key: ${{ secrets.LLVM_UPDATER_PRIVATE_KEY }}

- name: Get GitHub App user ID
id: get-user-id
run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}

- name: Configure git and environment
run: |
echo "GH_TOKEN=${{ steps.app-token.outputs.token }}" >> "$GITHUB_ENV"
git config --global user.name "${{ steps.app-token.outputs.app-slug }}[bot]"
git config --global user.email "${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com"

- uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
token: ${{ steps.app-token.outputs.token }}

- uses: actions/setup-python@v5
- uses: astral-sh/setup-uv@v5
Expand All @@ -47,19 +28,42 @@ jobs:
id: pre-commit
uses: pre-commit/action@v3.0.1

- name: Push auto-fixes
- name: Create auto-fix diff
id: diff
if: ${{ !cancelled() && steps.pre-commit.outcome == 'failure' }}
run: |
if git diff --quiet; then
echo "::error::no auto-fixable changes; pre-commit failure requires manual attention."
elif [ "$(git log -1 --format='%ae')" = "$(git config user.email)" ]; then
echo "::error::pre-commit auto-fixes were not idempotent. Please fix manually."
echo "has-fixes=false" >> "$GITHUB_OUTPUT"
else
git add -A
git commit -m "Apply pre-commit auto-fixes"
git push
git diff > /tmp/pre-commit-fixes.patch
echo "has-fixes=true" >> "$GITHUB_OUTPUT"
fi

- name: Save PR metadata
if: ${{ !cancelled() && steps.diff.outputs.has-fixes == 'true' }}
run: |
jq -n \
--argjson number "$PR_NUMBER" \
--arg head_repo "$PR_HEAD_REPO" \
--arg head_ref "$PR_HEAD_REF" \
--argjson maintainer_can_modify "$PR_MAINTAINER_CAN_MODIFY" \
'$ARGS.named' | tee /tmp/pr-metadata.json
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
PR_HEAD_REF: ${{ github.event.pull_request.head.ref }}
PR_MAINTAINER_CAN_MODIFY: ${{ github.event.pull_request.maintainer_can_modify }}

- name: Upload auto-fix artifacts
if: ${{ !cancelled() && steps.diff.outputs.has-fixes == 'true' }}
uses: actions/upload-artifact@v4
with:
name: pre-commit-fixes
path: |
/tmp/pre-commit-fixes.patch
/tmp/pr-metadata.json
retention-days: 1

- name: Annotate codespell errors
if: ${{ !cancelled() && steps.pre-commit.outcome == 'failure' }}
run: |
Expand Down
Loading