Skip to content

πŸ“‹ Gemini Scheduled Issue Triage #2874

πŸ“‹ Gemini Scheduled Issue Triage

πŸ“‹ Gemini Scheduled Issue Triage #2874

name: "πŸ“‹ Gemini Scheduled Issue Triage"
on:
schedule:
- cron: "0 * * * *" # Runs every hour
workflow_dispatch:
concurrency:
group: "${{ github.workflow }}"
cancel-in-progress: true
defaults:
run:
shell: "bash"
permissions:
contents: "read"
id-token: "write"
issues: "write"
statuses: "write"
jobs:
triage-issues:
timeout-minutes: 5
runs-on: "ubuntu-latest"
steps:
- name: "Checkout repository"
uses: "actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683" # ratchet:actions/checkout@v4
- name: "Generate GitHub App Token"
id: "generate_token"
if: |-
${{ vars.APP_ID }}
uses: "actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e" # ratchet:actions/create-github-app-token@v2
with:
app-id: "${{ vars.APP_ID }}"
private-key: "${{ secrets.APP_PRIVATE_KEY }}"
- name: "Find untriaged issues"
id: "find_issues"
env:
GITHUB_TOKEN: "${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}"
GITHUB_REPOSITORY: "${{ github.repository }}"
GITHUB_OUTPUT: "${{ github.output }}"
run: |-
set -euo pipefail
echo 'πŸ” Finding issues without labels...'
NO_LABEL_ISSUES="$(gh issue list --repo "${GITHUB_REPOSITORY}" \
--search 'is:open is:issue no:label' --json number,title,body)"
echo '🏷️ Finding issues that need triage...'
NEED_TRIAGE_ISSUES="$(gh issue list --repo "${GITHUB_REPOSITORY}" \
--search 'is:open is:issue label:"status/needs-triage"' --json number,title,body)"
echo 'πŸ”„ Merging and deduplicating issues...'
ISSUES="$(echo "${NO_LABEL_ISSUES}" "${NEED_TRIAGE_ISSUES}" | jq -c -s 'add | unique_by(.number)')"
echo 'πŸ“ Setting output for GitHub Actions...'
echo "issues_to_triage=${ISSUES}" >> "${GITHUB_OUTPUT}"
ISSUE_COUNT="$(echo "${ISSUES}" | jq 'length')"
echo "βœ… Found ${ISSUE_COUNT} issues to triage! 🎯"
- name: "Run Gemini Issue Triage"
if: |-
${{ steps.find_issues.outputs.issues_to_triage != '[]' }}
uses: "google-github-actions/run-gemini-cli@v0"
id: "gemini_issue_triage"
env:
GITHUB_TOKEN: "${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}"
ISSUES_TO_TRIAGE: "${{ steps.find_issues.outputs.issues_to_triage }}"
REPOSITORY: "${{ github.repository }}"
with:
gemini_cli_version: "${{ vars.GEMINI_CLI_VERSION }}"
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)",
"run_shell_command(gh label list)",
"run_shell_command(gh issue edit)",
"run_shell_command(gh issue list)"
],
"telemetry": {
"enabled": false,
"target": "gcp"
}
}
prompt: |-
## Role
You are an issue triage assistant. Analyze issues and apply
appropriate labels. Use the available tools to gather information;
do not ask for information to be provided.
## Steps
1. Run: `gh label list`
2. Check environment variable: "${ISSUES_TO_TRIAGE}" (JSON array
of issues)
3. For each issue, apply labels:
`gh issue edit "${ISSUE_NUMBER}" --add-label "label1,label2"`.
If available, set labels that follow the `kind/*`, `area/*`,
and `priority/*` patterns.
4. For each issue, if the `status/needs-triage` label is present,
remove it using:
`gh issue edit "${ISSUE_NUMBER}" --remove-label "status/needs-triage"`
## Guidelines
- Only use existing repository labels
- Do not add comments
- Triage each issue independently
- Reference all shell variables as "${VAR}" (with quotes and braces)