This latest instalment in the Jupiter Dev Log series covers the newly added “automatic release process” in some detail. The release process was decidedly manual before this work. I ran make docker-push
on my local machine, and a new Docker image replaced the one on Docker Hub. There are in fact two key improvements: having versioned releases (and a versioning process to boot), and having an automated release process which acts on some pushes to GitHub and uploads the current version to DockerHub.
The version of the code spoken about in this release can be found under the v0.0.2 tag on GitHub. It’s not radically different than what was before it, however. But I’ll walk through the thought process here.
The first thing that was needed was a way to decouple the push to Docker Hub from my local machine state and my login status to Docker Hub. This is achieved via access tokens which are essentially alternatives to the one password for the account. But they can be managed much better than the password - issues for a single use case, revoked, etc.
The manual release process described in the previous article like so:
$ make docker-build
$ docker login
$ make docker-push
Can now become:
$ make docker-build
$ echo MY_TOKEN | docker login --username horia141 --password-stdin
$ make docker-push
The second thing I did was set up a very simple GitHub Actions workflow to essentially automatically run the above on every push to a branch.
I chose GitHub Actions for convenience’s sake. It looks quite fully featured, but I didn’t really do that much of a comparison between Travis, Circle, any other hosted CI/CD tool, and it. Self-hosted was out of the question of course, but the others could have been better. Or at least Circle, cause it seemed to be innovating a bit with its orbs repositories. I knew Travis wasn’t what it used to be, but I used it a lot in the past and was familiar with it. That said it was a neat tool to learn, and seems to be pretty powerful - especially the ability to have multiple workflows, actions modularity, etc.
I setup a secret named DOCKERHUB_TOKEN
to the repo in GitHub. After that I added the following workflow under .github/workflows/release.yml
:
name: Release
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build the docker image
run: make docker-build
- name: Publish the docker image
run: |
echo $ | docker login --username horia141 --password-stdin
make docker-push
The bulk of the work is actually done with this setup. However, it’s a bit aggressive when it does a release. More precisely:There’s only one version - latest, with no notion of “release version”.We really don’t want every push to any branch to be a “release”. We want some control of what gets exposed to people.
We can tackle both via process. Namely, we’re gonna implement something like gitflow for this thing, and a small setup for storing the version and other global variables.
I added the following Config
file to the root of the repo:
BASENAME=jupiter
VERSION=0.0.1
DOCKERHUB_USER=horia141
The Makefile
can be evolved a little bit to reference the Config
file via the include & export
commands, but mostly stays the same:
include Config
export
docker-build:
docker build -t jupiter .
docker-push:
docker login --username=${DOCKERHUB_USER} --password-stdin
docker tag jupiter ${DOCKERHUB_USER}/${BASENAME}:${VERSION}
docker push ${DOCKERHUB_USER}/${BASENAME}:${VERSION}
.PHONY: docker-build docker-push
One’ll have to run docker-push
via echo $MY_TOKEN | make docker-push
which is a little bizzaro. But a human shouldn’t be running this command at all, rather the system should do it.
With this set, I could then operate some process changes, inspired by gitflow:
- I added a new
develop
branch and made this the primary branch in GitHub. Every work will start off of it as a feature / bugfix branch, and end up in it via a merge. - I relegated the
master
branch to a “log of releases”. It has about 30 commits of history. But from now on it should just be built out of releases of the form “Releases vX.Y.Z”, each with a tagvx.y.z
. - Added a
docs/releases/version-x.y.z.md
series of documents, which are the release notes log too! - Other than this, it’s a standard gitflow process. There’s no other scripts, though they will come.
Finally the release.yml
file can be morphed by restricting it only to the master
branch with certain tags, and using the new docker-push
rule:
name: Release
on:
push:
branches:
- master
tags:
- v*
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build the docker image
run: make docker-build
- name: Publish the docker image
run: echo $(( secrets.DOCKERHUB_TOKEN )) | make docker-push
OK, this should be about it. Took a bit of time, but hopefully the gradual buildup of something more professional-looking can help you in your projects. There’s still a bunch to go for the future:
- Having some
git flow
style scripts in the repo. - Learning to squash commits on the
master
branch. - Building a
scripts
directory both the make and Actions can reference. - Factoring out the steps into actions referencing the scripts.
- Adding some tests (!) and having tests run as a separate workflow for each branch.But those I’ll add in later efforts. Till next time.
Top comments (0)