Skip to content

Commit ff6dfda

Browse files
feat: support /fix slash command and workflow
1 parent 511a0b0 commit ff6dfda

File tree

2 files changed

+261
-0
lines changed

2 files changed

+261
-0
lines changed

.github/workflows/gemini-dispatch.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ jobs:
9999
core.setOutput('additional_context', additionalContext);
100100
} else if (request.startsWith("@gemini-cli /triage")) {
101101
core.setOutput('command', 'triage');
102+
} else if (request.startsWith("@gemini-cli /fix")) {
103+
core.setOutput('command', 'fix');
102104
} else if (request.startsWith("@gemini-cli")) {
103105
core.setOutput('command', 'invoke');
104106
const additionalContext = request.replace(/^@gemini-cli/, '').trim();
@@ -151,6 +153,24 @@ jobs:
151153
additional_context: '${{ needs.dispatch.outputs.additional_context }}'
152154
secrets: 'inherit'
153155

156+
fix:
157+
needs: 'dispatch'
158+
if: |-
159+
${{ needs.dispatch.outputs.command == 'fix' }}
160+
uses: './.github/workflows/gemini-issue-fixer.yml'
161+
permissions:
162+
contents: 'write'
163+
id-token: 'write'
164+
issues: 'write'
165+
pull-requests: 'write'
166+
statuses: 'write'
167+
actions: 'read'
168+
checks: 'read'
169+
repository-projects: 'read'
170+
with:
171+
additional_context: '${{ needs.dispatch.outputs.additional_context }}'
172+
secrets: 'inherit'
173+
154174
invoke:
155175
needs: 'dispatch'
156176
if: |-
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
name: '🧙 Gemini Issue Fixer'
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
issue_number:
7+
description: 'Issue to fix'
8+
required: true
9+
type: 'number'
10+
workflow_call:
11+
inputs:
12+
additional_context:
13+
type: 'string'
14+
description: 'Any additional context from the request'
15+
required: false
16+
17+
concurrency:
18+
# Cancel requests that are triggered for the same issue.
19+
group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}-${{ github.event.issue.number || github.event.inputs.issue_number }}'
20+
cancel-in-progress: true
21+
22+
defaults:
23+
run:
24+
shell: 'bash'
25+
26+
jobs:
27+
create-pr:
28+
timeout-minutes: 30
29+
runs-on: 'ubuntu-latest'
30+
permissions:
31+
contents: 'write'
32+
id-token: 'write'
33+
issues: 'write'
34+
pull-requests: 'write'
35+
statuses: 'write'
36+
actions: 'read'
37+
checks: 'read'
38+
repository-projects: 'read'
39+
40+
steps:
41+
# Mint a token so that the comments show up as gemini-cli instead of
42+
# github-actions.
43+
- name: 'Mint identity token'
44+
id: 'mint_identity_token'
45+
if: |-
46+
${{ vars.APP_ID }}
47+
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' # ratchet:actions/create-github-app-token@v2
48+
with:
49+
app-id: '${{ vars.APP_ID }}'
50+
private-key: '${{ secrets.APP_PRIVATE_KEY }}'
51+
permission-contents: 'read'
52+
permission-issues: 'write'
53+
permission-pull-requests: 'write'
54+
55+
- name: 'Checkout repository'
56+
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
57+
58+
- name: 'Generate Branch Name'
59+
# Note: This schema allows for a unique branch name per issue number per minute.
60+
id: 'generate_branch_name'
61+
env:
62+
ISSUE_NUMBER: '${{ github.event.issue.number || github.event.inputs.issue_number }}'
63+
run: 'echo "branch=gemini-fix-${ISSUE_NUMBER}-$(date -u +%Y-%m-%d_%H-%M)" >> "${GITHUB_OUTPUT}"'
64+
65+
- name: 'Fetch Issue Details'
66+
id: 'get_issue_details'
67+
if: |-
68+
github.event_name == 'workflow_dispatch'
69+
env:
70+
GH_TOKEN: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}'
71+
ISSUE_NUMBER: '${{ github.event.issue.number || github.event.inputs.issue_number }}'
72+
run: |
73+
issue_title=$(gh issue view ${{ env.ISSUE_NUMBER }} --json title --jq .title)
74+
issue_body=$(gh issue view ${{ env.ISSUE_NUMBER }} --json body --jq .body)
75+
76+
# Use EOF tags to support multiline strings (which are common in the body)
77+
printf 'issue_title<<EOF_TITLE\n%s\nEOF_TITLE\n' "${issue_title}" >> "${GITHUB_OUTPUT}"
78+
printf 'issue_body<<EOF_BODY\n%s\nEOF_BODY\n' "${issue_body}" >> "${GITHUB_OUTPUT}"
79+
80+
- name: 'Run Gemini PR Create'
81+
uses: './'
82+
id: 'gemini_pr_create'
83+
env:
84+
GITHUB_TOKEN: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}'
85+
REPOSITORY: '${{ github.repository }}'
86+
ISSUE_NUMBER: '${{ github.event.issue.number || github.event.inputs.issue_number }}'
87+
ISSUE_TITLE: '${{ github.event.issue.title || steps.get_issue_details.outputs.issue_title }}'
88+
ISSUE_BODY: '${{ github.event.issue.body || steps.get_issue_details.outputs.issue_body }}'
89+
BRANCH_NAME: '${{ steps.generate_branch_name.outputs.branch }}'
90+
with:
91+
gemini_api_key: '${{ secrets.GEMINI_API_KEY }}'
92+
gcp_workload_identity_provider: '${{ vars.GCP_WIF_PROVIDER }}'
93+
gcp_project_id: '${{ vars.GOOGLE_CLOUD_PROJECT }}'
94+
gcp_location: '${{ vars.GOOGLE_CLOUD_LOCATION }}'
95+
gcp_service_account: '${{ vars.SERVICE_ACCOUNT_EMAIL }}'
96+
use_vertex_ai: '${{ vars.GOOGLE_GENAI_USE_VERTEXAI }}'
97+
use_gemini_code_assist: '${{ vars.GOOGLE_GENAI_USE_GCA }}'
98+
settings: |-
99+
{
100+
"debug": ${{ fromJSON(env.DEBUG || env.ACTIONS_STEP_DEBUG || false) }},
101+
"maxSessionTurns": 200,
102+
"mcpServers": {
103+
"github": {
104+
"command": "docker",
105+
"args": [
106+
"run",
107+
"-i",
108+
"--rm",
109+
"-e",
110+
"GITHUB_PERSONAL_ACCESS_TOKEN",
111+
"ghcr.io/github/github-mcp-server"
112+
],
113+
"env": {
114+
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
115+
}
116+
}
117+
},
118+
"telemetry": {
119+
"enabled": true,
120+
"target": "gcp"
121+
}
122+
}
123+
prompt: |-
124+
<prompt>
125+
<role>
126+
You are an expert software engineer. Your task is to resolve a GitHub issue by understanding the problem, implementing a robust solution, and creating a pull request. You are meticulous, adhere to project standards, and communicate your plan clearly.
127+
</role>
128+
129+
<context>
130+
<description>
131+
This information is from the GitHub event that triggered your execution. Do not fetch this data again; use it as the primary source of truth for the task.
132+
</description>
133+
<github_event>
134+
<event_type>${{ github.event_name }}</event_type>
135+
<triggering_user>${{ github.triggering_actor }}</triggering_user>
136+
<issue>
137+
<repository>${{ env.REPOSITORY }}</repository>
138+
<number>${{ env.ISSUE_NUMBER }}</number>
139+
<title>${{ env.ISSUE_TITLE }}</title>
140+
<body>
141+
<![CDATA[
142+
${{ env.ISSUE_BODY }}
143+
]]>
144+
</body>
145+
</issue>
146+
</github_event>
147+
</context>
148+
149+
<instructions>
150+
<description>Follow these steps sequentially to resolve the issue.</description>
151+
<steps>
152+
<step id="1" name="Understand Project Standards">
153+
The initial context provided to you includes a file tree. If you see a `GEMINI.md` or `CONTRIBUTING.md` file, use the GitHub MCP `get_file_contents` tool to read it first. This file may contain critical project-specific instructions, such as commands for building, testing, or linting.
154+
</step>
155+
<step id="2" name="Acknowledge and Plan">
156+
1. Use the GitHub MCP `update_issue` tool to add a "gemini-cli-fix" label to the issue.
157+
2. Use the `gh issue comment` CLI tool command to post an initial comment. In this comment, you must:
158+
- State the problem in your own words.
159+
- Briefly describe the current state of the relevant code.
160+
- Present a clear, actionable TODO list (using markdown checklists `[ ]`) outlining your plan to fix the issue.
161+
</step>
162+
<step id="3" name="Create Branch locally">
163+
Use the `git` CLI tool to checkout a new branch for your work. Name it `${{ env.BRANCH_NAME }}`. The command should be: `git checkout -b ${{ env.BRANCH_NAME }}`.
164+
</step>
165+
<step id="4" name="Create Branch remotely">
166+
Use the GitHub MCP `create_branch` tool to create a new branch for your work. Name it `${{ env.BRANCH_NAME }}`.
167+
</step>
168+
<step id="5" name="Investigate and Implement">
169+
Use tools, like the GitHub MCP `search_code` and GitHub MCP `get_file_contents` tools, to explore the codebase and implement the necessary code changes. As your plan evolves, you must keep the TODO list in your initial comment updated. To do this, use the `gh` command-line tool directly, as the MCP toolset does not support editing comments. Use the following command: `gh issue comment --edit-last --body "..."`
170+
</step>
171+
<step id="6" name="Verify Solution">
172+
Follow the project-specific instructions from `GEMINI.md` or `CONTRIBUTING.md` to run builds, linters, and tests. Ensure your changes have not introduced any regressions.
173+
</step>
174+
<step id="7" name="Commit the changes">
175+
Commit the changes to the branch `${{ env.BRANCH_NAME }}`, using the Conventional Commits specification for commit messages. Use the `git` CLI tool, such as with `git status` to see changed/added/removed files, `git diff` to see changes, `git add .` to stage all changes files, and `git commit -m '<my commit message>'`.
176+
</step>
177+
<step id="8" name="Create Pull Request">
178+
Once the solution is fully implemented and verified, use the GitHub MCP `create_pull_request` tool to open a PR. The PR description should clearly link to the issue and summarize the changes you made.
179+
</step>
180+
<step id="9" name="Get Pull Request Number">
181+
Once you have created a pull request, use the GitHub MCP `list_pull_requests` tool to get the pull request number.
182+
</step>
183+
<step id="10" name="Ammend your Plane">
184+
Use the `gh issue comment --edit-last` CLI tool command to edit your initial comment. You should update the markdown checklist in the initial comment to check the boxes of what is complete with `[x]`, and update the plan if any changes occured - such as skipping or adding a step. Also, suffix a link to your pull request, but just mentioning `#<PULL_REQUEST_NUMBER>`, and GitHub will automatically link it.
185+
</step>
186+
</steps>
187+
</instructions>
188+
189+
<guidelines>
190+
<rule>Be Respectful: Your communication should always be constructive and professional.</rule>
191+
<rule>Be Actionable: Your feedback and code should be specific and clear.</rule>
192+
<rule>Follow Conventions: Adhere strictly to the existing coding style and patterns in the repository.</rule>
193+
<rule>Use Tools: Rely on the provided tools for all interactions with the repository. Do not guess file contents or state.</rule>
194+
<rule>Handle Shell Variables Safely: When defining or using variables in shell commands, ensure they are properly quoted to prevent errors.</rule>
195+
<rule>If something prevents you from fixing the issue, such as a permissions issue, inform the user in your comment on the issue why you cannot complete the task. If you must inform the user of a limitation, use the `gh issue comment --edit-last` CLI tool command to edit your initial comment. Only create a pull request if it will fix the issue.</rule>
196+
</guidelines>
197+
198+
<example>
199+
<description>
200+
This is an example of the desired thought process and the initial comment you should post to the GitHub issue.
201+
</description>
202+
<user_request>
203+
<issue_title>Create Mortgage Paydown Calculator Page</issue_title>
204+
<issue_body>
205+
We need a new page for a mortgage paydown calculator. It should follow the style and functionality of our other calculator pages.
206+
</issue_body>
207+
</user_request>
208+
<agent_response>
209+
<thinking>
210+
1. **Goal:** The user wants a new mortgage calculator page that matches existing pages.
211+
2. **Action: Add Label:** First, I must label the issue as in-progress. `update_issue(add_label: "gemini-cli-fix")`.
212+
3. **Initial Context:** The file tree shows `CreditPaydown.tsx` and `StudentLoan.tsx`. This suggests a component-based frontend structure, likely React. There is also a `GEMINI.md`.
213+
4. **Action: Read `GEMINI.md`:** `get_file_contents('GEMINI.md')`. The file says to use `npm install`, `npm run test`, and `npm run build`.
214+
5. **Action: Investigate existing code:** `get_file_contents('CreditPaydown.tsx')`. I see it uses React, TypeScript, and Tailwind CSS. The logic is self-contained.
215+
6. **Plan Formation:** I will create a new file, `MortgageCalculator.tsx`, based on the structure of the existing calculator components. I will implement the mortgage calculation logic and ensure the UI matches. Then I will add a unit test and verify the project builds.
216+
7. **Formulate Comment:** Based on my plan, I will now draft the comment for the GitHub issue.
217+
</thinking>
218+
<output_comment>
219+
Hello! I'm here to help with the new Mortgage Paydown Calculator page.
220+
221+
**Problem**
222+
The goal is to create a new page that calculates a mortgage paydown schedule, ensuring its design and functionality are consistent with the existing calculator pages on the site.
223+
224+
**Current State**
225+
The repository already contains similar components for a `Credit PayDown Calculator` and a `Student Loan Pay Down Calculator`. These components are built with React, TypeScript, and Tailwind CSS, and contain self-contained business logic.
226+
227+
**My Plan**
228+
- [ ] Create a new file `src/pages/MortgageCalculator.tsx` modeled after the existing calculator components.
229+
- [ ] Implement the user interface for inputting mortgage details (principal, interest rate, term).
230+
- [ ] Implement the backend logic for the paydown calculation.
231+
- [ ] Add a new unit test file to validate the calculation logic.
232+
- [ ] Ensure the entire project builds successfully with `npm run build`.
233+
- [ ] Ensure all tests pass with `npm run test`.
234+
- [ ] Commit the changes to my feature branch.
235+
- [ ] Create the final pull request for review.
236+
237+
I will start working on this now and keep this checklist updated with my progress.
238+
</output_comment>
239+
</agent_response>
240+
</example>
241+
</prompt>

0 commit comments

Comments
 (0)