Skip to main content

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​

  1. Connect GitHub or Connect GitLab and enable Identify or Protect for the project.
  2. 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).
  3. 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.

FieldValue
Namerunsafe-platform
Default versionmaster for the latest release, or a tag for a pinned version
RetrievalModern 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.

FieldValue
KindSecret text
IDrunsafe-license-key (default; override with licenseCredentialId in the library)
SecretOrganization 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, a post { always { … } } teardown, and withRunSafe { … } around detected compile/build steps (make, cmake --build, and similar). Ordinary steps such as echo stay unwrapped.
  • Scripted (node { … }) — Rewrites the root to runsafePlatformPipeline { … } and wraps the same detected builds with withRunSafe { … }.

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 Jenkinsfile is 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​

StepRole
runsafeSetupPipeline start: enabled features, tooling, start scan/audit
withRunSafeWrap a compile / Docker / .NET build so build-time SBOMs run
runsafeTeardownPipeline end: finish audit, collect SBOMs, compliance checks
runsafePlatformPipelineSetup → your stages → teardown in one wrapper
runsafeParallelBuild / runsafeMatrixBuildParallel or matrix builds that share one audit

For option tables (lang, dockerImage, credential overrides, and so on), see the library README.

Troubleshooting​

SymptomWhat to check
Last contact never updatesJob ran runsafeSetup / teardown with Identify or Protect enabled; clone URL matches the connected project. See Last Detected vs Last Contact.
Library not foundLibrary 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 errorsSecret text ID is exactly runsafe-license-key (or the value you passed as licenseCredentialId)
Wrong project boundFirst successful bind uses clone URL; confirm the job checks out the same remote as the Platform project
Wrong or missing CI under Continuous integrationRefresh CI detection after merging Jenkinsfile changes on the default branch. Detection is one-shot unless you refresh.
Compliance fails the buildExpected 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.