small pixel drawing of a pufferfish j3s.sh

thought/my-deployment-platform-is-a-shell-script.html

my deployment platform is a shell script
2024-04-09

like many people, i fell in love with free software
because i could install it. i'd come home from work and
install a bunch of software.

what fun! tee hee! a playground and i'm the prince!

but eventually, relentlessly, it all starts to feel more
like a horror show.

proxmox needs an upgrade! *SPOOKY WIND*
how the fuck does k8s work again?? *SPOOKY CRICKETS*
promql *EXISTENTIAL SCREAM*


i'm too old now - i'm more fickle with my time. i like
things that work for years with as little interaction
from me as possible.

when it comes to my own projects, i always prioritize
maintainability.

to that end, i built a little deployment system that i
run on a single virtual machine - it's a shell script!

i run it every minute via cron.

here's the script, in its entirety:

  #!/bin/sh

  println() {
    printf "%s\n" "$1" >> /root/gocicd.log
  }

  die() {
    printf "%s\n" "$1" >> /root/gocicd.log
    exit 1
  }

  cd /root
  for project in $(ls go-cicd); do
    cd "/root/go-cicd/$project" 2>&1 >> /root/gocicd.log
    git fetch origin 2>&1 >> /root/gocicd.log
    if git status | grep -q behind; then
      println "$(date): building $project"
      git merge origin/main ||
        git merge origin/master ||
	  die "could not merge $project"
      go build ||
        die "could not build $project"
      mv "$project" "/usr/local/bin/$project"
      cat <<EOF >/etc/init.d/$project"
      #!/sbin/openrc-run

      supervisor="supervise-daemon"
      command="/usr/local/bin/$project"
      directory="/root/go-cicd/$project"
      EOF
      service "$project" restart
    fi
  done

whenever i make an upstream change to any of my tracked
projects, it is cloned, built, and running within 60
seconds.

this gives me a lot of joy. the blog post you're reading
right now was deployed using this system (j3s.sh is a go
application).

this has worked for many years with no maintenance at
all!

my script will never:
  - go down
  - require an upgrade
  - force me to migrate
  - surprise me
  - keep me up at night

all of this makes jes very happy.


digging in a little, the contents of the go-cicd dir look like this:

  $ ls go-cicd/
  existentialcrisis.sh  jackal                nekobot
  j3s.sh                vore                  neoarkbot

these are all of my "tracked projects".

to start tracking a new project, i only need to clone a
repository:

  $ cd go-cicd
  $ git clone git.j3s.sh/newproject

now whenever a new commit is made to
git.j3s.sh/newproject, it is deployed within 60 seconds.

ez.

here's a little taste of the log file:

  $ tail -n 5 go-cicd.log
  Thu Feb  8 00:13:12 UTC 2024: building vore
  Fri Feb  9 22:08:25 UTC 2024: building vore
  Mon Apr  8 02:07:00 UTC 2024: building j3s.sh
  Mon Apr  8 02:59:00 UTC 2024: building j3s.sh
  Tue Apr  9 21:11:00 UTC 2024: building vore

cool! i wonder what happened in march.
(oh, i moved to Virginia, right)


i recognize that this script is pretty limited. it can
only deploy golang applications to my alpine system, but
that's exactly the point i'm trying to prove:

a little, specific solution might be  easier to maintain
and straight up more enjoyable than a larger, more
general system.

i spent maybe 10 minutes writing this script in December
of 2021, and i'm proud of how reliable it has been.

consider keeping your little things little.

it worked for little old me.


until next time, with love from virginia,


  lil jes