gitinject 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. gitinject/__init__.py +1 -0
  2. gitinject/__main__.py +5 -0
  3. gitinject/analyzer.py +67 -0
  4. gitinject/attacks/__init__.py +27 -0
  5. gitinject/attacks/autoinject.py +165 -0
  6. gitinject/attacks/base.py +33 -0
  7. gitinject/attacks/static.py +25 -0
  8. gitinject/cli.py +768 -0
  9. gitinject/data/research/scenarios/claude_skills_injection.md +96 -0
  10. gitinject/data/research/scenarios/cline_issue_body_injection.md +93 -0
  11. gitinject/data/research/scenarios/codex_agents_md_injection.md +109 -0
  12. gitinject/data/research/scenarios/dos_request_flood.md +133 -0
  13. gitinject/data/research/scenarios/dropped/ci_log_injection_workflow_poisoning.md +138 -0
  14. gitinject/data/research/scenarios/dropped/claude_md_instructions_injection.md +158 -0
  15. gitinject/data/research/scenarios/dropped/supply_chain_token_pivot.md +101 -0
  16. gitinject/data/research/scenarios/gemini_api_key_exfiltration.md +68 -0
  17. gitinject/data/research/scenarios/gemini_api_key_exfiltration_replication.md +0 -0
  18. gitinject/data/research/scenarios/gemini_md_instructions_injection.md +131 -0
  19. gitinject/data/research/scenarios/nsfw_api_key_block.md +114 -0
  20. gitinject/data/research/scenarios/pr_token_exfiltration_via_git_config.md +117 -0
  21. gitinject/data/research/scenarios/supply_chain_malicious_code.md +135 -0
  22. gitinject/evaluators.py +169 -0
  23. gitinject/evidence.py +72 -0
  24. gitinject/gl_runner.py +163 -0
  25. gitinject/resources.py +30 -0
  26. gitinject/run_context.py +72 -0
  27. gitinject/run_record.py +113 -0
  28. gitinject/runner.py +1024 -0
  29. gitinject/scanner/__init__.py +22 -0
  30. gitinject/scanner/baselines/__init__.py +0 -0
  31. gitinject/scanner/baselines/actionlint_runner.py +44 -0
  32. gitinject/scanner/baselines/zizmor_runner.py +35 -0
  33. gitinject/scanner/diagnostics.py +174 -0
  34. gitinject/scanner/hypothesis_generator.py +164 -0
  35. gitinject/scanner/live_validator.py +284 -0
  36. gitinject/scanner/llm_ranker.py +120 -0
  37. gitinject/scanner/memory.py +239 -0
  38. gitinject/scanner/primitives.py +236 -0
  39. gitinject/scanner/prompt_extractor.py +134 -0
  40. gitinject/scanner/recipe_scenario.py +203 -0
  41. gitinject/scanner/report_generator.py +230 -0
  42. gitinject/scanner/types.py +179 -0
  43. gitinject/scenario_base.py +147 -0
  44. gitinject/scenario_loader.py +77 -0
  45. gitinject/scenarios/__init__.py +0 -0
  46. gitinject/scenarios/benign/documentation_out_of_sync/contents/math_utils.py +3 -0
  47. gitinject/scenarios/benign/documentation_out_of_sync/contents/pydantic/v1/utils.py +21 -0
  48. gitinject/scenarios/benign/documentation_out_of_sync/scenario.py +57 -0
  49. gitinject/scenarios/benign/issue_deduplication_utility/scenario.py +76 -0
  50. gitinject/scenarios/benign/repository_onboarding_qa/contents/README.md +3 -0
  51. gitinject/scenarios/benign/repository_onboarding_qa/scenario.py +52 -0
  52. gitinject/scenarios/benign/secrets_false_positive/contents/tests/test_auth.py +14 -0
  53. gitinject/scenarios/benign/secrets_false_positive/scenario.py +58 -0
  54. gitinject/scenarios/benign/test_coverage_gap/contents/src/requests/auth_extra.py +33 -0
  55. gitinject/scenarios/benign/test_coverage_gap/scenario.py +56 -0
  56. gitinject/scenarios/benign/vulnerability_fix_verification/contents/src/flask/utils.py +15 -0
  57. gitinject/scenarios/benign/vulnerability_fix_verification/scenario.py +57 -0
  58. gitinject/scenarios/benign/vulnerable_code_review/contents/examples/tutorial/flaskr/db_utils.py +18 -0
  59. gitinject/scenarios/benign/vulnerable_code_review/scenario.py +55 -0
  60. gitinject/scenarios/benign/weekly_activity_summary/scenario.py +83 -0
  61. gitinject/scenarios/malicious/agents_md_approval_manipulation/contents/AGENTS.md +25 -0
  62. gitinject/scenarios/malicious/agents_md_approval_manipulation/contents/src/flask/csrf.py +151 -0
  63. gitinject/scenarios/malicious/agents_md_approval_manipulation/contents/tests/test_csrf.py +71 -0
  64. gitinject/scenarios/malicious/agents_md_approval_manipulation/scenario.py +121 -0
  65. gitinject/scenarios/malicious/claude_md_instructions_injection/contents/CLAUDE.md +23 -0
  66. gitinject/scenarios/malicious/claude_md_instructions_injection/contents/scripts/deploy_check.sh +29 -0
  67. gitinject/scenarios/malicious/claude_md_instructions_injection/scenario.py +93 -0
  68. gitinject/scenarios/malicious/cline_issue_body_injection/scenario.py +132 -0
  69. gitinject/scenarios/malicious/codex_agents_md_injection/contents/AGENTS.md +36 -0
  70. gitinject/scenarios/malicious/codex_agents_md_injection/contents/scripts/utils.py +12 -0
  71. gitinject/scenarios/malicious/codex_agents_md_injection/scenario.py +128 -0
  72. gitinject/scenarios/malicious/dos_request_flood/scenario.py +80 -0
  73. gitinject/scenarios/malicious/gemini_md_approval_manipulation/contents/src/flask/csrf.py +151 -0
  74. gitinject/scenarios/malicious/gemini_md_approval_manipulation/contents/tests/test_csrf.py +71 -0
  75. gitinject/scenarios/malicious/gemini_md_approval_manipulation/scenario.py +121 -0
  76. gitinject/scenarios/malicious/gemini_md_instructions_injection/contents/scripts/deploy_check.sh +38 -0
  77. gitinject/scenarios/malicious/gemini_md_instructions_injection/scenario.py +105 -0
  78. gitinject/scenarios/malicious/issue_onboarding_secret_exfiltration/scenario.py +76 -0
  79. gitinject/scenarios/malicious/pr_token_exfiltration_via_git_config/contents/scripts/deploy_check.sh +7 -0
  80. gitinject/scenarios/malicious/pr_token_exfiltration_via_git_config/scenario.py +113 -0
  81. gitinject/scenarios/malicious/supply_chain_malicious_code/contents/CLAUDE.md +25 -0
  82. gitinject/scenarios/malicious/supply_chain_malicious_code/contents/src/flask/csrf.py +151 -0
  83. gitinject/scenarios/malicious/supply_chain_malicious_code/contents/tests/test_csrf.py +71 -0
  84. gitinject/scenarios/malicious/supply_chain_malicious_code/scenario.py +123 -0
  85. gitinject/scenarios/malicious/unauthorized_pr_approval/contents/django/utils/crypto.py +13 -0
  86. gitinject/scenarios/malicious/unauthorized_pr_approval/scenario.py +57 -0
  87. gitinject/simulator.py +89 -0
  88. gitinject/utils/__init__.py +0 -0
  89. gitinject/utils/gh_client.py +628 -0
  90. gitinject/utils/gl_client.py +132 -0
  91. gitinject/utils/gl_provisioner.py +83 -0
  92. gitinject/utils/llm.py +205 -0
  93. gitinject/utils/provisioner.py +114 -0
  94. gitinject/utils/scenario_resources.py +33 -0
  95. gitinject/utils/types.py +49 -0
  96. gitinject/workflows/__init__.py +0 -0
  97. gitinject/workflows/claude-ci-auto-fix/contents/.github/workflows/main.yml +107 -0
  98. gitinject/workflows/claude-ci-auto-fix/metadata.json +10 -0
  99. gitinject/workflows/claude-general/contents/.github/workflows/main.yml +58 -0
  100. gitinject/workflows/claude-general/metadata.json +10 -0
  101. gitinject/workflows/claude-gitlab-mr-review/contents/.gitlab-ci.yml +36 -0
  102. gitinject/workflows/claude-gitlab-mr-review/metadata.json +11 -0
  103. gitinject/workflows/claude-issue-deduplication/contents/.github/workflows/main.yml +66 -0
  104. gitinject/workflows/claude-issue-deduplication/metadata.json +10 -0
  105. gitinject/workflows/claude-issue-triage/contents/.github/workflows/main.yml +34 -0
  106. gitinject/workflows/claude-issue-triage/metadata.json +10 -0
  107. gitinject/workflows/claude-manual-analysis/contents/.github/workflows/main.yml +42 -0
  108. gitinject/workflows/claude-manual-analysis/metadata.json +10 -0
  109. gitinject/workflows/claude-pr-review/contents/.github/workflows/main.yml +77 -0
  110. gitinject/workflows/claude-pr-review/metadata.json +10 -0
  111. gitinject/workflows/claude-pr-review-authors/contents/.github/workflows/main.yml +48 -0
  112. gitinject/workflows/claude-pr-review-authors/metadata.json +10 -0
  113. gitinject/workflows/claude-pr-review-paths/contents/.github/workflows/main.yml +49 -0
  114. gitinject/workflows/claude-pr-review-paths/metadata.json +10 -0
  115. gitinject/workflows/claude-test-analysis/contents/.github/workflows/main.yml +114 -0
  116. gitinject/workflows/claude-test-analysis/metadata.json +10 -0
  117. gitinject/workflows/cline-assistant/contents/.github/workflows/main.yml +87 -0
  118. gitinject/workflows/cline-assistant/contents/git-scripts/analyze-issue.sh +43 -0
  119. gitinject/workflows/cline-assistant/metadata.json +10 -0
  120. gitinject/workflows/codex-pr-review/contents/.github/workflows/main.yml +73 -0
  121. gitinject/workflows/codex-pr-review/metadata.json +10 -0
  122. gitinject/workflows/copilot-ci-doctor/contents/.github/workflows/ci-doctor.yml +1161 -0
  123. gitinject/workflows/copilot-ci-doctor/metadata.json +10 -0
  124. gitinject/workflows/copilot-lean-squad/contents/.github/workflows/lean-squad.yml +1313 -0
  125. gitinject/workflows/copilot-lean-squad/metadata.json +10 -0
  126. gitinject/workflows/copilot-malicious-scan/contents/.github/workflows/daily-malicious-code-scan.yml +899 -0
  127. gitinject/workflows/copilot-malicious-scan/metadata.json +10 -0
  128. gitinject/workflows/copilot-repo-assist/contents/.github/workflows/repo-assist.yml +1503 -0
  129. gitinject/workflows/copilot-repo-assist/metadata.json +10 -0
  130. gitinject/workflows/copilot-wiki-writer/contents/.github/workflows/agentic-wiki-writer.yml +1316 -0
  131. gitinject/workflows/copilot-wiki-writer/metadata.json +10 -0
  132. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-invoke.yml +122 -0
  133. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-plan-execute.yml +130 -0
  134. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-review.yml +118 -0
  135. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-scheduled-triage.yml +220 -0
  136. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-triage.yml +160 -0
  137. gitinject/workflows/gemini-assistant/contents/.github/workflows/main.yml +220 -0
  138. gitinject/workflows/gemini-assistant/metadata.json +10 -0
  139. gitinject/workflows/gemini-assistant-original/AWESOME.md +118 -0
  140. gitinject/workflows/gemini-assistant-original/CONFIGURATION.md +162 -0
  141. gitinject/workflows/gemini-assistant-original/README.md +93 -0
  142. gitinject/workflows/gemini-assistant-original/gemini-assistant/README.md +192 -0
  143. gitinject/workflows/gemini-assistant-original/gemini-assistant/gemini-invoke.toml +94 -0
  144. gitinject/workflows/gemini-assistant-original/gemini-assistant/gemini-invoke.yml +131 -0
  145. gitinject/workflows/gemini-assistant-original/gemini-assistant/gemini-plan-execute.toml +100 -0
  146. gitinject/workflows/gemini-assistant-original/gemini-assistant/gemini-plan-execute.yml +139 -0
  147. gitinject/workflows/gemini-assistant-original/gemini-dispatch/README.md +49 -0
  148. gitinject/workflows/gemini-assistant-original/gemini-dispatch/gemini-dispatch.yml +221 -0
  149. gitinject/workflows/gemini-assistant-original/issue-triage/README.md +190 -0
  150. gitinject/workflows/gemini-assistant-original/issue-triage/gemini-scheduled-triage.toml +96 -0
  151. gitinject/workflows/gemini-assistant-original/issue-triage/gemini-scheduled-triage.yml +223 -0
  152. gitinject/workflows/gemini-assistant-original/issue-triage/gemini-triage.toml +32 -0
  153. gitinject/workflows/gemini-assistant-original/issue-triage/gemini-triage.yml +167 -0
  154. gitinject/workflows/gemini-assistant-original/metadata.json +10 -0
  155. gitinject/workflows/gemini-assistant-original/pr-review/README.md +337 -0
  156. gitinject/workflows/gemini-assistant-original/pr-review/gemini-review.toml +176 -0
  157. gitinject/workflows/gemini-assistant-original/pr-review/gemini-review.yml +119 -0
  158. gitinject/workflows/opencode-pr-review/contents/.github/workflows/main.yml +28 -0
  159. gitinject/workflows/opencode-pr-review/metadata.json +10 -0
  160. gitinject-0.1.0.dist-info/METADATA +128 -0
  161. gitinject-0.1.0.dist-info/RECORD +164 -0
  162. gitinject-0.1.0.dist-info/WHEEL +4 -0
  163. gitinject-0.1.0.dist-info/entry_points.txt +2 -0
  164. gitinject-0.1.0.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,139 @@
1
+ name: '🧙 Gemini Plan Execution'
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ additional_context:
7
+ type: 'string'
8
+ description: 'Any additional context from the request'
9
+ required: false
10
+
11
+ concurrency:
12
+ group: '${{ github.workflow }}-plan-execute-${{ github.event_name }}-${{ github.event.pull_request.number || github.event.issue.number }}'
13
+ cancel-in-progress: true
14
+
15
+ defaults:
16
+ run:
17
+ shell: 'bash'
18
+
19
+ jobs:
20
+ plan-execute:
21
+ timeout-minutes: 30
22
+ runs-on: 'ubuntu-latest'
23
+ permissions:
24
+ contents: 'write'
25
+ id-token: 'write'
26
+ issues: 'write'
27
+ pull-requests: 'write'
28
+
29
+ steps:
30
+ - name: 'Mint identity token'
31
+ id: 'mint_identity_token'
32
+ if: |-
33
+ ${{ vars.APP_ID }}
34
+ uses: 'actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf' # ratchet:actions/create-github-app-token@v2
35
+ with:
36
+ app-id: '${{ vars.APP_ID }}'
37
+ private-key: '${{ secrets.APP_PRIVATE_KEY }}'
38
+ permission-contents: 'write'
39
+ permission-issues: 'write'
40
+ permission-pull-requests: 'write'
41
+
42
+ - name: 'Checkout Code'
43
+ uses: 'actions/checkout@v4' # ratchet:exclude
44
+ with:
45
+ persist-credentials: 'false'
46
+
47
+ - name: 'Prepare prompt context'
48
+ shell: 'bash'
49
+ run: |-
50
+ mkdir -p .gemini
51
+ jq -n \
52
+ --arg title "${TITLE}" \
53
+ --arg desc "${DESCRIPTION}" \
54
+ --arg event "${EVENT_NAME}" \
55
+ --arg pr "${IS_PULL_REQUEST}" \
56
+ --arg num "${ISSUE_NUMBER}" \
57
+ --arg repo "${REPOSITORY}" \
58
+ --arg context "${ADDITIONAL_CONTEXT}" \
59
+ '{title: $title, description: $desc, event_name: $event, is_pull_request: $pr, issue_number: $num, repository: $repo, additional_context: $context}' > .gemini/context.json
60
+ env:
61
+ TITLE: '${{ github.event.pull_request.title || github.event.issue.title }}'
62
+ DESCRIPTION: '${{ github.event.pull_request.body || github.event.issue.body }}'
63
+ EVENT_NAME: '${{ github.event_name }}'
64
+ IS_PULL_REQUEST: '${{ !!github.event.pull_request }}'
65
+ ISSUE_NUMBER: '${{ github.event.pull_request.number || github.event.issue.number }}'
66
+ REPOSITORY: '${{ github.repository }}'
67
+ ADDITIONAL_CONTEXT: '${{ inputs.additional_context }}'
68
+
69
+ - name: 'Run Gemini CLI'
70
+ id: 'run_gemini'
71
+ uses: 'google-github-actions/run-gemini-cli@v0' # ratchet:exclude
72
+ env:
73
+ GEMINI_CLI_TRUST_WORKSPACE: 'true'
74
+ GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}'
75
+ with:
76
+ gcp_location: '${{ vars.GOOGLE_CLOUD_LOCATION }}'
77
+ gcp_project_id: '${{ vars.GOOGLE_CLOUD_PROJECT }}'
78
+ gcp_service_account: '${{ vars.SERVICE_ACCOUNT_EMAIL }}'
79
+ gcp_workload_identity_provider: '${{ vars.GCP_WIF_PROVIDER }}'
80
+ gemini_api_key: '${{ secrets.GEMINI_API_KEY }}'
81
+ gemini_cli_version: '${{ vars.GEMINI_CLI_VERSION }}'
82
+ gemini_debug: '${{ fromJSON(vars.GEMINI_DEBUG || vars.ACTIONS_STEP_DEBUG || false) }}'
83
+ gemini_model: '${{ vars.GEMINI_MODEL }}'
84
+ google_api_key: '${{ secrets.GOOGLE_API_KEY }}'
85
+ use_gemini_code_assist: '${{ vars.GOOGLE_GENAI_USE_GCA }}'
86
+ use_vertex_ai: '${{ vars.GOOGLE_GENAI_USE_VERTEXAI }}'
87
+ upload_artifacts: '${{ vars.UPLOAD_ARTIFACTS }}'
88
+ workflow_name: 'gemini-plan-execute'
89
+ # Assistant workflows can be triggered by comments on either Issues or PRs.
90
+ # We explicitly map both fields so the CLI can correctly categorize the interaction.
91
+ github_pr_number: '${{ github.event.pull_request.number }}'
92
+ github_issue_number: '${{ github.event.issue.number }}'
93
+ settings: |-
94
+ {
95
+ "model": {
96
+ "maxSessionTurns": 25
97
+ },
98
+ "telemetry": {
99
+ "enabled": true,
100
+ "target": "local",
101
+ "outfile": ".gemini/telemetry.log"
102
+ },
103
+ "mcpServers": {
104
+ "github": {
105
+ "command": "docker",
106
+ "args": [
107
+ "run",
108
+ "-i",
109
+ "--rm",
110
+ "-e",
111
+ "GITHUB_PERSONAL_ACCESS_TOKEN",
112
+ "ghcr.io/github/github-mcp-server:v0.27.0"
113
+ ],
114
+ "includeTools": [
115
+ "add_issue_comment",
116
+ "issue_read",
117
+ "list_issues",
118
+ "search_issues",
119
+ "create_pull_request",
120
+ "pull_request_read",
121
+ "list_pull_requests",
122
+ "search_pull_requests",
123
+ "create_branch",
124
+ "create_or_update_file",
125
+ "delete_file",
126
+ "fork_repository",
127
+ "get_commit",
128
+ "get_file_contents",
129
+ "list_commits",
130
+ "push_files",
131
+ "search_code"
132
+ ],
133
+ "env": {
134
+ "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
135
+ }
136
+ }
137
+ }
138
+ }
139
+ prompt: '/gemini-plan-execute'
@@ -0,0 +1,49 @@
1
+ # Gemini Dispatch Workflow
2
+
3
+ This workflow acts as a central dispatcher for Gemini CLI, routing requests to the appropriate workflow based on the triggering event and the command provided in the comment.
4
+
5
+ - [Gemini Dispatch Workflow](#gemini-dispatch-workflow)
6
+ - [Triggers](#triggers)
7
+ - [Dispatch Logic](#dispatch-logic)
8
+ - [In-Built Workflows](#in-built-workflows)
9
+ - [Adding Your Own Workflows](#adding-your-own-workflows)
10
+ - [Usage](#usage)
11
+
12
+ ## Triggers
13
+
14
+ This workflow is triggered by the following events:
15
+
16
+ - Pull request review comment (created)
17
+ - Pull request review (submitted)
18
+ - Pull request (opened)
19
+ - Issue (opened, reopened)
20
+ - Issue comment (created)
21
+
22
+ ## Dispatch Logic
23
+
24
+ The workflow uses a dispatch job to determine which command to execute based on the following logic:
25
+
26
+ - If a comment contains `@gemini-cli /review`, it calls the `gemini-review.yml` workflow.
27
+ - If a comment contains `@gemini-cli /triage`, it calls the `gemini-triage.yml` workflow.
28
+ - If a comment contains `@gemini-cli` (without a specific command), it calls the `gemini-invoke.yml` workflow.
29
+ - When a new pull request is opened, it calls the `gemini-review.yml` workflow.
30
+ - When a new issue is opened or reopened, it calls the `gemini-triage.yml` workflow.
31
+
32
+ ## In-Built Workflows
33
+
34
+ - **[gemini-review.yml](../pr-review/gemini-review.yml):** This workflow reviews a pull request.
35
+ - **[gemini-triage.yml](../issue-triage/gemini-triage.yml):** This workflow triages an issue.
36
+ - **[gemini-invoke.yml](../gemini-assistant/gemini-invoke.yml):** This workflow is a general-purpose workflow that can be used to perform various tasks.
37
+
38
+ ## Adding Your Own Workflows
39
+
40
+ You can easily extend the dispatch workflow to include your own custom workflows. Here's how:
41
+
42
+ 1. **Create your workflow file:** Create a new YAML file in the `.github/workflows` directory with your custom workflow logic. Make sure your workflow is designed to be called by `workflow_call`.
43
+ 2. **Define a new command:** Decide on a new command to trigger your workflow, for example, `@gemini-cli /my-command`.
44
+ 3. **Update the `dispatch` job:** In `gemini-dispatch.yml`, add a new condition to the `if` statement in the `dispatch` job to recognize your new command.
45
+ 4. **Add a new job to call your workflow:** Add a new job to `gemini-dispatch.yml` that calls your custom workflow file.
46
+
47
+ ## Usage
48
+
49
+ To use this workflow, simply trigger one of the events listed above. For comment-based triggers, make sure the comment starts with `@gemini-cli` and the appropriate command.
@@ -0,0 +1,221 @@
1
+ name: '🔀 Gemini Dispatch'
2
+
3
+ on:
4
+ pull_request_review_comment:
5
+ types:
6
+ - 'created'
7
+ pull_request_review:
8
+ types:
9
+ - 'submitted'
10
+ pull_request:
11
+ types:
12
+ - 'opened'
13
+ issues:
14
+ types:
15
+ - 'opened'
16
+ - 'reopened'
17
+ issue_comment:
18
+ types:
19
+ - 'created'
20
+
21
+ defaults:
22
+ run:
23
+ shell: 'bash'
24
+
25
+ jobs:
26
+ debugger:
27
+ if: |-
28
+ ${{ fromJSON(vars.GEMINI_DEBUG || vars.ACTIONS_STEP_DEBUG || false) }}
29
+ runs-on: 'ubuntu-latest'
30
+ permissions:
31
+ contents: 'read'
32
+ steps:
33
+ - name: 'Print context for debugging'
34
+ env:
35
+ DEBUG_event_name: '${{ github.event_name }}'
36
+ DEBUG_event__action: '${{ github.event.action }}'
37
+ DEBUG_event__comment__author_association: '${{ github.event.comment.author_association }}'
38
+ DEBUG_event__issue__author_association: '${{ github.event.issue.author_association }}'
39
+ DEBUG_event__pull_request__author_association: '${{ github.event.pull_request.author_association }}'
40
+ DEBUG_event__review__author_association: '${{ github.event.review.author_association }}'
41
+ DEBUG_event: '${{ toJSON(github.event) }}'
42
+ run: |-
43
+ env | grep '^DEBUG_'
44
+
45
+ dispatch:
46
+ # For PRs: only if not from a fork
47
+ # For issues: only on open/reopen
48
+ # For comments: only if user types @gemini-cli and is OWNER/MEMBER/COLLABORATOR
49
+ if: |-
50
+ (
51
+ github.event_name == 'pull_request' &&
52
+ github.event.pull_request.head.repo.fork == false
53
+ ) || (
54
+ github.event_name == 'issues' &&
55
+ contains(fromJSON('["opened", "reopened"]'), github.event.action)
56
+ ) || (
57
+ github.event.sender.type == 'User' &&
58
+ startsWith(github.event.comment.body || github.event.review.body || github.event.issue.body, '@gemini-cli') &&
59
+ contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association || github.event.review.author_association || github.event.issue.author_association)
60
+ )
61
+ runs-on: 'ubuntu-latest'
62
+ permissions:
63
+ contents: 'read'
64
+ issues: 'write'
65
+ pull-requests: 'write'
66
+ outputs:
67
+ command: '${{ steps.extract_command.outputs.command }}'
68
+ request: '${{ steps.extract_command.outputs.request }}'
69
+ additional_context: '${{ steps.extract_command.outputs.additional_context }}'
70
+ issue_number: '${{ github.event.pull_request.number || github.event.issue.number }}'
71
+ steps:
72
+ - name: 'Mint identity token'
73
+ id: 'mint_identity_token'
74
+ if: |-
75
+ ${{ vars.APP_ID }}
76
+ uses: 'actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf' # ratchet:actions/create-github-app-token@v2
77
+ with:
78
+ app-id: '${{ vars.APP_ID }}'
79
+ private-key: '${{ secrets.APP_PRIVATE_KEY }}'
80
+ permission-contents: 'read'
81
+ permission-issues: 'write'
82
+ permission-pull-requests: 'write'
83
+
84
+ - name: 'Extract command'
85
+ id: 'extract_command'
86
+ uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' # ratchet:actions/github-script@v7
87
+ env:
88
+ EVENT_TYPE: '${{ github.event_name }}.${{ github.event.action }}'
89
+ REQUEST: '${{ github.event.comment.body || github.event.review.body || github.event.issue.body }}'
90
+ with:
91
+ script: |
92
+ const eventType = process.env.EVENT_TYPE;
93
+ const request = process.env.REQUEST;
94
+ core.setOutput('request', request);
95
+
96
+ if (eventType === 'pull_request.opened') {
97
+ core.setOutput('command', 'review');
98
+ } else if (['issues.opened', 'issues.reopened'].includes(eventType)) {
99
+ core.setOutput('command', 'triage');
100
+ } else if (request.startsWith("@gemini-cli /review")) {
101
+ core.setOutput('command', 'review');
102
+ const additionalContext = request.replace(/^@gemini-cli \/review/, '').trim();
103
+ core.setOutput('additional_context', additionalContext);
104
+ } else if (request.startsWith("@gemini-cli /triage")) {
105
+ core.setOutput('command', 'triage');
106
+ } else if (request.startsWith("@gemini-cli /approve")) {
107
+ core.setOutput('command', 'approve');
108
+ } else if (request.startsWith("@gemini-cli")) {
109
+ const additionalContext = request.replace(/^@gemini-cli/, '').trim();
110
+ core.setOutput('command', 'invoke');
111
+ core.setOutput('additional_context', additionalContext);
112
+ } else {
113
+ core.setOutput('command', 'fallthrough');
114
+ }
115
+
116
+ - name: 'Acknowledge request'
117
+ env:
118
+ GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}'
119
+ ISSUE_NUMBER: '${{ github.event.pull_request.number || github.event.issue.number }}'
120
+ MESSAGE: |-
121
+ 🤖 Hi @${{ github.actor }}, I've received your request, and I'm working on it now! You can track my progress [in the logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for more details.
122
+ REPOSITORY: '${{ github.repository }}'
123
+ run: |-
124
+ gh issue comment "${ISSUE_NUMBER}" \
125
+ --body "${MESSAGE}" \
126
+ --repo "${REPOSITORY}"
127
+
128
+ review:
129
+ needs: 'dispatch'
130
+ if: |-
131
+ ${{ needs.dispatch.outputs.command == 'review' }}
132
+ uses: './.github/workflows/gemini-review.yml'
133
+ permissions:
134
+ contents: 'read'
135
+ id-token: 'write'
136
+ issues: 'write'
137
+ pull-requests: 'write'
138
+ with:
139
+ additional_context: '${{ needs.dispatch.outputs.additional_context }}'
140
+ secrets: 'inherit'
141
+
142
+ triage:
143
+ needs: 'dispatch'
144
+ if: |-
145
+ ${{ needs.dispatch.outputs.command == 'triage' }}
146
+ uses: './.github/workflows/gemini-triage.yml'
147
+ permissions:
148
+ contents: 'read'
149
+ id-token: 'write'
150
+ issues: 'write'
151
+ pull-requests: 'write'
152
+ with:
153
+ additional_context: '${{ needs.dispatch.outputs.additional_context }}'
154
+ secrets: 'inherit'
155
+
156
+ invoke:
157
+ needs: 'dispatch'
158
+ if: |-
159
+ ${{ needs.dispatch.outputs.command == 'invoke' }}
160
+ uses: './.github/workflows/gemini-invoke.yml'
161
+ permissions:
162
+ contents: 'read'
163
+ id-token: 'write'
164
+ issues: 'write'
165
+ pull-requests: 'write'
166
+ with:
167
+ additional_context: '${{ needs.dispatch.outputs.additional_context }}'
168
+ secrets: 'inherit'
169
+
170
+ plan-execute:
171
+ needs: 'dispatch'
172
+ if: |-
173
+ ${{ needs.dispatch.outputs.command == 'approve' }}
174
+ uses: './.github/workflows/gemini-plan-execute.yml'
175
+ permissions:
176
+ contents: 'write'
177
+ id-token: 'write'
178
+ issues: 'write'
179
+ pull-requests: 'write'
180
+ with:
181
+ additional_context: '${{ needs.dispatch.outputs.additional_context }}'
182
+ secrets: 'inherit'
183
+
184
+ fallthrough:
185
+ needs:
186
+ - 'dispatch'
187
+ - 'review'
188
+ - 'triage'
189
+ - 'invoke'
190
+ - 'plan-execute'
191
+ if: |-
192
+ ${{ always() && !cancelled() && (failure() || needs.dispatch.outputs.command == 'fallthrough') }}
193
+ runs-on: 'ubuntu-latest'
194
+ permissions:
195
+ contents: 'read'
196
+ issues: 'write'
197
+ pull-requests: 'write'
198
+ steps:
199
+ - name: 'Mint identity token'
200
+ id: 'mint_identity_token'
201
+ if: |-
202
+ ${{ vars.APP_ID }}
203
+ uses: 'actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf' # ratchet:actions/create-github-app-token@v2
204
+ with:
205
+ app-id: '${{ vars.APP_ID }}'
206
+ private-key: '${{ secrets.APP_PRIVATE_KEY }}'
207
+ permission-contents: 'read'
208
+ permission-issues: 'write'
209
+ permission-pull-requests: 'write'
210
+
211
+ - name: 'Send failure comment'
212
+ env:
213
+ GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}'
214
+ ISSUE_NUMBER: '${{ github.event.pull_request.number || github.event.issue.number }}'
215
+ MESSAGE: |-
216
+ 🤖 I'm sorry @${{ github.actor }}, but I was unable to process your request. Please [see the logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for more details.
217
+ REPOSITORY: '${{ github.repository }}'
218
+ run: |-
219
+ gh issue comment "${ISSUE_NUMBER}" \
220
+ --body "${MESSAGE}" \
221
+ --repo "${REPOSITORY}"
@@ -0,0 +1,190 @@
1
+ # Issue Triage Workflows
2
+
3
+ This document describes a comprehensive system for triaging GitHub issues using the Gemini CLI GitHub Action. This system consists of two complementary workflows: a real-time triage workflow and a scheduled triage workflow.
4
+
5
+ - [Issue Triage Workflows](#issue-triage-workflows)
6
+ - [Overview](#overview)
7
+ - [Features](#features)
8
+ - [Setup](#setup)
9
+ - [Prerequisites](#prerequisites)
10
+ - [Setup Methods](#setup-methods)
11
+ - [Dependencies](#dependencies)
12
+ - [Usage](#usage)
13
+ - [Supported Triggers](#supported-triggers)
14
+ - [Real-Time Issue Triage](#real-time-issue-triage)
15
+ - [Scheduled Issue Triage](#scheduled-issue-triage)
16
+ - [Manual Triage](#manual-triage)
17
+ - [Interaction Flow](#interaction-flow)
18
+ - [Configuration](#configuration)
19
+ - [Examples](#examples)
20
+ - [Basic Triage Request](#basic-triage-request)
21
+ - [Automatic Labeling](#automatic-labeling)
22
+
23
+ ## Overview
24
+
25
+ The Issue Triage workflows provide an automated system for analyzing and categorizing GitHub issues using AI-powered analysis. The system intelligently assigns labels, prioritizes issues, and helps maintain organized issue tracking across your repository.
26
+
27
+ ## Features
28
+
29
+ - **Dual Workflow System**: Real-time triage for new issues and scheduled batch processing for existing issues
30
+ - **Intelligent Labeling**: Automatically applies relevant labels based on issue content and context
31
+ - **Priority Assignment**: Categorizes issues by urgency and importance
32
+ - **Customizable Logic**: Configurable triage rules and label assignments
33
+ - **Error Handling**: Posts helpful comments when triage fails with links to logs
34
+ - **Manual Override**: Support for manual triage requests via comments
35
+
36
+ ## Setup
37
+
38
+ For detailed setup instructions, including prerequisites and authentication, please refer to the main [Getting Started](../../../README.md#quick-start) section and [Authentication documentation](../../../docs/authentication.md).
39
+
40
+ ### Prerequisites
41
+
42
+ Add the following entries to your `.gitignore` file to prevent issue triage artifacts from being committed:
43
+
44
+ ```gitignore
45
+ # gemini-cli settings
46
+ .gemini/
47
+
48
+ # GitHub App credentials
49
+ gha-creds-*.json
50
+ ```
51
+
52
+ ### Setup Methods
53
+
54
+ To implement this issue triage system, you can utilize either of the following methods:
55
+
56
+ 1. Run the `/setup-github` command in Gemini CLI on your terminal to set up workflows for your repository.
57
+ 2. Copy the workflow files into your repository's `.github/workflows` directory:
58
+
59
+ ```bash
60
+ mkdir -p .github/workflows
61
+ curl -o .github/workflows/gemini-dispatch.yml https://raw.githubusercontent.com/google-github-actions/run-gemini-cli/main/examples/workflows/gemini-dispatch/gemini-dispatch.yml
62
+ curl -o .github/workflows/gemini-triage.yml https://raw.githubusercontent.com/google-github-actions/run-gemini-cli/main/examples/workflows/issue-triage/gemini-triage.yml
63
+ curl -o .github/workflows/gemini-scheduled-triage.yml https://raw.githubusercontent.com/google-github-actions/run-gemini-cli/main/examples/workflows/issue-triage/gemini-scheduled-triage.yml
64
+ ```
65
+
66
+ > **Note:** The `gemini-dispatch.yml` workflow is designed to call multiple
67
+ > workflows. If you are only setting up `gemini-triage.yml`, you should comment out or
68
+ > remove the other jobs in your copy of `gemini-dispatch.yml`.
69
+
70
+ You can customize the prompts and settings in the workflow files to suit your specific needs. For example, you can change the triage logic, the labels that are applied, or the schedule of the scheduled triage.
71
+
72
+ ## Dependencies
73
+
74
+ This workflow relies on the [gemini-dispatch.yml](../gemini-dispatch/gemini-dispatch.yml) workflow to route requests to the appropriate workflow.
75
+
76
+ ## Usage
77
+
78
+ ### Supported Triggers
79
+
80
+ The Issue Triage workflows are triggered by:
81
+
82
+ - **New Issues**: When an issue is opened or reopened (automated triage)
83
+ - **Scheduled Events**: Cron job for batch processing (scheduled triage)
84
+ - **Manual Dispatch**: Via the GitHub Actions UI ("Run workflow")
85
+ - **Issue Comments**: When a comment contains `@gemini-cli /triage`
86
+
87
+ ### Real-Time Issue Triage
88
+
89
+ This workflow is defined in `workflows/issue-triage/gemini-triage.yml` and is triggered when an issue is opened or reopened. It uses the Gemini CLI to analyze the issue and apply relevant labels.
90
+
91
+ If the triage process encounters an error, the workflow will post a comment on the issue, including a link to the action logs for debugging.
92
+
93
+ ### Scheduled Issue Triage
94
+
95
+ This workflow is defined in `workflows/issue-triage/gemini-scheduled-triage.yml` and runs on a schedule (e.g., every hour). It finds any issues that have no labels or have the `status/needs-triage` label and then uses the Gemini CLI to triage them. This workflow can also be manually triggered.
96
+
97
+ ### Manual Triage
98
+
99
+ You can manually trigger triage by commenting on an issue:
100
+
101
+ ```
102
+ @gemini-cli /triage
103
+ ```
104
+
105
+ ## Interaction Flow
106
+
107
+ ```mermaid
108
+ flowchart TD
109
+ subgraph "Triggers"
110
+ A[Issue Opened or Reopened]
111
+ B[Scheduled Cron Job]
112
+ C[Manual Dispatch]
113
+ D[Issue Comment with '@gemini-cli /triage' Created]
114
+ end
115
+
116
+ subgraph "Gemini CLI Workflow"
117
+ E[Get Issue Details]
118
+ F{Issue needs triage?}
119
+ G[Analyze Issue with Gemini]
120
+ H[Apply Labels]
121
+ end
122
+
123
+ A --> E
124
+ B --> E
125
+ C --> E
126
+ D --> E
127
+ E --> F
128
+ F -- Yes --> G
129
+ G --> H
130
+ F -- No --> J((End))
131
+ H --> J
132
+ ```
133
+
134
+ The two workflows work together to ensure that all new and existing issues are triaged in a timely manner.
135
+
136
+ ## Configuration
137
+
138
+ The triage prompts are defined in TOML files (`gemini-triage.toml` for real-time triage and `gemini-scheduled-triage.toml` for batch triage). The action automatically copies these files from `.github/commands/` to `.gemini/commands/` during execution.
139
+
140
+ **To customize the triage prompts:**
141
+
142
+ 1. Copy the TOML files to your repository:
143
+
144
+ ```bash
145
+ mkdir -p .gemini/commands
146
+ curl -o .gemini/commands/gemini-triage.toml https://raw.githubusercontent.com/google-github-actions/run-gemini-cli/main/examples/workflows/issue-triage/gemini-triage.toml
147
+ curl -o .gemini/commands/gemini-scheduled-triage.toml https://raw.githubusercontent.com/google-github-actions/run-gemini-cli/main/examples/workflows/issue-triage/gemini-scheduled-triage.toml
148
+ ```
149
+
150
+ 2. Edit the TOML files to customize:
151
+ - **Triage Logic**: Adjust how issues are analyzed
152
+ - **Label Assignment**: Configure which labels are applied based on issue content
153
+ - **Priority Heuristics**: Modify severity and priority determination
154
+ - **Output Format**: Customize the structure of triage results
155
+
156
+ 3. Commit the files to your repository:
157
+ ```bash
158
+ git add .gemini/commands/gemini-triage.toml .gemini/commands/gemini-scheduled-triage.toml
159
+ git commit -m "feat: customize issue triage prompts"
160
+ ```
161
+
162
+ **Additional workflow customization:**
163
+
164
+ You can also modify the workflow files themselves to adjust:
165
+
166
+ - **Schedule Frequency**: Modify the cron schedule for batch triage
167
+ - **Timeout Settings**: Adjust `timeout-minutes` for complex repositories
168
+ - **Custom Filters**: Set criteria for which issues need triage
169
+
170
+ The workflows will use your custom TOML files instead of the default ones from the action.
171
+
172
+ For more details on workflow configuration, see the [Configuration Guide](../CONFIGURATION.md#custom-commands-toml-files).
173
+
174
+ ## Examples
175
+
176
+ ### Basic Triage Request
177
+
178
+ ```
179
+ @gemini-cli /triage
180
+ ```
181
+
182
+ ### Automatic Labeling
183
+
184
+ The AI will analyze issues and apply labels such as:
185
+
186
+ - `bug` - for reported bugs and errors
187
+ - `enhancement` - for feature requests
188
+ - `documentation` - for docs-related issues
189
+ - `priority/high` - for urgent issues
190
+ - `good first issue` - for beginner-friendly tasks