Continuous integration server, ghetto style
Ghetto-CI is a Python script in 145 statements fullfilling your dirty continuous integration needs.
Source code (one file, only 145 statements) is on Github and for your convenience the script is bundled in VVV package on PyPi.
To improve the quality and cost effectiveness of your little software project, you want to detect code changes breaking your project [automated tests].
You might want to do this without installing 48 MB of Java software on your server. On the other hand, very good SaaS oriented alternatives are tied to public Github repositories. Homebrew shell scripts for tasks like this are nice, but no one wants to read or touch shell scripts written by others.
Ghetto-CI script is mostly self-contained, easy to understand, easy to hack into pieces, for your very own need. It is a solution that scales down. Just toss it on a corner of a server and it will churn happily and keep its owners proud. Ghetto-CI does not you give fancy web interface, statistics, bling bling or even a pony. However, it tells when someone breaks something and it is time for team building via blanket party.
As a prerequisitement you need a working Python 3 command installed on your operating system with virtualenv package. For detailed instructions see VVV installation manual
If you don’t feel eggy you can just grab the self-contained source file as long as you have plac package also installed for your Python.
Create Python 3 virtualenv and run Ghetto-CI script using Python interpreter configured under this virtualenv:
# We install GhettoCI directly under our UNIX user home folder cd ~ virtualenv -p python3 vvv-venv source vvv-venv/bin/activate pip install vvv # ghetto-ci now lives in vvv-venv/bin/ghetto-ci # Running the script, using the Python environment prepared # to see that everything works (source command above # has added this to PATH) ghetto-ci -h
You need to prepare
Example of a command for running continuous integration against /my/svn/repo checkout where bin/test command is used to run the unit tests:
# Will print output to console because email notification details are not given ghetto-ci /my/svn/repo /tmp/status-file.ci "cd /my/svn/repo && bin/test"
If the tests status have changed since the last run, or the running fails due to internal error, the command outputs the result. Otherwise command outputs nothing. Exit code 0 indicates that test succeeded.
Then just make Ghetto-CI to poll the repository in UNIX cron clock deamon. Create a dummy UNIX user which can checkout and pull updates on the source code. Create file /etc/cron.hourly/continuous-integration-tests which will hourly run the tests (Ubuntu example):
#/bin/sh sudo -i -u yourunixuser "ghetto-ci /my/svn/repo /tmp/status-file.ci 'cd /my/svn/repo && bin/test'
Naturally the command to launch the tests is specific to your software project.
On Windows you can accomplish this using any automator provided by your operating system vendor.
You might to use -force -alwaysoutput arguments with test runs.
You can also evaluate against UNIX command true and false to e.g. test email output:
ghetto-ci -force -alwaysoutput ...email settings here... /repo /tmp/status-file.ci true
Below is a real life example how you define one shell script, again triggered by Cron job, to poll several SVN repositories which have different tests to run.
#!/bin/sh # # Example ghetto-ci integration for Plone buildout and custom add-ons. # Using dummy gmail account for outgoing messages. # # Install VVV under buildout # # Run this file in buildout main folder: # # cd ~/mybuildoutfolder # src/my-repo/continuos-integration.sh # # # The list of persons who will receive resports of test status changes RECEIVERS="email@example.com, firstname.lastname@example.org, email@example.com" # Ghetto-CI template command which is run against multiple repos / multiple test commands # We use localhost 25 as the SMTP server -> assume your UNIX server has postfix # or something configured... could be gmail.com servers also here GHETTOCI="vvv-venv/bin/ghetto-ci -smtpserver smtp.gmail.com -smtpport 465 -smtpuser firstname.lastname@example.org -smtppassword OMGITISFULLofKITT3NS -receivers "$RECEIVERS" -envelopefrom "Continuous integration service <email@example.com>" -smtpfrom firstname.lastname@example.org" # Note that SVN revision info is folding down in the folders # so you can target tests to a specific SVN repo subfolder # Note: eval needs to be used due to shell script quotation mark fuzz # See that buildout completes (no changes in the external environment, like someone accidentally # publishing broken packages on PyPI). We actually place buildout.cfg under this SVN repo # and then just symlink it eval $GHETTOCI src/my-repo buildout.ci 'bin/buildout' # Run tests against hospital product eval $GHETTOCI src/my-repo/Products.Hospital hospital.ci "bin/test -s Products.Hospital" # Run tests against patient product eval $GHETTOCI src/my-repo/Products.Patient patient.ci "bin/test -s Products.Patient"
plac rocks for command line parsing, especially with Python 3.
The code is pylint valid - and beautiful, Pythonic.
To make this script even more awesome, the following can be considered