Using Puppet Blacksmith

Part of tidying up my module management is automating publishing of my Forge modules. One of my biggest gripes about the Forge is that I need to go the site and do point-n-click things to update modules. That annoys me. I’d much prefer a nice simple command line interface that I can automate as part of the build process.

So I went looking for options and found Puppet Blacksmith. It’s a Ruby Gem written by the team at MaestroDev that provides some Rake tasks for automating the uploading of new Puppet module versions to the Forge. I’m going to step you through the process of installing it and adding it to your Puppet module.

Installing Puppet Blacksmith

Puppet Blacksmith is easy to install via the gem command.

$ sudo gem install puppet-blacksmith

Adding Puppet Blacksmith to your module

To enable Puppet Blacksmith we need to add it to our Rakefile. We require it in the top of the Rakefile like so:

require 'puppet_blacksmith/rake_tasks'

You should also have the Puppet Labs spec helper installed and added to your Rakefile too.

require 'puppetlabs_spec_helper/rake_tasks'

So now my final Rakefile for the Sensu Puppet module looks like:

require 'rubygems'
require 'puppetlabs_spec_helper/rake_tasks'
require 'puppet-lint'
require 'puppet-syntax/tasks/puppet-syntax'

exclude_paths = [
  "pkg/**/*",
  "vendor/**/*",
  "spec/**/*",
]

PuppetLint.configuration.log_format = "%{path}:%{linenumber}:%{check}:%{KIND}:%{message}"
PuppetLint.configuration.send("disable_80chars")
PuppetLint.configuration.send("disable_autoloader_layout")
PuppetLint.configuration.send("disable_quoted_booleans")
PuppetLint.configuration.ignore_paths = exclude_paths
PuppetSyntax.exclude_paths = exclude_paths

This Rakefile provides Puppet spec testing and Puppet linting.

We also need to configure our credentials for the Forge. To do this we create a new file called .puppetforge.yml in our home directory.

$ cd ~ && touch .puppetforge.yml

We populate that file like so:

---
url: https://forgeapi.puppetlabs.com
username: username
password: password

As it has some credentials in it let’s make sure it is reasonably permissioned.

$ chmod 0600 ~/.puppetforge.yml

Testing Puppet Blacksmith

Adding the supporting code to our Rakefile should enable some new Puppet Blacksmith Rake tasks. Let’s look at those new tasks now by running rake -T.

$ rake -T
. . .
rake module:bump         # Bump module version to the next minor
rake module:bump_commit  # Bump version and git commit
rake module:clean        # Runs clean again
rake module:push         # Push module to the Puppet Forge
rake module:release      # Release the Puppet module, doing a clean, build, tag, push, bump_commit and git push.
rake module:tag          # Git tag with the current module version
. . .

Running Puppet Blacksmith

Now we’ve got Puppet Blacksmith installed we can use it to ship a new release of our module. Firstly, we make the required changes we want for our new releases and then commit them.

. . . edit files . . .
$ git commit -a -m "Adding awesome new feature"

Next, we ensure we have a clean environment.

$ rake module:clean
Cleaning for module build

Then we increment our module version.

$ rake module:bump_commit
Bumping version from 1.3.0 to 1.3.1

This will open our module’s Modulefile, increment the version it finds inside, and then create a new commit in our project with our updated Modulefile.

$ git log
commit bc925778c36ad9abc1bf784cdf906ba14d1fc817
Author: James Turnbull <james@lovedthanlost.net>
Date:   Sat Oct 18 13:07:48 2014 -0400

    [blacksmith] Bump version to 1.3.1

We can also tag that version if required.

$ rake module:tag

We can then build our new module version.

$ rake build

And finally, the pièce de résistance, we can push our module to the Forge.

$ rake module:push
Uploading to Puppet Forge sensu/sensu

There’s also a handy shortcut task available that does all of this called release.

$ rake module:release

I am really happy I’ve found Puppet Blacksmith, it makes the module release process so much easier, at least until Puppet’s module tooling supports a proper build and upload API.

comments powered by Disqus