For a long time now, most of my command-line app projects have been written using Go. Without going into a sales pitch for Go, I love using it for command-line apps because of the simple tool chain, and nice standard library (also the flag package is great).
At work I wrote a Ruby command-line app for us to use to generate release notes comprising of merged pull requests and closed issues on GitHub. I started this project before I was introduced to Go, and was a big Ruby programmer. More features were added to the project to support our needs and it grew to where it wasn’t nice to work on. Also I wanted to get rid of the dependency on Ruby (it’s slow).
I ended up working over a weekend on the initial implementation of ReleaseKit. I was more familiar with Go and building command-line apps using it. I implemented the minimum required functionality for us to be able to replace our existing project.
While I’m quite the slacker when it comes to writing unit/integration tests for these command-line apps, I did want to have CI setup to make sure they build correctly without errors. I decided to check out CircleCI to set this up as I had seen other projects using it, and it helps that the web UI is nice and simple.
After setting it up to just build ReleaseKit, I had a thought.
Since ReleaseKit can generate a release and upload assets to that release on GitHub, why not have ReleaseKit release itself.
CircleCI was setup to use the workflows feature to build ReleaseKit when a tag is pushed to GitHub, then use that built copy to create a release and upload itself for that release. This includes builds for macOS, Windows, and Linux.
I created a bot user on GitHub, because I didn’t want to give GitHub API tokens to CircleCI for my own user. I have public and private repositories for work I don’t want to give access to. So the action of doing a release are performed by this bot. I just add the bot user as a collaborator to the repository on GitHub, and generate a new API token for the CircleCI job.
That is some almost-inception level shit right there. While it took some tweaking of the CircleCI configuration, I got it working (which is probably still more complex than it really should be, if someone wants to double check it, I’ll greatly appreciate it)!
Anyway, that’s the ball that got all this rolling.
Roll on (get it, cos the ball got rolling?) to Christmas, I have an unwritten tradition where I just spend Christmas writing code. I ended up writing a command-line app to check cryptocurrency prices. Eventually I hooked this up to CircleCI and ReleaseKit to upload a release to GitHub.
Being the dirty Apple and macOS hipster I am, I wanted to add ReleaseKit and coin to Homebrew so it was easier for me (and others) to install and update. I created my own tap for my command-line apps, and other projects. Another thing I would like to look into is potentially looking into a way to update the formula in the tap for the new release. This will probably be another command-line app that clones the tap repository, updates the correct formula, commits and pushes to change back to GitHub.
Since the beginning of 2018, I’ve ended up writing a few more command-line apps that have gone on to utilise this CircleCI + ReleaseKit CI/CD pipeline.
There is no doubt that 2018 will be filled with more command-line apps written in Go, and making use of this pipeline.