<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ricardo Baltazar Chaves</title>
    <description>The latest articles on DEV Community by Ricardo Baltazar Chaves (@ricardochaves).</description>
    <link>https://dev.to/ricardochaves</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F271854%2F0d7f553e-9a7b-4bb5-beb3-43dd74b748c4.jpeg</url>
      <title>DEV Community: Ricardo Baltazar Chaves</title>
      <link>https://dev.to/ricardochaves</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ricardochaves"/>
    <language>en</language>
    <item>
      <title>Python Lint with GitHub Actions</title>
      <dc:creator>Ricardo Baltazar Chaves</dc:creator>
      <pubDate>Mon, 02 Dec 2019 21:46:34 +0000</pubDate>
      <link>https://dev.to/ricardochaves/python-lint-with-github-actions-2i7p</link>
      <guid>https://dev.to/ricardochaves/python-lint-with-github-actions-2i7p</guid>
      <description>&lt;p&gt;There are a lot of ways to control the code quality, you have an option to put a hook on save file event and then apply black, isort, pylint or mypy, you can use a pre-commit on git to validate or fix the file on the fly too.&lt;/p&gt;

&lt;p&gt;The problem is: it is very hard to maintain all your develop team  having all of this configured. This will create the following situation: You get a task, change the code and put the famous if, simple thing, two lines of code, but when you apply your lint you change all the file. It happens because the guy who changed the file before you did not apply the lint and the last PR reviewer didn’t see the missing lint.&lt;/p&gt;

&lt;p&gt;Now you have to open a PR with a lot of lints changes, your PR is more complex now.&lt;/p&gt;

&lt;p&gt;You can solve this by creating a GitHub Action that triggers for all PRs and after that you apply the lints which you think necessary.&lt;/p&gt;

&lt;p&gt;Let's create an Action to apply the following libs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/psf/black"&gt;black&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pylint.org/"&gt;pylint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/timothycrosley/isort"&gt;isort&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pycodestyle.readthedocs.io"&gt;pycodestyle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://flake8.pycqa.org"&gt;flake8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mypy-lang.org/"&gt;mypy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you use a GitHub suggestion, which is used for preparing the pipe for Python, to install and to execute every lib, it will be more or less like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Python application&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v1&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Python &lt;/span&gt;&lt;span class="m"&gt;3.7&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-python@v1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3.7&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;python -m pip install --upgrade pip&lt;/span&gt;
        &lt;span class="s"&gt;pip install -r requirements.txt&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lint with flake8&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;pip install flake8&lt;/span&gt;
        &lt;span class="s"&gt;# stop the build if there are Python syntax errors or undefined names&lt;/span&gt;
        &lt;span class="s"&gt;flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics&lt;/span&gt;
        &lt;span class="s"&gt;# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide&lt;/span&gt;
        &lt;span class="s"&gt;flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lint with pylint&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;pip install pylint&lt;/span&gt;
        &lt;span class="s"&gt;pylint .&lt;/span&gt;
        &lt;span class="s"&gt;...&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lint with black&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;pip install black&lt;/span&gt;
        &lt;span class="s"&gt;black .&lt;/span&gt;
        &lt;span class="s"&gt;...&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lint with isort&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;pip install isort&lt;/span&gt;
        &lt;span class="s"&gt;isort .&lt;/span&gt;
        &lt;span class="s"&gt;...&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lint with pycodestyle&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;pip install pycodestyle&lt;/span&gt;
        &lt;span class="s"&gt;pycodestyle .&lt;/span&gt;
        &lt;span class="s"&gt;...&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lint with mypy&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;pip install mypy&lt;/span&gt;
        &lt;span class="s"&gt;mypy .&lt;/span&gt;
        &lt;span class="s"&gt;...&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This was my first try, when I understood that I would need to create all the configuration for every microservice project, I realized that I would need to create my own action to abstract all those things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;To you apply the lint today, just use this action: &lt;a href="https://github.com/ricardochaves/python-lint"&gt;python-lint&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On your project root dir, create a directory with the name .github, inside this create another directory with the name workflow and inside this last one create one file with the name lint.yml (you can use any name here), with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Python Lint&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;lint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v1&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ricardochaves/python-lint@test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; - Just the action name in your project&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;on&lt;/code&gt; - A list with all events that will trigger your action.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;runs-on&lt;/code&gt; - It's the image where your job will run&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;steps&lt;/code&gt; - It is what the job will execute. Here we will execute two steps, one for checkout your code and the other to apply the lint&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Options
&lt;/h3&gt;

&lt;p&gt;There are some options to use with this action&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ricardochaves/python-lint@test&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;python-root-list&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;python_alelo&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tests'&lt;/span&gt;
        &lt;span class="na"&gt;use-pylint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
        &lt;span class="na"&gt;use-pycodestyle&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
        &lt;span class="na"&gt;use-flake8&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
        &lt;span class="na"&gt;use-black&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
        &lt;span class="na"&gt;use-mypy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
        &lt;span class="na"&gt;use-isort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can pass a list with all directories where the files need to be tested and you can disable each lib.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real World
&lt;/h2&gt;

&lt;p&gt;Check &lt;a href="https://github.com/ricardochaves/python-alelo/blob/master/.github/workflows/lint.yml"&gt;python-alelo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>github</category>
      <category>pylint</category>
      <category>mypy</category>
    </item>
  </channel>
</rss>
