Skip to content

infra :: gemini git workflow 2차 수정 #483

infra :: gemini git workflow 2차 수정

infra :: gemini git workflow 2차 수정 #483

name: '📋 Gemini Scheduled Issue Triage'
on:
schedule:
- cron: '0 * * * *'
pull_request:
branches: [chatforyou_v2]
paths: ['.github/workflows/gemini-scheduled-triage.yml']
push:
branches: [chatforyou_v2]
paths: ['.github/workflows/gemini-scheduled-triage.yml']
workflow_dispatch:
concurrency:
group: '${{ github.workflow }}'
cancel-in-progress: true
defaults:
run:
shell: 'bash'
jobs:
triage:
runs-on: 'ubuntu-latest'
timeout-minutes: 7
permissions:
contents: 'read'
id-token: 'write'
issues: 'read'
pull-requests: 'read'
outputs:
available_labels: '${{ steps.get_labels.outputs.available_labels }}'
triaged_issues: '${{ steps.collect_triage_output.outputs.triaged_issues }}'
steps:
- name: 'Get repository labels'
id: 'get_labels'
uses: 'actions/github-script@v7'
with:
script: |-
const labels = [];
for await (const response of github.paginate.iterator(github.rest.issues.listLabelsForRepo, {
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100,
})) {
labels.push(...response.data);
}
if (!labels || labels.length === 0) {
core.setFailed('There are no issue labels in this repository.')
}
const labelNames = labels.map(label => label.name).sort();
core.setOutput('available_labels', labelNames.join(','));
core.info(`Found ${labelNames.length} labels: ${labelNames.join(', ')}`);
return labelNames;
- name: 'Find untriaged issues'
id: 'find_issues'
env:
GITHUB_REPOSITORY: '${{ github.repository }}'
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN || github.token }}'
run: |-
ISSUES="$(gh issue list \
--state 'open' \
--search 'no:label OR label:"status/needs-triage"' \
--json number,title,body \
--limit '100' \
--repo "${GITHUB_REPOSITORY}" \
| jq -c '.'
)"
echo "issues_to_triage=${ISSUES}" >> "${GITHUB_OUTPUT}"
- name: 'Run Gemini Issue Analysis'
id: 'gemini_issue_analysis'
if: |-
${{ steps.find_issues.outputs.issues_to_triage != '[]' }}
uses: 'google-github-actions/run-gemini-cli@v0'
env:
GITHUB_TOKEN: ''
ISSUES_TO_TRIAGE: '${{ steps.find_issues.outputs.issues_to_triage }}'
REPOSITORY: '${{ github.repository }}'
AVAILABLE_LABELS: '${{ steps.get_labels.outputs.available_labels }}'
GEMINI_TRUST_WORKSPACE: 'true'
with:
gemini_api_key: '${{ secrets.GEMINI_API_KEY }}'
gemini_cli_version: '${{ vars.GEMINI_CLI_VERSION }}'
gemini_debug: '${{ fromJSON(vars.GEMINI_DEBUG || vars.ACTIONS_STEP_DEBUG || false) }}'
gemini_model: '${{ vars.GEMINI_MODEL }}'
upload_artifacts: '${{ vars.UPLOAD_ARTIFACTS }}'
workflow_name: 'gemini-scheduled-triage'
settings: |-
{
"model": {
"maxSessionTurns": 25
},
"telemetry": {
"enabled": true,
"target": "local",
"outfile": ".gemini/telemetry.log"
},
"tools": {
"core": [
"run_shell_command(echo)",
"run_shell_command(jq)",
"run_shell_command(printenv)"
]
}
}
prompt: '/gemini-scheduled-triage'
- name: 'Collect triage output'
id: 'collect_triage_output'
if: |-
${{ steps.find_issues.outputs.issues_to_triage != '[]' }}
env:
TRIAGED_ISSUES: '${{ env.TRIAGED_ISSUES }}'
run: |-
TRIAGED_ISSUES_COMPACT="$(echo "${TRIAGED_ISSUES:-[]}" | jq -c '.')"
echo "triaged_issues=${TRIAGED_ISSUES_COMPACT}" >> "${GITHUB_OUTPUT}"
label:
runs-on: 'ubuntu-latest'
needs: [triage]
if: |-
needs.triage.outputs.available_labels != '' &&
needs.triage.outputs.triaged_issues != '' &&
needs.triage.outputs.triaged_issues != '[]'
permissions:
contents: 'read'
issues: 'write'
pull-requests: 'write'
steps:
- name: 'Mint identity token'
id: 'mint_identity_token'
if: |-
${{ vars.APP_ID }}
uses: 'actions/create-github-app-token@v2'
with:
app-id: '${{ vars.APP_ID }}'
private-key: '${{ secrets.APP_PRIVATE_KEY }}'
permission-contents: 'read'
permission-issues: 'write'
permission-pull-requests: 'write'
- name: 'Apply labels'
env:
AVAILABLE_LABELS: '${{ needs.triage.outputs.available_labels }}'
TRIAGED_ISSUES: '${{ needs.triage.outputs.triaged_issues }}'
uses: 'actions/github-script@v7'
with:
github-token: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}'
script: |-
const availableLabels = (process.env.AVAILABLE_LABELS || '').split(',')
.map((label) => label.trim())
.sort()
const triagedIssues = JSON.parse(process.env.TRIAGED_ISSUES || '[]')
for (const issue of triagedIssues) {
if (!issue || !issue.issue_number) continue;
let labelsToSet = (issue.labels_to_set || [])
.map((label) => label.trim())
.filter((label) => availableLabels.includes(label))
.sort()
if (labelsToSet.length === 0) continue;
await github.rest.issues.setLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.issue_number,
labels: labelsToSet,
});
}