Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/theasp/mini-ci
A lightweight continuous integration daemon
https://github.com/theasp/mini-ci
bash continuous-integration git subversion
Last synced: 4 days ago
JSON representation
A lightweight continuous integration daemon
- Host: GitHub
- URL: https://github.com/theasp/mini-ci
- Owner: theasp
- License: gpl-2.0
- Created: 2014-12-11T21:48:10.000Z (almost 10 years ago)
- Default Branch: master
- Last Pushed: 2017-03-25T14:12:58.000Z (over 7 years ago)
- Last Synced: 2024-01-30T04:20:26.642Z (10 months ago)
- Topics: bash, continuous-integration, git, subversion
- Language: Shell
- Size: 201 KB
- Stars: 6
- Watchers: 3
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.html
- License: LICENSE
Awesome Lists containing this project
README
Mini-CI
<!--/*--><![CDATA[/*><!--*/
.title { text-align: center; }
.todo { font-family: monospace; color: red; }
.done { color: green; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.right { margin-left: auto; margin-right: 0px; text-align: right; }
.left { margin-left: 0px; margin-right: auto; text-align: left; }
.center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #ccc;
box-shadow: 3px 3px 3px #eee;
padding: 8pt;
font-family: monospace;
overflow: auto;
margin: 1.2em;
}
pre.src {
position: relative;
overflow: visible;
padding-top: 1.2em;
}
pre.src:before {
display: none;
position: absolute;
background-color: white;
top: -10px;
right: 10px;
padding: 3px;
border: 1px solid black;
}
pre.src:hover:before { display: inline;}
pre.src-sh:before { content: 'sh'; }
pre.src-bash:before { content: 'sh'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-R:before { content: 'R'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-java:before { content: 'Java'; }
pre.src-sql:before { content: 'SQL'; }table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.right { text-align: center; }
th.left { text-align: center; }
th.center { text-align: center; }
td.right { text-align: right; }
td.left { text-align: left; }
td.center { text-align: center; }
dt { font-weight: bold; }
.footpara:nth-child(2) { display: inline; }
.footpara { display: block; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
/*]]>*/-->/*
@licstart The following is the entire license notice for the
JavaScript code in this tag.Copyright (C) 2012-2013 Free Software Foundation, Inc.
The JavaScript code in this tag is free software: you can
redistribute it and/or modify it under the terms of the GNU
General Public License (GNU GPL) as published by the Free Software
Foundation, either version 3 of the License, or (at your option)
any later version. The code is distributed WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.As additional permission under GNU GPL version 3 section 7, you
may distribute non-source (e.g., minimized or compacted) forms of
that code without the copy of the GNU GPL normally required by
section 4, provided you include this license notice and a URL
through which recipients can access the Corresponding Source.@licend The above is the entire license notice
for the JavaScript code in this tag.
*/
<!--/*--><![CDATA[/*><!--*/
function CodeHighlightOn(elem, id)
{
var target = document.getElementById(id);
if(null != target) {
elem.cacheClassElem = elem.className;
elem.cacheClassTarget = target.className;
target.className = "code-highlighted";
elem.className = "code-highlighted";
}
}
function CodeHighlightOff(elem, id)
{
var target = document.getElementById(id);
if(elem.cacheClassElem)
elem.className = elem.cacheClassElem;
if(elem.cacheClassTarget)
target.className = elem.cacheClassTarget;
}
/*]]>*///-->Mini-CI
Table of Contents
- 1. Introduction
- 2. Features
3. Installation
- 4. Usage
- 5. Configuration
6. Contents of a Job Directory
7. Examples
- 7.1. Mini-CI Job Directory
- 7.2. Starting the Mini-CI Daemon as a User
- 7.3. Notifying a Mini-CI Daemon from GIT
8. Plugin API
1 Introduction
Mini-CI is a small daemon to perform continuous integration (CI) for a single repository/project. Most other CI software is complicated to setup and use due to feature bloat and hiding what is going on underneath with GUIs. If you know how to build your project from the command line, setting up Mini-CI should be easy.
2 Features
- NO web interface!
- Configuration is done with a small config file and shell scripts.
- Daemon controlled through a command.
- NO user authentication!
- Unix already has multiple users, use groups or make a shared account.
- NO support for multiple projects!
- You can run it more than once…
- Plugin system
- Low resource requirements.
- Just a small bash script.
- Can monitor any repository and use any build system.
- The only limits are the scripts you provide.
3 Installation
3.1 Ubuntu PPA
- Stable release: https://launchpad.net/~theasp/+archive/ubuntu/mini-ci
- Snapshot release: https://launchpad.net/~theasp/+archive/ubuntu/mini-ci-snapshot
3.2 From Source
To install into/usr/local
:make clean install
To install into your home directory (~/opt/mini-ci
):make clean install prefix=~/opt/mini-ci
4 Usage
From the output ofmini-ci --help
:
Usage: mini-ci [option ...] [command ...]Options:
-d|--job-dir directory for job
-c|--config-file config file to use, relative to job-dir
-m|--message [timeout] send commands to running daemon, then exit
-o|--oknodo exit quietly if already running
-D|--debug log debugging information
-F|--foreground do not become a daemon, run in foreground
-h|--help show usage information and exitCommands:
status log the current status
poll poll the source code repository for updates, queue update if
updates are available
update update the source code repository, queue tasks if updates are made
tasks run the tasks in the tasks directory
clean remove the work directory
abort abort the currently running command
quit|shutdown
shutdown the daemon, aborting any running command
reload reread the config file, aborting any running commandCommands given while not in message mode will be queued. For instance
the following command will have a repository polled for updates (which
will trigger update and tasks if required) then quit.
mini-ci -d -F poll quit
5 Configuration
You can configure a Mini-CI job by copying theskeleton
directory somewhere and then editing where required. This directory is referred to has the "job directory". The skeleton contains the fileconfig
and the directorytasks.d
, see their description later. Once you have the configuration in place you can try it by runningmini-ci -F
in the directory you created, which will run Mini-CI in the foreground.
6 Contents of a Job Directory
config
: The configuration file for the job.tasks.d
: Contains all the tasks that would be executed during a build of your repositoryplugins.d
: Contains any additional plugins to be used for this job.builds
: The builds directory contains the output of each build of a job in numbered directories.workspace
: The directory your repository is checked out into, and built in.mini-ci.log
: The main log for Mini-CI.poll.log
: The log for the last poll operation.tasks.log
: The log for the last tasks operation.update.log
: The log for the last update operation.control.fifo
: This is a FIFO used to communicate with the Mini-CI daemon.
6.1config
Theconfig
file is a shell script that is sourced when Mini-CI is started which contains the configuration to use for your job. Every option should have sane defaults, so feel free to only have the entries you wish to use. If you want a variable exported during your job, for instancePATH
, this would also be a good place to do so.
Theconfig
file inskeleton
is:# All paths are relative to the job directory.####################
# Main Configuration# JOB_NAME: The name of the job. Defaults to "$(basename $JOB_DIR)"
JOB_NAME="$(basename $JOB_DIR)"# REPO_PLUGIN: This is the name of a plugin that will handle
# repository actions. The following plugins come with Mini-CI:
# - git
# - svn
# - external
REPO_PLUGIN=""# POLL_FREQ: If this is set to a number greater than zero, it will
# poll the repository using the repo-handler every this many seconds,
# starting at startup. To have a more complicated scheme, use cron.
# Defaults to 600.
POLL_FREQ=600# POLL_DELAY: If this is set to a number greater than zero, mini-ci
# will sleep this many seconds after a poll that indicates a change
# was made in the repository. Use this to delay doing an update to
# allow a series of commits to take place. Defaults to 0.
POLL_DELAY=0# WORKSPACE: The directory where the repository will be checked out
# into, and where tasks are launched. Defaults to "./workspace".
WORKSPACE="./workspace"# TASKS_DIR: The directory which holds the tasks to be performed on
# the checked out repository. Defaults to "./tasks.d"
TASKS_DIR="./tasks.d"# BUILDS_DIR: The directory which stores the output of each build when
# tasks run. Defaults to "./builds".
BUILDS_DIR="./builds"# CONTROL_FIFO: The fifo that mini-ci will read to accept commands.
# Defaults to "./control.fifo".
CONTROL_FIFO="./control.fifo"# PID_FILE: The file containing the process ID for mini-ci. Defaults
# to "./minici.pid".
PID_FILE="./mini-ci.pid"# STATUS_FILE: A file where status information is kept. Defaults to
# "./status".
STATUS_FILE="./status"# POLL_LOG: Name of the poll log. Defaults to "./poll.log".
POLL_LOG="./poll.log"# UPDATE_LOG: Name of the update log. Defaults to "./update.log".
UPDATE_LOG="./update.log"# TASKS_LOG: Name of the tasks log. Defaults to "./tasks.log".
TASKS_LOG="./tasks.log"# MINICI_LOG: Name of the mini-ci log. Defaults to "./mini-ci.log".
MINICI_LOG="./mini-ci.log"####################
# Plugin Configuration# GIT_URL: The URL to the repository. Fetching the URL must not ask
# for a username or password. Use ~/.netrc or ssh keys for remote
# repositories.
#GIT_URL=""# GIT_BRANCH: The branch of the repository. Only affects the initial
# checkout. Defaults to "master".
GIT_BRANCH="master"# SVN_URL: The URL to the repository. Fetching the URL must not ask
# for a username or password. Use ~/.netrc or ssh keys for remote
# repositories.
#SVN_URL=""# EMAIL_NOTIFY: A space and/or comma separated list of conditions to
# notify about. Valid options are "NEVER", "ERROR", "OK", "UNKNOWN",
# "RECOVER" (when a state changes from "ERROR" or "UNKNOWN" to "OK")
# and "NEWPROB" (when a state changes from "OK" to "ERROR" or
# "UNKNOWN"). Defaults to "NEWPROB, RECOVER".
EMAIL_NOTIFY="NEWPROB, RECOVER"# EMAIL_ADDRESS: A space and/or comma separated list of addresses to
# email. If not specified, will be sent to the user that is running
# the script. Defaults to "".
EMAIL_ADDRESS=""# EMAIL_SUBJECT: The subject to have for notification emails.
# Defaults to "Mini-CI Notification - $JOB_NAME".
EMAIL_SUBJECT="Mini-CI Notification - $JOB_NAME"# BUILD_ARCHIVE_WORKSPACE: When set to "yes" will copy the workspace into
# the $BUILDS_DIR/$BUILD_NUM/workspace. Defaults to "no".
BUILD_ARCHIVE_WORKSPACE=""# BUILD_KEEP: If this is set to a number greater than zero, only this
# many build log directories will be kept. Defaults to "0".
BUILD_KEEP=0# BUILD_DEPENDENCY_LIST: This is a list of status files, seperated by
# spaces, for other Mini-CI jobs that will cause tasks to wait until
# they are "idle" and the status of their tasks is "OK". Defaults to
# "".
BUILD_DEPENDENCY_LIST=""# BUILD_DEPENDENCY_TIMEOUT: The number of seconds to wait for
# dependencies to be ready. Defaults to "1200" (20 minutes).
BUILD_DEPENDENCY_TIMEOUT=1200
6.2tasks.d
Thetasks.d
directory contains all the tasks that would be executed during a build of your repository. Theskeleton
contains a few examples. Each script must match the regular expression^[a-zA-Z0-9_-]+$
and will be ran in sort order, therefore it is recommended that each script be named in the form-
. If a script exits with a return code that is not zero, it is considered a build error and no further scripts are executed.
Mini-CI exports the following variables:
MINI_CI_DIR
: The data directory for Mini-CIMINI_CI_VER
: The version of the Mini-CI runningBUILD_DISPLAY_NAME
: The build number with "#" prepended. i.e. "#123"BUILD_ID
: The date and time the build started in the following format:%Y-%m-%d_%H-%M-%S
BUILD_OUTPUT_DIR
: The directory used for storage for the current buildBUILD_NUMBER
: The current build number.BUILD_TAG
: A string of the form:mini-ci-${JOB_NAME}-${JOB_NUMBER}
JOB_DIR
: The directory where the job is storedJOB_NAME
: Name of the the jobWORKSPACE
: The current workspace directoryGIT_URL
: The URL of the GIT repository (when using the GIT plugin)SVN_URL
: The URL of the Subversion repository (when using the Subversion plugin)
7 Examples
7.1 Mini-CI Job Directory
This example will configure to monitor Mini-CI's GIT repository and run tests whenever it's updated.
Create and enter a directory calledmini-ci-job
, then place the following inconfig
:REPO_PLGUIN="git"
GIT_URL="https://github.com/theasp/mini-ci"
POLL_FREQ=600
This configuration will use the GIT repository handler with the URL to the Mini-CI repository, and then poll it every 10 minutes.
Create the directorytasks.d
, then place the following file intasks.d/100-make
#!/bin/shset -ex
# Override the prefix to install into ~/opt/mini-ci
make prefix=~/opt/mini-ci
Place the following file intasks.d/500-run_tests
:#!/bin/sh
make test
Runchmod +x tasks.d/500-run_tests
to make the script executable. Now when you runmini-ci -F
in the job directory you will get:
2014-12-18 17:20:03 mini-ci/7145 Starting up
2014-12-18 17:20:05 mini-ci/7369 Missing workdir, doing update instead
2014-12-18 17:20:05 mini-ci/7145 Updating workspace
2014-12-18 17:20:06 mini-ci/7145 Update finished sucessfully, queuing tasks
2014-12-18 17:20:06 mini-ci/7145 Mailing update notification to user due to RECOVER (New:OK Old:UNKNOWN)
2014-12-18 17:20:06 mini-ci/7145 Mailing poll notification to user due to RECOVER (New:OK Old:UNKNOWN)
2014-12-18 17:20:07 mini-ci/7145 Starting tasks as run number 1
2014-12-18 17:20:07 mini-ci/7145 Tasks finished sucessfully, run number 1
2014-12-18 17:20:07 mini-ci/7145 Mailing tasks notification to user due to RECOVER (New:OK Old:UNKNOWN)
Mini-CI started in foreground mode, downloaded the repository, then ran all the tasks in thetasks.d
directory. Notice that it also sent 3 mail notifications due to update, poll and tasks transitioning fromUNKNOWN
toRECOVER
. The default email settings will only send mail when they change state. The process is still running and will check the repository for changes every 10 minutes.
You can stop the daemon by pressingctrl-c
, or by runningmini-ci -m quit
in the job directory in another shell.
7.2 Starting the Mini-CI Daemon as a User
The easiest way to run Mini-CI as a user is to havecron
start it. For instance, the following crontab will start Mini-CI every 10 minutes, and if it is already running for that job directory it will exit quietly, otherwise it will poll the repository for any updates it missed when it starts:
*/10 * * * * mini-ci --oknodo -d ~/some-mini-ci-job-directory poll
Mini-CI will run in the background doing it's thing whenever it needs to.
7.3 Notifying a Mini-CI Daemon from GIT
You can have git notify Mini-CI upon every push to a repository, which makes polling the repository unnecessary. Put this inhooks/post-update
in your git repository directory (or.git/hooks/post-update
if you aren't using a bare repository), and it will send a message to Mini-CI to do an update, which will trigger a build.#!/bin/shset -e
mini-ci -d ~/some-mini-ci-job-directory -m update
You can easily change the above script to SSH to another system, or user.
8 Plugin API
Mini-CI can be extended with plugins written as bash functions. Any plugin matching*.sh
in theplugins.d
directory in either the Mini-CI installation path or the current job directory will be sourced when Mini-CI starts up. Plugins must declare their variables usingdeclare
(ordeclare -x
if the variable is to be exported). Variables that are to be set using the config file should be set the default value using a function of the nameplugin_on_load_config_pre_
. In most cases the plugin's functions will run in the same shell as the rest of Mini-CI so that the plugin can modify variables, but this also introduces the chance that a plugin will introduce unwanted side-effects.
8.1 Repository Plugins
Repository plugins are ran in a subshell withSTDOUT
redirected to the appropriate logfile. A repository plugin must provide the following functions:
plugin_repo_update_
- Must exit with a return code of 0 if successful.
plugin_repo_poll_
- Must exit with a return code of 0 if successful.
- Must exit with a return code of 1 if there is an error.
- Must exit with a return code of 2 if the repository is out of date.
8.2 Notification Plugins
A notification plugin must provide a function namedplugin_notify_
, which accepts the following arguments:
- item: The name of the state that triggered the notification, i.e.
poll
,update
,tasks
, etc.- old: The old status of that state, i.e.
UNKNOWN
,ERROR
, orOK
- oldtime: The time in epoch seconds the old status was set
- new: The new status of the state
- newtime: The time in epoch seconds the new status was set
- activestates: A string containing one of
OK
,ERROR
,UNKNOWN
, additionally it may containNEWPROB
orRECOVER
.
8.3 Generic Hooks
Your plugin can provide functions using the following names:
on_abort_post_
on_abort_pre_
on_acquire_lock_post_
on_acquire_lock_pre_
on_clean_post_
on_clean_pre_
on_load_config_post_
on_load_config_pre_
on_notify_status_post_
on_notify_status_pre_
on_poll_finish_post_
on_poll_finish_pre_
on_poll_start_post_
on_poll_start_pre_
on_process_queue_post_
on_process_queue_pre_
on_queue_post_
on_queue_pre_
on_quit_post_
on_quit_pre_
on_read_commands_post_
on_read_commands_pre_
on_read_status_post_
on_read_status_pre_
on_reload_config_post_
on_reload_config_pre_
on_run_cmd_pre_
on_run_cmd_pre_
on_run_tasks_post_
on_run_tasks_pre_
on_schedule_poll_post_
on_schedule_poll_pre_
on_send_message_post_
on_send_message_pre_
on_status_post_
on_status_pre_
on_tasks_finish_post_
on_tasks_finish_pre_
on_tasks_start_post_
on_tasks_start_pre_
on_update_finish_post_
on_update_finish_pre_
on_update_start_post_
on_update_start_pre_
on_update_status_post_
on_update_status_pre_
on_write_status_post_
on_write_status_pre_
8.4 Example Plugin
Thebuild-keep.sh
plugin uses a variableBUILD_KEEP
which is settable from the config file and used thetasks_finish_post
hook:declare BUILD_KEEPplugin_on_load_config_pre_build_keep() {
BUILD_KEEP="0"
}plugin_on_tasks_finish_post_build_keep() {
if [[ "$BUILD_KEEP" -gt 0 ]]; then
while read num; do
[[ -d "$BUILDS_DIR/$num" ]] && rm -r "$BUILDS_DIR/$num"
done < <(seq 1 $(( $BUILD_NUMBER - $BUILD_KEEP)))
fi
}
Date: 2015-02-18 Wed 21:04