Skip to content

Commit bd71163

Browse files
authored
Update
1 parent dfc9a29 commit bd71163

2 files changed

Lines changed: 228 additions & 7 deletions

File tree

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
# On-Demand AI Assistant for Issues and PRs (Secure)
2+
# Triggered by @gemini-cli mentions in comments
3+
4+
name: Gemini AI Assistant (Secure)
5+
6+
on:
7+
issue_comment:
8+
types: [created]
9+
10+
permissions:
11+
contents: read
12+
issues: write
13+
pull-requests: write
14+
15+
jobs:
16+
ai-assistant:
17+
name: AI Assistant Response
18+
runs-on: ubuntu-latest
19+
if: |
20+
github.event.issue.state == 'open' &&
21+
contains(github.event.comment.body, '@gemini-cli')
22+
23+
steps:
24+
- name: Checkout code (Safe - base branch only)
25+
uses: actions/checkout@v5
26+
with:
27+
fetch-depth: 0
28+
# SECURITY: Never checkout PR head for comment-triggered workflows
29+
30+
- name: Extract AI Command (Secure)
31+
id: extract-command
32+
env:
33+
# SECURITY: Use environment variable to prevent code injection
34+
COMMENT_BODY: ${{ github.event.comment.body }}
35+
run: |
36+
# SECURITY: Use environment variable instead of direct interpolation
37+
# Extract everything after @gemini-cli safely
38+
COMMAND=$(echo "$COMMENT_BODY" | sed -n 's/.*@gemini-cli \(.*\)/\1/p' | head -1)
39+
40+
# Sanitize the command to prevent injection
41+
# Remove potentially dangerous characters
42+
CLEAN_COMMAND=$(echo "$COMMAND" | tr -cd '[:alnum:][:space:]._-' | head -c 200)
43+
44+
echo "command=$CLEAN_COMMAND" >> $GITHUB_OUTPUT
45+
echo "Extracted command: $CLEAN_COMMAND"
46+
47+
- name: Get PR context safely (if applicable)
48+
id: pr-context
49+
if: github.event.issue.pull_request
50+
env:
51+
# SECURITY: Use environment variable for safe access
52+
PR_NUMBER: ${{ github.event.issue.number }}
53+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54+
run: |
55+
# SECURITY: Use GitHub API to get PR info without checkout
56+
# Validate PR number is numeric only
57+
if [[ ! "$PR_NUMBER" =~ ^[0-9]+$ ]]; then
58+
echo "Invalid PR number format"
59+
exit 1
60+
fi
61+
62+
# Get PR information safely via API
63+
curl -H "Authorization: token $GITHUB_TOKEN" \
64+
-H "Accept: application/vnd.github.v3+json" \
65+
"https://api.github.com/repos/${{ github.repository }}/pulls/$PR_NUMBER" \
66+
> pr_info.json
67+
68+
# Extract safe metadata
69+
BASE_SHA=$(jq -r '.base.sha' pr_info.json)
70+
HEAD_SHA=$(jq -r '.head.sha' pr_info.json)
71+
72+
# Validate SHA format (40 character hex)
73+
if [[ ! "$BASE_SHA" =~ ^[a-f0-9]{40}$ ]] || [[ ! "$HEAD_SHA" =~ ^[a-f0-9]{40}$ ]]; then
74+
echo "Invalid SHA format"
75+
exit 1
76+
fi
77+
78+
# Get diff via API (no checkout needed)
79+
curl -H "Authorization: token $GITHUB_TOKEN" \
80+
-H "Accept: application/vnd.github.v3.diff" \
81+
"https://api.github.com/repos/${{ github.repository }}/compare/$BASE_SHA..$HEAD_SHA" \
82+
> pr_diff.txt
83+
84+
echo "pr-available=true" >> $GITHUB_OUTPUT
85+
86+
- name: Run Gemini AI Assistant
87+
env:
88+
# SECURITY: Use environment variables for safe handling
89+
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
90+
USER_COMMAND: ${{ steps.extract-command.outputs.command }}
91+
ISSUE_TITLE: ${{ github.event.issue.title }}
92+
ISSUE_NUMBER: ${{ github.event.issue.number }}
93+
ISSUE_AUTHOR: ${{ github.event.issue.user.login }}
94+
IS_PR: ${{ github.event.issue.pull_request && 'Pull Request' || 'Issue' }}
95+
run: |
96+
npx @google/gemini-cli@latest --prompt "
97+
You are an expert WordPress plugin development assistant for the \"Optimizations ACE MC\" plugin.
98+
99+
CONTEXT:
100+
- Repository: WordPress optimization plugin for WooCommerce and WP Store Locator
101+
- WordPress 6.5+, PHP 7.4+
102+
- Single-site deployment with guaranteed plugin dependencies
103+
104+
USER REQUEST: \"$USER_COMMAND\"
105+
106+
ISSUE/PR CONTEXT:
107+
- Type: $IS_PR
108+
- Title: \"$ISSUE_TITLE\"
109+
- Number: #$ISSUE_NUMBER
110+
- Author: @$ISSUE_AUTHOR
111+
112+
RESPONSE GUIDELINES:
113+
114+
📋 For Code Analysis Requests:
115+
- Review code for WordPress standards compliance
116+
- Check for security vulnerabilities
117+
- Suggest performance improvements
118+
- Provide specific, actionable recommendations
119+
120+
🔧 For Implementation Help:
121+
- Provide WordPress-specific solutions
122+
- Include proper error handling
123+
- Follow plugin coding standards
124+
- Reference WordPress Codex when helpful
125+
126+
🐛 For Bug Investigation:
127+
- Analyze potential root causes
128+
- Suggest debugging approaches
129+
- Recommend testing strategies
130+
- Consider WordPress environment factors
131+
132+
✨ For Feature Requests:
133+
- Evaluate WordPress compatibility
134+
- Consider performance implications
135+
- Suggest implementation approaches
136+
- Identify potential conflicts
137+
138+
📚 For Documentation:
139+
- Provide clear, actionable information
140+
- Include relevant code examples
141+
- Reference WordPress documentation
142+
- Consider user experience impact
143+
144+
SECURITY NOTICE: This analysis is performed safely without accessing untrusted code.
145+
Always be helpful, specific, and focus on WordPress best practices.
146+
If you need more information to provide a complete answer, ask clarifying questions.
147+
" > assistant-response.txt
148+
149+
- name: Post AI Assistant Response
150+
uses: actions/github-script@v7
151+
env:
152+
# SECURITY: Use environment variables for safe handling
153+
COMMENT_USER: ${{ github.event.comment.user.login }}
154+
USER_COMMAND: ${{ steps.extract-command.outputs.command }}
155+
ISSUE_NUMBER: ${{ github.event.issue.number }}
156+
with:
157+
github-token: ${{ secrets.GITHUB_TOKEN }}
158+
script: |
159+
const fs = require('fs');
160+
const commentUser = process.env.COMMENT_USER;
161+
const userCommand = process.env.USER_COMMAND;
162+
const issueNumber = process.env.ISSUE_NUMBER;
163+
164+
// SECURITY: Validate inputs
165+
if (!commentUser || !userCommand) {
166+
throw new Error('Missing required environment variables');
167+
}
168+
169+
let assistantResponse = 'No response generated.';
170+
try {
171+
if (fs.existsSync('assistant-response.txt')) {
172+
assistantResponse = fs.readFileSync('assistant-response.txt', 'utf8');
173+
}
174+
} catch (error) {
175+
console.log('Error reading assistant response file:', error);
176+
assistantResponse = 'Error reading AI assistant response.';
177+
}
178+
179+
const aiResponse = `
180+
## 🤖 AI WordPress Assistant Response
181+
182+
Hi @${commentUser}! I've analyzed your request: **"${userCommand}"**
183+
184+
### 📝 Expert Analysis & Recommendations
185+
186+
${assistantResponse}
187+
188+
---
189+
190+
### 🔗 Helpful Resources
191+
- [WordPress Plugin Developer Handbook](https://developer.wordpress.org/plugins/)
192+
- [WordPress Coding Standards](https://developer.wordpress.org/coding-standards/)
193+
- [Plugin Security Guidelines](https://developer.wordpress.org/plugins/security/)
194+
- [WooCommerce Developer Documentation](https://woocommerce.com/document/create-a-plugin/)
195+
196+
### 💡 Available Commands
197+
Try these commands with @gemini-cli:
198+
- \`@gemini-cli review this code\` - Code review and analysis
199+
- \`@gemini-cli suggest improvements\` - Performance and structure suggestions
200+
- \`@gemini-cli check security\` - Security vulnerability analysis
201+
- \`@gemini-cli explain this function\` - Code explanation and documentation
202+
- \`@gemini-cli write tests for X\` - Test implementation guidance
203+
- \`@gemini-cli debug this issue\` - Bug investigation and resolution
204+
205+
> 🔄 **Note:** This is an AI-generated response for Optimizations ACE MC (latest version). Please review suggestions carefully and test thoroughly.
206+
207+
**Analysis Date:** ${new Date().toISOString()}
208+
`;
209+
210+
await github.rest.issues.createComment({
211+
issue_number: issueNumber,
212+
owner: context.repo.owner,
213+
repo: context.repo.repo,
214+
body: aiResponse
215+
});

.github/workflows/gemini-issue-assistant.yml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,20 @@ jobs:
3333
3434
- name: Determine analysis type
3535
id: analysis-type
36+
env:
37+
EVENT_NAME: ${{ github.event_name }}
38+
ISSUE_TITLE: ${{ github.event.issue.title }}
39+
ISSUE_AUTHOR: ${{ github.event.issue.user.login }}
40+
COMMENT_AUTHOR: ${{ github.event.comment.user.login }}
3641
run: |
37-
if [ "${{ github.event_name }}" = "issues" ]; then
42+
if [ "$EVENT_NAME" = "issues" ]; then
3843
echo "type=issue-analysis" >> $GITHUB_OUTPUT
39-
echo "Issue: ${{ github.event.issue.title }}"
40-
echo "Author: ${{ github.event.issue.user.login }}"
41-
elif [ "${{ github.event_name }}" = "issue_comment" ]; then
44+
echo "Issue: $ISSUE_TITLE"
45+
echo "Author: $ISSUE_AUTHOR"
46+
elif [ "$EVENT_NAME" = "issue_comment" ]; then
4247
echo "type=comment-analysis" >> $GITHUB_OUTPUT
43-
echo "Comment on issue: ${{ github.event.issue.title }}"
44-
echo "Comment author: ${{ github.event.comment.user.login }}"
48+
echo "Comment on issue: $ISSUE_TITLE"
49+
echo "Comment author: $COMMENT_AUTHOR"
4550
else
4651
echo "type=skip" >> $GITHUB_OUTPUT
4752
fi
@@ -109,8 +114,9 @@ jobs:
109114
- name: Run Gemini Analysis
110115
env:
111116
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
117+
ANALYSIS_SKIPPED: ${{ steps.analysis-type.outputs.analysis-skipped }}
112118
run: |
113-
if [ "${{ steps.analysis-type.outputs.analysis-skipped }}" = "true" ]; then
119+
if [ "$ANALYSIS_SKIPPED" = "true" ]; then
114120
echo "Analysis skipped"
115121
exit 0
116122
fi

0 commit comments

Comments
 (0)