I'm a big fan of Ruby. I've literally used it almost every day since 2008 when I picked up the "hummingbird" book (v1.8.7). Naturally, I am likely to have a Rakefile at the root of all my repositories. GNU Make has its place, but Rake is always the clear winner in my book.
I've noticed that CI/CD pipelines for Docker images can be challenging for newcomers, so I wanted to share a best practice for bumping versions in a codified manner. And no, I don't mean the goto VERSION
text file. This method works of course, but if you want something more sophisticated read on.
To get started, you'll need Ruby installed and create the following two files:
.version.yml
Rakefile
In our .version.yml
file, let's add some content
---
version: 0.0.1
promote: major
phase: # optional
Our intention here is to cook up an initial release version 1.0.0
. The value we're passing for the version doesn't really matter, as long as its below major version 1
. The promote:
key is going to determine the semantic bump that we plan to use. Now let's create our Rakefile:
require 'semantic'
require 'yaml'
def next_version
# load the current version
version_yml = YAML.safe_load(File.read('.version.yml'))
current = version_yml['version']
level = version_yml['level'].to_sym
phase = version_yml['phase']
# create a forecast of what our future version will be
version = Semantic::Version.new current
version = version.increment!(level)
"#{version}.#{phase}"
end
task :bump do
sh "docker tag myproject:#{next_version}" # => myproject:1.0.0
end
So what exactly is happening here? We've defined a method in the #Kernel
namespace that we can employ throughout our Rake tasks. It reads the YAML file and provides the appropriate bump to our version. The :bump
task simple runs the docker tag
command, but could be used in conjunction with any other release mechanisms.
Putting it to Work
In order for this to be useful to you and your team, you will need to discuss your release strategy. Ideally, you should only bump your semantic versions on merges to master. Depending on your CI/CD process, you would only run the :bump
task during the release phase.
Benefits
Rake is more than it appears at first glance. It's not simply a Makefile with some Ruby features. It is Ruby; or rather a Ruby environment. By putting Rake to good use, you avoid mangled Makefiles with pseudo-bash scripting baked in.
I also view this as a great mechanism for peer reviews / pull requests. It allows the team visibility on what you're planning to release and why your chosen promotion level is appropriate (or inappropriate). Simply dropping off a number in VERSION
doesn't provide the same stimulus in my experience.
The YAML File
Why YAML and not JSON or something else? Meh. I say do what you want! I chose YAML because its human readable and ubiquitous in the DevOps realm lately. You can also add additional fields at any time without breaking functionality. In the above example I left phase:
blank. This is great for any modifiers such as pre-release, alpha, beta, rc1, etc.
Requirements
Unlike the yaml
gem, you will need to install semantic
yourself. Either use bundler or simply run the following command:
$ gem install semantic
Additionally, this gem (and of course Ruby) will have to be installed on your CI/CD agent(s). I would suggest using Bundler with a Gemfile to accomplish this. If you're concerned about keeping your agents pristine, read up on installing the gems locally to the vendor/
folder.
Final Thoughts
The DevOps frontier is still very "wild west". I'm sure someone will invent a tool that handles versioning in a more succinct way, but what would the fun be in that?
Top comments (0)