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.