Build with Jenkins
Use Jenkins when a connected GitHub or GitLab repository builds on a Jenkins controller. Jenkins is CI-only: connect the GitLab/GitHub repository first, then use the public RunSafe Global Pipeline Library so Jenkins connects properly to the Platform.
The Platform does not install a Jenkins plugin or receive Jenkins webhooks. Scans appear when your pipeline calls the library (or, on supported hosts, after an automated Jenkinsfile remediation merge request).
Library install details, step options, and release tags live in the runsafe-jenkins-pipeline-library repository.
Before you start
- Connect GitHub or Connect GitLab and enable Identify or Protect for the project.
- Set Jenkins as primary CI: open the project → Settings → Integrations. Under Continuous integration, choose Jenkins (requires a detected
Jenkinsfile, or choose Jenkins when multiple CI systems are detected). - Use a Unix agent that can run Docker (or pass an agent label into
withRunSafe) for builds that use the library’s default image.
When Jenkins is primary CI, GitHub Actions and GitLab CI webhooks for that project are ignored for scan creation.
After adding or changing a Jenkinsfile on the default branch, use Refresh CI detection on Project → Settings → Integrations if Jenkins does not appear yet. Detection is one-shot unless you refresh; see Last Detected vs Last Contact.
Install the Global Pipeline Library
Do this once per Jenkins controller: Manage Jenkins → System → Global Trusted Pipeline Libraries.
| Field | Value |
|---|---|
| Name | runsafe-platform |
| Default version | master for the latest release, or a tag for a pinned version |
| Retrieval | Modern SCM → Git → runsafe-jenkins-pipeline-library |
Add the organization license credential
Create a Jenkins Secret text credential before the first build. Prefer folder scope when one org owns the jobs in a folder; otherwise use a global credential with the same ID.
| Field | Value |
|---|---|
| Kind | Secret text |
| ID | runsafe-license-key (default; override with licenseCredentialId in the library) |
| Secret | Organization license key from Use your license key or Account → License key |
runsafeSetup injects the secret as RUNSAFE_LICENSE_KEY. Do not put the key in the Jenkinsfile or plain environment variables.
Call the library from your Jenkinsfile
The first successful setup binds the Jenkins job id to the Platform project via the repository clone URL. Cloud Jenkins controllers reach https://app.runsafesecurity.com by default; set RUNSAFE_SBOM_SERVER only when pointing a job to an on-prem Platform install.
Declarative pipeline (typical)
@Library('runsafe-platform') _
pipeline {
agent any
environment {
// optional: compliance → UNSTABLE instead of FAILURE
RUNSAFE_COMPLIANCE_ALLOW_FAILURE = 'true'
}
stages {
stage('RunSafe Setup') {
steps { script { runsafeSetup() } }
}
stage('Build') {
steps {
script {
withRunSafe {
sh 'make release'
}
}
}
}
}
post {
always {
// Teardown must run even when Build fails (Declarative skips later stages)
script { runsafeTeardown() }
}
}
}
Build language is inferred from the workspace (or RUNSAFE_BUILD_LANGUAGE). Pass lang: / dockerImage: to withRunSafe only when inference is wrong or you need a specific build container.
Scripted / all-in-one wrapper
@Library('runsafe-platform') _
runsafePlatformPipeline {
stage('Build') {
withRunSafe {
sh 'make release'
}
}
}
Let the Platform open a Jenkinsfile merge request
For Jenkinsfiles on GitLab-hosted repos (with remediations enabled), the Platform opens a merge request that wires in the library:
- Declarative — Adds
@Library('runsafe-platform'), a RunSafe Setup stage, apost { always { … } }teardown, andwithRunSafe { … }around detected compile/build steps (make,cmake --build, and similar). Ordinary steps such asechostay unwrapped. - Scripted (
node { … }) — Rewrites the root torunsafePlatformPipeline { … }and wraps the same detected builds withwithRunSafe { … }.
If you do not see that automation:
- Ambiguous shell commands (for example
./build.sh) are left alone — wrap those manually when they should generate SBOMs. - GitHub- and Bitbucket-hosted repos are not auto-remediated yet; apply the examples above manually.
- Confirm remediations are not set to do-nothing for the organization, and that a
Jenkinsfileis on the default branch so a scan finds it.
After a successful Identify-enabled build, SBOMs and compliance results appear on the project in the Platform the same way they do for GitLab CI.
What the library steps do
| Step | Role |
|---|---|
runsafeSetup | Pipeline start: enabled features, tooling, start scan/audit |
withRunSafe | Wrap a compile / Docker / .NET build so build-time SBOMs run |
runsafeTeardown | Pipeline end: finish audit, collect SBOMs, compliance checks |
runsafePlatformPipeline | Setup → your stages → teardown in one wrapper |
runsafeParallelBuild / runsafeMatrixBuild | Parallel or matrix builds that share one audit |
For option tables (lang, dockerImage, credential overrides, and so on), see the library README.
Troubleshooting
| Symptom | What to check |
|---|---|
| Last contact never updates | Job ran runsafeSetup / teardown with Identify or Protect enabled; clone URL matches the connected project. See Last Detected vs Last Contact. |
| Library not found | Library name is exactly runsafe-platform; Git repository is runsafe-jenkins-pipeline-library at https://gitlab.com/runsafe-foss/runsafe-jenkins-pipeline-library; controller must reach that URL |
| Credential errors | Secret text ID is exactly runsafe-license-key (or the value you passed as licenseCredentialId) |
| Wrong project bound | First successful bind uses clone URL; confirm the job checks out the same remote as the Platform project |
| Wrong or missing CI under Continuous integration | Refresh CI detection after merging Jenkinsfile changes on the default branch. Detection is one-shot unless you refresh. |
| Compliance fails the build | Expected when policy is violated; set RUNSAFE_COMPLIANCE_ALLOW_FAILURE=true for UNSTABLE instead of FAILURE |
If this page does not resolve the issue, email support@runsafesecurity.com.