| name | github-workflow-automation |
| description | Patterns for automating GitHub workflows with AI assistance, inspired by [Gemini CLI](https://github.com/google-gemini/gemini-cli) and modern DevOps practices. |
| risk | unknown |
| source | community |
| date_added | 2026-02-27 |
🔧 GitHub Workflow Automation
Patterns for automating GitHub workflows with AI assistance, inspired by Gemini CLI and modern DevOps practices.
When to Use This Skill
Use this skill when:
- Automating PR reviews with AI
- Setting up issue triage automation
- Creating GitHub Actions workflows
- Integrating AI into CI/CD pipelines
- Automating Git operations (rebases, cherry-picks)
1. Automated PR Review
1.1 PR Review Action
name: AI Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get changed files
id: changed
run: |
files=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
echo "files<<EOF" >> $GITHUB_OUTPUT
echo "$files" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Get diff
id: diff
run: |
diff=$(git diff origin/${{ github.base_ref }}...HEAD)
echo "diff<<EOF" >> $GITHUB_OUTPUT
echo "$diff" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: AI Review
uses: actions/github-script@v7
with:
script: |
const { Anthropic } = require('@anthropic-ai/sdk');
const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
const response = await client.messages.create({
model: "claude-3-sonnet-20240229",
max_tokens: 4096,
messages: [{
role: "user",
content: `Review this PR diff and provide feedback:
Changed files: ${{ steps.changed.outputs.files }}
Diff:
${{ steps.diff.outputs.diff }}
Provide:
1. Summary of changes
2. Potential issues or bugs
3. Suggestions for improvement
4. Security concerns if any
Format as GitHub markdown.`
}]
});
await github.rest.pulls.createReview({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
body: response.content[0].text,
event: 'COMMENT'
});
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
1.2 Review Comment Patterns
# AI Review Structure
## 📋 Summary
Brief description of what this PR does.
## ✅ What looks good
- Well-structured code
- Good test coverage
- Clear naming conventions
## ⚠️ Potential Issues
1. **Line 42**: Possible null pointer exception
```javascript
// Current
user.profile.name;
// Suggested
user?.profile?.name ?? "Unknown";
```
- Line 78: Consider error handling
💡 Suggestions
- Consider extracting the validation logic into a separate function
- Add JSDoc comments for public methods
🔒 Security Notes
- No sensitive data exposure detected
- API key handling looks correct
### 1.3 Focused Reviews
```yaml
# Review only specific file types
- name: Filter code files
run: |
files=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | \
grep -E '\.(ts|tsx|js|jsx|py|go)$' || true)
echo "code_files=$files" >> $GITHUB_OUTPUT
# Review with context
- name: AI Review with context
run: |
# Include relevant context files
context=""
for file in ${{ steps.changed.outputs.files }}; do
if [[ -f "$file" ]]; then
context+="=== $file ===\n$(cat $file)\n\n"
fi
done
# Send to AI with full file context
2. Issue Triage Automation
2.1 Auto-label Issues
name: Issue Triage
on:
issues:
types: [opened]
jobs:
triage:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Analyze issue
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
// Call AI to analyze
const analysis = await analyzeIssue(issue.title, issue.body);
// Apply labels
const labels = [];
if (analysis.type === 'bug') {
labels.push('bug');
if (analysis.severity
} {
} {
}
{
{}
}
{
{
,
,
,
,
, ,
}
}
2.2 Issue Analysis Prompt
const TRIAGE_PROMPT = `
Analyze this GitHub issue and classify it:
Title: {title}
Body: {body}
Return JSON with:
{
"type": "bug" | "feature" | "question" | "docs" | "other",
"severity": "low" | "medium" | "high" | "critical",
"area": "frontend" | "backend" | "api" | "docs" | "ci" | "other",
"summary": "one-line summary",
"hasReproSteps": boolean,
"isFirstContribution": boolean,
"suggestedLabels": ["label1", "label2"],
"suggestedAssignees": ["username"] // based on area expertise
}
`;
2.3 Stale Issue Management
name: Manage Stale Issues
on:
schedule:
- cron: "0 0 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
stale-issue-message: |
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed in 14 days if no further activity occurs.
If this issue is still relevant:
- Add a comment with an update
3. CI/CD Integration
3.1 Smart Test Selection
name: Smart Test Selection
on:
pull_request:
jobs:
analyze:
runs-on: ubuntu-latest
outputs:
test_suites: ${{ steps.analyze.outputs.suites }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Analyze changes
id: analyze
run: |
changed=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
suites="[]"
if echo "$changed" | grep -q "^src/api/"; then
suites=$(echo $suites | jq '. + ["api"]'
[ ]
[ ]
3.2 Deployment with AI Validation
name: Deploy with AI Validation
on:
push:
branches: [main]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get deployment changes
id: changes
run: |
last_deploy=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -n "$last_deploy" ]; then
changes=$(git log --oneline $last_deploy..HEAD)
else
changes=$(git log --oneline -10)
fi
echo
{
,
[, ],
[, ],
}
{
}
3.3 Rollback Automation
name: Automated Rollback
on:
workflow_dispatch:
inputs:
reason:
description: "Reason for rollback"
required: true
jobs:
rollback:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Find last stable version
id: stable
run: |
stable=$(git tag -l 'v*' --sort=-version:refname | head -1)
echo "version=$stable" >> $GITHUB_OUTPUT
- name: Rollback
run: |
git checkout ${{
{
,
[
{
,
{
,
}
}
]
}
4. Git Operations
4.1 Automated Rebasing
name: Auto Rebase
on:
issue_comment:
types: [created]
jobs:
rebase:
if: github.event.issue.pull_request && contains(github.event.comment.body, '/rebase')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Rebase PR
run: |
gh pr checkout ${{
4.2 Smart Cherry-Pick
async function smartCherryPick(commitHash: string, targetBranch: string) {
const commitInfo = await exec(`git show ${commitHash} --stat`);
const targetDiff = await exec(
`git diff ${targetBranch}...HEAD -- ${affectedFiles}`
);
const analysis = await ai.analyze(`
I need to cherry-pick this commit to ${targetBranch}:
${commitInfo}
Current state of affected files on ${targetBranch}:
${targetDiff}
Will there be conflicts? If so, suggest resolution strategy.
`);
if (analysis.willConflict) {
await exec(
`git checkout -b cherry-pick-${commitHash.slice(0, 7)} ${targetBranch}`
);
const result = await exec(`git cherry-pick ${commitHash}`, {
allowFail: ,
});
(result.) {
conflicts = ();
( conflict conflicts) {
resolution = ai.(conflict);
(conflict., resolution);
}
}
} {
();
();
}
}
4.3 Branch Cleanup
name: Branch Cleanup
on:
schedule:
- cron: '0 0 * * 0'
workflow_dispatch:
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Find stale branches
id: stale
run: |
stale=$(git for-each-ref --sort=-committerdate refs/remotes/origin \
--format='%(refname:short) %(committerdate:relative)' | \
grep -E '[3-9][0-9]+ days|[0-9]+ months|[0-9]+ years' | \
grep -v 'origin/main\|origin/develop' | \
cut -d'
[ ]
[ ]
[]
5. On-Demand Assistance
5.1 @mention Bot
name: AI Mention Bot
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
jobs:
respond:
if: contains(github.event.comment.body, '@ai-helper')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Extract question
id: question
run: |
question=$(echo "${{ github.event.comment.body }}" | sed 's/.*@ai-helper//')
echo "question=$question" >> $GITHUB_OUTPUT
- name: Get context
id: context
run: |
if [ "$" ]
5.2 Command Patterns
## Available Commands
| Command | Description |
| :------------------- | :-------------------------- |
| `@ai-helper explain` | Explain the code in this PR |
| `@ai-helper review` | Request AI code review |
| `@ai-helper fix` | Suggest fixes for issues |
| `@ai-helper test` | Generate test cases |
| `@ai-helper docs` | Generate documentation |
| `/rebase` | Rebase PR onto main |
| `/update` | Update PR branch from main |
| `/approve` | Mark as approved by bot |
| `/label bug` | Add 'bug' label |
| `/assign @user` | Assign to user |
6. Repository Configuration
6.1 CODEOWNERS
# .github/CODEOWNERS
# Global owners
* @org/core-team
# Frontend
/src/frontend/ @org/frontend-team
*.tsx @org/frontend-team
*.css @org/frontend-team
# Backend
/src/api/ @org/backend-team
/src/database/ @org/backend-team
# Infrastructure
/.github/ @org/devops-team
/terraform/ @org/devops-team
Dockerfile @org/devops-team
# Docs
/docs/ @org/docs-team
*.md @org/docs-team
# Security-sensitive
/src/auth/ @org/security-team
/src/crypto/ @org/security-team
6.2 Branch Protection
- name: Configure branch protection
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.updateBranchProtection({
owner: context.repo.owner,
repo: context.repo.repo,
branch: 'main',
required_status_checks: {
strict: true,
contexts: ['test', 'lint', 'ai-review']
},
enforce_admins: true,
required_pull_request_reviews: {
required_approving_review_count: 1,
require_code_owner_reviews: true,
dismiss_stale_reviews: true
},
restrictions: null,
required_linear_history: true,
allow_force_pushes: false,
allow_deletions: false
});
Best Practices
Security
Performance
Reliability
Resources