Auto-update pre-commit hooks with GitHub Actions

Pre-commit hooks are great to reduce the feedback loop for things like linting and auto-formatting. Git supports them out of the box, but they are not easy to share across all developers working on a project, they need to be installed by each developers.

Several tools exist to solve this problem, but my favorite is pre-commit. It’s written in Python, but it aims at being language agnostic. It saves your setup in a config file and developers can install all of them with a single command.

Each tool is referenced by their github repo and tag to install, which is great because each tool is pinned to a specific version. However, I usually have the tool versions already elsewhere in my repository, for example in requirements.txt, causing some duplication. The main project dependencies are automatically updated with Dependabot, PyUP or Renovate but none of these tools supports the pre-commit config file. After a while, it’s easy to end up with versions discrepancies.

That is until this week-end, where I stumbled upon the autoupdate command from pre-commit. I’m not sure how I missed this before, it looks like it’s been part of pre-commit for a really long time. By combining this with the power of Github actions, I was able to get it to send me a pull request each time a new version is available:

<span>name</span><span>:</span> <span>Pre-commit auto-update</span>
<span>on</span><span>:</span>
<span>schedule</span><span>:</span>
<span>-</span> <span>cron</span><span>:</span> <span>'</span><span>0</span><span> </span><span>0</span><span> </span><span>*</span><span> </span><span>*</span><span> </span><span>*'</span>
<span>jobs</span><span>:</span>
<span>auto-update</span><span>:</span>
<span>runs-on</span><span>:</span> <span>ubuntu-latest</span>
<span>steps</span><span>:</span>
<span>-</span> <span>uses</span><span>:</span> <span>actions/checkout@v2</span>
<span>-</span> <span>name</span><span>:</span> <span>Set up Python</span>
<span>uses</span><span>:</span> <span>actions/setup-python@v2</span>
<span>with</span><span>:</span>
<span>python-version</span><span>:</span> <span>3.8</span>
<span>-</span> <span>name</span><span>:</span> <span>Install pre-commit</span>
<span>run</span><span>:</span> <span>pip install pre-commit</span>
<span>-</span> <span>name</span><span>:</span> <span>Run pre-commit autoupdate</span>
<span>run</span><span>:</span> <span>pre-commit autoupdate</span>
<span>-</span> <span>name</span><span>:</span> <span>Create Pull Request</span>
<span>uses</span><span>:</span> <span>peter-evans/create-pull-request@v2</span>
<span>with</span><span>:</span>
<span>token</span><span>:</span> <span>${{ secrets.CPR_GITHUB_TOKEN }}</span>
<span>branch</span><span>:</span> <span>update/pre-commit-autoupdate</span>
<span>title</span><span>:</span> <span>Auto-update pre-commit hooks</span>
<span>commit-message</span><span>:</span> <span>Auto-update pre-commit hooks</span>
<span>body</span><span>:</span> <span>|</span>
<span>Update versions of tools in pre-commit </span>
<span>configs to latest version</span>
<span>labels</span><span>:</span> <span>dependencies</span>
<span>name</span><span>:</span> <span>Pre-commit auto-update</span>

<span>on</span><span>:</span>
  <span>schedule</span><span>:</span>
    <span>-</span> <span>cron</span><span>:</span> <span>'</span><span>0</span><span> </span><span>0</span><span> </span><span>*</span><span> </span><span>*</span><span> </span><span>*'</span>

<span>jobs</span><span>:</span>
  <span>auto-update</span><span>:</span>
    <span>runs-on</span><span>:</span> <span>ubuntu-latest</span>
    <span>steps</span><span>:</span>
      <span>-</span> <span>uses</span><span>:</span> <span>actions/checkout@v2</span>

      <span>-</span> <span>name</span><span>:</span> <span>Set up Python</span>
        <span>uses</span><span>:</span> <span>actions/setup-python@v2</span>
        <span>with</span><span>:</span>
          <span>python-version</span><span>:</span> <span>3.8</span>

      <span>-</span> <span>name</span><span>:</span> <span>Install pre-commit</span>
        <span>run</span><span>:</span> <span>pip install pre-commit</span>

      <span>-</span> <span>name</span><span>:</span> <span>Run pre-commit autoupdate</span>
        <span>run</span><span>:</span> <span>pre-commit autoupdate</span>

      <span>-</span> <span>name</span><span>:</span> <span>Create Pull Request</span>
        <span>uses</span><span>:</span> <span>peter-evans/create-pull-request@v2</span>
        <span>with</span><span>:</span>
          <span>token</span><span>:</span> <span>${{ secrets.CPR_GITHUB_TOKEN }}</span>
          <span>branch</span><span>:</span> <span>update/pre-commit-autoupdate</span>
          <span>title</span><span>:</span> <span>Auto-update pre-commit hooks</span>
          <span>commit-message</span><span>:</span> <span>Auto-update pre-commit hooks</span>
          <span>body</span><span>:</span> <span>|</span>
            <span>Update versions of tools in pre-commit </span>
            <span>configs to latest version</span>
          <span>labels</span><span>:</span> <span>dependencies</span>
name: Pre-commit auto-update on: schedule: - cron: '0 0 * * *' jobs: auto-update: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: 3.8 - name: Install pre-commit run: pip install pre-commit - name: Run pre-commit autoupdate run: pre-commit autoupdate - name: Create Pull Request uses: peter-evans/create-pull-request@v2 with: token: ${{ secrets.CPR_GITHUB_TOKEN }} branch: update/pre-commit-autoupdate title: Auto-update pre-commit hooks commit-message: Auto-update pre-commit hooks body: | Update versions of tools in pre-commit configs to latest version labels: dependencies

Enter fullscreen mode Exit fullscreen mode

This workflow is scheduled every day at midnight, runs pre-commit autoupdate and sends a pull request if there are any changes.

The piece that required a bit of fiddling is the action creating the pull request, partly to get commit message, title, content and labels right, but mostly because I initially used secrets.GITHUB_TOKEN as token, but it wouldn’t trigger the CI build for that pull request.

It’s a limitation which is well documented on the action’s README, and is intentional from Github. I chose the solution to create a PAT scoped to repo and added it to the secrets as CPR_GITHUB_TOKEN. It’s deployed and running on the repo of django-codemod.

The pull request action has fixed inputs, so it will create one pull request at a time for all updates. If several tools get a new version, they would all be updated at once, and if a pull request already exists, it would receive more updates. This is not necessarily a bad thing, but if one tool breaks the build due to new linting rules, all are stuck.

Maybe I’ll look into making the pull request content a bit more dynamic, but for now it does the job I need to. I’m also planning to add this to my Cookiecutter template for Python package, so I can get it for all my new projects.

I hope this can help folks keep their pre-commit hook up to date, maybe this will become obsolete when pre-commit CI is ready, or maybe it will be a cheaper and simpler alternative

原文链接:Auto-update pre-commit hooks with GitHub Actions

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
Seeing your adorable smile is the absolute best part of my day.
看见你可爱的笑容绝对是我一天中最美好的事
评论 抢沙发

请登录后发表评论

    暂无评论内容