<?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: Ron Powell</title>
    <description>The latest articles on DEV Community by Ron Powell (@ronpowelljr).</description>
    <link>https://dev.to/ronpowelljr</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%2F50341%2Fc9c8f468-6673-4993-b84e-1ebf298e58d1.jpeg</url>
      <title>DEV Community: Ron Powell</title>
      <link>https://dev.to/ronpowelljr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ronpowelljr"/>
    <language>en</language>
    <item>
      <title>Setting up continuous integration with GitHub</title>
      <dc:creator>Ron Powell</dc:creator>
      <pubDate>Mon, 17 Sep 2018 19:48:00 +0000</pubDate>
      <link>https://dev.to/ronpowelljr/setting-up-continuous-integration-with-github-2apd</link>
      <guid>https://dev.to/ronpowelljr/setting-up-continuous-integration-with-github-2apd</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally posted on CircleCI's &lt;a href="https://circleci.com/blog/setting-up-continuous-integration-with-github/"&gt;blog&lt;/a&gt; by Stanley Ndagi&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://circleci.com/continuous-integration/"&gt;Continuous Integration (CI)&lt;/a&gt; involves the test automation of feature branches before they are merged to the main Git branch in a project. This ensures that a codebase does not get updated with changes that could break something. Continuous Delivery (CD), on the other hand, builds upon CI by automating releases of these branches and/or the main branch. This allows small incremental updates to reach your users faster, in line with Agile software development philosophy.&lt;/p&gt;

&lt;p&gt;In this article, I will take you through setting up CI with GitHub. We will use a Python application to demonstrate our CI pipeline.&lt;/p&gt;

&lt;p&gt;Here are the steps we will take:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a simple Python application (with Flask)&lt;/li&gt;
&lt;li&gt;Create tests for this app&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;config.yml&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Push to GitHub&lt;/li&gt;
&lt;li&gt;Configure CircleCI&lt;/li&gt;
&lt;li&gt;Update our &lt;code&gt;README&lt;/code&gt; with a badge&lt;/li&gt;
&lt;li&gt;Create a PR and see CircleCI in action&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Creating a simple Python app
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Prerequisites
&lt;/h4&gt;

&lt;p&gt;If you don’t have Python installed, follow the instructions &lt;a href="https://www.python.org/downloads/"&gt;here&lt;/a&gt; for your local system. The Python installation comes with &lt;code&gt;pip&lt;/code&gt; (The PyPA recommended tool for installing Python packages).&lt;/p&gt;

&lt;h4&gt;
  
  
  Building the app
&lt;/h4&gt;

&lt;p&gt;For simplicity, in terms of fewest lines of code, we will create a Flask application. Flask is a microframework for Python. For our exercise, little knowledge of the framework is necessary. We’ll use the example found &lt;a href="http://flask.pocoo.org/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, create a project directory (folder) and &lt;code&gt;cd&lt;/code&gt; into it. Type this into Terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;python_app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, open your favorite editor and create a &lt;code&gt;hello.py&lt;/code&gt; file. Then, copy the following lines into that file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello World!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Virtual environments in Python
&lt;/h4&gt;

&lt;p&gt;When working in Python, it is strongly advised that you use a virtual environment. This allows you to install Python packages in an abstracted environment that is not your entire local machine. Some common ways to do this are to use &lt;a href="https://virtualenv.pypa.io/en/stable/"&gt;&lt;code&gt;virtualenv&lt;/code&gt;&lt;/a&gt; or, even better, &lt;a href="http://virtualenvwrapper.readthedocs.io/en/latest/"&gt;&lt;code&gt;virtualenvwrapper&lt;/code&gt;&lt;/a&gt;. We’ll use the module &lt;code&gt;venv&lt;/code&gt; that comes as a part of Python3. This is how it’s done:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create the virtual environment:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Note that we can use other names for our virtual environment, like in the next example.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv Env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Activate this environment:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Replace &lt;em&gt;venv&lt;/em&gt; if you used another name for the environment)&lt;/p&gt;

&lt;p&gt;You will notice &lt;code&gt;(venv)&lt;/code&gt; just before the shell prompt telling you that the virtual environment is active. Any Python package that is installed will be installed within this environment. To deactivate this environment simply run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;deactivate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Running the app
&lt;/h4&gt;

&lt;p&gt;Now, let’s create a &lt;code&gt;requirements.txt&lt;/code&gt; file in our editor. Add the word &lt;code&gt;Flask&lt;/code&gt; to the file and save it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Flask




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

&lt;/div&gt;



&lt;p&gt;Then, within the virtual environment, install the package by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final command to run this application is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;FLASK_APP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;hello.py flask run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see the application running on your browser at &lt;a href="http://localhost:5000/"&gt;http://localhost:5000/&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests
&lt;/h2&gt;

&lt;p&gt;In your editor, create a &lt;code&gt;tests.py&lt;/code&gt; file and paste these lines into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;hello&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s"&gt;'Hello World!'&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please see these references for more information on tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://flask.pocoo.org/docs/1.0/testing/"&gt;http://flask.pocoo.org/docs/1.0/testing/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://damyanon.net/post/flask-series-testing/"&gt;https://damyanon.net/post/flask-series-testing/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let’s run our test. Open Terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 tests.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing should be returned to our Terminal. Why? The reason is that we structured our Flask app so that it does not output to Terminal on a pass. This means that our tests are passing. The resources mentioned above give better examples of Terminal UX (user experience) on tests passing and failing, but this will suffice for our case.&lt;/p&gt;

&lt;h2&gt;
  
  
  CircleCI config file
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;.circleci&lt;/code&gt; folder and inside of that create a &lt;a href="https://circleci.com/docs/2.0/sample-config/"&gt;&lt;code&gt;config.yml&lt;/code&gt;&lt;/a&gt; file. Then, copy these lines into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&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;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;circleci/python:3.6&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="s"&gt;checkout&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;restore_cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deps1-{{ .Branch }}-{{ checksum "requirements.txt" }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;python3 -m venv venv&lt;/span&gt;
            &lt;span class="s"&gt;. venv/bin/activate&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;save_cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deps1-{{ .Branch }}-{{ checksum "requirements.txt" }}&lt;/span&gt;
          &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;venv"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&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;Running tests&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;. venv/bin/activate&lt;/span&gt;
            &lt;span class="s"&gt;python3 tests.py&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;store_artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test-reports/&lt;/span&gt;
          &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python_app&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more information regarding this &lt;code&gt;config&lt;/code&gt; file, see: &lt;a href="https://circleci.com/docs/2.0/language-python/"&gt;https://circleci.com/docs/2.0/language-python/&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pushing to GitHub
&lt;/h2&gt;

&lt;p&gt;We should have initialized Git earlier and had atomic commits (the philosophy of committing your code early and often). However, since this tutorial is about integration of CircleCI and GitHub, I intentionally put it on hold until now.&lt;/p&gt;

&lt;p&gt;Our current code structure looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mql13FWZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/oicdlnc7jv92m3u3rocv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mql13FWZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/oicdlnc7jv92m3u3rocv.png" alt="2018-09-11-Stanley01.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open your editor and create a &lt;code&gt;.gitignore&lt;/code&gt; file in the working directory to state which files and folders that we &lt;em&gt;don’t&lt;/em&gt; want to commit to Git. Copy the following lines into that file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

# Virtualenv
venv/*

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

&lt;/div&gt;



&lt;p&gt;We are now going to commit our code by running the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Initial commit"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to &lt;a href="https://github.com"&gt;https://github.com&lt;/a&gt; and create a GitHub account, if you don’t already have one. Then, create a repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CW9q8qNd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cokim8dy78eet3ejzp0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CW9q8qNd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cokim8dy78eet3ejzp0g.png" alt="2018-09-11-Stanley02.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BuVmRFeq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/rw9mlh7qgc8fbggkn8r9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BuVmRFeq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/rw9mlh7qgc8fbggkn8r9.png" alt="2018-09-11-Stanley03.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After creating your new repository, you will get to a page like this one:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5ED2IDaS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/i36fkx81mia51u3w2bx8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5ED2IDaS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/i36fkx81mia51u3w2bx8.png" alt="2018-09-11-Stanley04.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’ll go with the second option, &lt;strong&gt;…push an existing repository&lt;/strong&gt;. Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote add origin https://github.com/NdagiStanley/python_app.git
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring CircleCI
&lt;/h2&gt;

&lt;p&gt;Now that the repo is on GitHub, we can finalize the CI by configuring CircleCI.&lt;/p&gt;

&lt;p&gt;Head on over to &lt;a href="https://circleci.com/"&gt;https://circleci.com/&lt;/a&gt;. Then click &lt;strong&gt;Sign Up&lt;/strong&gt; at the top right.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1dDxEtQn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/djn0jkk1dt7gghfwcjwx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1dDxEtQn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/djn0jkk1dt7gghfwcjwx.png" alt="2018-09-11-Stanley05.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sign up for CircleCI with your GitHub account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2P8IvOkI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kx77jzo1rkyxronku8bo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2P8IvOkI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kx77jzo1rkyxronku8bo.png" alt="2018-09-11-Stanley06.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you are logged in, ensure that your personal GitHub account is active. If you are in several GitHub organizations, one of them might be active. Just click the drop down menu (top left) and select your GitHub username. Then, click &lt;strong&gt;Add Projects&lt;/strong&gt;. The most recent project, ‘python_app’, appears there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KqrY2sBV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/uuief10r77yulxmslqa7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KqrY2sBV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/uuief10r77yulxmslqa7.png" alt="2018-09-11-Stanley07.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Set up Project&lt;/strong&gt; at the right side of the row that includes our project. On the redirected page, you’ll notice the &lt;strong&gt;Next Steps&lt;/strong&gt; section. Had we not had our own &lt;code&gt;.circleci/config.yml&lt;/code&gt; file, we would have started at &lt;strong&gt;No. 1&lt;/strong&gt;. We just need to scroll to &lt;strong&gt;No. 5&lt;/strong&gt; and click &lt;strong&gt;Start building&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---u43UY4H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ygu0aifdhfybsgxukele.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---u43UY4H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ygu0aifdhfybsgxukele.png" alt="2018-09-11-Stanley08.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Within no time, the build passes. It's successful!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UI-uxTET--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/uajmhch8kz9iek5g0l10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UI-uxTET--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/uajmhch8kz9iek5g0l10.png" alt="2018-09-11-Stanley09.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the top right corner, click the &lt;strong&gt;Settings&lt;/strong&gt; cog. Then click &lt;strong&gt;Projects&lt;/strong&gt; on the left, and finally, &lt;strong&gt;python_app&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PPJaAWjM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9nm8siqv4s1zezca5q7n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PPJaAWjM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9nm8siqv4s1zezca5q7n.png" alt="2018-09-11-Stanley10.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will be on a path like this one: &lt;code&gt;circleci.com/gh/&amp;lt;username&amp;gt;/python_app&lt;/code&gt;. Mine is &lt;code&gt;https://circleci.com/gh/NdagiStanley/python_app&lt;/code&gt;. Click the &lt;strong&gt;settings&lt;/strong&gt; cog next to the repo name: &lt;strong&gt;python_app&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tre3KU2n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cmskp3k9ugp10rt75rjv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tre3KU2n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cmskp3k9ugp10rt75rjv.png" alt="2018-09-11-Stanley11.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is important that you to become familiar with the settings that you can change for this project. I will touch on what is relevant to us now. &lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Advanced Settings&lt;/strong&gt;, notice that &lt;strong&gt;Only build pull requests&lt;/strong&gt; is turned off. This means that every push to GitHub will run on CircleCI, including PRs.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Chat Notifications&lt;/strong&gt;, notice that you can configure your Slack, HipChat, FlowDock, Campfire and IRC to be notified on every build. For Slack, &lt;a href="https://circleci.com/blog/slack-integration/"&gt;this&lt;/a&gt; resource is handy.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;&lt;a href="https://circleci.com/docs/1.0/status-badges/"&gt;Status Badges&lt;/a&gt;&lt;/strong&gt;, notice the Markdown embed code. We will copy this code to paste into our README.&lt;/p&gt;

&lt;h2&gt;
  
  
  ReadME - status badge
&lt;/h2&gt;

&lt;p&gt;On our local machine, checkout to another Git branch by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; add_readme
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open your editor and create a &lt;code&gt;README.md&lt;/code&gt; file. Copy and paste the following lines into this file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;README.md
# PYTHON APPLICATION
This Python application repo was created to showcase the integration between GitHub and CircleCI.
[![CircleCI](https://circleci.com/gh/NdagiStanley/python_app.svg?style=svg)](https://circleci.com/gh/NdagiStanley/python_app)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I added a title and a brief description to mine.&lt;/p&gt;

&lt;p&gt;Now, run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add README"&lt;/span&gt;
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin add_readme
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you go to &lt;a href="https://github.com/"&gt;https://github.com/&lt;/a&gt;/python_app you will notice that we have a new branch: &lt;code&gt;add_readme&lt;/code&gt;. We can go ahead and click &lt;strong&gt;Compare and pull request&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C1W8oUYB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wd4ab4pavrn86s1bms45.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C1W8oUYB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wd4ab4pavrn86s1bms45.png" alt="2018-09-11-Stanley12.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Opening a pull request
&lt;/h2&gt;

&lt;p&gt;This is how I set up my PR:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P8_R-2Fv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vgozvrujkiaro78dohf6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P8_R-2Fv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vgozvrujkiaro78dohf6.png" alt="2018-09-11-Stanley13.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Create pull request&lt;/strong&gt; and in no time, this is what we get:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Asu7CnFH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/j3ybpqysy55kja7vc7so.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Asu7CnFH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/j3ybpqysy55kja7vc7so.png" alt="2018-09-11-Stanley14.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A successful build! Now, click &lt;strong&gt;Show all checks&lt;/strong&gt;. You will see that the check is from CircleCI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hHISsnrq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7jbfdi45kd2oe9wm9w9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hHISsnrq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7jbfdi45kd2oe9wm9w9v.png" alt="2018-09-11-Stanley15.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even the browser’s tab favicon shows a tick for the successful run: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iv2AN-7j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qaa44wp3hqpe0p2bnii7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iv2AN-7j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qaa44wp3hqpe0p2bnii7.png" alt="2018-09-11-Stanley16.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click &lt;strong&gt;Details&lt;/strong&gt;, this will redirect you to the build on CircleCI:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KWTonCby--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5l8z4xacmt6pfivn8sr6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KWTonCby--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5l8z4xacmt6pfivn8sr6.png" alt="2018-09-11-Stanley17.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that the favicon here also shows that the build is successful:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qpE84G09--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4759lygr9oto3q3yns7p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qpE84G09--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/4759lygr9oto3q3yns7p.png" alt="2018-09-11-Stanley18.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the top, click &lt;strong&gt;python_app&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uc1LKXTU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/f27khgbq24zjvkesa4qb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uc1LKXTU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/f27khgbq24zjvkesa4qb.png" alt="2018-09-11-Stanley19.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You are redirected to the builds for this project:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iMxh5olQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/rz51hdmxetkpbbxp34fz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iMxh5olQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/rz51hdmxetkpbbxp34fz.png" alt="2018-09-11-Stanley20.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;And there you have it! We have integrated GitHub with CircleCI. In summary, we set up a Python application and created tests for it. We then created a CircleCI config file and pushed the codebase to GitHub. Finally, we connected the GitHub repository we created to CircleCI.&lt;/p&gt;

&lt;p&gt;If you followed through successfully, you can now set up your own project in GitHub and configure CI builds on CircleCI. The following links point to my references while writing this article.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://circleci.com/docs/2.0/configuration-reference/#full-example"&gt;https://circleci.com/docs/2.0/configuration-reference/#full-example&lt;/a&gt;&lt;br&gt;
&lt;a href="http://flask.pocoo.org/"&gt;http://flask.pocoo.org/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://circleci.com/docs/2.0/configuration-reference/"&gt;https://circleci.com/docs/2.0/configuration-reference/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;i&gt;About Stanley: From a young age, Stanley tinkered with electronics and building things with tech. Now, he’s an engineer at Andela and his work involves data, the web, and IoT. Stemming from his lifelong love of DIY, he’s on a personal journey of invoking the builder within and teaching others along the way. He cares about how technology affects society and seeks collaborations with others who are working to create positive impact.&lt;/i&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>github</category>
      <category>circleci</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
