tiny custom CI runner for your selfhosted just-git repositories
Find a file
2024-12-10 11:57:48 +01:00
src fix: clone from correct branch 2024-05-10 03:12:31 +02:00
.editorconfig chore: initial commit from template 2024-02-13 15:57:58 +01:00
.gitignore chore: initial commit from template 2024-02-13 15:57:58 +01:00
.rustfmt.toml chore: initial commit from template 2024-02-13 15:57:58 +01:00
.tci docs: documented that tci uses custom hook 2024-02-14 12:36:43 +01:00
Cargo.toml chore: big refactor 2024-02-15 03:04:53 +01:00
README.md docs: update tci alias 2024-12-10 11:57:48 +01:00

tci

tiny custom CI runner for your selfhosted just-git repositories

why

continuous integration is really convenient when you have quite some tiny projects which you'd like to keep updated.

this one has its doc page, that one compiles to a minified js file that i should serve, this one has a demo instance that i should restart...

i don't want to bother doing these things every time i write some fixes!

also, i really like the idea of keeping CI configuration committed with the repository itself

how

git natively supports hooks. they are extremely convenient and pleasant to use (just a shell script!), but aren't version-controlled in the repository they belong to.

i use them on my client to validate my commits and sometimes configure/cleanup projects

because i self-host my git repositories (did you know you just need to git init --bare <name> in your home and you can pull/push from there! git clone <user>@<host>:<repo-path> just works), i can't just use github/gitlab, and would rather not go mad configuring jenkins

most of my CIs are super simple: cargo doc; cp * /srv/http/docs/, configuring something complex like jenkins seems overkill

introducing tci!

tci is a Tiny CI runner

just set it as post-update hook in your repository and, each time such repository gets updated, tci will:

  • make sure repo is allowed to run CI: checks said repo git config for tci.allow == true
  • make sure the branch being updated is tci (customizable in server settings)
  • create a temp dir (under /tmp) with unique name
  • clone your repository in that dir
  • change current working directory to be inside your freshly cloned repo
  • run .tci script (customizable in repo settings)
  • print script's stdout and stderr to console
  • delete temporary directory

and that's it! could not be simpler

using tci

a very simple example: i'd like to auto-update cargo documentation for my project

first step is enabling tci for such repo: git config tci.allow true on my server

then i can just add a .tci script in the project root:

#!/bin/bash

cargo doc
rm -rf /srv/http/docs/*
cp ./build/* /srv/http/docs/

just mark it executable, commit and push!

setting tci as default runner for every repository

configuring tci as post-update hook for each repository is definitely annoying

luckily, git allows us to configure a default hook location valid for every repository! inside your ~/.gitconfig just insert:

[core]
	hooksPath = /path/to/some/directory/

inside such directory, place tci and rename it to post-update

and done! should enable tci for all repos (if they are configured to allow it)

making a git alias to quickly merge and push on tci branch

just run

git config --global alias.tci '!func(){ BRANCH=\"$1\"; REMOTE=\"origin\"; if [ -n \"$2\" ]; then REMOTE=\"$2\"; fi; git checkout tci && git pull $REMOTE tci && git merge $BRANCH && git push $REMOTE tci; git checkout $BRANCH; }; func"'

it will add a git tci <branch> alias, which you can use to quickly checkout, pull, merge and push on tci branch