diff options
-rw-r--r-- | LICENSE | 17 | ||||
-rw-r--r-- | README.md | 55 | ||||
-rw-r--r-- | jobs/example | 3 | ||||
-rwxr-xr-x | simepleci.sh | 71 |
4 files changed, 146 insertions, 0 deletions
@@ -0,0 +1,17 @@ +Copyright (c) 2024 Philipp Geyer [Nistur] + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution.
\ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..f80bd35 --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +# Simple CI + +The simplest pseudo-Continuous Integration tool I could conceive + +This does not have a web UI +This does not have error reporting +This does not require docker + +This is just a script which is intended to be run by cron, or some +other mechanism, and it will just check a git repository, update if +there's a change, and then run a command within this directory. + +This can be a deployment command (making this a CD, not CI) or it can +be kicking off a test suite, or it can be whatever you want. + +## The reason +I have a small VPS, I wanted it to deploy a static site when I pushed +a change to a live branch. I could have used a post-receive hook on +the server, but the repository is currently within a docker container, +something I intend to change at some point. I am sure I could change +it, but I just wanted a solution. I couldn't find anything that just +did the bare minimum I wanted without bells and whistles, so I wrote +one. + +## Configuration +Within simpleci.sh there are two variables: +* `JOB_DIR` - sets the location for jobs +* `WORKSPACE_DIR` - sets the location that simpleci will use for local + copies + +These default to being 'jobs' and 'workspaces' within the simpleci +directory, but can be changed. + +## Jobs +Jobs are names of projects which can be run. These are stored within +`JOB_DIR`. These are a simple file with up to three pieces of +information: +* `REPO` - the repository to monitor +* `BRANCH` - the branch to monitor [live] +* `COMMAND` - the command to run within the directory [make publish] + +## Running +It is possible to run simpleci manually +`/path/to/simpleci.sh` - this will check for any updates in any of the +jobs, and run them where required +`/path/to/simpleci.sh JOB1 [JOB1 [JOB3 ..]].` - this will force-run +specific jobs, regardless if there is an update or not. + +The job names are the filenames within `JOB_DIR`. +eg +`/path/to/simpleci.sh example` + +It is also possible to add to cron to run it periodically. +eg +`*/30 * * * * /path/to/simpleci.sh >> /path/to/simpleci.log 2>&1` diff --git a/jobs/example b/jobs/example new file mode 100644 index 0000000..4bfbcb7 --- /dev/null +++ b/jobs/example @@ -0,0 +1,3 @@ +#REPO="https://github.com/example/example.git" +#BRANCH="live" +#COMMAND="make install"
\ No newline at end of file diff --git a/simepleci.sh b/simepleci.sh new file mode 100755 index 0000000..43aef34 --- /dev/null +++ b/simepleci.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +SCRIPT_DIR="$(readlink -f $(dirname ${BASH_SOURCE[0]}))" + +JOB_DIR="${SCRIPT_DIR}/jobs" +WORKSPACE_DIR="${SCRIPT_DIR}/workspaces" + +check_for_remote_changes() { + local DIR=$1 + local BRANCH=$2 + + pushd "${DIR}" > /dev/null || { echo "Directory ${DIR} not found!"; return 1; } + + # Fetch the latest changes from the remote + git fetch + + # Get the local and remote commit hashes for the branch + LOCAL=$(git rev-parse "${BRANCH}") + REMOTE=$(git rev-parse "origin/${BRANCH}") + + # Check if local and remote are different + if [ "${LOCAL}" != "${REMOTE}" ]; then + echo $(date +"%Y-%m-%d %H:%M:%S") "Remote changes detected in ${DIR}" + popd > /dev/null + return 0 + else + echo $(date +"%Y-%m-%d %H:%M:%S") "No remote changes in ${DIR}" + popd > /dev/null + return 1 + fi +} + +trigger() { + REPO="" + BRANCH="live" + COMMAND="make publish" + source "${1}" + DIR="$(echo ${REPO##*/} | sed -e 's/\.git$//')" + FORCE=${2} + +# echo REPO=${REPO} +# echo BRANCH=${BRANCH} +# echo COMMAND=${COMMAND} +# echo DIR=${DIR} +# echo FORCE=${FORCE} + + if [ ${REPO} ]; then + if ! [ -e "${WORKSPACE_DIR}/${DIR}" ] ; then + git clone -b ${BRANCH} ${REPO} "${WORKSPACE_DIR}/${DIR}" + FORCE=1 + fi + if [ "${FORCE}" ] || check_for_remote_changes "${WORKSPACE_DIR}/${DIR}" "${BRANCH}"; then + pushd "${WORKSPACE_DIR}/${DIR}" + git pull origin ${BRANCH} # Pull the latest changes + ${COMMAND} + popd + fi + fi +} + +mkdir -p "${WORKSPACE_DIR}" + +if [ $# -gt 0 ] ; then + for i in $@ ; do + trigger "${JOB_DIR}/$i" 1 + done +else + for i in ${JOB_DIR}/* ; do + trigger "$i" + done +fi |