CI/CD Integrations

CI/CD Integrations

GauntletCI runs anywhere that can execute a .NET tool. Install it with dotnet tool install -g GauntletCI on any runner that has .NET 8 available - GitHub Actions, GitLab CI, Azure Pipelines, Bitbucket Pipelines, or your local machine.

GitHub Actions

The simplest setup uses the published Marketplace action. Add this workflow to analyze every pull request:

name: GauntletCI Analysis

on:
  pull_request:
    branches: [main]

permissions:
  pull-requests: write   # required for inline-comments: 'true'

jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: EricCogen/GauntletCI@v2.1.0
        with:
          sensitivity: 'balanced'
          inline-comments: 'true'
          fail-on-findings: 'true'

The action installs .NET, installs GauntletCI, runs analysis against the PR commit, and optionally posts findings as inline review comments. Set inline-comments: 'false' to write findings to the Actions log only.

Manual install (without the Marketplace action)

Use this approach if you need full control over the workflow steps or are pinning to a specific tool version.

name: GauntletCI Analysis

on:
  pull_request:
    branches: [main]

jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '8.0.x'

      - name: Install GauntletCI
        run: dotnet tool install -g GauntletCI

      - name: Analyze PR diff
        run: |
          git diff origin/${{ github.base_ref }}...HEAD > pr.diff
          gauntletci analyze --diff pr.diff --github-annotations
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

The workflow exits with code 1 if blocking findings are detected, failing the check and blocking the merge until findings are addressed or accepted.

GitLab CI

Add this job to your .gitlab-ci.yml. The job runs only on merge request pipelines and uses the official Microsoft .NET SDK Docker image.

gauntletci-analysis:
  image: mcr.microsoft.com/dotnet/sdk:8.0
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script:
    - export PATH="$PATH:$HOME/.dotnet/tools"
    - dotnet tool install -g GauntletCI
    - git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
    - git diff origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME...HEAD > pr.diff
    - gauntletci analyze --diff pr.diff --no-banner --ascii
  allow_failure: false

GitLab CI exposes $CI_MERGE_REQUEST_TARGET_BRANCH_NAME automatically on merge request pipelines. The allow_failure: false line blocks the merge if findings are detected. Set it to true to make the job advisory only.

Azure Pipelines

trigger: none
pr:
  branches:
    include: [main]

pool:
  vmImage: ubuntu-latest

steps:
  - task: UseDotNet@2
    inputs:
      version: '8.0.x'

  - script: dotnet tool install -g GauntletCI
    displayName: Install GauntletCI

  - script: |
      git diff origin/$(System.PullRequest.TargetBranch)...HEAD > pr.diff
      gauntletci analyze --diff pr.diff --no-banner
    displayName: Analyze PR diff

Bitbucket Pipelines

Add this to your bitbucket-pipelines.yml. The job runs on all pull request branches using the Microsoft .NET SDK image.

image: mcr.microsoft.com/dotnet/sdk:8.0

pipelines:
  pull-requests:
    '**':
      - step:
          name: GauntletCI Analysis
          script:
            - export PATH="$PATH:$HOME/.dotnet/tools"
            - dotnet tool install -g GauntletCI
            - git fetch origin $BITBUCKET_PR_DESTINATION_BRANCH
            - git diff origin/$BITBUCKET_PR_DESTINATION_BRANCH...HEAD > pr.diff
            - gauntletci analyze --diff pr.diff --no-banner --ascii

Bitbucket exposes $BITBUCKET_PR_DESTINATION_BRANCH automatically on pull request pipelines. The step fails (blocking merge) if GauntletCI exits with code 1.

Pre-commit hook (local)

The fastest setup. Runs automatically before every commit; no CI required.

$ cd your-repo

$ gauntletci init

This installs a .git/hooks/pre-commit script that runs gauntletci analyze --staged on every commit attempt. The commit is blocked if exit code 1 is returned.

Exit code behavior

Exit codeMeaningCI result
0No findingsPass
1Findings detectedFail / block merge
2Unhandled errorFail

Control which severity triggers a failure via exitOn in your .gauntletci.json.

JSON output for downstream tooling

Use --output json to consume findings in scripts, dashboards, or custom integrations.

With jq

$ gauntletci analyze --staged --output json | jq .findings

With PowerShell (no jq required)

PS> gauntletci analyze --staged --output json | ConvertFrom-Json | Select-Object -ExpandProperty findings

With Python (no jq required)

$ gauntletci analyze --staged --output json | python -c "import sys,json; data=json.load(sys.stdin); print(json.dumps(data['findings'], indent=2))"

Save to file

$ gauntletci analyze --staged --output json > report.json

Writing to a file works with any downstream tool: upload to S3, attach to a Slack notification, parse in a build script, or archive as a CI artifact.

LLM enrichment in CI/CD

The built-in ONNX engine (Option 1 in the Local LLM Setup docs) is not available in CI. Loading a 2 GB model in an ephemeral runner is impractical. To use --with-llm in CI, configure a remote OpenAI-compatible endpoint:

# In your CI environment secrets
GAUNTLETCI_LLM_API_KEY=sk-...

# In .gauntletci.json
{
  "llm": {
    "ciEndpoint": "https://api.openai.com/v1",
    "ciModel": "gpt-4o-mini"
  }
}

If --with-llm is passed in CI with no endpoint configured, GauntletCI prints a loud warning to stderr and skips enrichment. Detection findings are still reported normally.