Skip to content

Commit 225eca7

Browse files
committed
feat(examples): separate staleness check from agent via github-script
1 parent 1cdeb18 commit 225eca7

3 files changed

Lines changed: 78 additions & 21 deletions

File tree

examples/workflows/issue-cleanup/README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ This document describes a workflow to batch-process and clean up older open issu
66

77
The Issue Cleanup workflow is designed to automate the triage of stale issues by using the Gemini CLI to:
88

9-
1. **Check for Staleness and Vagueness**: Identifies issues with insufficient information. If a request for more information has gone unanswered for over a week, it closes the issue. If it's a new vague issue, it asks the reporter for specific details.
10-
2. **Check Code Validity**: Determines if an issue is still relevant against the current codebase. If the issue has already been resolved implicitly, it will close the issue with an explanation.
11-
3. **Find Duplicates**: Checks if the issue has a more recent duplicate. If a duplicate exists, it closes the issue and links to the duplicate.
12-
4. **Summarize for Triage**: If an issue is still valid and unique, it provides a summary comment based on customizable instructions (e.g., categorizing it as `Maintainer-only` or `Help-wanted`). If no custom instructions are provided, it falls back to a standard triage summary (identifying the core problem, impact, and next steps).
9+
1. **Check for Staleness (Native)**: Identifies if an issue has been waiting for reporter feedback for over 7 days. If so, it closes the issue directly via a GitHub Action script to save AI resources.
10+
2. **Check for Vagueness (AI)**: If an issue is not stale but lacks sufficient information (e.g., reproduction steps), the agent asks the reporter for specific details and stops.
11+
3. **Check Code Validity (AI)**: Determines if an issue is still relevant against the current codebase. If the issue has already been resolved implicitly, it will close the issue with an explanation.
12+
4. **Find Duplicates (AI)**: Checks if the issue has a more recent duplicate. If a duplicate exists, it closes the issue and links to the duplicate.
13+
5. **Summarize for Triage (AI)**: If an issue is still valid and unique, it provides a summary comment based on customizable instructions (e.g., categorizing it as `Maintainer-only` or `Help-wanted`). If no custom instructions are provided, it falls back to a standard triage summary.
1314

1415
## Usage
1516

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,38 @@
11
description = "Analyzes and cleans up older issues by checking code validity, duplicates, and providing a triage summary."
22
prompt = """
3-
## Role
43
You are an automated triage bot for the `!{echo $REPOSITORY}` repository. Your job is to process Issue #!{echo $ISSUE_NUMBER} as efficiently as possible.
54
65
## Critical Constraints
76
1. **NO META-ANALYSIS**: DO NOT read local files in the repository you are running in (like `package.json`, `README.md`, or `.github/`). Only read files within the `target-repo/` folder you clone in Step 1.
8-
2. **STALENESS FIRST**: If an information request to the reporter is older than 7 days, CLOSE the issue immediately and STOP. Do not investigate the code.
9-
3. **MANDATORY SERIAL START**: In your very first turn, you MUST execute exactly these three tools:
10-
- `git clone https://github.com/!{echo $REPOSITORY}.git target-repo`
11-
- `gh issue view !{echo $ISSUE_NUMBER} --repo !{echo $REPOSITORY} --json author,comments,updatedAt`
12-
- `date`
7+
2. **EFFICIENCY**: If the issue is too vague, close it immediately and stop. Do not investigate code for vague issues.
138
149
## Task Lifecycle
1510
16-
### Step 1: Staleness & Vagueness Check
17-
- Examine the `gh issue view` output.
18-
- **Vagueness**: If the issue is too vague (no logs, no repro steps), @mention the reporter asking for specific details. STOP.
19-
- **Staleness**: If a maintainer or bot previously asked for information and it has been more than 7 days (check against `date`) and the reporter has NOT replied:
20-
- `gh issue close !{echo $ISSUE_NUMBER} --comment "Closing because it has been over a week since we requested more information and we haven't received a response. Feel free to reopen if you can provide the requested details." --repo !{echo $REPOSITORY}`
21-
- STOP execution.
22-
- If not stale or vague, proceed to Step 2.
11+
### Step 1: Setup & Vagueness Check
12+
- Run `git clone https://github.com/!{echo $REPOSITORY}.git target-repo`
13+
- Run `gh issue view !{echo $ISSUE_NUMBER} --repo !{echo $REPOSITORY} --json title,body,author,comments`
14+
- **Vagueness Check**: If the issue description is fundamentally missing context (no logs, no repro steps, just "it's broken") AND no one has asked for more information yet:
15+
- Ask the reporter: `gh issue comment !{echo $ISSUE_NUMBER} --body "@<reporter_username>, thank you for the report! Could you please provide more specific details (e.g., reproduction steps, expected behavior, and environment)? Closing this as vague if no response is received in a week." --repo !{echo $REPOSITORY}`
16+
- **STOP EXECUTION IMMEDIATELY**.
17+
- If the issue is clear or the reporter has provided info, proceed to Step 2.
2318
2419
### Step 2: Code Validity Check
2520
- Search `target-repo/` to see if the bug still exists or the feature is already implemented.
26-
- If fixed: `gh issue close !{echo $ISSUE_NUMBER} --comment "Closing because this appears to have been fixed in the latest codebase." --repo !{echo $REPOSITORY}`. STOP.
21+
- If definitively NO LONGER VALID:
22+
- Close it: `gh issue close !{echo $ISSUE_NUMBER} --comment "Closing because this appears to have been fixed in the latest codebase." --repo !{echo $REPOSITORY}`
23+
- **STOP EXECUTION IMMEDIATELY**.
2724
2825
### Step 3: Duplicate Check
29-
- Search for duplicates using `gh issue list`.
30-
- If found: `gh issue close !{echo $ISSUE_NUMBER} --reason "not planned" --comment "Closing as duplicate of #<duplicate_number>." --repo !{echo $REPOSITORY}`. STOP.
26+
- Search for duplicates using `gh issue list --search "<keywords>" --repo !{echo $REPOSITORY} --state all`
27+
- If a clear duplicate is found:
28+
- Close it: `gh issue close !{echo $ISSUE_NUMBER} --reason "not planned" --comment "Closing as duplicate of #<duplicate_number>." --repo !{echo $REPOSITORY}`
29+
- **STOP EXECUTION IMMEDIATELY**.
3130
3231
### Step 4: Triage Summary
3332
- If unique and valid, provide a summary comment using these instructions:
3433
```
3534
!{echo $CUSTOM_INSTRUCTIONS}
3635
```
3736
- Action: `gh issue comment !{echo $ISSUE_NUMBER} --body "### Triage Summary\n\n<your summary>" --repo !{echo $REPOSITORY}`
38-
- STOP.
37+
- **STOP EXECUTION**.
3938
"""

examples/workflows/issue-cleanup/gemini-issue-cleanup.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,67 @@ jobs:
6161
id-token: 'write'
6262
issues: 'write'
6363
steps:
64+
- name: 'Check for Staleness'
65+
id: 'staleness'
66+
uses: 'actions/github-script@v7'
67+
env:
68+
ISSUE_NUMBER: '${{ matrix.issue_number }}'
69+
with:
70+
script: |-
71+
const issueNumber = parseInt(process.env.ISSUE_NUMBER, 10);
72+
console.log(`Checking staleness for issue #${issueNumber}`);
73+
74+
const { data: issue } = await github.rest.issues.get({
75+
owner: context.repo.owner,
76+
repo: context.repo.repo,
77+
issue_number: issueNumber,
78+
});
79+
const reporter = issue.user.login;
80+
81+
const { data: comments } = await github.rest.issues.listComments({
82+
owner: context.repo.owner,
83+
repo: context.repo.repo,
84+
issue_number: issueNumber,
85+
});
86+
87+
// Find last maintainer comment
88+
const maintainerComments = comments.filter(c => c.user.login !== reporter && !c.user.login.includes('github-actions') && c.user.type !== 'Bot');
89+
90+
if (maintainerComments.length > 0) {
91+
const lastMaintainerComment = maintainerComments[maintainerComments.length - 1];
92+
const reporterReplied = comments.some(c => c.user.login === reporter && new Date(c.created_at) > new Date(lastMaintainerComment.created_at));
93+
94+
if (!reporterReplied) {
95+
const daysAgo = (new Date() - new Date(lastMaintainerComment.created_at)) / (1000 * 60 * 60 * 24);
96+
console.log(`Last maintainer comment was ${daysAgo.toFixed(1)} days ago.`);
97+
98+
if (daysAgo > 7) {
99+
console.log(`Issue is stale. Closing.`);
100+
await github.rest.issues.createComment({
101+
owner: context.repo.owner,
102+
repo: context.repo.repo,
103+
issue_number: issueNumber,
104+
body: "Closing because it has been over a week since we requested more information and we haven't received a response. Feel free to reopen if you can provide the requested details."
105+
});
106+
await github.rest.issues.update({
107+
owner: context.repo.owner,
108+
repo: context.repo.repo,
109+
issue_number: issueNumber,
110+
state: 'closed'
111+
});
112+
core.setOutput('is_stale', 'true');
113+
return;
114+
}
115+
}
116+
}
117+
core.setOutput('is_stale', 'false');
118+
64119
- name: 'Checkout Current Repository'
120+
if: steps.staleness.outputs.is_stale != 'true'
65121
uses: 'actions/checkout@v4'
66122

67123
- name: 'Run Gemini Issue Cleanup'
124+
if: steps.staleness.outputs.is_stale != 'true'
68125
uses: 'google-github-actions/run-gemini-cli@v0' # Replace with actual version when deploying
69126
env:
70127
ISSUE_NUMBER: '${{ matrix.issue_number }}'

0 commit comments

Comments
 (0)