Skip to main content

Integration: GitHub Actions

This guide shows how to integrate Manicode prompts into CI/CD pipelines using GitHub Actions. The examples cover security-aware code generation and automated validation.

Validation Pipeline​

The most common CI integration: validate code changes against a security prompt and fail the build if issues are detected.

Workflow Definition​

# .github/workflows/security-validation.yml
name: Security Validation
on:
pull_request:
paths:
- 'src/**'
- 'app/**'

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

- name: Get changed files
id: changed
run: |
FILES=$(git diff --name-only origin/main...HEAD -- '*.py' '*.js' '*.ts' | head -20)
echo "files=$FILES" >> $GITHUB_OUTPUT

- name: Run security validation
if: steps.changed.outputs.files != ''
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
pip install anthropic

python - <<'SCRIPT'
import anthropic
import subprocess
import sys
import json

client = anthropic.Anthropic()

# Load the validation prompt
with open("prompts/validation/SV-U-01-nlp-security-guardrail-high.md") as f:
validation_prompt = f.read()

# Get changed files
result = subprocess.run(
["git", "diff", "--name-only", "origin/main...HEAD", "--", "*.py", "*.js", "*.ts"],
capture_output=True, text=True
)
changed_files = [f for f in result.stdout.strip().split("\n") if f][:20]

issues_found = False
for filepath in changed_files:
try:
with open(filepath) as f:
code = f.read()
except FileNotFoundError:
continue

if len(code) > 15000:
continue # Skip very large files

response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
system=validation_prompt,
messages=[
{"role": "user", "content": f"Review this code for security issues:\n\n```\n{code}\n```"}
]
)

output = response.content[0].text

if "BLOCK" in output or "HIGH" in output.upper():
print(f"SECURITY ISSUE in {filepath}:")
print(output)
print("---")
issues_found = True
else:
print(f"PASS: {filepath}")

if issues_found:
print("\nSecurity validation failed. See issues above.")
sys.exit(1)
else:
print("\nAll files passed security validation.")
SCRIPT

- name: Comment on PR
if: failure()
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr comment ${{ github.event.pull_request.number }} \
--body "Security validation failed. Check the workflow logs for details."

What This Does​

  1. Triggers on pull requests that modify source code files
  2. Identifies changed files (limits to 20 to control cost)
  3. Runs each file through the SV-U-01 NLP Security Guardrail validation prompt
  4. Fails the build if any file triggers a BLOCK or HIGH severity finding
  5. Comments on the PR if validation fails

Cost Control​

  • The workflow only processes files that changed in the PR, not the entire codebase
  • File count is capped at 20 per run
  • Files larger than 15,000 characters are skipped
  • Uses claude-sonnet-4-6 (faster, cheaper) rather than claude-opus-4-6 for validation

Threat Model Generation on Architecture Changes​

Automatically generate a threat model diagram when infrastructure or architecture files change:

# .github/workflows/threat-model.yml
name: Threat Model Update
on:
push:
branches: [main]
paths:
- 'docs/architecture.md'
- 'infrastructure/**'
- 'docker-compose*.yml'
- '*.tf'

jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Generate threat model
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
pip install anthropic

python - <<'SCRIPT'
import anthropic

client = anthropic.Anthropic()

with open("prompts/threat-modeling/12-threat-model-diagram-generator-opus.md") as f:
diagram_prompt = f.read()

with open("docs/architecture.md") as f:
architecture = f.read()

response = client.messages.create(
model="claude-opus-4-6",
max_tokens=8192,
system=diagram_prompt,
messages=[
{"role": "user", "content": architecture}
]
)

with open("docs/threat-model-diagram.md", "w") as f:
f.write(response.content[0].text)
SCRIPT

- name: Commit updated diagram
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
git add docs/threat-model-diagram.md
git diff --cached --quiet || git commit -m "chore: Update threat model diagram"
git push

Compliance Check on Schedule​

Run a quarterly compliance review and create a tracking issue:

# .github/workflows/compliance-review.yml
name: Quarterly Compliance Review
on:
schedule:
- cron: '0 9 1 */3 *' # First day of each quarter at 9am UTC
workflow_dispatch:

jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Run compliance review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
pip install anthropic
python scripts/run-compliance-review.py \
--framework soc2 \
--output compliance-report.md

- name: Create tracking issue
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
QUARTER="Q$(( ($(date +%-m)-1)/3+1 ))"
gh issue create \
--title "Quarterly SOC 2 Compliance Review - $(date +%Y)-$QUARTER" \
--body-file compliance-report.md \
--label "compliance"

Tips​

  • Use secrets — Store API keys in GitHub Secrets, never in workflow files
  • Limit scope — Only process changed files to control cost and runtime
  • Use cheaper models for validation — Validation prompts work well with smaller, faster models (Sonnet, Haiku)
  • Set timeouts — Add timeout-minutes: 10 to jobs to prevent runaway API costs
  • Cache prompts — If your prompts are in a separate repository, cache them to avoid re-fetching on every run