Skip to main content

A Jenkinsfile linter that validates Jenkinsfiles using Jenkins API

Project description

Jenkinsfile Lint

CI codecov PyPI version

Catch Jenkinsfile syntax errors before they break your CI.

jenkinsfilelint validates your Declarative Pipeline syntax via Jenkins's /pipeline-model-converter/validate endpoint. It's primarily a pre-commit hook, but also works as a standalone CLI tool.

📖 Read the official blog post for the story behind this tool.

demo

Table of Contents

Quick Start

pip install jenkinsfilelint

Then add the pre-commit hook (see below) or use the CLI directly.

Pre-commit Hook

Add the hook to your .pre-commit-config.yaml and install. Once configured, every commit that touches a Jenkinsfile is automatically validated.

Remote mode (with a Jenkins server)

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/jenkinsci/jenkinsfilelint
    rev: # use the latest or a specific version, e.g. v1.4.0
    hooks:
      - id: jenkinsfilelint

Set credentials via environment variables, then install:

export JENKINS_URL=https://jenkins.example.com
export JENKINS_USER=your-username
export JENKINS_TOKEN=your-api-token

pip install pre-commit
pre-commit install

Local mode (with Docker, no Jenkins server needed)

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/jenkinsci/jenkinsfilelint
    rev: # use the latest or a specific version, e.g. v1.4.0
    hooks:
      - id: jenkinsfilelint
        args: ["--local"]

Docker (or Podman) is the only requirement — no credentials needed:

pip install pre-commit
pre-commit install

The first commit pulls a minimal Jenkins container (~20–40s cold start). Subsequent commits reuse the running container and complete in milliseconds.

[!IMPORTANT] Local mode validates vanilla Declarative Pipeline syntax only. If your production Jenkins has plugins that provide custom options, agents, or steps (e.g., custom shared libraries), local mode may not catch errors related to those plugins. For authoritative validation, use remote mode pointing at your real Jenkins server.

In short: --local = fast syntax gate, remote = authoritative validation.

When you're done, stop the container:

jenkinsfilelint server stop

What happens on commit

A valid file passes silently:

git commit -m "Update Jenkinsfile"
jenkinsfilelint..........................................................Passed

A syntax error blocks the commit with a clear message:

git commit -m "Update Jenkinsfile"
jenkinsfilelint..........................................................Failed
- hook id: jenkinsfilelint
- exit code: 1

Errors encountered validating Jenkinsfile:
WorkflowScript: 17: Expected a step @ line 17, column 11.
             test
             ^

Fix the error and re-commit.

CLI

You can also run jenkinsfilelint directly on any file:

pip install jenkinsfilelint

jenkinsfilelint Jenkinsfile
jenkinsfilelint Jenkinsfile Jenkinsfile.prod tests/Jenkinsfile
jenkinsfilelint --local Jenkinsfile

Filtering files

Use --include (whitelist) and --skip (blacklist) to control which files are validated:

# Only validate Jenkinsfiles
jenkinsfilelint --include 'Jenkinsfile*' Jenkinsfile src/Utils.groovy

# Exclude shared-library helper classes
jenkinsfilelint --skip '*/src/*.groovy' --skip 'vars/*.groovy' Jenkinsfile src/Utils.groovy

These work in pre-commit too:

Exclude non-pipeline Groovy files (shared library helpers):

- id: jenkinsfilelint
  args: ["--skip=*/src/*.groovy", "--skip=vars/*.groovy"]

Only validate files matching specific patterns:

- id: jenkinsfilelint
  args: ["--include=Jenkinsfile*", "--include=pipelines/*.groovy"]

You can also combine both — --include narrows first, then --skip removes from that set:

- id: jenkinsfilelint
  args: ["--include=Jenkinsfile*", "--skip=*/src/*.groovy"]

Configuration

Supply credentials via environment variables (recommended) or CLI flags:

Env Variable CLI Flag Required
JENKINS_URL --jenkins-url Yes *
JENKINS_USER --username No **
JENKINS_TOKEN --token No **
JENKINSFILELINT_SERVER_IMAGE No

* Not required in --local mode. ** Only required if your Jenkins requires authentication (not used in --local mode).

[!TIP] Even if your Jenkins allows anonymous access for validation, using an API token is recommended for production setups.

CLI flags override env vars. There is no config file.

Local Docker image

By default, --local mode uses the official image ghcr.io/jenkinsci/jenkinsfilelint-server:latest. You can override this with the JENKINSFILELINT_SERVER_IMAGE environment variable if you maintain a custom build.

Security

[!WARNING] Never hardcode credentials in config files — use environment variables.

  • Never put --token or --username in .pre-commit-config.yaml — use environment variables.
  • Use an API token, not your password.
  • A regular user token with read access is sufficient — no need for admin privileges.

How It Works

jenkinsfilelint POSTs your Jenkinsfile to Jenkins's /pipeline-model-converter/validate endpoint and reports whether the syntax is valid. That's it — it only answers: "Will Jenkins accept this syntax?"

  • Remote mode: validates against your existing Jenkins server using the URL and credentials you configure.
  • Local mode (--local): automatically starts a lightweight Jenkins container (via Docker or Podman) and validates against it. The container is reused across runs for near-instant validation.

Requirements

  • Python 3.10+
  • For remote mode: a Jenkins server with the Pipeline plugin installed
  • For --local mode: Docker or Podman

Contributing

See CONTRIBUTING.md.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jenkinsfilelint-1.5.0.tar.gz (147.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jenkinsfilelint-1.5.0-py3-none-any.whl (14.3 kB view details)

Uploaded Python 3

File details

Details for the file jenkinsfilelint-1.5.0.tar.gz.

File metadata

  • Download URL: jenkinsfilelint-1.5.0.tar.gz
  • Upload date:
  • Size: 147.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for jenkinsfilelint-1.5.0.tar.gz
Algorithm Hash digest
SHA256 9d6d108b8b256b76eb41bb80b68c370efa990e73c71241d62242cc4cedb68991
MD5 4b76b7e0f3a927aba2e002d4fd7ce3a1
BLAKE2b-256 6017cdc76d4a739f493908db14910a4b7751fd511f4cda5ba73cbd98827d1b32

See more details on using hashes here.

Provenance

The following attestation bundles were made for jenkinsfilelint-1.5.0.tar.gz:

Publisher: release.yml on jenkinsci/jenkinsfilelint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jenkinsfilelint-1.5.0-py3-none-any.whl.

File metadata

  • Download URL: jenkinsfilelint-1.5.0-py3-none-any.whl
  • Upload date:
  • Size: 14.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for jenkinsfilelint-1.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 982a8ff7678617a2beda7ff2c6f7a6552902b6d37fb076fcf0a79d572032eb70
MD5 04e8f164d742d49c86666dd08ecf7e08
BLAKE2b-256 d30fbbaf5873558f27a874e601ecbf5935d9c22555fb2568edff5e52a01cf884

See more details on using hashes here.

Provenance

The following attestation bundles were made for jenkinsfilelint-1.5.0-py3-none-any.whl:

Publisher: release.yml on jenkinsci/jenkinsfilelint

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page