Noah Luskey
  • Resume

CI/CD Freedom - Sun, May 12, 2019

You should move build logic to make/cmake and writing a thin CI build shim.


For no particular reason, I wanted to move from one CI service to another.

This process involves some amount of converting the build scripts, and thankfully my project is not particularly complicated (it’s this half baked website / blog / whatever).

Here’s what you should do

Move your build logic to make/cmake and write a thin CI build shim

How

Well let’s take my simple hugo site as an example. This is the whole thing

before_script:
  - 'which hugo || ( apt install ./hugo_0.54.0_Linux-64bit.deb )'
  - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
  - mkdir -p ~/.ssh
  - chmod 700 ~/.ssh
  - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
  - chmod 644 ~/.ssh/known_hosts

stages:
  - everything

compile_and_deploy:
  stage: everything
  script:
    - cd hugo
    - hugo
    - scp -rp public/* root@134.209.60.242:/srv/www/noahluskey.com

(It’s probably not well written, that’s beside the point.)

  1. Let’s change each target to a make target

    before_script:
      - ...
    
    stages:
      - everything
    
    compile_and_deploy:
      stage: everything
      script:
      - ... 
    

    Becomes:

    .PHONY:
    all: everything
    
    .PHONY:
    before_script:
       ...
    
    .PHONY:
    everything: before_script compile_and_deploy
    
    .PHONY:
    compile_and_deploy: before_script
       ...
    
    

Notice the dependencies. This is so before_script runs first, then every target in the everything class is run. Simply run make all

  1. Add your scripts to the Makefile

    before_script:
    - 'which hugo || ( apt install ./hugo_0.54.0_Linux-64bit.deb )'
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
      ...
    
    .PHONY:
    before_script: 
       which hugo || ( apt install ./hugo_0.54.0_Linux-64bit.deb ) && \
       which ssh-agent || (apt-get update -y && apt-get install openssh-client -y ) && \
       ...
    

    Notice the && \ at the end of every line. This is each Makefile recipe line runs in a separate shell 1.

  1. Create your CI yml file

    before_script:
    
    stages:
      - everything
    
    compile_and_deploy:
      stage: everything
      script:
        - make all
    

Why?

Now you can make your project locally, or easily integrate with a new CI/CD provider (or multiple CI/CD providers, just by providing multiple CI shims).

Cheers.


Photo by Junior Moran on Unsplash


  1. https://stackoverflow.com/questions/1789594/how-do-i-write-the-cd-command-in-a-makefile ↩︎

Back to Home


© Noah Luskey 2020

Linkedin GitHub