CI/CD Integrations Guideο
Complete guide for integrating ai-slop-gate into your CI/CD pipelines.
Quick Referenceο
Platform |
Status |
|---|---|
GitHub Actions |
Full Support |
GitLab CI |
Full Support |
Before You Startο
--policy is required for every run commandο
policy.yml controls which directories are sent to providers via include_paths.
Without it, LLM providers receive the entire repository and fail with token-limit errors.
Policy discovery order:
--policy <explicit path>β always wins<--path>/policy.ymlβ auto-discovered if the scanned repo has its own policy./policy.ymlβ current working directoryBundled default (permissive, no
include_pathsβ not safe for LLM providers)
Recommendation: every repository you scan should have its own minimal policy.yml
(see the Minimal Policy section below).
Enforcement levelsο
Flag |
Behaviour |
When to use |
|---|---|---|
|
Findings reported, CI always passes |
Initial rollout, noise tuning |
|
CI fails on violations |
Production gate |
|
Report only, exit 0 always |
Dry-run / debugging |
Start with advisory. Switch to blocking once the baseline is clean.
Minimal Policy for a Target Repositoryο
Place this policy.yml in the root of the repository you want to scan.
The gate will auto-discover it when you pass --path pointing to that repository.
# policy.yml β minimal config for the scanned repository
version: "v1.4"
project_name: "my-project"
enforcement: advisory # start here; tighten to blocking after tuning
# Required for LLM providers.
# Without include_paths, the entire repo is sent to the API β token limit errors.
include_paths:
- src # adjust to your source directory
ai_provider:
name: groq
models:
groq: llama-3.3-70b-versatile
compliance:
enabled: false
rules:
- id: block-hardcoded-secrets
when:
signal: "hardcoded_.*"
then:
action: blocking
message: "Hardcoded secret detected."
Supported Providersο
Provider |
API key required |
Mode |
|---|---|---|
|
No |
Deterministic β secrets, Dockerfile, PII, supply-chain |
|
|
LLM β PR diff or |
|
|
LLM β PR diff or |
|
No (local) |
LLM β local only, 100% private |
LLM providers in --llm-local mode automatically exclude: .env, policy.yml,
docs/, scripts/, lock files, minified bundles.
GitHub Actionsο
Recommended Workflow Structureο
The official workflow uses parallel jobs so static, LLM, and compliance steps
run independently and never block each other by accident.
Use --enforcement advisory while tuning; switch individual jobs to blocking when ready.
name: AI Slop Gate Analyze
on:
push:
branches: [main]
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
jobs:
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# STATIC ANALYSIS β runs on every push and PR
# Fast, no API key required. Trivy and Syft must be installed for
# vulnerability scanning and SBOM generation.
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
static-analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
- name: Install ai-slop-gate
run: pip install -e .
- name: Install Trivy
run: |
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \
| sh -s -- -b /usr/local/bin v0.69.2
- name: Install Syft
run: |
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh \
| sh -s -- -b /usr/local/bin
- name: Run Static Analysis
run: |
python -m ai_slop_gate.cli run \
--provider static \
--policy policy.yml \
--path . \
--enforcement advisory \
--verbose
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# LLM ANALYSIS β PR only
# Groq analyses the local source code. policy.yml must define include_paths
# or the run aborts before sending anything to the API.
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
llm-analysis:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
- name: Install ai-slop-gate
run: pip install -e .
- name: Cache LLM responses
uses: actions/cache@v3
with:
path: .ai-slop-cache
key: llm-cache-${{ hashFiles('**/*.py', '**/*.js', '**/*.ts') }}
restore-keys: llm-cache-
- name: Run Groq LLM Analysis
env:
GROQ_API_KEY: ${{ secrets.SLOPE_GATE_GROQ }}
run: |
python -m ai_slop_gate.cli run \
--provider groq \
--llm-local \
--policy policy.yml \
--path . \
--enforcement advisory \
--verbose
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# COMPLIANCE β runs on every push and PR
# License audit, GDPR, secret detection. Scoped to application code only.
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
compliance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
- name: Install ai-slop-gate
run: pip install -e .
- name: Run Compliance Check
run: |
python -m ai_slop_gate.cli run \
--compliance \
--policy policy.yml \
--path ai_slop_gate \
--enforcement advisory \
--verbose
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# PR COMMENT β PR only, runs after the other jobs
# Posts a consolidated Groq report as a PR comment.
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
pr-comment:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
needs: [static-analysis, llm-analysis, compliance]
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
- name: Install ai-slop-gate
run: pip install -e .
- name: Restore LLM cache
uses: actions/cache@v3
with:
path: .ai-slop-cache
key: llm-cache-${{ hashFiles('**/*.py', '**/*.js', '**/*.ts') }}
restore-keys: llm-cache-
- name: Post PR Comment
env:
GROQ_API_KEY: ${{ secrets.SLOPE_GATE_GROQ }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python -m ai_slop_gate.cli run \
--provider groq \
--github-repo ${{ github.repository }} \
--pr-id ${{ github.event.pull_request.number }} \
--policy policy.yml \
--path . \
--enforcement advisory
Minimal Static-Only Workflowο
Fast gate with no API keys required:
name: Static Analysis
on: [pull_request]
jobs:
static:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
- run: pip install -e .
- run: |
python -m ai_slop_gate.cli run \
--provider static \
--policy policy.yml \
--enforcement advisory
GitHub PR Comment (All-in-One)ο
name: PR Analysis
on:
pull_request:
types: [opened, synchronize]
jobs:
pr-comment:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
- run: pip install -e .
- name: Analyze PR and Post Comment
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GROQ_API_KEY: ${{ secrets.SLOPE_GATE_GROQ }}
run: |
python -m ai_slop_gate.cli run \
--provider groq \
--github-repo ${{ github.repository }} \
--pr-id ${{ github.event.pull_request.number }} \
--policy policy.yml \
--enforcement advisory
--github-repo,--pr-id, andGITHUB_TOKENare all required together for PR commenting. In PR mode the LLM receives only the diff βinclude_pathsguard is skipped.
GitHub Secrets Setupο
Go to Settings β Secrets and variables β Actions and add:
Secret |
Description |
|---|---|
|
Groq API key |
|
Google Gemini API key (if using Gemini) |
|
Auto-provided by GitHub β no setup needed |
GitLab CIο
Recommended .gitlab-ci.ymlο
stages:
- analyze
variables:
GROQ_API_KEY: $SLOPE_GATE_GROQ
GITLAB_TOKEN: $GITLAB_TOKEN
# ββ Static analysis βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
static_analysis:
stage: analyze
image: ghcr.io/sergudo/ai-slop-gate:latest
script:
- ai-slop-gate run
--provider static
--policy policy.yml
--path .
--enforcement advisory
--verbose
only:
- merge_requests
- main
# ββ LLM analysis βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# policy.yml must define include_paths β otherwise the job aborts before any
# files are sent to the API.
llm_analysis:
stage: analyze
image: ghcr.io/sergudo/ai-slop-gate:latest
variables:
GROQ_API_KEY: $SLOPE_GATE_GROQ
cache:
key: llm-cache-$CI_COMMIT_REF_SLUG
paths:
- .ai-slop-cache/
script:
- ai-slop-gate run
--provider groq
--llm-local
--policy policy.yml
--path .
--enforcement advisory
only:
- merge_requests
# ββ MR comment βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
mr_comment:
stage: analyze
image: ghcr.io/sergudo/ai-slop-gate:latest
variables:
GITLAB_TOKEN: $GITLAB_TOKEN
GROQ_API_KEY: $GROQ_API_KEY
script:
- ai-slop-gate run
--provider groq
--gitlab-project $CI_PROJECT_PATH
--mr-iid $CI_MERGE_REQUEST_IID
--gitlab-url $CI_SERVER_URL
--policy policy.yml
--enforcement advisory
only:
- merge_requests
# ββ Compliance βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
compliance:
stage: analyze
image: ghcr.io/sergudo/ai-slop-gate:latest
script:
- ai-slop-gate run
--compliance
--policy policy.yml
--path .
--enforcement advisory
only:
- merge_requests
- main
GitLab Variables Setupο
Go to Settings β CI/CD β Variables and add (protected + masked):
Variable |
Description |
|---|---|
|
Groq API key |
|
Google Gemini API key (if using Gemini) |
|
GitLab access token with |
Advanced Patternsο
Progressive Enforcementο
Run advisory on feature branches, blocking on main:
- name: Run Analysis
run: |
ENFORCEMENT="advisory"
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
ENFORCEMENT="blocking"
fi
python -m ai_slop_gate.cli run \
--provider static \
--policy policy.yml \
--enforcement $ENFORCEMENT
Matrix Strategy (Multiple Providers in Parallel)ο
jobs:
analyze:
strategy:
fail-fast: false
matrix:
provider: [static, groq]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
- run: pip install -e .
- name: Cache (LLM only)
if: matrix.provider != 'static'
uses: actions/cache@v3
with:
path: .ai-slop-cache
key: llm-cache-${{ matrix.provider }}-${{ hashFiles('**/*.py') }}
- name: Run ${{ matrix.provider }}
env:
GROQ_API_KEY: ${{ secrets.SLOPE_GATE_GROQ }}
run: |
EXTRA=""
if [ "${{ matrix.provider }}" != "static" ]; then
EXTRA="--llm-local"
fi
python -m ai_slop_gate.cli run \
--provider ${{ matrix.provider }} \
--policy policy.yml \
--enforcement advisory \
$EXTRA
Scheduled Deep Scan (Weekly)ο
name: Weekly Deep Scan
on:
schedule:
- cron: '0 2 * * 1' # Every Monday at 2 AM
jobs:
deep-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
- run: pip install -e .
- name: Full Scan (no cache β fresh results)
env:
GROQ_API_KEY: ${{ secrets.SLOPE_GATE_GROQ }}
run: |
python -m ai_slop_gate.cli run \
--provider static groq \
--llm-local \
--compliance \
--policy policy.yml \
--no-cache \
--enforcement advisory \
--verbose
Best Practicesο
1. Always include --policy with include_pathsο
# β
GOOD β scoped to source directory
python -m ai_slop_gate.cli run --provider groq --llm-local --policy policy.yml
# β BAD β entire repo sent to the API, token limit hit
python -m ai_slop_gate.cli run --provider groq --llm-local
2. Start with advisory, tighten laterο
# Step 1: understand findings
--enforcement advisory
# Step 2: once baseline is clear
--enforcement blocking
3. Always cache LLM responses in CIο
- uses: actions/cache@v3
with:
path: .ai-slop-cache
key: llm-cache-${{ hashFiles('**/*.py', '**/*.js') }}
restore-keys: llm-cache-
4. Use secrets, never inline API keysο
# β
GOOD
env:
GROQ_API_KEY: ${{ secrets.SLOPE_GATE_GROQ }}
# β BAD β visible in logs and git history
env:
GROQ_API_KEY: "gsk_actual_key_here"
5. Run static and LLM jobs in parallelο
Static analysis is fast (~5s). LLM analysis takes ~15s on first run (cached after). Running them as separate parallel jobs gives faster overall feedback.
Troubleshootingο
βthe following arguments are required: βpolicyβο
Every run command requires --policy. Add it:
python -m ai_slop_gate.cli run --provider static --policy policy.yml
βLLM providers require include_pathsβο
Your policy.yml is missing include_paths. Add it:
include_paths:
- src
βAPI rate limit exceededβο
Enable cache (default) and avoid --no-cache in CI. Cache persists between runs
with actions/cache.
βTrivy / Syft binary not foundβο
Install them explicitly in the workflow before running static analysis:
- name: Install Trivy
run: |
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \
| sh -s -- -b /usr/local/bin v0.69.2
- name: Install Syft
run: |
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh \
| sh -s -- -b /usr/local/bin