Migrating a Jenkins OWASP Dependency-Check step into a GitHub Actions workflow, inspecting Jenkins JSON with helper transformers and mapping CLI flags and publisher logic to Actions
In this lesson we inspect the OWASP Dependency-Check stage from a Jenkins pipeline and demonstrate how to migrate it into a GitHub Actions workflow. We’ll:
Review the migrated workflow that the importer produced.
Identify Dependency-Check-related steps that lacked matching transformers.
Use a helper transformer to print the Jenkins JSON for those steps.
Map the Jenkins configuration to an appropriate GitHub Action that runs OWASP Dependency-Check.
Overview: the migrated workflow already contains environment variables and a runner configuration. The first job installs dependencies:
A dry-run of the actions-importer confirms the GitHub Actions workflow file was generated:
root@jenkins in /home via 💎> gh actions-importer dry-run jenkins --source-url http://139.84.149.83:8080/job/ci-pipeline-poll-scm/ --output-dir tmp/dry-run --custom-transformers ss-pipeline-transformer.rb[2025-05-22 18:54:06] Logs: 'tmp/dry-run-log/valet-20250522_185406.log'[2025-05-22 18:54:07] Output file(s):[2025-05-22 18:54:07] tmp/dry-run/ci-pipeline-poll-scm/.github/workflows/ci-pipeline-poll-scm.ymlroot@jenkins in /home via 💎 took 15s
The pipeline includes an NPM dependency audit job and an OWASP Dependency-Check job. Both migrated, but the Dependency-Check step (and the Dependency-Check publisher) had no matching transformers in the default migration. To implement a correct translation, inspect the JSON representation emitted by the importer for those Jenkins identifiers.Use a helper transformer that prints the item JSON for multiple identifiers. For example:
transform "sleep", "dependencyCheck", "dependencyCheckPublisher" do |item| puts "JSON for identifier: #{item}"end
Run the importer with the helper transformer to emit the JSON for the dependencyCheck and dependencyCheckPublisher items. Example (abridged) output:
root@jenkins in /home via ◇> gh actions-importer dry-run jenkins --source-url http://139.84.149.83:8080/job/ci-pipeline-poll-scm/ --output-dir tmp/dry-run --custom-transformers ss-pipeline-transformer.rb --custom-transformers helper-transformer.rb[2025-05-22 19:01:42] Logs: 'tmp/dry-run/log/valet-20250522-190142.log'JSON for identifier: {"name"=>"dependencyCheck", "arguments"=>[{"key"=>"additionalArguments", "value"=>{"isLiteral"=>true, "value"=>"\n --scan './' \n --out ./ \n --format ALL \n --disableYarnAudit \n --prettyPrint --failOnCVSS 9"}}, {"key"=>"nvdCredentialsId", "value"=>{"isLiteral"=>true, "value"=>"owasp-dependency-check"}}, {"key"=>"odcInstallation", "value"=>{"isLiteral"=>true, "value"=>"OWASP-DepCheck-10"}}]}JSON for identifier: {"name"=>"dependencyCheckPublisher", "arguments"=>[{"key"=>"failedTotalCritical", "value"=>{"isLiteral"=>true, "value"=>1}}, {"key"=>"pattern", "value"=>{"isLiteral"=>true, "value"=>"dependency-check-report.xml"}}, {"key"=>"stopBuild", "value"=>{"isLiteral"=>true, "value"=>true}}]}[2025-05-22 19:01:43] Output file(s):[2025-05-22 19:01:43] tmp/dry-run/ci-pipeline-poll-scm/.github/workflows/ci-pipeline-poll-scm.ymlroot@jenkins in /home via ◇ took 20s
The important fields from the emitted JSON for the dependencyCheck step are:
additionalArguments contains the CLI flags passed to OWASP Dependency-Check. Key items: --scan (path), --out (output path), --format (report formats), and --failOnCVSS 9 (fail build for CVSS ≥ 9).
nvdCredentialsId and odcInstallation are Jenkins-specific entries referencing credentials and installer configurations used to accelerate NVD downloads or select a preinstalled Dependency-Check binary. These typically do not translate directly to ephemeral GitHub Actions runners.
CVSS score ranges are commonly used to gate failures. For reference, scores ≥ 9 are considered Critical, and scores between 7 and 8.9 are High:
Jenkins’ nvdCredentialsId and odcInstallation point to server-side configuration. When migrating to Actions, prefer a maintained Action or Docker image that packages Dependency-Check. If you need authenticated or mirrored NVD access, you’ll need to provide credentials or a custom DB image to the Action.
Because GitHub Actions runners are ephemeral, the typical approach is to use an existing Action that runs Dependency-Check inside a Docker image. The GitHub Marketplace project dependency-check/dependency-check-action runs OWASP Dependency-Check in a container and exposes inputs for common CLI options.A mapped GitHub Actions job that runs Dependency-Check might look like this:
Pass as args: --failOnCVSS 9 or implement follow-up checks
nvdCredentialsId, odcInstallation
Jenkins-specific credentials/installer
Usually omitted; the Action provides the runtime. Use custom runner or additional Action inputs for special NVD access.
If your Jenkins pipeline relied on a pre-downloaded NVD DB (via odcInstallation) or private NVD credentials, you must plan how to supply that to Actions: either use a self-hosted runner with the database pre-populated or configure the Action to use an authenticated/mirrored NVD feed. Otherwise scans may be slower or behave differently.
Best practices when migrating Dependency-Check:
Translate CLI flags (--scan, --out, --format, --failOnCVSS) into the Action’s with inputs or into args.
Upload generated reports with actions/upload-artifact@v3 so they are available in the Actions UI.
For “publisher” logic (e.g., “fail build if N critical vulnerabilities”), convert to --failOnCVSS or implement a follow-up step that parses the XML report and fails the job based on thresholds from the Jenkins dependencyCheckPublisher config.
Next steps (next lesson/article):
Implement a custom transformer that extracts format, failOnCVSS, --scan path, and other important flags from the Jenkins JSON and emits a corresponding GitHub Actions step.
Translate the Dependency-Check publisher config: detect the XML pattern, and translate the “fail build if N criticals” logic into Action flags or a separate report-parsing step.