This project demonstrates use of Continuous Integration (CI) to build and test a Python project. Some CI services you can use are Github Actions, Circle-CI, and Travis-CI. Travis-CI is no longer free, except for a trial period. Github is the simplest choice for Github projects.
To use any CI service, you create a “script” of instructions for the CI server. You also define the “events” which should cause the script to execute, such as every time a commit is made on the master branch.
Finally, you need to give the CI server access to your repository and define a “hook” to notify the CI server when an event occurs (such as a commit). If using Github Actions, this step isn’t needed.
What you will do is:
- Create a git repository containing some code and tests
- Run the tests. Some test will fail. That’s OK (don’t fix it).
- Create a Github repo and push your local repo to Github
- Create a Github Action to run flake8 and unit tests
- View the build results and fix problems
- Add a Github “Badge” to your project README.md
Create & Run a Github Action for a Sample Code (demo-pyci)
-
Download the
demo-pyci.zip
using a link on the Google Classroom coursework page. -
Create your own Python project using the ZIP file.
- Change to a directory where you store projects (not inside another git repo) and unpack the zip file.
- Unzip will create a
demo-pyci
directory containing these files:demo-pyci/ README.md statistics.py test_statistics.py
INCORRECT: Your repo should not have an extra layer of directories.
This is wrong:demo-pyci/ demo-pyci/ README.md ...
- Run the unit tests locally. One test should fail.
- This is expected.
- Please do not fix the defect. We want to see if Github reports it.
- In the
demo-pyci
directory do this:- create a git repository
- add a .gitignore file for Python projects. By now, you probably have your own .gitignore for Python projects. Your .gitignore should include
__pycache__
and.coverage
. - add all files to the git repository, including .gitignore
- commit everything to your git repo
-
Create a public
demo-pyci
repository on Github. Push your local git repo to Github. -
Add a Github Action: On Github, select the Actions tab. Read the suggested choices for actions.
-
Select the “Python Application” Action, and click “Configure”.
- The “Configure” dialog lets you edit a
.yml
configuration file.- make some changes, such as change Python 3.10 to 3.9
- change the action name (this name is shown on the “badge” so it should be descriptive)
name: Unit Tests
- don’t install pytest (pip install pytest) since the tests use unittest
-
Change the unit test command from “pytest” to unittest:
- name: Test with unittest run: | python -m unittest
-
Write a commit message and commit these changes to the
.yml
file. - Wait a few seconds for the Action to run and look at the results. (You did this in Programming 2.)
- It should show that flake8 failed due a missing import of
sqrt
.
- It should show that flake8 failed due a missing import of
- In your local repo, “pull” changes from Github in order to get the
.github
directory containing your Action script.- if you don’t do this, you won’t be able to “push” any work to Github because the Github repo is “ahead” of your local repo by 1 commit.
- instead of “pull” you can use “fetch” and “merge”. There should not be any conflicts.
- Fix the code: add the missing import to
statistics.py
.from math import sqrt
- commit the fix and push to Github
-
Watch Github re-run your Action.
- Add a Github Badge to README.md.
- See https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/adding-a-workflow-status-badge
- In README.md, use Markdown for adding an image:

- Badges are added after the header line and before the first paragraph.
- You can use any descriptive text instead of “Unittest Workflow”.
Add Code Coverage and Codecov.io
Codecov.io provides useful online visualization and detailed reports of test code coverage. It uses data from the Python coverage
command (same command you run on your own computer).
The idea is this:
- Create an account on Codecov.io using your Github login for authentication
- Configure Codecov to access your Github repository. This involves granting Codecov.io some permissions.
- Define a Github Action to run
coverage
and then upload the report to Codecov.io. Either:- create a new Github Action (Instructions on Codecov), or
- add steps to an existing Github Action. Since you already run tests in a Github Action, this is easiest and efficient.
Suppose you choose to add coverage to the Github Action you already have. You need to make a few changes to the .yml
file for that Action:
- install the
coverage
package usingpip
- in your “Run tests” step, change
python -m unittest
tocoverage run -m unittest
- create an XML report for Codecov.io by adding a
coverage xml
command after run unit tests with coveragecoverage run -m unittest coverage xml
- add a new step (see Codecov Github Actions) to upload the report a Github predefined action (no need to download the “codecov” uploader using curl):
- name: Upload coverage report using Github Action
uses: codecov/codecov-action@v3
Codecov.io has details of using a Github Action
Get a Codecov “Badge” for README.md
On Codecov.io, navigate to your repository and click the “Settings” tab.
In the “Badges & Graphs” section it has Markdown code you can add to README.md.
As usual, you should put this badge on a line after the title line in README.
(Not Done in 2022) Using Travis-CI for Automatic Testing
Travis-CI is a continuous integration server for building, testing, and deploying software projects. It works with many lanaguages and integrates easily with Github.
- Create a Travis account on Travis-ci.com using Github for authentication.
- When you connect your Travis account to Github, a dialog will ask which Github projects you want to allow Travis to access.
- You can grant access to specific projects or all projects. The next step shows how to grant access to a project at any time.
- On Github, open your Account Settings page, then:
- select Applications from left (near bottom)
- Next to “Travis CI” click Configure
- Under
(x) Only select repositories
Selectdemo-pyci
- Click “Save”
- (Alternate Way) On Travis-CI open “Setting”. In setting it shows your repositories. There is a link “Manage repositories on Github”. This link takes you to the Github Account Settings -> Applications -> Travis CI dialog.
- choose which projects to grant Travis access, as in step 2.
Now Travis has permission to “pull” your demo-pyci
project, but you must create a configuration file to tell Travis what to do!
Create a Travis Configuration File (.travis.yml)
Many applications use YAML file format for configuration, including Travis and Github Actions. The Travis CI web site has many example config files you can use to get started, and detailed explanation of what the settings mean.
In your local repository, create a file named .travis.yml
that describes your
project. Here is a simple .travis.yml
for this project:
language: python
# you can use a different version of Python
python: "3.6"
# don't clone more than necessary
git:
depth: 1
# Install dependencies
install:
- pip install -r requirements.txt
# script to run tests. Script can have many commands, one per line.
script:
- python -m unittest discover -p "*_test.py"
In this file, the indentation must be spaces, not tab. You should consistently use at least 2 spaces per indent level. Just like Python, yaml requires consistent indentation.
-
Add the
.travis.yml
file to your local git repo and push to Github. -
Travis should automatically pull your code and start “building” your project
- If Travis doesn’t do this automatically, click a button at right to force a new build.
Become Familiar with the Travis Web Interface
Look at all the steps Travis is performing. Can you tell what it’s doing?
Your Travis home pages shows
Left Side:
- your repositories that Travis is monitoring
- status of recent “builds”
Right Side (details for one repo selected on left side):
- Current build and screen showing console log
- Branches that Travis is monitoring and building (if any)
- History
- Pull Requests - Travis knows about Pull Requests!
Your Job Log screen will look something like this:
The “Build System Information” section of the log output is collapsed.
Expand it and see how much work Travis is doing for you!
Travis runs Python apps in a Virtual Environment
The “Build system information” section of Travis Job Log
shows that Travis uses a “virtualenv” to run Python projects,
and uses pip
and requirements.txt
to add required packages.
You will use this when testing and deploying your Django project(s).
Our .travis.yml
file did not specify what virtual environment to use
(except the Python version) so Travis used the defaults, which is a Linux
virtual machine with common packages installed.
Adding a Badge to your Project README.md
Add a Travis status notification at the top of your README.md file, called a “badge”. It looks like this:
Note: Get the actual URL for your badge by clicking on the badge shown on Travis CI. The URL is shown under “Result”.
Example: The Markdown for this is:
[](https://app.travis-ci.com/your_acctid/demo-pyci)
[](https://app.travis-ci.com/borrabeam/demo-pyci)
Don’t rely on this example! Get the actual URL by clicking on the badge shown on the Travis build page for your repo.
Fix the Bug and Watch Travis Rebuild your Project
- Fix the bug in
stats.py
. It should throw aValueError
when the list is empty. - Run the tests locally. They should all pass.
- Commit and push your fix.
- Visit your Travis-CI page again. It may take a minute or two to pull the new code, but you should see it rebuild the project and everything passes.
- Visit (or refresh) your project on Github. Does the “badge” show the tests are passing?
Add Code Coverage and the Codecov Site
Codecov is a web app that graphically shows code coverage reports.
It’s easy to use.
- Go to https://codecov.io
- Sign up using your Github ID
- Click the “Choose your first repository” button and give Codecov access to your
demo-pyci
repository.- if you have used Codecov before, then add your
demo-pyci
repo.
- if you have used Codecov before, then add your
Codecov shows some instructions including a Token. You don’t need the Token for use with Travis-CI.
Add Coverage to your .travis.yml file
Tell travis to run code coverage along with the unit tests, and send the report to Codecov.io.
-
Edit
requirements.txt
and add thecoverage
package:# required packages coverage
(or, you could add a
- pip install coverage
command in .travis.yml under the “install” section) -
Modify the
script
section in.travis.ci
to run “coverage” instead of “python”:script: - coverage run -m unittest discover -p "*_test.py"
-
Add a section to send the result to Codecov
after_script: - bash <(curl -s https://codecov.io/bash)
The “curl” command gets a Bash script form codecov.io, then
bash <
feeds the script to Bash to execute the commands. (Don’t do this with a site you don’t trust.) - Commit these changes and push to Github.
- After a few seconds, Travis should rebuild your project.
Note: This script uses after_script
so that coverage is always run.
Many sample Travis build scripts use after_succcess
instead of after_script
.
View your Coverage Report. Add a Badge to README.md
-
View the report at codecov.io. It may take a few seconds after Travis finishes.
-
Get a Codecov “badge” and add to your README.md file.
Questions
-
On Github there is repo with name https://github.com/fatalaijon/tictactoe. What should be the URL for this project on Travis-CI?
-
A CI service like Travis-CI helps you achieve which of the Tips in Practices of an Agile Developer? There may be more than one.
Required Reading
Read these short articles. The content may be asked on a quiz.
- Travis-CI Getting Started Guide short instructions how to get started.
- Core CI Concepts for Beginners - you can study this later, but you must read it
- Building a Python Project with Travis CI. Has many example scripts for Python projects.
Travis CI Lifecycle
- https://docs.travis-ci.com/user/job-lifecycle/ - lists all the “phases” you can specify in a .travis-ci.yml file
Useful to Know Later
- Travis-CI Language-specific Guides at bottom of this page has additional info for Python
- Beginner’s Guide to using Codecov with Travis CI, but his example configuration is incomplete
Travis for Makers
Travis can “build” and test projects using the venerable (ancient) GNU Make utility.
Make is a build system configured using a Makefile
that defines relationships between targets and dependencies, along with commands to run.
You can use “make” to build almost any kind of project. Make is used to compile the Linux operating sytem, C projects like MySQL (from source code), and books written using LaTeX.
There is an introduction to Make on the ISP course page.
To use “make” in your project, in .travis.yml
write:
script:
- make test
you must provide a Makefile with a test
target that runs your tests.
There’s really no benefit to using Make for Python, unless you really love make.