Jenkins shared library: Shared defaults and a package name - Part 3

Jenkins shared library: Shared defaults and a package name - Part 3

Building Jenkins Shared Library

~5 min read

The first version of syncBlog had its release tag written straight into the step: v0.2.0 as a default, the Ghost repository URL inside the shell snippet, and the two credential IDs as string literals. That works for one step. This post is about moving those values somewhere central, and about the package name I put them under.

Where to keep a shared value

I weighed three places:

  • The default in the step. Simplest. Bump it, tag the library, and every project that doesn't pass version: follows when it moves to the new tag. For one value used by one step, it's enough.
  • A Jenkins global environment variable. Changes everything instantly, with no library release. But the value is no longer in Git, so a change can't be reviewed or rolled back, and a bad value breaks every build at once. That's the opposite of the pinning I've been careful about.
  • A constants class in src/. More than the single value needs today, but it gives the next step somewhere to put its own shared values.

I went with the class, because this library is groundwork for more steps, and a second step needing the same tool version or credential IDs is likely.

It lives in src/, not vars/, on purpose. Every file in vars/ becomes a global variable and shows up in Jenkins' Pipeline Syntax page, so a file of constants there is clutter. In src/ it's a plain class that steps import:

package uk.co.brightbot

class Defaults implements Serializable {
    static final String BLOG_SYNC_REPO    = 'https://github.com/atownsend247/ghost-blog-sync.git'
    static final String BLOG_SYNC_VERSION = 'v0.2.0'

    static final String GHOST_URL_CREDENTIAL       = 'ghost-url'
    static final String GHOST_ADMIN_KEY_CREDENTIAL = 'ghost-admin-key'
}

and syncBlog reads args.version ?: Defaults.BLOG_SYNC_VERSION. A project can still override the version per call. Bumping blog-sync for everyone is now one edit and one library tag.

The package name

The scaffold shipped with a placeholder package, org.acme, in src/ and in resources/. Replacing it touches more places than I expected, because the name appears in three kinds of spot that all have to agree:

  • the folder path under src/ and resources/,
  • the package line in each class (the folder must match it, or Groovy reports unable to resolve class),
  • every import and libraryResource('...') path that refers to it, plus the docs and examples.

The convention for Java and Groovy packages is the reversed domain name. My domain is brightbot.co.uk, so the package is uk.co.brightbot, not co.uk.brightbot - I got that backwards on the first attempt and had to move the folders a second time. It's a cheap mistake to make and a tedious one to undo, and it's far cheaper to fix now than once other projects import from it.

What's next

The pieces are in place: a step, a place for its defaults, and a real package name. What remains is to register the library in Jenkins, tag a first release, and switch the Jenkinsfiles over to syncBlog().


Previous: ← Extracting the Sync blog stage · Next: Linting and unit testing the library → · Back to series index