Skip to content

Commit fafcd74

Browse files
committed
feat(actions): use the dispatcher pattern to separate concerns
This introduces a new top-level workflow "gemini-dispatch" that listens for a series of events. Based on the trigger or contents, it calls another workflow (using `workflow_call`). This helps keep each workflow separate and allows us to re-use workflows in the future. The generic "invoke" command still needs a lot of work, but this is progress.
1 parent 066033b commit fafcd74

7 files changed

Lines changed: 704 additions & 816 deletions
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
name: '🔀 Gemini Dispatch'
2+
3+
on:
4+
pull_request_review_comment:
5+
types:
6+
- 'created'
7+
pull_request_review:
8+
types:
9+
- 'submitted'
10+
pull_request:
11+
types:
12+
- 'opened'
13+
issue_comment:
14+
types:
15+
- 'created'
16+
17+
defaults:
18+
run:
19+
shell: 'bash'
20+
21+
jobs:
22+
dispatch:
23+
if: |-
24+
(
25+
github.event_name == 'pull_request' &&
26+
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association)
27+
) ||
28+
(
29+
github.event.sender.type == 'User' &&
30+
startsWith(github.event.comment.body || github.event.review.body || github.event.issue.body, '@gemini-cli') &&
31+
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association || github.event.review.author_association || github.event.issue.author_association)
32+
)
33+
runs-on: 'ubuntu-latest'
34+
permissions:
35+
contents: 'read'
36+
issues: 'write'
37+
pull-requests: 'write'
38+
outputs:
39+
command: '${{ steps.extract_command.outputs.command }}'
40+
request: '${{ steps.extract_command.outputs.request }}'
41+
additional_context: '${{ steps.extract_command.outputs.additional_context }}'
42+
issue_number: '${{ github.event.pull_request.number || github.event.issue.number }}'
43+
steps:
44+
- name: 'Mint identity token'
45+
id: 'mint_identity_token'
46+
if: |-
47+
${{ vars.APP_ID }}
48+
uses: 'actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e' # ratchet:actions/create-github-app-token@v2
49+
with:
50+
app-id: '${{ vars.APP_ID }}'
51+
private-key: '${{ secrets.APP_PRIVATE_KEY }}'
52+
permission-contents: 'read'
53+
permission-issues: 'write'
54+
permission-pull-requests: 'write'
55+
56+
- name: 'Extract command'
57+
id: 'extract_command'
58+
uses: 'actions/github-script@v7'
59+
env:
60+
EVENT_TYPE: '${{ github.event_name }}.${{ github.event.action }}'
61+
REQUEST: '${{ github.event.comment.body || github.event.review.body || github.event.issue.body }}'
62+
with:
63+
script: |
64+
const request = process.env.REQUEST;
65+
const eventType = process.env.EVENT_TYPE
66+
core.setOutput('request', request);
67+
68+
if (false) {
69+
// Just for aligning the conditions
70+
} else if (request.startsWith("@gemini-cli /review")) {
71+
core.setOutput('command', 'review');
72+
const additionalContext = request.replace(/^@gemini-cli \/review/, '').trim();
73+
core.setOutput('additional_context', additionalContext);
74+
} else if (request.startsWith("@gemini-cli /triage")) {
75+
core.setOutput('command', 'triage');
76+
} else if (request.startsWith("@gemini-cli")) {
77+
core.setOutput('command', 'invoke');
78+
const additionalContext = request.replace(/^@gemini-cli/, '').trim();
79+
core.setOutput('additional_context', additionalContext);
80+
} else if (eventType === 'pull_request.opened') {
81+
core.setOutput('command', 'review');
82+
} else {
83+
core.setOutput('command', 'fallthrough');
84+
}
85+
86+
- name: 'Acknowledge request'
87+
env:
88+
GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}'
89+
ISSUE_NUMBER: '${{ github.event.pull_request.number || github.event.issue.number }}'
90+
MESSAGE: |-
91+
🤖 Hi @${{ github.actor }}, I've received your request. I'm working on it now!
92+
REPOSITORY: '${{ github.repository }}'
93+
run: |-
94+
gh issue comment "${ISSUE_NUMBER}" \
95+
--body "${MESSAGE}" \
96+
--repo "${REPOSITORY}"
97+
98+
review:
99+
needs: 'dispatch'
100+
if: |-
101+
${{ needs.dispatch.outputs.command == 'review' }}
102+
uses: './.github/workflows/gemini-review.yml'
103+
permissions:
104+
contents: 'read'
105+
pull-requests: 'write'
106+
issues: 'write'
107+
with:
108+
additional_context: '${{ needs.dispatch.outputs.additional_context }}'
109+
secrets: 'inherit'
110+
111+
triage:
112+
needs: 'dispatch'
113+
if: |-
114+
${{ needs.dispatch.outputs.command == 'triage' }}
115+
uses: './.github/workflows/gemini-triage.yml'
116+
permissions:
117+
contents: 'read'
118+
issues: 'write'
119+
pull-requests: 'write'
120+
with:
121+
additional_context: '${{ needs.dispatch.outputs.additional_context }}'
122+
secrets: 'inherit'
123+
124+
invoke:
125+
needs: 'dispatch'
126+
if: |-
127+
${{ needs.dispatch.outputs.command == 'invoke' }}
128+
uses: './.github/workflows/gemini-invoke.yml'
129+
permissions:
130+
contents: 'read'
131+
issues: 'write'
132+
pull-requests: 'write'
133+
with:
134+
additional_context: '${{ needs.dispatch.outputs.additional_context }}'
135+
secrets: 'inherit'
136+
137+
fallthrough:
138+
needs:
139+
- 'dispatch'
140+
- 'review'
141+
- 'triage'
142+
- 'invoke'
143+
if: |-
144+
${{ always() && !cancelled() && (failure() || needs.dispatch.outputs.command == 'fallthrough') }}
145+
runs-on: 'ubuntu-latest'
146+
permissions:
147+
contents: 'read'
148+
issues: 'write'
149+
pull-requests: 'write'
150+
steps:
151+
- name: 'Mint identity token'
152+
id: 'mint_identity_token'
153+
if: |-
154+
${{ vars.APP_ID }}
155+
uses: 'actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e' # ratchet:actions/create-github-app-token@v2
156+
with:
157+
app-id: '${{ vars.APP_ID }}'
158+
private-key: '${{ secrets.APP_PRIVATE_KEY }}'
159+
permission-contents: 'read'
160+
permission-issues: 'write'
161+
permission-pull-requests: 'write'
162+
163+
- name: 'Send failure comment'
164+
env:
165+
GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}'
166+
ISSUE_NUMBER: '${{ github.event.pull_request.number || github.event.issue.number }}'
167+
MESSAGE: |-
168+
🤖 I'm sorry @${{ github.actor }}, but I was unable to process your request. Please [see the logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for more details.
169+
REPOSITORY: '${{ github.repository }}'
170+
run: |-
171+
gh issue comment "${ISSUE_NUMBER}" \
172+
--body "${MESSAGE}" \
173+
--repo "${REPOSITORY}"

0 commit comments

Comments
 (0)