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