Skip to content

Commit 04924bf

Browse files
committed
ci(workflows): Support running analysis on pull request comments
Enables issue analysis workflow to trigger on comments posted to pull requests. This is done by removing the `!github.event.issue.pull_request` check from the GHA issue analysis workflow definition, since GitHub models PR comments under the `issue_comment` event. The fix implementation workflow remains restricted to issues to prevent PR-on-PR loops and permission issues. - Update scripts/run_antigravity.py to include comments and review comments in JSON payloads fetched by helper tools. - Update adk-issue and adk-issue-analyze skills to prevent routing conflicts when /adk-issue-analyze is explicitly requested. - Update branch validation in issue-fix workflow to fail if the agent does not successfully create and checkout fix/issue-<number>. - Update adk-issue-fix skill branch template to match expected GHA workflow fallback pattern. Change-Id: I34405266bb6b11cc4ad18878ef932bb46677c89d
1 parent 9d139ea commit 04924bf

7 files changed

Lines changed: 213 additions & 24 deletions

File tree

.agents/skills/adk-issue-analyze/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: adk-issue-analyze
3-
description: Analyze and triage a GitHub issue for the adk-python repository. Use this skill to retrieve issue details, inspect the codebase, evaluate legitimacy, check for existing PRs, and produce a structured analysis report.
3+
description: Analyze and triage a GitHub issue for the adk-python repository. Use this skill to retrieve issue details, inspect the codebase, evaluate legitimacy, check for existing PRs, and produce a structured analysis report. Triggers on "/adk-issue-analyze" commands. This skill is strictly read-only and must be used whenever the "/adk-issue-analyze" command is explicitly called.
44
---
55

66
# ADK Issue Triage & Analysis (Read-Only)
Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: adk-issue-fix
3-
description: Implement a bug fix or feature for a GitHub issue in the adk-python repository. Use this skill after the triage/analysis is complete and approved. It creates a new branch, implements code changes, adds tests, and updates relevant documentation/samples.
3+
description: Implement a bug fix or feature for a GitHub issue in the adk-python repository. Use this skill after the triage/analysis is complete and approved. It creates a new branch, implements code changes, adds tests, and updates relevant documentation/samples. Triggers on "/adk-issue-fix" commands.
44
---
55

66
# ADK Issue Fix Implementation
@@ -9,19 +9,28 @@ This skill provides a structured workflow for implementing bug fixes or new feat
99

1010
## Implementation Steps
1111

12-
### 1. Base the Branch on Remote HEAD & Create Branch
12+
### 1. Check for Existing Pull Requests (Entry Gate)
13+
- **Check linked pull requests**: Before creating a branch or implementing changes, check if the issue is already linked to any pull requests by querying the issue details:
14+
```bash
15+
gh issue view <issue_number> --repo google/adk-python --json closedByPullRequestsReferences
16+
```
17+
- **Refuse to Proceed**: If the `closedByPullRequestsReferences` list is not empty (which indicates that there are already pull requests linked to this issue):
18+
- **Stop immediately**: You MUST refuse to proceed with the fix implementation.
19+
- **Output details**: Report the linked PR details (PR number, URL) to the user and terminate the skill execution.
20+
21+
### 2. Base the Branch on Remote HEAD & Create Branch
1322
- **Do NOT commit the changes**: Leave them uncommitted in the workspace so the user can review and iterate on them.
1423
- **Base the branch on remote HEAD**: When creating the new branch, ensure it is based on the remote tracking branch HEAD (`origin/main`), not the current local branch. For example:
1524
```bash
16-
git checkout -b fix/<issue_number>-<desc> origin/main
25+
git checkout -b fix/issue-<issue_number> origin/main
1726
```
1827

19-
### 2. Implement the Fix
28+
### 3. Implement the Fix
2029
- Modify the necessary source files implementing clean, robust logic following `adk-style` and `adk-architecture`.
2130

22-
### 3. Add or Update Unittests
31+
### 4. Add or Update Unittests
2332
- Write comprehensive unit tests to verify the behavior and prevent regressions. Refer to the testing patterns in the testing guides.
2433

25-
### 4. Update Documentation & Samples
34+
### 5. Update Documentation & Samples
2635
- Update `/docs/design` and `/docs/guides` if applicable to the changes.
2736
- Update `/contributing/samples` if applicable to demonstrate the new capability or updated behavior.

.agents/skills/adk-issue/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: adk-issue
3-
description: Orchestrate analyzing and triaging GitHub issues for the adk-python repository. Use this skill when a user provides a GitHub issue number or link. It coordinates triage analysis via `adk-issue-analyze` and implementation via `adk-issue-fix`. Triggers on "analyze issue", "issue #", "github issue", "github.com/google/adk-python/issues/".
3+
description: Orchestrate analyzing, triaging, and resolving GitHub issues for the adk-python repository. Use this skill when a user provides a GitHub issue number or link to perform both analysis and implementation. It coordinates triage analysis via `adk-issue-analyze` and implementation via `adk-issue-fix`. Triggers on "analyze issue", "issue #", "github issue", "github.com/google/adk-python/issues/". Do NOT trigger or use this skill when the prompt explicitly requests the "/adk-issue-analyze" command (use the read-only "adk-issue-analyze" skill instead).
44
---
55

66
# ADK Issue Resolution Orchestrator

.github/workflows/issue-analyze.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ jobs:
3333
github.event_name == 'issues' ||
3434
github.event_name == 'workflow_dispatch' ||
3535
(github.event_name == 'issue_comment' &&
36-
!github.event.issue.pull_request &&
3736
startsWith(github.event.comment.body, '/adk-issue-analyze') && (
3837
github.event.comment.author_association == 'OWNER' ||
3938
github.event.comment.author_association == 'MEMBER' ||

.github/workflows/issue-fix.yml

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
name: ADK Issue Fix Implementation
16+
17+
on:
18+
issue_comment:
19+
types: [created]
20+
workflow_dispatch:
21+
inputs:
22+
issue_url:
23+
description: 'The URL of the GitHub issue to fix'
24+
required: true
25+
type: string
26+
27+
jobs:
28+
issue-fix:
29+
if: >-
30+
github.repository == 'google/adk-python' && (
31+
github.event_name == 'workflow_dispatch' ||
32+
(github.event_name == 'issue_comment' &&
33+
!github.event.issue.pull_request &&
34+
startsWith(github.event.comment.body, '/adk-issue-fix') && (
35+
github.event.comment.author_association == 'OWNER' ||
36+
github.event.comment.author_association == 'MEMBER' ||
37+
github.event.comment.author_association == 'COLLABORATOR'
38+
))
39+
)
40+
runs-on: ubuntu-latest
41+
permissions:
42+
issues: write
43+
contents: write
44+
pull-requests: write
45+
46+
steps:
47+
- name: Checkout repository
48+
uses: actions/checkout@v6
49+
with:
50+
token: ${{ secrets.ADK_TRIAGE_AGENT }}
51+
fetch-depth: 0
52+
53+
- name: Set up Python
54+
uses: actions/setup-python@v6
55+
with:
56+
python-version: '3.11'
57+
58+
- name: Authenticate to Google Cloud
59+
id: auth
60+
uses: 'google-github-actions/auth@v3'
61+
with:
62+
credentials_json: '${{ secrets.ADK_GCP_SA_KEY }}'
63+
64+
- name: Install Google Antigravity SDK
65+
run: pip install google-antigravity
66+
67+
- name: Run Antigravity Fix
68+
env:
69+
GITHUB_TOKEN: ${{ secrets.ADK_TRIAGE_AGENT }}
70+
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
71+
run: |
72+
python scripts/run_antigravity.py "/adk-issue-fix ${{ github.event.issue.html_url || inputs.issue_url }}"
73+
74+
- name: Check for changes and create Pull Request
75+
env:
76+
GITHUB_TOKEN: ${{ secrets.ADK_TRIAGE_AGENT }}
77+
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
78+
run: |
79+
if [ -n "$(git status --porcelain)" ]; then
80+
echo "Changes detected in workspace. Committing and creating Pull Request..."
81+
82+
# Setup git configs
83+
git config --local user.name "adk-bot"
84+
git config --local user.email "adk-bot@google.com"
85+
86+
# Extract issue number and export it for python
87+
ISSUE_URL="${{ github.event.issue.html_url || inputs.issue_url }}"
88+
export ISSUE_NUMBER=$(echo "$ISSUE_URL" | grep -oP '/issues/\K[0-9]+')
89+
90+
# Determine branch name to push
91+
CURRENT_BRANCH=$(git branch --show-current)
92+
EXPECTED_BRANCH="fix/issue-${ISSUE_NUMBER}"
93+
if [ "$CURRENT_BRANCH" != "$EXPECTED_BRANCH" ]; then
94+
echo "Error: Current branch is '$CURRENT_BRANCH', but expected '$EXPECTED_BRANCH'."
95+
echo "The Antigravity Agent was expected to create and checkout '$EXPECTED_BRANCH'."
96+
exit 1
97+
fi
98+
BRANCH_NAME="$CURRENT_BRANCH"
99+
100+
# Run Antigravity to stage and commit changes with autogenerated message
101+
python scripts/run_antigravity.py "Analyze the unstaged changes in the workspace, stage all of them, and commit them using git. Generate a highly precise conventional commit message based on the diff."
102+
103+
# Append the closes tag using Python to avoid relying on LLM formatting
104+
python -c "import os, subprocess; msg = subprocess.check_output(['git', 'log', '-1', '--pretty=%B'], text=True); tag = 'closes https://github.com/google/adk-python/issues/' + os.environ['ISSUE_NUMBER']; subprocess.run(['git', 'commit', '--amend', '-m', msg.strip() + '\n\n' + tag], check=True) if tag not in msg else None"
105+
106+
# Push the branch to the bot fork
107+
git remote add fork https://x-access-token:${{ secrets.ADK_TRIAGE_AGENT }}@github.com/adk-bot/adk-python.git
108+
git push fork "$BRANCH_NAME" --force
109+
110+
# Retrieve the commit message of the last commit
111+
COMMIT_MSG=$(git log -1 --pretty=%B)
112+
113+
# Create PR from the bot fork to the main repository
114+
gh pr create \
115+
--repo google/adk-python \
116+
--title "fix(issue): fix issue #${ISSUE_NUMBER}" \
117+
--body "$COMMIT_MSG" \
118+
--head "adk-bot:$BRANCH_NAME" \
119+
--base "main"
120+
else
121+
echo "No changes made by the agent. Skipping PR creation."
122+
fi

AGENTS.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ For all matters regarding ADK development, please use the appropriate skill:
1616
- Read `.agents/skills/adk-sample-creator/SKILL.md` for full instructions.
1717
- **`adk-review`**: Use this skill to review local changes for errors, style compliance, unintended outcomes, and to check if associated design docs, guides, samples, or tests need updates.
1818
- Read `.agents/skills/adk-review/SKILL.md` for full instructions.
19-
- **`adk-issue`**: Use this skill when analyzing, triaging, and resolving GitHub issues for the adk-python repository. It orchestrates the process by delegating to `adk-issue-analyze` and `adk-issue-fix`.
19+
- **`adk-issue`**: Use this skill when analyzing, triaging, and resolving GitHub issues for the adk-python repository (orchestrating both triage and fix implementation). Do NOT use this skill if the "/adk-issue-analyze" command is explicitly requested.
2020
- Read `.agents/skills/adk-issue/SKILL.md` for full instructions.
21-
- **`adk-issue-analyze`**: Use this skill to fetch, inspect, and analyze a GitHub issue to verify legitimacy, existing PRs, and recommend a fix in a structured report.
21+
- **`adk-issue-analyze`**: Use this skill to fetch, inspect, and analyze a GitHub issue in a strictly read-only manner. Use this skill when the "/adk-issue-analyze" command is explicitly called.
2222
- Read `.agents/skills/adk-issue-analyze/SKILL.md` for full instructions.
23-
- **`adk-issue-fix`**: Use this skill to implement the code changes, unit tests, and documentation updates for an approved GitHub issue fix.
23+
- **`adk-issue-fix`**: Use this skill to implement the code changes, unit tests, and documentation updates for an approved GitHub issue fix. Use this skill when the "/adk-issue-fix" command is explicitly called.
2424
- Read `.agents/skills/adk-issue-fix/SKILL.md` for full instructions.
2525
- **`adk-pr-triage`**: Use this skill when triaging and analyzing GitHub pull requests (PRs) to evaluate their objectives, legitimacy, value, and alignment with ADK's architectural, styling, and testing principles.
2626
- Read `.agents/skills/adk-pr-triage/SKILL.md` for full instructions.

scripts/run_antigravity.py

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616

1717
import argparse
1818
import asyncio
19+
import json
1920
import os
2021
import shlex
22+
import subprocess
2123
import sys
2224
from typing import Any
2325

@@ -82,8 +84,6 @@ def fetch_github_issue(issue_number: int) -> str:
8284
Args:
8385
issue_number: The issue number (e.g. 5949).
8486
"""
85-
import subprocess
86-
8787
# Use curl to fetch the issue details.
8888
# This supports running it outside of the gh CLI environment (e.g. without login/remotes setup).
8989
cmd = [
@@ -93,17 +93,40 @@ def fetch_github_issue(issue_number: int) -> str:
9393
token = os.environ.get("GITHUB_TOKEN")
9494
if token:
9595
cmd.extend(["-H", f"Authorization: token {token}"])
96-
cmd.append(
96+
97+
issue_cmd = cmd + [
9798
f"https://api.github.com/repos/google/adk-python/issues/{issue_number}"
98-
)
99+
]
100+
comments_cmd = cmd + [
101+
f"https://api.github.com/repos/google/adk-python/issues/{issue_number}/comments"
102+
]
99103

100104
try:
101-
res = subprocess.run(cmd, capture_output=True, text=True, check=False)
105+
res = subprocess.run(issue_cmd, capture_output=True, text=True, check=False)
102106
if res.returncode != 0:
103107
return (
104108
f"Error: Failed to fetch issue {issue_number}: {res.stderr.strip()}"
105109
)
106-
return res.stdout.strip()
110+
111+
try:
112+
issue_data = json.loads(res.stdout.strip())
113+
except json.JSONDecodeError as e:
114+
return (
115+
f"Error: Failed to parse issue JSON response: {e}. Output:"
116+
f" {res.stdout.strip()}"
117+
)
118+
119+
res_comments = subprocess.run(
120+
comments_cmd, capture_output=True, text=True, check=False
121+
)
122+
if res_comments.returncode == 0:
123+
try:
124+
comments_data = json.loads(res_comments.stdout.strip())
125+
issue_data["comments_data"] = comments_data
126+
except json.JSONDecodeError:
127+
pass
128+
129+
return json.dumps(issue_data, indent=2)
107130
except Exception as e:
108131
return f"Error: Failed to run curl command: {e}"
109132

@@ -114,8 +137,6 @@ def fetch_github_pr(pr_number: int) -> str:
114137
Args:
115138
pr_number: The PR number (e.g. 5956).
116139
"""
117-
import subprocess
118-
119140
# Use curl to fetch the PR details.
120141
# This supports running it outside of the gh CLI environment (e.g. without login/remotes setup).
121142
cmd = [
@@ -125,15 +146,53 @@ def fetch_github_pr(pr_number: int) -> str:
125146
token = os.environ.get("GITHUB_TOKEN")
126147
if token:
127148
cmd.extend(["-H", f"Authorization: token {token}"])
128-
cmd.append(
149+
150+
pr_cmd = cmd + [
129151
f"https://api.github.com/repos/google/adk-python/pulls/{pr_number}"
130-
)
152+
]
153+
issue_comments_cmd = cmd + [
154+
f"https://api.github.com/repos/google/adk-python/issues/{pr_number}/comments"
155+
]
156+
review_comments_cmd = cmd + [
157+
f"https://api.github.com/repos/google/adk-python/pulls/{pr_number}/comments"
158+
]
131159

132160
try:
133-
res = subprocess.run(cmd, capture_output=True, text=True, check=False)
161+
res = subprocess.run(pr_cmd, capture_output=True, text=True, check=False)
134162
if res.returncode != 0:
135163
return f"Error: Failed to fetch PR {pr_number}: {res.stderr.strip()}"
136-
return res.stdout.strip()
164+
165+
try:
166+
pr_data = json.loads(res.stdout.strip())
167+
except json.JSONDecodeError as e:
168+
return (
169+
f"Error: Failed to parse PR JSON response: {e}. Output:"
170+
f" {res.stdout.strip()}"
171+
)
172+
173+
# Fetch issue-level comments
174+
res_issue_comments = subprocess.run(
175+
issue_comments_cmd, capture_output=True, text=True, check=False
176+
)
177+
if res_issue_comments.returncode == 0:
178+
try:
179+
pr_data["comments_data"] = json.loads(res_issue_comments.stdout.strip())
180+
except json.JSONDecodeError:
181+
pass
182+
183+
# Fetch review/inline comments
184+
res_review_comments = subprocess.run(
185+
review_comments_cmd, capture_output=True, text=True, check=False
186+
)
187+
if res_review_comments.returncode == 0:
188+
try:
189+
pr_data["review_comments_data"] = json.loads(
190+
res_review_comments.stdout.strip()
191+
)
192+
except json.JSONDecodeError:
193+
pass
194+
195+
return json.dumps(pr_data, indent=2)
137196
except Exception as e:
138197
return f"Error: Failed to run curl command: {e}"
139198

0 commit comments

Comments
 (0)