mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 21:32:56 -07:00
320 lines
20 KiB
YAML
320 lines
20 KiB
YAML
name: '📋 Gemini Scheduled Issue Triage'
|
|
|
|
on:
|
|
issues:
|
|
types:
|
|
- 'opened'
|
|
- 'reopened'
|
|
schedule:
|
|
- cron: '0 * * * *' # Runs every hour
|
|
workflow_dispatch:
|
|
|
|
concurrency:
|
|
group: '${{ github.workflow }}-${{ github.event.number || github.run_id }}'
|
|
cancel-in-progress: true
|
|
|
|
defaults:
|
|
run:
|
|
shell: 'bash'
|
|
|
|
permissions:
|
|
id-token: 'write'
|
|
issues: 'write'
|
|
|
|
jobs:
|
|
triage-issues:
|
|
timeout-minutes: 60
|
|
if: |-
|
|
${{ github.repository == 'google-gemini/gemini-cli' }}
|
|
runs-on: 'ubuntu-latest'
|
|
steps:
|
|
- name: 'Checkout'
|
|
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
|
|
|
|
- name: 'Generate GitHub App Token'
|
|
id: 'generate_token'
|
|
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' # ratchet:actions/create-github-app-token@v2
|
|
with:
|
|
app-id: '${{ secrets.APP_ID }}'
|
|
private-key: '${{ secrets.PRIVATE_KEY }}'
|
|
permission-issues: 'write'
|
|
|
|
- name: 'Get issue from event'
|
|
if: |-
|
|
${{ github.event_name == 'issues' }}
|
|
id: 'get_issue_from_event'
|
|
env:
|
|
ISSUE_EVENT: '${{ toJSON(github.event.issue) }}'
|
|
run: |
|
|
set -euo pipefail
|
|
echo "$ISSUE_EVENT" | jq -c '[{number: .number, title: .title, body: .body}]' > issues_to_triage.json
|
|
echo "has_issues=true" >> "${GITHUB_OUTPUT}"
|
|
echo "✅ Found issue #${{ github.event.issue.number }} from event to triage! 🎯"
|
|
|
|
- name: 'Sync Issue Types'
|
|
if: |-
|
|
${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
|
|
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
|
|
with:
|
|
github-token: '${{ steps.generate_token.outputs.token }}'
|
|
script: |-
|
|
const syncIssueTypes = require('./.github/scripts/sync-issue-types.cjs');
|
|
await syncIssueTypes({ github, context, core });
|
|
|
|
- name: 'Find untriaged issues'
|
|
if: |-
|
|
${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
|
|
id: 'find_issues'
|
|
env:
|
|
GITHUB_TOKEN: '${{ steps.generate_token.outputs.token }}'
|
|
GITHUB_REPOSITORY: '${{ github.repository }}'
|
|
run: |-
|
|
set -euo pipefail
|
|
|
|
echo '🔍 Finding issues missing area labels...'
|
|
gh issue list --repo "${GITHUB_REPOSITORY}" \
|
|
--search 'is:open is:issue -label:status/bot-triaged -label:area/core -label:area/agent -label:area/enterprise -label:area/non-interactive -label:area/security -label:area/platform -label:area/extensions -label:area/documentation -label:area/unknown' --limit 50 --json number,title,body > no_area_issues.json
|
|
|
|
echo '🔍 Finding issues missing kind labels...'
|
|
gh issue list --repo "${GITHUB_REPOSITORY}" \
|
|
--search 'is:open is:issue -label:status/bot-triaged -label:kind/bug -label:kind/enhancement -label:kind/customer-issue -label:kind/question' --limit 50 --json number,title,body > no_kind_issues.json
|
|
|
|
echo '🏷️ Finding issues missing priority labels...'
|
|
gh issue list --repo "${GITHUB_REPOSITORY}" \
|
|
--search 'is:open is:issue -label:status/bot-triaged -label:priority/p0 -label:priority/p1 -label:priority/p2 -label:priority/p3 -label:priority/unknown' --limit 50 --json number,title,body > no_priority_issues.json
|
|
|
|
echo '📏 Finding issues missing effort labels...'
|
|
gh issue list --repo "${GITHUB_REPOSITORY}" \
|
|
--search 'is:open is:issue -label:status/bot-triaged -label:effort/small -label:effort/medium -label:effort/large label:area/core,area/extensions,area/site,area/non-interactive' --limit 20 --json number,title,body > no_effort_issues.json
|
|
|
|
echo '🔄 Merging and deduplicating issues...'
|
|
jq -c -s 'add | unique_by(.number)' no_area_issues.json no_kind_issues.json no_priority_issues.json no_effort_issues.json no_type_issues.json > issues_to_triage.json
|
|
|
|
ISSUE_COUNT="$(jq 'length' issues_to_triage.json)"
|
|
if [ "$ISSUE_COUNT" -gt 0 ]; then
|
|
echo "has_issues=true" >> "${GITHUB_OUTPUT}"
|
|
else
|
|
echo "has_issues=false" >> "${GITHUB_OUTPUT}"
|
|
fi
|
|
echo "✅ Found ${ISSUE_COUNT} unique issues to triage! 🎯"
|
|
|
|
- name: 'Create Gemini CLI Experiments Override'
|
|
if: |-
|
|
steps.get_issue_from_event.outputs.has_issues == 'true' || steps.find_issues.outputs.has_issues == 'true'
|
|
run: |
|
|
cat << 'EOF' > gemini_exp.json
|
|
{
|
|
"flags": [
|
|
{
|
|
"flagId": 45750526,
|
|
"boolValue": false
|
|
}
|
|
],
|
|
"experimentIds": []
|
|
}
|
|
EOF
|
|
|
|
- name: 'Get Repository Labels'
|
|
id: 'get_labels'
|
|
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
|
|
with:
|
|
github-token: '${{ steps.generate_token.outputs.token }}'
|
|
script: |-
|
|
const { data: labels } = await github.rest.issues.listLabelsForRepo({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
});
|
|
const labelNames = labels.map(label => label.name);
|
|
core.setOutput('available_labels', labelNames.join(','));
|
|
core.info(`Found ${labelNames.length} labels: ${labelNames.join(', ')}`);
|
|
return labelNames;
|
|
|
|
- name: 'Run Gemini Issue Analysis'
|
|
if: |-
|
|
steps.get_issue_from_event.outputs.has_issues == 'true' || steps.find_issues.outputs.has_issues == 'true'
|
|
uses: 'google-github-actions/run-gemini-cli@a3bf79042542528e91937b3a3a6fbc4967ee3c31' # ratchet:google-github-actions/run-gemini-cli@v0
|
|
id: 'gemini_issue_analysis'
|
|
env:
|
|
GITHUB_TOKEN: '' # Do not pass any auth token here since this runs on untrusted inputs
|
|
REPOSITORY: '${{ github.repository }}'
|
|
AVAILABLE_LABELS: '${{ steps.get_labels.outputs.available_labels }}'
|
|
GEMINI_CLI_TRUST_WORKSPACE: 'true'
|
|
GEMINI_EXP: 'gemini_exp.json'
|
|
GEMINI_STRICT_TELEMETRY_LIMITS: 'true'
|
|
with:
|
|
gcp_workload_identity_provider: '${{ vars.GCP_WIF_PROVIDER }}'
|
|
gcp_project_id: '${{ vars.GOOGLE_CLOUD_PROJECT }}'
|
|
gcp_location: '${{ vars.GOOGLE_CLOUD_LOCATION }}'
|
|
gcp_service_account: '${{ vars.SERVICE_ACCOUNT_EMAIL }}'
|
|
gemini_api_key: '${{ secrets.GEMINI_API_KEY }}'
|
|
use_vertex_ai: '${{ vars.GOOGLE_GENAI_USE_VERTEXAI }}'
|
|
use_gemini_code_assist: '${{ vars.GOOGLE_GENAI_USE_GCA }}'
|
|
settings: |-
|
|
{
|
|
"maxSessionTurns": 25,
|
|
"coreTools": [
|
|
"run_shell_command(echo)",
|
|
"grep_search",
|
|
"glob",
|
|
"read_file"
|
|
],
|
|
"telemetry": {
|
|
"enabled": true,
|
|
"target": "gcp"
|
|
}
|
|
}
|
|
prompt: |-
|
|
## Role
|
|
|
|
You are an issue triage assistant. Analyze issues and identify
|
|
appropriate labels. Use the available tools to gather information;
|
|
do not ask for information to be provided.
|
|
|
|
## Steps
|
|
|
|
1. You are only able to use the echo and read_file commands. Review the available labels in the environment variable: "${AVAILABLE_LABELS}".
|
|
2. Use the read_file tool to read the file "issues_to_triage.json" which contains the JSON array of issues to triage.
|
|
3. Review the issue title, body and any comments provided in the JSON file.
|
|
4. Identify the most relevant labels from the existing labels, specifically focusing on area/*, kind/*, priority/*, and effort/*.
|
|
5. Label Policy:
|
|
- If the issue already has a kind/ label, do not change it.
|
|
- If the issue already has a priority/ label, do not change it.
|
|
- If the issue already has an area/ label, do not change it.
|
|
- If the issue already has an effort/ label, do not change it.
|
|
- If the issue is missing an effort/ label AND its area is area/core, area/extensions, area/site, or area/non-interactive, you must evaluate the architectural complexity to determine the effort level. You MUST NOT guess the root cause. You MUST actively use your codebase search tools (grep_search and glob) to search for keywords from the issue and explore the codebase. You must identify the specific files and components involved before deciding the effort. Do NOT evaluate or assign an effort/ label to issues in any other areas (such as area/agent).
|
|
- If any of these are missing, select exactly ONE appropriate label for the missing category.
|
|
6. Identify other applicable labels based on the issue content, such as status/*, help wanted, good first issue, etc.
|
|
7. Give me a single short explanation about why you are selecting each label in the process.
|
|
8. Output a JSON array of objects, each containing the issue number
|
|
and the labels to add and remove, along with an explanation. If you assigned an effort/ label, you MUST also include an effort_analysis field. This effort_analysis must be highly detailed, technical, and empirical. It MUST NOT contain vague guesses (e.g., avoid words like "likely points to" or "possibly"). You must explicitly cite the specific file paths and architectural mechanisms you discovered using your search tools, explain the root cause, and then explicitly state how that complexity maps to the chosen effort level guidelines. For example:
|
|
```
|
|
[
|
|
{
|
|
"issue_number": 123,
|
|
"labels_to_add": ["area/core", "kind/bug", "priority/p2", "effort/small"],
|
|
"labels_to_remove": ["status/need-triage"],
|
|
"explanation": "This issue is a UI bug that needs to be addressed with medium priority.",
|
|
"effort_analysis": "The `vscode-ide-companion` extension indiscriminately tracks active text editors via `vscode.window.onDidChangeActiveTextEditor` in `open-files-manager.ts`. When a user opens `.vscode/settings.json`, its content is sent to the CLI's context. The fix is highly localized to the VS Code companion extension's event listener. It involves adding a simple conditional check to exclude specific configuration files from the active editor tracking logic, which is a trivial logic adjustment with a clear root cause."
|
|
}
|
|
]
|
|
```
|
|
If an issue cannot be classified, do not include it in the output array.
|
|
9. For each issue please check if CLI version is present, this is usually in the output of the /about command and will look like 0.1.5
|
|
- Anything more than 6 versions older than the most recent should add the status/need-retesting label
|
|
10. If you see that the issue doesn't look like it has sufficient information recommend the status/need-information label and leave a comment politely requesting the relevant information, eg.. if repro steps are missing request for repro steps. if version information is missing request for version information into the explanation section below.
|
|
11. If you think an issue might be a Priority/P0 do not apply the priority/p0 label. Instead apply a status/manual-triage label and include a note in your explanation.
|
|
12. If you are uncertain about a category, use the area/unknown, kind/question, or priority/unknown labels as appropriate. If you are extremely uncertain, apply the status/manual-triage label.
|
|
|
|
## Guidelines
|
|
|
|
- Output only valid JSON format
|
|
- Do not include any explanation or additional text, just the JSON
|
|
- Only use labels that already exist in the repository.
|
|
- Do not add comments or modify the issue content.
|
|
- Do not remove the following labels maintainer, help wanted or good first issue.
|
|
- Triage only the current issue.
|
|
- Identify only one area/ label.
|
|
- Identify only one kind/ label (Do not apply kind/duplicate or kind/parent-issue)
|
|
- Identify only one priority/ label.
|
|
- Once you categorize the issue if it needs information bump down the priority by 1 eg.. a p0 would become a p1 a p1 would become a p2. P2 and P3 can stay as is in this scenario.
|
|
|
|
Categorization Guidelines (Effort):
|
|
effort/small (1 day or less):
|
|
- Trivial Logic & Config: Schema updates (Zod), feature flag toggles, adding missing fields to package.json or settings.json.
|
|
- UI/Aesthetic Adjustments: Fixing minor layout bugs in Ink components (e.g., adding flexShrink, correcting padding in a single Box), text color changes.
|
|
- Documentation & Strings: Typos, log message updates, CLI argument descriptions.
|
|
- Localized Bug Fixes: Single-file logic errors, straightforward promise rejections (e.g., wrapping a known failure in a try/catch), simple regex or string parsing fixes.
|
|
effort/medium (2-3 days):
|
|
- React/Ink State Management: Debugging useState/useEffect/useReducer bugs, component lifecycle issues (memory leaks in the UI), terminal redraw flickering, or state synchronization between the CLI's internal input buffer and the interactive React components.
|
|
- Asynchronous Flow & Integration: Resolving complex Promise chains, ERR_STREAM_PREMATURE_CLOSE, debugging IDE companion extensions (VS Code, Android Studio) or resolving hanging HTTP requests/IPC between the CLI and external plugins, timeouts in non-interactive/ACP modes.
|
|
- Tooling & Output Parsers: Modifying how tools parse streaming stdout/stderr buffers, adding new built-in tools that don't require native bindings.
|
|
- Cross-Component Refactors: Changes that span across packages/cli and packages/core to pass new data models or telemetry state.
|
|
effort/large (3+ days):
|
|
- Platform-Specific Complexities (PTY/Signals): Any issue involving node-pty, child_process.spawn, OS-level shell behavior (Windows vs Linux vs macOS), pseudo-terminal exhaustion (ENXIO), raw mode terminal desyncs, or POSIX signal forwarding (SIGINT/SIGTERM).
|
|
- Core Architecture & Protocols: Refactoring the Scheduler, Agent-to-Agent (A2A) protocol implementation, low-level MCP (Model Context Protocol) transport mechanisms.
|
|
- Performance & Memory: Diagnosing massive disk/memory leaks, severe boot time regressions, high-throughput streaming optimizations (e.g., voice streaming pipelines).
|
|
Note: Any bug that is described as intermittent, flickering, difficult to reproduce, platform-specific, or requiring cross-environment setups (e.g., involving the VS Code IDE companion, GCA plugin, or Android Studio) MUST NOT be rated as effort/small because of the increased overhead of testing and reproducing.
|
|
|
|
Categorization Guidelines (Priority):
|
|
P0 - Urgent Blocking Issues:
|
|
- DO NOT APPLY THIS LABEL AUTOMATICALLY. Use status/manual-triage instead.
|
|
- Definition: Urgent, block a significant percentage of the user base, and prevent frequent use of the Gemini CLI.
|
|
- This includes core stability blockers (e.g., authentication failures, broken upgrades), critical crashes, and P0 security vulnerabilities.
|
|
- Impact: Blocks development or testing for the entire team; Major security vulnerability; Causes data loss or corruption with no workaround; Crashes the application or makes a core feature completely unusable for all or most users.
|
|
- Qualifier: Is the main function of the software broken?
|
|
P1 - High-Impact Issues:
|
|
- Definition: Affect a large number of users, blocking them from using parts of the Gemini CLI, or make the CLI frequently unusable even with workarounds available.
|
|
- Impact: A core feature is broken or behaving incorrectly for a large number of users or use cases; Severe performance degradation; No straightforward workaround exists.
|
|
- Qualifier: Is a key feature unusable or giving very wrong results?
|
|
P2 - Significant Issues:
|
|
- Definition: Affect some users significantly, such as preventing the use of certain features or authentication types.
|
|
- Can also be issues that many users complain about, causing annoyance or hindering daily use.
|
|
- Impact: Affects a non-critical feature or a smaller, specific subset of users; An inconvenient but functional workaround is available; Noticeable UI/UX problems that look unprofessional.
|
|
- Qualifier: Is it an annoying but non-blocking problem?
|
|
P3 - Low-Impact Issues:
|
|
- Definition: Typically usability issues that cause annoyance to a limited user base.
|
|
- Includes feature requests that could be addressed in the near future and may be suitable for community contributions.
|
|
- Impact: Minor cosmetic issues; An edge-case bug that is very difficult to reproduce and affects a tiny fraction of users.
|
|
- Qualifier: Is it a "nice-to-fix" issue?
|
|
|
|
Categorization Guidelines (Area):
|
|
area/agent: Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality
|
|
area/core: User Interface, OS Support, Core Functionality
|
|
area/documentation: End-user and contributor-facing documentation, website-related
|
|
area/enterprise: Telemetry, Policy, Quota / Licensing
|
|
area/extensions: Gemini CLI extensions capability
|
|
area/non-interactive: GitHub Actions, SDK, 3P Integrations, Shell Scripting, Command line automation
|
|
area/platform: Build infra, Release mgmt, Testing, Eval infra, Capacity, Quota mgmt
|
|
area/security: security related issues
|
|
|
|
Additional Context:
|
|
- If users are talking about issues where the model gets downgraded from pro to flash then i want you to categorize that as a performance issue.
|
|
- This product is designed to use different models eg.. using pro, downgrading to flash etc.
|
|
- When users report that they dont expect the model to change those would be categorized as feature requests.
|
|
|
|
- name: 'Apply Labels to Issues'
|
|
if: |-
|
|
${{ steps.gemini_issue_analysis.outcome == 'success' &&
|
|
steps.gemini_issue_analysis.outputs.summary != '[]' }}
|
|
env:
|
|
REPOSITORY: '${{ github.repository }}'
|
|
LABELS_OUTPUT: '${{ steps.gemini_issue_analysis.outputs.summary }}'
|
|
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
|
|
with:
|
|
github-token: '${{ steps.generate_token.outputs.token }}'
|
|
script: |-
|
|
const applyLabels = require('./.github/scripts/apply-issue-labels.cjs');
|
|
await applyLabels({ github, context, core });
|
|
|
|
- name: 'Sync Issue Types (Post-Analysis)'
|
|
if: |-
|
|
always() && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
|
|
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
|
|
with:
|
|
github-token: '${{ steps.generate_token.outputs.token }}'
|
|
script: |-
|
|
const syncIssueTypes = require('./.github/scripts/sync-issue-types.cjs');
|
|
await syncIssueTypes({ github, context, core });
|
|
|
|
- name: 'Find Triaged Issues to Clean Up'
|
|
if: |-
|
|
always() && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
|
|
env:
|
|
GITHUB_TOKEN: '${{ steps.generate_token.outputs.token }}'
|
|
GITHUB_REPOSITORY: '${{ github.repository }}'
|
|
run: |-
|
|
set -euo pipefail
|
|
echo '🧹 Finding issues that have both bot-triaged and need-triage labels...'
|
|
gh issue list --repo "${GITHUB_REPOSITORY}" \
|
|
--search 'is:open is:issue label:status/bot-triaged label:status/need-triage' --limit 50 --json number > issues_to_cleanup.json
|
|
|
|
- name: 'Clean Up Triage Labels'
|
|
if: |-
|
|
always() && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
|
|
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
|
|
with:
|
|
github-token: '${{ steps.generate_token.outputs.token }}'
|
|
script: |-
|
|
const cleanupLabels = require('./.github/scripts/cleanup-triage-labels.cjs');
|
|
await cleanupLabels({ github, context, core });
|