Autoupdate pre-commit config #39
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Autoupdate pre-commit config | |
on: | |
schedule: | |
- cron: "0 0 * * 0" | |
jobs: | |
pre_commit_autoupdate: | |
env: | |
config_path: .pre-commit-config.yaml | |
update_message_path: /tmp/message.txt | |
update_branch: chore/pre-commit-autoupdate | |
runs-on: ubuntu-latest | |
steps: | |
- name: Generate a token | |
id: generate-token | |
uses: actions/create-github-app-token@v1 | |
with: | |
app-id: ${{ vars.WRITE_CONTENTS_PR_APP }} | |
private-key: ${{ secrets.WRITE_CONTENTS_PR_KEY }} | |
- uses: actions/checkout@v4 | |
with: | |
ref: main | |
- name: Create or checkout update branch | |
id: create_branch | |
env: | |
GH_TOKEN: ${{ steps.generate-token.outputs.token }} | |
run: | | |
export pr_number=$( gh pr view ${{ env.update_branch }} --json number --jq '.number' ) | |
export pr_state=$( gh pr view ${{ env.update_branch }} --json state --jq '.state' ) | |
echo "pr_number=$pr_number" >> "$GITHUB_OUTPUT" | |
echo "pr_state=$pr_state" >> "$GITHUB_OUTPUT" | |
if git fetch origin ${{ env.update_branch }}; then | |
# If branch wasn't deleted after merge, do so here | |
if [ "$pr_state" = "MERGED" ]; then | |
git push -d origin ${{ env.update_branch }} | |
git checkout -b ${{ env.update_branch }} | |
git push origin ${{ env.update_branch }} | |
fi | |
git checkout ${{ env.update_branch }} | |
else | |
git checkout -b ${{ env.update_branch }} | |
git push origin ${{ env.update_branch }} | |
fi | |
# Pre-commit setup and autoupdate steps | |
- name: Set up Python 3.12 | |
uses: actions/setup-python@v5 | |
with: | |
python-version: 3.12 | |
cache: pip | |
- name: Upgrade Pip | |
run: python -m pip install --upgrade pip | |
- name: Install pre-commit | |
run: pip install pre-commit | |
- name: Store hash of baseline pre-commit config for comparison | |
id: old_file | |
run: echo "hash=$( sha256sum $config_path )" >> $GITHUB_OUTPUT | |
- name: Overwrite config on branch with version from main | |
run: git checkout main ${{ env.config_path }} | |
- name: Store hash of main pre-commit config for comparison | |
id: main_file | |
run: echo "hash=$( sha256sum $config_path )" >> $GITHUB_OUTPUT | |
- name: Run pre-commit autoupdate on main pre-commit config | |
id: autoupdate | |
run: | | |
pre-commit autoupdate > ${{ env.update_message_path }} | |
sed -i "/updating/!d" ${{ env.update_message_path }} | |
- name: Store hash of new pre-commit config for comparison | |
id: new_file | |
run: echo "hash=$( sha256sum $config_path )" >> $GITHUB_OUTPUT | |
# Commit authoring and pull-request creation/updating | |
- name: Commit (with signature) pre-commit config | |
id: commit | |
if: steps.old_file.outputs.hash != steps.new_file.outputs.hash | |
env: | |
GH_TOKEN: ${{ steps.generate-token.outputs.token }} | |
run: | | |
export message="chore(deps): autoupdate pre-commit hooks" | |
export sha=$( git rev-parse ${{ env.update_branch }}:${{ env.config_path }} ) | |
export content=$( base64 -i ${{ env.config_path }} ) | |
gh api --method PUT /repos/:owner/:repo/contents/${{ env.config_path }} \ | |
--field message="$message" \ | |
--field content="$content" \ | |
--field branch=${{ env.update_branch }} \ | |
--field sha="$sha" | |
- name: Create or update pre-commit-autoupdate pull-request | |
if: steps.commit.conclusion == 'success' || ( steps.main_file.outputs.hash != steps.new_file.outputs.hash ) | |
env: | |
GH_TOKEN: ${{ steps.generate-token.outputs.token }} | |
run : | | |
export title="chore(deps): autoupdate pre-commit hooks" | |
export body=$( cat ${{ env.update_message_path }} ) | |
export pr_number=${{ steps.create_branch.outputs.pr_number }} | |
export pr_state=${{ steps.create_branch.outputs.pr_state }} | |
# If the PR is closed, can it be reopened, or is the PR already open? | |
if ( [ "$pr_state" = "CLOSED" ] && gh pr reopen $pr_number ) || [ "$pr_state" = "OPEN" ]; then | |
gh api --method PATCH /repos/:owner/:repo/pulls/$pr_number \ | |
--field title="$title" \ | |
--field body="$body" | |
else | |
# If a PR doesn't already exist, and no previous PR can be reopened, create a new PR. | |
gh pr create -t "$title" -b "$body" -l dependencies -B main -H ${{ env.update_branch }} | |
fi |