How To Self-Reference

I work on a lot of little side projects. Many of them are short-lived and small scale. I start them to learn a new technology, to learn a new concept, try an idea, or just to see if I can actually build something cool. I should also mention that my memory is terrible. I “remember” things by figuring them out again. Rote memorization is basically non-existent to me. I’ve recently come up with a new best practice for my side projects which has saved my butt several times now.

It’s a deploy.sh script and I put one in every project that I do which needs to be built, deployed, or executed beyond the typical compile step. This very blog has one. There are also a few best practices I’ve developed for making this file useful and not just another headache.

Runable

This seems like a no-brainer, but hear me out. This file should be executable on its own. It should not be deploy.rb. It should not need to be compiled or otherwise prepared to run. You are writing a script. Script away all of that tedium. If you need to deploy with ruby, make your deploy.sh simply contain ruby deploy.rb. The point here is that you can cd into your project and run this script. Period. If you have to remember to initialize your Python virtualenv first, you’ve missed the point. Set it and forget it.

Helpful

Not everything can be scripted away. Sometimes a deploy requires some unique information, such as an environment or version number. Every microservice I create is meant to run in a docker container on kubernetes. In order to automate building, tagging, pushing the image, and then updating the deployment, the deploy script needs to know the version number. Since I’ve deployed 10 times today to “fix” that one bug, I can easily remember to pass the version to the script: ./deploy.sh v1.0.1337. However, I won’t be so hip to that fact tomorrow. Good thing we are writing a script. Just add some checks and helpful error messages to guide your future self down the right path. Here’s an easy one for requiring an argument to your script:

#!/bin/bash

if [ -z "$1" ]
then
  echo "Please provide a version number, like v35"
  exit 1
fi

# other deploy code here

It may seem like a drag, but you’ll be so happy that you took the time to take care of your own self now.

Complete

Lastly, your deploy script needs to do every step on its own. It’s a grown-up script now and can handle it. If you need to do just one more thing after the deploy finishes, you might as well just rm deploy.sh. Even steps which you might consider “optional” now, need to be included. For example, this blog is hosted on AWS S3 and CDN’ed by CloudFront. It really is enough to only upload (read: sync; save those bits) the files. Eventually the cache will expire and the new content will be shown. However, in just one more line in the deploy.sh, I can invalidate the CloudFront distribution and see this awesome new post right away. If you think it’s optional, it’s required.

Well, those are my three tips for keeping your side project deployments sane.

Happy deploying!!

P.S. I’ve recently had a resurgence of shell scripting in general. In the past, I’ve certainly been one to (ab)use zsh’s history substring search to re-run the same set of commands over and again. See also: “Up 12 times then enter. 6 times.” By committing those mini-scripts to ~/bin/, it really has made me much more efficient. A practical example is streamlining my workflow at work. We use Github for code hosting and reviews. We also use YouTrack for our project management. I wrote a command line client for YouTrack and combined all the commands I was doing to checkout branches by story number or create new branches as well as marking stories In Progress/Under Review/etc. into shell scripts like review_story c-1234 or

$ start_story -t bug -s c-1234 -b this-is-a-heisenbug
Applying "Assignee: me In Progress" to story c-1234
Switched to new branch 'bugs/c-1234-this-is-a-heisenbug'

Get creative and really push yourself to save some time. Again, you’ll thank yourself, and then me. ;)

Image

Christopher R Marshall

@codegoalie

Enjoys programming web applications; especially in Ruby and Go. Also enjoys playing ice hockey as a goalie and playing the guitar.

Categories