How to automate code formatting for Python projects with GitHub Actions - A study

mritunjay394

Mritunjay Sharma

Posted on September 8, 2020

How to automate code formatting for Python projects with GitHub Actions - A study

This is a beginner-friendly post that will tell you how easy it will become to conform to Python coding styles using autoyapf GitHub Action in your Python projects!

Introduction

To begin with - let's discuss first what are GitHub Actions and what magic they bring πŸ˜ƒ?

GitHub Actions

GitHub Actions is that piece of magic which enables you to automate, customize, and execute your software development workflows right in your repository.

But hey? What are words without actions? And so what are actions without workflows? Yes, you got it right! For GitHub Actions to work you need to use Workflows but what are Workflows?
A workflow is a configurable automated process made up of one or more jobs. Now, these jobs can be like the accounting of the trigger for the GitHub action to work - like push on the main branch.

Workflow files use YAML syntax and must have either a .yml or .yaml file extension.

For GitHub Actions to work you must store workflow files in the .github/workflows directory of your repository.

Brief Introduction to building a GitHub Action

Note: In order to use an existing GitHub action all you require is just a Workflow YAML file in .github/workflows. The files mentioned in this part of the blog are required when you start building your own GitHub Actions πŸ˜„

In order to make almost any GitHub Action - you require at least these files:

  • Dockerfile β€” GitHub actions are of three types - Docker actions, Javascript actions and composite run steps action. In our case- we are going to use Docker Action and so Dockerfile is used to define the container environment that runs the action.

  • action.yml β€” This will define inputs, outputs, Entrypoint for our action, and other details like name of the action, description, author name, etc.

  • script β€” An action might require a script to perform a task, in our case we just need an Entrypoint script named as entrypoint.sh

  • README.md β€” This is optional, but if we want to publish our action on the Marketplace we need it. README.md file is useful to provide examples that are needed for the action to run without any hassles.

This is the basic skeleton of how the GitHub actions are built. If you want to start with making your own first action, check out this official Hello World tutorial

Let's move on to the main part of preparing and setting up the workflow for the autoyapf GitHub Action we are going to use.

What is autoyapf?

autoyapf is a GitHub action for yapf, an open-source tool that automatically formats Python code to conform to the PEP 8 style guide. It is in essence, the algorithm that takes the code and reformats it to the best formatting that conforms to the style guide, even if the original code didn't violate the style guide.

This action is designed to be used in conjunction with the 'push' trigger. In simple words - everytime the maintainer pushes the code from their own playground or merges a Pull Request from a contributor it will be formatted automatically with the PEP 8 Style guidelines using the yapf tool. This action is a win-win situation for both contributors and maintainers of projects involving Python!

Choosing the Project

The first step is always choosing the repository where you will be using the GitHub action.
Since the GitHub action is made for python projects, I am going to use an open-source Python project that I created recently called sedpy

GitHub logo mritunjaysharma394 / sedpy

Building a cross-platform alternative of sed (stream editor)

sedpy


Sedpy Logo

Build Status CodeFactor Maintenance GitHub issues GitHub forks GitHub stars [PythonVersion

sedpy is an open-source project being built as a cross-platform alternative of sed for easier and more flexible stream line editing across BSD and GNU systems.

What is sed and what is sedpy?

The sed command, short for stream editor, performs editing operations on text coming from standard input or a file. sed edits line-by-line and in a non-interactive way.

This means that you make all of the editing decisions as you are calling the command, and sed executes the directions automatically. This may seem confusing or unintuitive, but it is a very powerful and fast way to transform text, especially as part of a script or automated workflow.

The problem with sed is that it's not purely cross-platform. Linux uses GNU-based sed while macOS has the BSD version of sed.As a result - both have quite important syntactic and usage difference. At the same time, sed…

Preparing the Workflow

  • We'll go to our repository and click on the Actions tab. That will then reflect an option like set up a workflow yourself. Click it.

Actions Tab

This will create a YAML file in the path:
.github/workflows/main.yml

You can rename the file to whatever you prefer like, in this case, I will give it the name autoyapf.yml instead of main.yml.

Now, let's dive in the autoyapf.yml file:

name: Formatting python code
on:
  push:
    paths:
    - '**.py'
Enter fullscreen mode Exit fullscreen mode

What we have done until here is:

  • Given a name to the workflow: Formatting python code
  • Defined what event will cause the workflow to trigger. In this case, it is triggered when the python file is pushed in the repository.

Next step is to define the jobs, further, we added:

jobs:
  autoyapf:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
        with:
          ref: ${{ github.head_ref }}
      - name: autoyapf
        id: autoyapf
        uses: mritunjaysharma394/autoyapf@v2
        with:
          args: --style pep8 --recursive --in-place .
      - name: Check for modified files
        id: git-check
        run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi)
      - name: Push changes
        if: steps.git-check.outputs.modified == 'true'
        run: |
          git config --global user.name 'Mritunjay Sharma'
          git config --global user.email 'mritunjaysharma394@users.noreply.github.com'
          git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
          git commit -am "Automated autoyapf fixes"
          git push
Enter fullscreen mode Exit fullscreen mode

Here's a brief detail about almost everything the above snippet does:

  • The jobs that the workflow has to perform will run on the GitHub hosted runner which is ubuntu-latest in our case.
jobs:
  autoyapf:
    runs-on: ubuntu-latest
Enter fullscreen mode Exit fullscreen mode
  • We define the steps of jobs next.
    • The first step checks out the repository where we want to workflow to execute. Since I am using it inside sedpy, it will check out this repository's master branch
steps:
      - uses: actions/checkout@master
        with:
          ref: ${{ github.head_ref }}
Enter fullscreen mode Exit fullscreen mode
  • In the next step - we checked out the GitHub action autoyapf which will perform all the formatting using yapf tool with the arguments supplied as: args: --style pep8 --recursive --in-place .
- name: autoyapf
        id: autoyapf
        uses: mritunjaysharma394/autoyapf@v2
        with:
          args: --style pep8 --recursive --in-place .
Enter fullscreen mode Exit fullscreen mode
  • This step checks if the above step has made any changes in the code. If it has made any changes then the next step will push the changes to the sedpy repository.
- name: Check for modified files
        id: git-check
        run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi)
Enter fullscreen mode Exit fullscreen mode
  • This will check the condition as detailed above and we will push the changes using run utility that makes us use terminal-like commands in the .yml files.
      - name: Push changes
        if: steps.git-check.outputs.modified == 'true'
        run: |
          git config --global user.name 'Mritunjay Sharma'
          git config --global user.email 'mritunjaysharma394@users.noreply.github.com'
          git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
          git commit -am "Automated autoyapf fixes"
          git push
Enter fullscreen mode Exit fullscreen mode

Woohoo! πŸ’ƒ We have completed our workflow autoyapf.yml and the complete file looks something like this:


name: Formatting python code
on:
  push:
    paths:
    - '**.py'
jobs:
  autoyapf:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
        with:
          ref: ${{ github.head_ref }}
      - name: autoyapf
        id: autoyapf
        uses: mritunjaysharma394/autoyapf@v2
        with:
          args: --style pep8 --recursive --in-place .
      - name: Check for modified files
        id: git-check
        run: echo ::set-output name=modified::$(if git diff-index --quiet HEAD --; then echo "false"; else echo "true"; fi)
      - name: Push changes
        if: steps.git-check.outputs.modified == 'true'
        run: |
          git config --global user.name 'Mritunjay Sharma'
          git config --global user.email 'mritunjaysharma394@users.noreply.github.com'
          git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
          git commit -am "Automated autoyapf fixes"
          git push
Enter fullscreen mode Exit fullscreen mode

See the below working example to see this GitHub action in action

If you have liked this action, please feel free to leave a star and yes it will be a blessing if you can contribute to it as well! Link below:

GitHub logo mritunjaysharma394 / autoyapf

Automating yapf formatting.

autoyapf

GitHub Marketplace Open Source Love

Worried whether your Python code is following the style guidelines or not? Well, you don't need to do that now πŸ˜„

autoyapf is a GitHub action for yapf, an open-source tool that automatically formats Python code to conform to the PEP 8 style guide It is in essence, the algorithm that takes the code and reformats it to the best formatting that conforms to the style guide, even if the original code didn't violate the style guide.

This action is designed to be used in conjunction with the 'push' trigger. In simple words - everytime the maintainer pushes the code from their own playground or merges a Pull Request from a contributor it will be formatted automatically with the PEP 8 Style guidelines using the yapf tool. This action is a win-win situation for both contributors and maintainers of projects involving Python! Yes, you heard it right!

This…






I hope this blog helped you how to start with creating workflows for GitHub actions (in our case: autoyapf) and you have learned something amazing! If you have doubts, suggestions or feedbacks, please feel free to ping me here:https://twitter.com/mritunjay394 !

Thank you so much for taking out time to read this blog! Sending you all the good vibes ✨

πŸ’– πŸ’ͺ πŸ™… 🚩
mritunjay394
Mritunjay Sharma

Posted on September 8, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related