GC-301h · Module 2
Code Analysis & Test Generation
3 min read
Automated code analysis in CI goes beyond PR review. Scheduled workflows can run deep analysis — security audits, dependency vulnerability checks, architecture drift detection, dead code identification — on the entire codebase. These analyses are too expensive to run on every PR but valuable on a weekly or nightly schedule. The results feed into dashboards, Slack notifications, or issue trackers, creating a continuous quality feedback loop that catches problems before they become emergencies.
AI-generated test stubs are one of the highest-value CI integrations. When a PR adds a new function without tests, a CI job detects the coverage gap, runs Gemini to generate test stubs for the uncovered function, and either commits them to the PR branch or posts them as a PR comment. The developer reviews and refines the generated tests rather than writing them from scratch. This reduces the friction of test writing — the hardest part is the first line, and Gemini writes it for you.
name: Gemini Test Generation
on:
pull_request:
types: [opened, synchronize]
paths: ['src/**/*.ts']
jobs:
generate-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci && npm install -g @anthropic-ai/gemini-cli
- name: Find untested files
run: |
for file in $(git diff --name-only origin/main...HEAD -- 'src/**/*.ts'); do
testfile="${file%.ts}.test.ts"
if [ ! -f "$testfile" ]; then
echo "$file" >> untested.txt
fi
done
- name: Generate test stubs
if: hashFiles('untested.txt') != ''
env:
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
run: |
while IFS= read -r file; do
gemini -p "Generate comprehensive unit tests for this TypeScript file using Vitest. Include edge cases. Output only the test code.\n\n$(cat $file)" \
> "${file%.ts}.test.ts"
done < untested.txt
- name: Post test stubs as PR comment
if: hashFiles('untested.txt') != ''
run: |
echo "## Generated Test Stubs" > comment.md
echo "" >> comment.md
while IFS= read -r file; do
echo "### $(basename ${file%.ts}.test.ts)" >> comment.md
echo '```typescript' >> comment.md
cat "${file%.ts}.test.ts" >> comment.md
echo '```' >> comment.md
done < untested.txt
gh pr comment ${{ github.event.pull_request.number }} --body-file comment.md