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.yamlconfiguration -
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:
-
Modify the JSL groovy function — extract the key and use it in logic
-
Document the key — update the reference with type, default, required status, description
-
Add examples — update the example yaml files (if commonly used)
-
Update CHANGELOG — note the new option and version introduced
-
Ensure backwards compatibility — old configs should continue to work
-
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.yamlor scripts (version frompom.xmlorpackage.json) -
Language differences matter — Java projects extract version from
pom.xml, JavaScript frompackage.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.yamlcontrols 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
withCredentialsscope 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:
-
Create/add credentials in Jenkins Credentials
-
Extend JSL credential mapping for the appropriate project type/environment
-
Update documentation and examples
-
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_VERSIONordeployVersion -
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.0to 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.yamlflags (for example Sonar, OIS, Flexline) -
Build parameters can run targeted scan-only flows (such as
RUN_SONAR_ONLYorRUN_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.
-
Choose your integration approach
-
Decide Docker vs Skaffold/Kustomize (and Helm usage if needed) based on current tooling and deployment complexity.
-
-
Prepare project metadata
-
Add/update
jenkins.yamlwith minimum required keys, then layer in scan/deploy/notification options.
-
-
Define version source
-
Confirm one source of truth for version (
pom.xmlorscripts/version.sh) before pipeline conversion.
-
-
Map credentials and environment variables
-
Verify Jenkins credentials, global env vars, and project-specific variables are complete for your build path.
-
-
Convert Jenkinsfile to JSL wrapper
-
Replace custom orchestration with
buildServiceProject()and keep project-specific logic minimal.
-
-
Enable scanning and quality controls intentionally
-
Start with required scanners, then tune branch rules and quality gate behavior by environment.
-
-
Validate in sandbox first
-
Run build, scan-only, and deploy-only paths; confirm image tags, namespaces, and report outputs are correct.
-
-
Promote to staging/prod with explicit rules
-
Lock in branch regex, deploy policy, and release behavior before rollout to higher environments.
-
-
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.