Sharing code is a must in today’s world of software development. But what if you had to repeat the same code over and over in each of your Jenkins pipelines? That would be a lot of wasted time, right? Thankfully, there is a way to keep your code neat and not have to duplicate your work, which is by using a Jenkins Pipeline Library, which lets you share code across all of your Jenkins pipelines. In this article, we’ll go over how a Jenkins Pipeline Library can help you, and why it is a must for any serious Jenkins user.
What Is a Jenkins Pipeline Library?
A Jenkins Pipeline Library, sometimes called a Shared Library, is a collection of Groovy scripts that you can use in your Jenkins pipelines. It allows you to make code that can be used across your jobs. This way you don’t have to write out the same steps each time. Think of it as a way to build a set of tools that all of your pipelines can use. This setup makes your pipeline code cleaner and easier to manage.
Why Use a Jenkins Pipeline Library?
Let’s talk about why you would want to use a Jenkins Pipeline Library. There are quite a few good reasons to do so.
-
Code Reuse: One of the main reasons to use a Jenkins Pipeline Library is code reuse. Instead of writing out the same steps for every job, you can keep them in a library. This way, you write the code once and use it many times.
-
Easier Maintenance: When your pipeline code is in one place, it’s much easier to keep up with. If you need to change something, you only have to change it in one spot, instead of looking for the same code across all your jobs. This keeps things simpler and less prone to errors.
-
Consistency: Using a Jenkins Pipeline Library helps keep your pipelines consistent. All your jobs will work in the same way because they are using the same code. This makes it easier to troubleshoot problems since you know the main steps are the same every time.
-
Faster Pipeline Creation: With a library, you do not need to start from scratch every time you make a new pipeline. You can use pre-built steps and functions from the library, which makes making new pipelines much faster. This lets you focus on the details that are unique to each job.
-
Team Collaboration: When using a Jenkins Pipeline Library, your team can all work on the same code base. This makes it simpler for developers to collaborate on building and improving pipelines. This shared approach helps make sure everyone is up to date on the best practices.
-
Centralized Logic: Putting your pipeline logic in a library keeps it separate from your actual pipeline definitions. This separation of logic means you can change your code without having to change your pipelines. This leads to a much cleaner and more structured project.
-
Less Error: Reusing code from a library also means there are fewer chances for typos or other errors. The more you reuse your tested code, the better and more dependable your pipelines will become. This helps keep your build process working smoothly.
How to Set up a Jenkins Pipeline Library
Setting up a Jenkins Pipeline Library involves a few steps, and it’s good to get them right to make sure things run smoothly. Here is how you can get started:
Step 1: Create a Git Repository
The first thing you will need is a Git repository to host your library code. This repository can be on GitHub, GitLab, Bitbucket, or any other Git platform you use. Make sure your repository is set up correctly with the right access and permissions, as this repo is where your shared code will live.
Step 2: Set up the Library Structure
The code inside your repository needs to be set up in a certain way so that Jenkins can understand it. Here’s how your directory structure should be:
-
src/
: This directory will have the Groovy source files for your library.your/package/
: If you choose to put your code in a Java-style package.YourClass.groovy
: Your Groovy class file.
vars/
: This directory will have your global variables and functions, such as your global functions that are used by all pipelines.yourGlobalFunction.groovy
: Your Groovy file defining the global function.resources/
: This directory will contain any other resources that your library may need.
Step 3: Write Your Groovy Scripts
Now you need to write the Groovy code that will make up your library. Make sure to organize it logically in the files and directories we just talked about, as this will make things easier when you come back to maintain the code.
- Groovy Classes: You can create Groovy classes that define functions or methods. These classes are stored in the
src
folder. For example, you may have a class calledTools.groovy
, which contains functions for common tasks. - Global Variables and Functions: Global variables and functions are made in the
vars
directory. For example, you could have a file calledsendSlackNotification.groovy
, which contains code to send messages to a Slack channel.
Step 4: Add the Library to Jenkins
You now need to tell Jenkins where to find your library so that your pipelines can use it. You can do this by setting it up as a Shared Library in Jenkins:
-
Go to “Manage Jenkins.” Click on the “Manage Jenkins” link in the sidebar on your Jenkins dashboard.
-
Go to “System.” Find the “System” link and click it to go to the system configuration page.
-
Find “Global Pipeline Libraries.” Locate “Global Pipeline Libraries” and click on it to open the settings page for your shared libraries.
-
Click “Add”. Click on “Add” to configure a new global library.
-
Configure the Library. Fill out the form:
- Name: Give your library a name (this is the name you will use in your pipelines). This can be anything, but something that tells what your library is about would be the best.
- Default Version: Choose a specific branch to use for this library or select “@” for the latest version.
- Retrieval Method: Select your type of repo, like “Modern SCM.”
- SCM: Here you will need to put in the URL of your repository, and set up your credentials to access the Git repo.
-
Save. Click save to save your new library settings.
Step 5: Use the Library in a Pipeline
After you have set up the library, you can use it in any of your Jenkins pipeline jobs. Here’s how to do it:
-
Load the Library: First, you need to use the
@Library
annotation in your pipeline to load your library using the name you used while setting up the library.groovy
@Library('your-library-name') _ -
Use Groovy Classes: To use a Groovy class you have in your
src
folder, you need to create a new object of your class to call its methods:groovy
def tools = new your.package.Tools()
tools.yourMethod() -
Use Global Variables and Functions: If you have defined a variable or a function in your
vars
folder, you can use them directly in your pipeline without having to create any objects or anything extra.groovy
sendSlackNotification(message: 'Your build has passed!')
Best Practices When Using a Jenkins Pipeline Library
Making a library is one thing, but doing it correctly takes a bit more care. Here are some best practices that will help you use your library to its full ability:
- Keep It Simple: Try not to make your library functions too complex. When the code is simple, it makes it easier to use and understand, as well as less prone to errors.
- Be Specific: Each function or method in your library should do one thing really well. This keeps the library functions easy to test and reuse.
- Version Your Library: When you make changes to your library, it is crucial to version the library, for example by using Git tags, and use that specific version for your pipeline instead of the
latest
version, this ensures that any changes you make to the library code don’t break your pipeline, and you can always go back to an older version if you have any problems. - Test Your Library: Before you start using your library, you need to make sure everything works as expected. You can use tests to verify that the logic is correct, and each function does its intended job.
- Document Your Library: Good documentation is just as important as the code. Document the functions of your library. Make sure that anyone using your library can easily understand what each function does, what inputs it needs, and what output it gives.
- Follow Naming Conventions: Make sure you follow clear and consistent naming conventions when writing your functions and variables. This will help make the library code easier to read and understand, which will also make debugging easier.
- Keep It Updated: You will need to make sure that your library is always up-to-date. Regularly review your library, update it with any new changes or bug fixes, and get rid of any code you do not use anymore. This ensures your library will not get bloated over time, and it will keep it working properly.
- Security: Be extra careful about what code you add to your library, especially if you will be dealing with passwords, secrets, or API keys. Use the built-in security features of Jenkins to handle such sensitive data in your library.
- Error Handling: Make sure your library functions have good error handling. If anything fails, log it correctly and give a useful error message. This will make it easier to debug any problems you might have in your pipelines.
- Review Code Changes: Get your code changes reviewed by your colleagues before merging to the library, this helps make sure the code follows the set conventions, and that no bugs were introduced.
- Consider Parameterization: Parameterization allows you to make your functions more dynamic. Consider using parameterization to let users define their own specific configuration, so they can tweak them without modifying the library.
Examples of a Jenkins Pipeline Library
To give you a better idea of how you can use a Jenkins Pipeline Library, let’s look at some practical examples.
Example 1: Sending Slack Notifications
A common task in pipelines is to send messages to a Slack channel. You can create a global function for this in your library:
-
vars/sendSlackNotification.groovy:
“`groovy
def call(Map params) {
def message = params.message
def channel = params.channel ?: ‘#general’slackSend( channel: channel, message: message )
}
“` -
Usage in Pipeline:
“`groovy
@Library(‘your-library-name’) _pipeline {
agent any
stages {
stage(‘Build’) {
steps {
echo ‘Building project…’
}
}
stage(‘Test’) {
steps {
echo ‘Running tests…’
sendSlackNotification(message: ‘Tests are done’, channel: ‘#testing’)
}
}
stage(‘Deploy’) {
steps {
echo ‘Deploying…’
sendSlackNotification(message: ‘Deployment successful!’)
}
}
}
}
“`In this example, the library is loaded at the top of the pipeline, and then the
sendSlackNotification
function is called within the pipeline steps.
Example 2: Running Docker Commands
You can make a Groovy class that holds functions to build and push Docker images.
-
src/com/yourcompany/docker/DockerTools.groovy:
“`groovy
package com.yourcompany.docker
class DockerTools {
def buildImage(String imageName, String dockerfilePath = ‘Dockerfile’) {
sh “docker build -t ${imageName} -f ${dockerfilePath} .”
}def pushImage(String imageName) { sh "docker push ${imageName}" }
}
“` -
Usage in Pipeline:
“`groovy
@Library(‘your-library-name’) _pipeline {
agent any
stages {
stage(‘Build Image’) {
steps {
def dockerTools = new com.yourcompany.docker.DockerTools()
dockerTools.buildImage(imageName: ‘my-docker-image’)
}
}
stage(‘Push Image’) {
steps {
def dockerTools = new com.yourcompany.docker.DockerTools()
dockerTools.pushImage(imageName: ‘my-docker-image’)
}
}
}
}
“`Here, the
DockerTools
class is made, and then its methods are called to build and push Docker images.
Example 3: Running Tests
To make sure all of your projects are tested the same way, you can use your library to run tests.
-
vars/runTests.groovy:
groovy
def call(Map params) {
def testCommand = params.testCommand ?: "npm test"
sh "${testCommand}"
} -
Usage in Pipeline:
“`groovy
@Library(‘your-library-name’) _pipeline {
agent any
stages {
stage(‘Test’) {
steps {
runTests()
}
}
}
}
“`In this case, the
runTests
function is used to perform tests, and the test command can be customized using parameters.
Common Pitfalls to Avoid with Jenkins Pipeline Libraries
While Jenkins Pipeline Libraries can be very useful, there are some common mistakes people make that can cause problems. It’s good to know about these pitfalls so you can avoid them:
-
Overcomplicating the Library: Trying to make your library do too much will end up in a big, hard-to-manage mess. Try to make the library only do essential tasks, and keep the logic simple and easy to understand.
-
Not Versioning: If you don’t use version control, changes to your library could unexpectedly break your pipelines. Each time you change your library, make sure you version it, this makes it much safer and easier to control.
-
Poor Documentation: If your library isn’t properly documented, no one will know how to use it. Make sure you add documentation so that others, including yourself in the future, can easily use your library.
-
Not Testing the Library: You must test the code in the library before you use it. If you don’t test it, you could end up using broken code that ruins your pipelines.
-
Not Using Parameters: If you hardcode values into your library, you are going to be repeating the same changes many times. Always remember to parameterize, so you can reuse the same function, just with different values.
-
Hard-Coding Secrets: Storing sensitive data, such as passwords or API keys in your library, is a big security risk. Instead, use Jenkins to handle those secrets.
-
Not Updating Library Frequently: If you do not maintain your library, it will become stale. Make sure you update the library often to add new changes, and remove outdated code, this makes your library more useful.
-
Too Many Changes at Once: Changing too much of the library at the same time can cause unexpected issues. Make smaller changes and test them to keep your library stable.
-
Not Collaborating: If only one person works on the library, they may not notice some issues, or come up with all of the necessary changes. Get your team to collaborate on library maintenance and improvement.
-
Not Considering the Impact: When you change the library you must understand the consequences of those changes in all the pipelines that use the library, so that you do not introduce breaking changes to your pipelines.
When to Use a Jenkins Pipeline Library
Knowing when you should and when you shouldn’t use a Jenkins Pipeline Library is just as important as knowing how to use one. Let’s look at when it’s a good idea and when you should reconsider:
Good Use Cases
-
Code Repetition: If you notice that you are copy-pasting the same code in many of your pipelines, that’s a good sign that you need a shared library to make the code reusable.
-
Standardized Processes: When you want to make sure your projects follow a certain standard, a library helps you make all the pipelines work the same way, with the same steps.
-
Centralized Logic: Putting all the logic in one place makes it easier to manage. It separates the business logic from the pipeline definitions, making your code cleaner and more organized.
-
Common Tools: If you use common tools like Docker, Slack, or other API clients across your pipelines, putting them in a library makes them easier to use and manage.
-
Team Collaboration: If your team needs to share a common codebase, a library helps improve team collaboration and keeps everyone using the same standards.
When to Reconsider
- Simple Pipelines: If your pipelines are very simple with just a few steps, using a library might be overkill. For very simple cases, keeping the code directly in the pipeline might work best.
- Rarely Used Code: If a piece of code is only used in one or two pipelines, it may not be worth adding it to a library.
- Fast Changing Logic: If some logic in your project changes often, putting it in a library might cause too much churn. You will want to consider whether changes are frequent before deciding if it belongs in the library.
- Single Team Use: If a library is specific to a team, or used by just a few pipelines, making it global might be too much and not useful for anyone else.
- Too Much Effort for Small Benefit: If setting up and maintaining the library takes more time than you would save, it might not be the best idea. Always weigh the effort against the benefits.
Taking Your Jenkins Pipelines to the Next Level
As you can see, using a Jenkins Pipeline Library can be a great way to organize your build process. By writing code only once, you’ll find it easier to build and maintain your pipelines. When you set up a library, make sure to keep it simple, version your code, and test everything you add. This will help you get the most out of your setup. Using a library will also help your team collaborate and standardize the build process. So, if you’re looking for ways to make your pipelines more manageable, give a Jenkins Pipeline Library a shot.