CI/CD Integration
Integrate whogitit with your CI/CD pipeline to automatically add AI attribution summaries to pull requests.
GitHub Action
Basic Setup
Create .github/workflows/ai-attribution.yml:
name: AI Attribution Summary
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Fetch git notes
run: |
git fetch origin refs/notes/whogitit:refs/notes/whogitit || true
continue-on-error: true
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-whogitit-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-whogitit-
- name: Install whogitit
run: |
if ! command -v whogitit &> /dev/null; then
cargo install --git https://github.com/dotsetlabs/whogitit
fi
- name: Generate summary
id: summary
run: |
BASE_SHA="${{ github.event.pull_request.base.sha }}"
# Generate markdown summary
SUMMARY=$(whogitit summary --base "$BASE_SHA" --format markdown 2>/dev/null || echo "")
if [ -n "$SUMMARY" ]; then
# Save to file for the comment step
echo "$SUMMARY" > attribution-summary.md
echo "has_attribution=true" >> $GITHUB_OUTPUT
else
echo "has_attribution=false" >> $GITHUB_OUTPUT
fi
- name: Comment on PR
if: steps.summary.outputs.has_attribution == 'true'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const summary = fs.readFileSync('attribution-summary.md', 'utf8');
// Find existing comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(c =>
c.user.type === 'Bot' &&
c.body.includes('AI Attribution Summary')
);
const body = `## 🤖 AI Attribution Summary\n\n${summary}\n\n---\n*Generated by [whogitit](https://github.com/dotsetlabs/whogitit)*`;
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: body
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
}
Example PR Comment
The action posts a comment like:
🤖 AI Attribution Summary
This PR contains 3 of 5 commits with AI-assisted changes.
Overview
| Metric | Lines | Percentage |
|---|---|---|
| 🟢 AI-generated | 145 | 58.0% |
| 🟡 AI-modified by human | 12 | 4.8% |
| 🔵 Human-added | 43 | 17.2% |
| ⚪ Original/unchanged | 50 | 20.0% |
| Total | 250 | 100% |
AI involvement: 62.8% of changed lines
Commits with AI Attribution
| Commit | Message | AI | Modified | Human | Files |
|---|---|---|---|---|---|
abc1234 | Add user authentication | 45 | 3 | 10 | 2 |
def5678 | Implement JWT tokens | 100 | 9 | 33 | 3 |
Prompts Used (2)
Add user authentication with bcrypt password hashing...
Add user authentication with bcrypt password hashing. Create a User struct
with email and password_hash fields. Implement register and login functions
that return Result types.
Caching Strategy
The workflow caches:
- Cargo registry and indices
- Compiled binaries
- whogitit itself
This significantly speeds up subsequent runs.
Handling Missing Notes
Git notes may not exist if:
- The contributor didn’t push notes
- Notes haven’t been fetched yet
- The commits have no AI attribution
The workflow handles this gracefully:
- name: Fetch git notes
run: git fetch origin refs/notes/whogitit:refs/notes/whogitit || true
continue-on-error: true
Branch Protection
Consider adding AI attribution requirements:
# In a separate check job
- name: Check AI disclosure
run: |
AI_PERCENT=$(whogitit summary --base main --format json | jq '.summary.ai_percentage')
if (( $(echo "$AI_PERCENT > 80" | bc -l) )); then
echo "::warning::This PR has >80% AI-generated code. Ensure thorough review."
fi
GitLab CI
For GitLab, create .gitlab-ci.yml:
ai-attribution:
stage: review
image: rust:latest
only:
- merge_requests
before_script:
- cargo install --git https://github.com/dotsetlabs/whogitit
- git fetch origin refs/notes/whogitit:refs/notes/whogitit || true
script:
- |
SUMMARY=$(whogitit summary --base $CI_MERGE_REQUEST_TARGET_BRANCH_NAME --format markdown)
if [ -n "$SUMMARY" ]; then
echo "$SUMMARY" > attribution.md
# Post to MR via GitLab API
fi
artifacts:
paths:
- attribution.md
Jenkins
For Jenkins pipelines:
pipeline {
agent any
stages {
stage('AI Attribution') {
when {
changeRequest()
}
steps {
sh '''
git fetch origin refs/notes/whogitit:refs/notes/whogitit || true
whogitit summary --base origin/main --format markdown > attribution.md
'''
script {
def summary = readFile('attribution.md')
if (summary.trim()) {
// Post comment via GitHub/GitLab API
}
}
}
}
}
}
Custom Integrations
Slack Notification
#!/bin/bash
SUMMARY=$(whogitit summary --base main --format json)
AI_PERCENT=$(echo "$SUMMARY" | jq '.summary.ai_percentage')
if (( $(echo "$AI_PERCENT > 50" | bc -l) )); then
curl -X POST "$SLACK_WEBHOOK" \
-H 'Content-type: application/json' \
-d "{\"text\": \"PR #$PR_NUMBER has ${AI_PERCENT}% AI-generated code\"}"
fi
Export for Analytics
# In CI, export attribution data for each release
whogitit export \
--since "$LAST_RELEASE_DATE" \
--format json \
-o "attribution-$VERSION.json"
# Upload to S3 or analytics platform
aws s3 cp "attribution-$VERSION.json" "s3://metrics/ai-attribution/"
See Also
- summary - Summary command reference
- export - Export command reference
- Team Collaboration - Team policies