CI/CD Integration
nitpik integrates with every major CI platform. This page covers setup for each, including token management, caching, and secret handling best practices.
Note: As of the initial release, only GitHub Actions has been thoroughly tested. More in-depth testing of other CI platforms will follow.
Docker
The official Docker image ships with git and the nitpik binary:
docker pull ghcr.io/nsrosenqvist/nitpik:latest
Mount your repository and pass environment variables:
docker run --rm \
-v "$(pwd)":/repo \
-e NITPIK_PROVIDER=anthropic \
-e ANTHROPIC_API_KEY \
-e NITPIK_LICENSE_KEY \
ghcr.io/nsrosenqvist/nitpik:latest review --diff-base main --scan-secrets
GitHub Actions
Using the Official Action (Recommended)
on: pull_request
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/cache/restore@v4
with:
path: ~/.config/nitpik/cache
key: nitpik-${{ github.repository }}
- uses: nsrosenqvist/nitpik@v1
with:
profiles: backend,security
fail_on: warning
scan_secrets: "true"
env:
NITPIK_PROVIDER: ${{ vars.NITPIK_PROVIDER }}
NITPIK_MODEL: ${{ vars.NITPIK_MODEL }}
NITPIK_API_KEY: ${{ secrets.NITPIK_API_KEY }}
NITPIK_LICENSE_KEY: ${{ secrets.NITPIK_LICENSE_KEY }}
- uses: actions/cache/save@v4
if: always()
with:
path: ~/.config/nitpik/cache
key: nitpik-${{ github.repository }}
The action auto-detects the PR target branch, downloads the binary, and outputs findings as inline annotations on the pull request.
Tip: Store
NITPIK_PROVIDERandNITPIK_MODELas repository variables (Settings → Secrets and variables → Actions → Variables) andNITPIK_API_KEYas a repository secret. Repository variables are not automatically available as environment variables — reference them with${{ vars.* }}in your workflow.
Manual Setup
If you prefer not to use the action:
on: pull_request
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/cache/restore@v4
with:
path: ~/.config/nitpik/cache
key: nitpik-${{ github.repository }}
- name: Install nitpik
run: curl -sSfL https://github.com/nsrosenqvist/nitpik/releases/latest/download/nitpik-x86_64-unknown-linux-gnu.tar.gz | sudo tar xz -C /usr/local/bin
- name: AI Code Review
run: |
nitpik review \
--diff-base "origin/$GITHUB_BASE_REF" \
--profile backend,security \
--format github \
--fail-on warning \
--scan-secrets
env:
NITPIK_PROVIDER: ${{ vars.NITPIK_PROVIDER }}
NITPIK_MODEL: ${{ vars.NITPIK_MODEL }}
NITPIK_API_KEY: ${{ secrets.NITPIK_API_KEY }}
NITPIK_LICENSE_KEY: ${{ secrets.NITPIK_LICENSE_KEY }}
- uses: actions/cache/save@v4
if: always()
with:
path: ~/.config/nitpik/cache
key: nitpik-${{ github.repository }}
Key details:
fetch-depth: 0is required for--diff-baseto have access to the full git history.--format githuboutputs findings as workflow commands that appear as inline PR annotations.--fail-on warningcauses the step to fail if any warning or error is found.actions/cache/restoreandactions/cache/saveare used as separate steps so the cache is always persisted — even when--fail-oncauses the review step to exit non-zero.
Security: Always pass API keys via
${{ secrets.* }}— never hardcode them in workflow files.
GitLab CI/CD
code-review:
stage: test
image: ghcr.io/nsrosenqvist/nitpik:latest
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- git fetch origin "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
- nitpik review
--diff-base "origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
--profile backend,security
--format gitlab
--fail-on warning
--scan-secrets
> gl-code-quality-report.json
cache:
key: nitpik
paths:
- .nitpik-cache/
when: always
artifacts:
reports:
codequality: gl-code-quality-report.json
variables:
NITPIK_PROVIDER: anthropic
ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY
NITPIK_LICENSE_KEY: $NITPIK_LICENSE_KEY
XDG_CONFIG_HOME: $CI_PROJECT_DIR/.nitpik-cache
Key details:
--format gitlaboutputs a Code Quality report JSON file.- Upload it as a
codequalityartifact to see findings in the merge request Code Quality widget. - Set
XDG_CONFIG_HOMEto a path inside the project directory so the cache is preserved between runs. when: alwaysensures the cache is saved even when--fail-oncauses the job to exit non-zero. Without it, GitLab only saves the cache on success.
Bitbucket Pipelines
The bitbucket format posts findings as Code Insights annotations via the Bitbucket API. Inside Bitbucket Pipelines, authentication is handled automatically — no token required.
Pipeline Config
definitions:
caches:
nitpik: /root/.config/nitpik/cache
pipelines:
pull-requests:
'**':
- step:
image: ghcr.io/nsrosenqvist/nitpik:latest
caches:
- nitpik
script:
- git fetch origin "$BITBUCKET_PR_DESTINATION_BRANCH"
- nitpik review
--diff-base "origin/$BITBUCKET_PR_DESTINATION_BRANCH"
--profile security,backend
--format bitbucket
--fail-on error
--scan-secrets
variables:
NITPIK_PROVIDER: anthropic
ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY
NITPIK_LICENSE_KEY: $NITPIK_LICENSE_KEY
Note: Inside Bitbucket Pipelines, nitpik uses the built-in authentication proxy at
localhost:29418to post Code Insights — noBITBUCKET_TOKENneeded. If you run nitpik outside Pipelines (e.g. a self-hosted runner), setBITBUCKET_TOKENwithpullrequestandrepository:writescopes.
Alternative: Checkstyle Format
If you prefer a file-based approach without any API calls, use --format checkstyle and pipe the output to the Checkstyle Code Insight Report pipe:
pipelines:
pull-requests:
'**':
- step:
image: ghcr.io/nsrosenqvist/nitpik:latest
script:
- git fetch origin "$BITBUCKET_PR_DESTINATION_BRANCH"
- nitpik review
--diff-base "origin/$BITBUCKET_PR_DESTINATION_BRANCH"
--profile security,backend
--format checkstyle
--fail-on error
--scan-secrets
> checkstyle-report.xml
variables:
NITPIK_PROVIDER: anthropic
ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY
NITPIK_LICENSE_KEY: $NITPIK_LICENSE_KEY
Security: Add
ANTHROPIC_API_KEYandNITPIK_LICENSE_KEYas secured pipeline variables — never hardcode them inbitbucket-pipelines.yml.
Other CI Platforms
For CI platforms without a dedicated output format, use --format checkstyle to produce standard Checkstyle XML and feed it into a tool that your platform supports:
- Jenkins — the Warnings Next Generation plugin natively ingests checkstyle XML and displays findings in build results.
- Any platform — reviewdog accepts checkstyle XML via
-f=checkstyleand posts annotations to GitHub, GitLab, Bitbucket, Gitea, and more.
# Example: pipe nitpik output through reviewdog
nitpik review --diff-base main --format checkstyle | reviewdog -f=checkstyle -reporter=github-pr-review
See Output Formats — Checkstyle XML for details.
Woodpecker CI (Forgejo / Gitea / Codeberg)
The forgejo format posts findings as inline PR review comments via the Forgejo/Gitea API.
Token Setup
Create a personal access token with at minimum the write:repository scope under User settings → Applications → Generate New Token in your Forgejo or Gitea instance.
Add it as a Woodpecker secret named forgejo_token so it's exposed as FORGEJO_TOKEN at runtime.
Pipeline Config
when:
event: pull_request
steps:
- name: ai-review
image: ghcr.io/nsrosenqvist/nitpik:latest
commands:
- git fetch origin "$CI_COMMIT_TARGET_BRANCH"
- nitpik review
--diff-base "origin/$CI_COMMIT_TARGET_BRANCH"
--profile backend,security
--format forgejo
--fail-on warning
--scan-secrets
secrets: [forgejo_token, anthropic_api_key, nitpik_license_key]
environment:
NITPIK_PROVIDER: anthropic
volumes:
- nitpik-cache:/root/.config/nitpik/cache
Security: Add
anthropic_api_key,nitpik_license_key, andforgejo_tokenas Woodpecker secrets — never hardcode them in the pipeline file.
CI Best Practices
Caching
Always cache ~/.config/nitpik/cache (or the Docker equivalent) between runs. This avoids re-reviewing unchanged files and reduces API cost significantly on iterative PRs.
Secret Scanning
Enable --scan-secrets in CI pipelines. This catches accidentally committed secrets and redacts them before they reach the LLM.
Fail-On Threshold
By default, nitpik exits non-zero when any finding has severity error. Use --fail-on to adjust the threshold:
--fail-on error— block only on confirmed bugs (default)--fail-on warning— block on likely issues (recommended for most teams)--fail-on info— block on any finding (strictest)
To disable failure entirely, pass --no-fail.
Quiet Mode
Add --quiet in CI to suppress the banner and progress display, keeping logs clean:
nitpik review --diff-base main --format github --quiet
Audit Logs as Build Artifacts
Use --audit-log <PATH> (or NITPIK_AUDIT_LOG) to write a JSON record of the run — per-task status, tool calls, retries, token usage, critic decisions, and final findings — and upload it as a build artifact for after-the-fact debugging:
# GitHub Actions
- name: Run nitpik
run: nitpik review --diff-base origin/main --audit-log nitpik-audit.json --format github
- uses: actions/upload-artifact@v4
if: always()
with:
name: nitpik-audit
path: nitpik-audit.json
Related Pages
- Output Formats — format details and
--fail-onbehavior - Configuration — environment variables and config files
- Secret Scanning — enabling secret detection
- Caching — how caching saves API cost