Turnkey Shared Libraries Development for Jenkins Pipeline

Duplicated build scripts slow down releases and multiply failures due to discrepancies between teams. We design and implement shared build libraries turnkey: unified modules, documentation, update procedures. Time to release a new build is reduced many times over, and the share of failures caused by configuration drops.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

Jenkins Shared Libraries: code duplication in build scripts

Almost any grown project repeats the same picture: dozens of repositories, and each has its own build script copied from a neighbor.

Steps for installing dependencies, running tests, style checks, and artifact publishing differ by a couple of lines—the very one added in one project and forgotten in the others.

The cost of such copy-paste does not show immediately. Code duplication in build scripts turns a fix to a common step into a dozen separate changes, some get lost in branches, and build tool versions diverge across projects.

Support of build scripts ceases to be a common task: identical actions are performed differently, and build behavior can no longer be predicted from one description.

Most dangerous is configuration desynchronization: a change goes straight to the main branch because there's nowhere to run it—the script itself has neither tests nor validation on a separate environment.

An error in the publish step is costly: the release either fails to build or ships with wrong artifacts, and it's discovered at release time.

The Shared Libraries approach in Jenkins moves such steps into a single versioned repository, from which projects include ready modules.

Below we break down how this is addressed: what is moved into common build modules, how changes are versioned, and how to verify that a fix doesn't break dozens of projects at once.

What a unified build library gives: measurable effects

Steps described once—dependency checks, tests, image build, publishing—live in a common library instead of being copied across repositories. Jenkins connects it as a regular version dependency, so services get identical build script behavior. What this changes measurably:

Build and release time

Common steps run in parallel, extra stages are not started for unchanged modules. Build run is reduced by tens of percent, and release no longer requires manual engineer actions on every branch.

Failure class of build script

Logic is concentrated in one place with automated test coverage, rather than smeared across dozens of files. Reduction in build failures occurs not due to 'carefulness', but because an incorrect step is caught by a single library test before reaching services.

Downtime cost

Clear logs, unified rollback steps, and environment repeatability reduce recovery time. The main part of downtime cost is hours of finding the cause, and it goes away when the script is identical everywhere.

Speed of connecting a new service

A new repository gets a script with one connection line and a set of parameters. The starter set of steps takes minutes instead of a day, and the team doesn't have to understand someone else's configuration.

Standardization of build scripts

The library version is pinned explicitly, so changes are rolled out gradually rather than breaking all services at once. Update goes through a separate branch, old builds are reproduced on the previous version.

Options for organizing common modules: comparison of approaches

Organizing common build modules is a choice between speed of changes and cost of their maintenance.

When build scripts lie in one place, a fix to the deploy step reaches all teams in one pass; when they diverge across projects, each team fixes its own, and after six months identical steps behave differently.

Option When suitable Honest limitations
Separate repository of common library Multiple teams, need unified release cycle and versioning Requires discipline: without tags and backward compatibility, a fix breaks other teams' builds
Modules inside monorepo One product line where code and build steps change synchronously Build code mixed with product, access rights broader than necessary, harder to reuse outside repository
Local team modules 1–2 teams with their own unique steps and fast pace Duplication, divergence from standard, knowledge locked to one engineer
External solutions Need a quick start on typical steps Update pace and compatibility outside your control, update pulls in others' changes

In practice, a combination often works: core with typical steps is moved to a separate repository with tags, while a specific team's specifics remain a local layer on top of it. Such repository structure gives build code reuse without losing autonomy.

Implementation order: from script audit to handover

Implementing a library for Jenkins is iterative: first we record what actually happens in current scripts, then isolate common modules, and only then roll them out to teams.

This order doesn't stop releases—projects build according to previous descriptions until new modules are confirmed on a pilot team.

  1. Build script audit — export pipeline descriptions from repositories, count repeated steps (build, tests, artifact publishing, deployment) and mark unique places that must not be broken.
  2. Module scheme — design library structure: common steps, environment wrappers, parameter conventions, extension points. What goes into common core and what remains on project side is agreed with teams.
  3. Environment setup — connect library to controller, distribute change permissions, set versioning and update order so a module cannot be changed unnoticed by other builds.
  4. Pilot project — migrate one team and run full build cycle: compare time and failure rate with previous description, roll back if deviations occur.
  5. Rollout to all projects — migrate in groups of several teams, old descriptions remain working until new ones are confirmed.
  6. Documentation handover — usage examples, instructions for adding a module, update regulations, and walkthrough with on-call engineers.

After handover, the team extends the library itself—our schemes and rules allow this without rebuilding the core.

Jenkins library repository: modules, documentation, regulations

The library remains in your environment: Jenkins library repository, rights, branches and tags are under your control, not ours.

We hand over not only working code but also the rules by which it is changed without our involvement: a new engineer understands the structure in a day.

  • Repository structure — vars, src, resources, tests directories, naming convention, new module template, and linter that does not allow a step without parameter descriptions.
  • Build and delivery modules — steps for build, tests, artifact publishing, notifications and deployment: parameters, default values, reuse in different projects.
  • Library versioning — semantic tags; the pipeline pins a specific version instead of a floating branch, so updates are deliberate, and rollback to previous tag takes minutes.
  • Secret access regulations — where credentials are stored, who may add and change them, what the module receives as input; no token remains in code.
  • Library documentation — description for each module: parameters, call example, limitations, plus a section on connecting the library in a new project.
  • Checks and update order — automated tests for steps, mandatory run on test environment, rule for approving major changes, and list of projects with their versions.

At acceptance you receive the repository, documentation and regulations—this is enough to develop the library with your own team.

Case: reducing build failures after switching to library

Before: common step lived in copies

The client is a product department of 14 teams and more than 60 repositories. Each team kept its own Jenkinsfile copied from neighbors, so a fix to a common step—test run order, agent parameters, artifact publishing—turned into a tour of all repositories and took 2-3 days.

Configurations diverged: build failure rate stayed around 18%, and most of them were not due to code but to environment discrepancies and different tool versions on different branches.

After: versioned step library

Steps were moved into a common Jenkins library: build, test and publishing modules, version pinned by tag, and the team's repository references a specific version.

Fixing a common step became one commit and a new tag—40-60 minutes instead of several days; teams switch to a fresh version at a convenient moment, rollback is changing the tag in one line.

Metric Before After
Build failure rate ~18% ~4%
Average build recovery time after failure 40 minutes 8 minutes
Fixing a common step in all repositories 2-3 days 40-60 minutes
Repositories with diverging configuration majority isolated exceptions

The remaining 4% are test failures and external environment unavailability, not configuration divergences: such issues are analyzed from logs of a specific step, not by searching for differences between repositories.

Recovery time decreased because diagnostics is built into the step itself and reports the cause immediately. A new team connects to the library in a day—not by copying someone else's file, but by adding a connection and a set of ready steps.

How is a common library different from build script templates?

A build script template is a file copied into every project. While there are two projects, copies match; by the tenth, they already have different stages, their own workarounds and different set of checks.

A fix has to be made in each repository separately, and some teams don't learn about it—builds begin to behave differently for the same code.

A common library (usually denoted by the term Shared Libraries) is structured differently: it is not copied but connected as a dependency with a version specified. Build, publishing and check steps live in one repository, and project scripts consist of calls to these steps. A rule changes once—all builds that switched to the new version receive the change centrally.

The difference is noticeable on rollback.

The library version is pinned in project configuration, so an incompatible change doesn't break other builds: some teams work on the previous version, others test the new one, and transition happens as ready, not as a fact of a fix in a common file. A template has no such boundary—copies update unevenly.

Migration from templates is gradual. First, the most repeated things are moved into common steps—getting code, running tests, building artifact; projects switch one by one, and old scripts continue working.

Then divergences and duplicates are cleaned up, the library gets its own tests and compatibility rules. Without this discipline it quickly turns into the same template, only lying in one repository.

Technical doubts: compatibility, access, migration

Technical doubts before adopting a common library usually come down to three questions: will an update break already working build scripts, how to distribute access to secrets, and what to do with local modules that teams have already deployed. We address them specifically—with how this is solved in a real environment, not a demo one.

Will updating the library break working build scripts?

The library is versioned as a regular artifact: a build script references a specific label, not "latest state". Until a team deliberately switches the reference, its pipeline builds on the same revision and behaves identically.

Changes that break previous calls are made in a major branch alongside the old one; deprecated steps continue to work but are marked in documentation as being phased out.

Transition to a new branch is done one pipeline at a time—with a run on test environment before switching production.

How is access to build secrets granted?

The library does not store values: it accesses credential storage and substitutes them at execution time, so no secret remains in the repository or build log output—values are masked.

Access is granted by roles, each team has its own set, and credential accesses are visible in audit: it's clear which script requested them and when. For local debugging, an engineer works with a separate set of placeholder values; full access is not needed.

Will already deployed local modules have to be rewritten?

No. The library connects alongside existing modules, and one build script can take some steps from the common set and some from local ones. Migration is incremental: first we move out what repeats across several teams, then layer by layer we transfer the specific.

Each transferred step is covered by a check before the local copy is deleted—at every step the build remains working.

Let's discuss your task and come back with an estimate and work plan

To make the review specific rather than general, it's enough to send a few artifacts—they replace long correspondence. We look at current builds, composition of repeated steps, and how the team introduces changes into the library today.

The order is this: we analyze the structure of your builds, identify blocks that move into a common set of steps, and determine what remains in team repositories.

Based on the results, we come back with an estimate and work plan, which describes the order of stages for implementing the build library.

  • Build description file of one or two typical services—it shows current stage logic and run parameters.
  • List of repositories and services that should switch to common steps.
  • How secrets are currently stored and how access to build agents is granted.
  • Requirements for branches and releases: what is considered a build for rollout and what is a check.
  • Environment constraints: how many environments, who manages them, whether there is a closed environment.
  • Responsible person on your side who will accept the library and maintain its versions.

Then we agree on the order of stages: pilot on one service, transfer of the rest, documentation and handover to the team. Describe the task—we'll come back with an estimate and plan.