Converting Projects to JSL

Jenkins Shared Libraries (JSL) consolidate pipeline logic that would otherwise be duplicated across service projects. Rather than each team maintaining their own Jenkinsfile with hundreds of lines of build, test, and deploy orchestration, JSL provides the core automation as a reusable library, while projects remain lean — just configuration and minimal local customization.

The payoff: Faster iteration (pipeline changes propagate immediately), consistency (all services follow the same patterns), and less toil (engineers focus on application code, not pipeline wiring).

Approaches to Integrating with JSL

JSL works with different container build and orchestration tooling. The right approach depends on your project’s current toolchain, deployment model, and team familiarity. This section covers the main options and how they pair with JSL.

Build vs Deployment tool selection guidance

Choosing between approaches starts with answering three questions:

1. Do you need environment-specific configuration management?

  • If yes (staging vs prod overlays, feature toggles, multi-tenant configs): Skaffold + Kustomize offers declarative, gitops-friendly config layering.

  • If no (single deployment pattern, env vars only): Docker or Docker + Helm are simpler.

2. What is your primary build artifact?

  • Java/Maven projects: Can leverage Maven profiles and pom.xml configuration. Skaffold + Kustomize is natural fit.

  • Node.js/JavaScript: Use Docker for build orchestration; Skaffold adds complexity unless already in use.

  • Go, Python, etc.: Docker is the simplest path; Helm if you need templating.

3. How do you prefer to manage deployment templates?

  • Kustomize (native Kubernetes, minimal templating): Pairs well with Skaffold.

  • Helm (full templating engine, pre-built charts): Works with JSL but less integrated.

  • Docker + env vars (simplest): No template layer at all.

Quick decision guide:

  • Start with Docker if: Project is not yet containerized, team is unfamiliar with Skaffold/Kustomize, deployment is straightforward.

  • Use Skaffold + Kustomize if: Java backend with multiple environments, already using these tools, complex configuration needs.

  • Consider Helm if: Using Helm charts already or for helm-based infrastructure; JSL support is more limited.

JSL with Skaffold/Kustomize

Overview: Skaffold orchestrates the local build and Kubernetes deployment workflow; Kustomize manages environment-specific Kubernetes manifests. JSL integrates with both, handling pipeline orchestration while delegating build/deploy details to these tools.

What it provides:

  • Declarative, environment-aware deployment (dev/sandbox/staging/prod profiles)

  • Manifest overlays for configuration differences without duplication

  • Skaffold’s development loop (watch-rebuild-redeploy)

  • Multi-profile builds (e.g., beta/standard feature flags)

When to use:

  • Backend services with multiple environments

  • Projects already using Skaffold/Kustomize

  • Teams comfortable with Kubernetes manifests and declarative config

Key config: Skaffold profiles and Kustomize overlays drive the pipeline stages. JSL reads these to determine build and deploy behavior.

Link to detailed conversion guide: [Adding link when available]

JSL with Docker

Overview: Docker alone handles containerization and image building. JSL orchestrates the pipeline around a Dockerfile-based build, with environment variables or simple config files for environment-specific behavior.

What it provides:

  • Minimal setup; works with any language/framework

  • Direct control over build process via Dockerfile

  • Simple deployment (push image to registry, update manifest refs)

  • Easy local development parity

When to use:

  • Projects not yet using Skaffold or Kustomize

  • Simple, single-deployment-pattern services

  • Teams preferring container tooling over Kubernetes abstractions

  • Full control over build steps needed

Key config: Dockerfile and JSL’s buildServiceProject() handle everything. Environment differences managed via env vars or docker build args.

Jenkinsfile Conversion

The Jenkinsfile transformation is the most visible part of adopting JSL. Instead of hundreds of lines of pipeline code managing build, test, scanning, and deployment, your Jenkinsfile becomes a thin wrapper that imports JSL and delegates to its orchestration functions.

What changes:

  • All pipeline logic (build steps, test commands, scanning, deployment) moves into JSL

  • Your Jenkinsfile specifies what to do via jenkins.yaml configuration

  • JSL’s buildServiceProject() function determines how to do it based on your tooling

Why this matters:

  • Consistency — all services follow the same pipeline patterns

  • Maintainability — pipeline updates in JSL benefit all projects immediately

  • Simplicity — engineers focus on configuration, not pipeline plumbing

  • Auditability — centralized, versioned pipeline logic

Key concepts:

  • Stages (build, test, scan, deploy, etc.) are orchestrated by JSL, not your Jenkinsfile

  • Configuration lives in jenkins.yaml — credentials, artifact repos, environment mappings, etc.

  • Customization happens via environment variables, Jenkins properties, or JSL extension points (when needed)

jenkins.yaml contract

Every JSL-based project needs a jenkins.yaml file in the repository root. This file defines the configuration contract between your project and JSL — what to build, how to deploy, which scanning tools to enable, etc.

What it contains:

  • Build configuration — image name, language, build tool (Skaffold/Kustomize, Docker, etc.), module directory

  • Deployment settings — target namespaces, version handling, auto-deploy behavior

  • Quality & scanning — OIS scanning, SonarQube, quality gates

  • Notifications — Slack channels for success/failure

  • Advanced options — release tagging, credential caching, periodic builds, Newman API tests

Why it matters:

  • Single source of truth for pipeline behavior (avoids Jenkins UI fragmentation)

  • Version controlled alongside your code (auditable, reproducible)

  • Language-agnostic — same JSL functions work with Java, JavaScript, Go, etc.

  • Extensible — new options can be added without JSL redeployment

Key principles:

  • Values have sensible defaults (minimalist configurations work)

  • Can be overridden at runtime via Jenkins parameters

  • Organized by concern (build, deploy, scan, notify, etc.)

Reference documentation: See jenkins.yaml Configuration Reference for all available keys, types, defaults, and usage examples.

Adding New Configuration Keys

As JSL evolves, new configuration options are added. To properly implement a new key:

  1. Modify the JSL groovy function — extract the key and use it in logic

  2. Document the key — update the reference with type, default, required status, description

  3. Add examples — update the example yaml files (if commonly used)

  4. Update CHANGELOG — note the new option and version introduced

  5. Ensure backwards compatibility — old configs should continue to work

  6. Test thoroughly — validate with a real project before merging

For step-by-step details, see the "Adding New Configuration Keys to JSL" section in the reference.

Environment variables & credentials

JSL relies on environment variables configured at the Jenkins instance level and used throughout the pipeline. These variables provide infrastructure access (Docker registries, Kubernetes APIs), secrets management (Vault, credential binding), and scanning tools (Flexline, SonarQube).

What you need to know:

  • Jenkins-level variables are set once at the Jenkins instance; they’re the same across all projects (DTR_URL, VAULT_ADDR, etc.)

  • Project-level extraction happens per-project via jenkins.yaml or scripts (version from pom.xml or package.json)

  • Language differences matter — Java projects extract version from pom.xml, JavaScript from package.json, others via custom scripts

  • Docker vs Skaffold/Kustomize have different env var needs (Docker is simpler; Skaffold/Kustomize need overlay/profile management variables)

Why it matters:

  • Version extraction must be correct or deployments fail with wrong image versions

  • Credential binding must be set up correctly or builds cannot authenticate to repositories

  • Environment mapping (sandbox/sqa/staging/prod) is the backbone of multi-environment pipelines

Reference documentation: See Environment Variables & Credentials Reference for all Jenkins-required variables, project-specific extraction methods, and language/implementation differences.

Key Variables by Category

Infrastructure (Docker, Kubernetes, registries):

  • DTR_URL, IMAGE_PULL_SECRET — container registry access

  • K8_API, K8_DEPLOY_IMAGE — Kubernetes deployment

Secrets & Configuration:

  • VAULT_ADDR, CONSUL_ADDR — secret/config servers

  • VA_NEXUS_USER, VA_NEXUS_PWD — Maven artifact repository (Java only)

Scanning & Quality:

  • FLEXLINE_IMAGE/HOST/API_KEY — security scanning

  • CNESREPORT_JAR — code analysis (Java only)

Per-Project Extraction:

  • Version source differs: pom.xml (Java), package.json (JavaScript), custom scripts (others)

  • See reference for language-specific extraction patterns

Credential Handling

Credential handling in JSL should stay centralized, predictable, and environment-safe. Projects should declare behavior in jenkins.yaml, while secret material remains in Jenkins Credentials and is injected only at runtime.

Operating model:

  • jenkins.yaml controls what capabilities are enabled (deploy, scans, tagging, etc.)

  • JSL controls which credentials are loaded for project type + target environment

  • Jenkins Credentials stores all secret values (tokens, usernames/passwords, API keys)

What to standardize during migration:

  • Keep credential IDs consistent across sandbox/staging/prod when possible

  • Use the same variable names across environments so scripts do not branch unnecessarily

  • Avoid embedding secrets in repo files, Jenkinsfile, or shell scripts

  • Keep credentials consumed inside withCredentials scope only

When custom credential work is needed:

  • New integration requires a credential JSL does not currently bind

  • Existing credentials differ by environment and need normalization

  • Project type needs a credential set not covered by current JSL logic

How to add support safely:

  1. Create/add credentials in Jenkins Credentials

  2. Extend JSL credential mapping for the appropriate project type/environment

  3. Update documentation and examples

  4. Validate in sandbox before promoting to higher environments

Reference documentation: See Credential Handling Reference for the current credential IDs JSL binds and the implementation path for adding new credential mappings.

Handling Versioning

Versioning should be deterministic and tool-agnostic. In a JSL pipeline, the build version is resolved early, then reused for image tagging, deploy steps, and notifications.

Version source strategy:

  • Java/Maven: version comes from pom.xml

  • Non-Maven projects: version comes from ./scripts/version.sh

  • Fallback behavior: if no version source is available, JSL falls back to 1.0.0 (this should be treated as a migration safety net, not a target state)

How JSL uses version values:

  • Build version is stored as config.version

  • Major version is derived as config.majorVersion

  • Manual deploy can override with DEPLOY_VERSION or deployVersion

  • Auto-deploy uses resolved config.version

Migration expectations:

  • Every project should have one clear, documented source of truth for version

  • Non-Maven projects should add and maintain scripts/version.sh

  • Release and snapshot/version-suffix conventions should be explicit and consistent across environments

Common pitfalls to avoid:

  • Different version logic between local scripts and CI

  • Using runtime overrides as a permanent workflow instead of fixing source versioning

  • Allowing fallback 1.0.0 to reach deployment paths

Reference documentation: See Versioning Reference for source precedence, override behavior, implementation patterns, and migration checklists by project type.

Scanning/quality gate

JSL lets you standardize scanning while keeping project-level control over which checks run. The goal is to make scan behavior consistent across services without forcing every project into the exact same scanner workflow.

Scanning model in JSL:

  • Scanning features are enabled through jenkins.yaml flags (for example Sonar, OIS, Flexline)

  • Build parameters can run targeted scan-only flows (such as RUN_SONAR_ONLY or RUN_OIS_SCAN_ONLY)

  • Quality gate enforcement is explicit (enableQualityGate) and can be branch-scoped (sonarMainBranchOnly)

What to define during migration:

  • Which scanners are required vs optional for your project

  • Which branches enforce blocking behavior (fail build) vs advisory behavior

  • Where scan reports are published and how long artifacts are retained

  • Which scans run pre-push vs post-push for release safety

Quality gate guidance:

  • Use quality gates for merge/release protection, not for experimentation branches

  • Keep failure behavior intentional and documented (especially in sandbox)

  • Align branch rules with your release strategy so developers see predictable outcomes

Common pitfalls to avoid:

  • Enabling scan flags without required config values (for example Sonar report target)

  • Treating all environments the same when risk tolerance differs

  • Running expensive/full scans on every branch without need

  • Mixing ad-hoc Jenkins parameters with undocumented default behavior

Reference documentation: See Scanning & Quality Gate Reference for supported flags, runtime parameters, branch/environment behavior, and extension points.

Migration sequence / flow

Use this sequence to migrate with low risk while keeping teams in control of implementation choices.

  1. Choose your integration approach

    • Decide Docker vs Skaffold/Kustomize (and Helm usage if needed) based on current tooling and deployment complexity.

  2. Prepare project metadata

    • Add/update jenkins.yaml with minimum required keys, then layer in scan/deploy/notification options.

  3. Define version source

    • Confirm one source of truth for version (pom.xml or scripts/version.sh) before pipeline conversion.

  4. Map credentials and environment variables

    • Verify Jenkins credentials, global env vars, and project-specific variables are complete for your build path.

  5. Convert Jenkinsfile to JSL wrapper

    • Replace custom orchestration with buildServiceProject() and keep project-specific logic minimal.

  6. Enable scanning and quality controls intentionally

    • Start with required scanners, then tune branch rules and quality gate behavior by environment.

  7. Validate in sandbox first

    • Run build, scan-only, and deploy-only paths; confirm image tags, namespaces, and report outputs are correct.

  8. Promote to staging/prod with explicit rules

    • Lock in branch regex, deploy policy, and release behavior before rollout to higher environments.

  9. Standardize and document final policy

    • Capture decisions (versioning, scans, credential mapping, overrides) so teams can migrate consistently.

Suggested rollout pattern: one pilot service first, then migrate similar services in batches using the same templates and references from this guide.

Troubleshooting common issues

…​

JSL enhancements needed

(e.g., npm Sonar path that JSL lacks) …​