Skip to content

Commit 0c2267c

Browse files
authored
Add GitHub Actions workflow to run Jetpack Compose performance skill (#1733)
## Summary Adds a new GitHub Actions workflow (`.github/workflows/compose_performance_skill.yml`) to run the [Jetpack Compose performance skill](https://github.com/android/skills/tree/main/jetpack-compose/jetpack-compose-performance) on Kotlin files in `android/compose-samples` using the [Android CLI](https://developer.android.com/tools/agents/android-cli) (`android skills add`) and [`google-github-actions/run-gemini-cli`](https://github.com/google-github-actions/run-gemini-cli). ## Details - **Triggers**: - `pull_request` when any `**/*.kt` file (or `.github/workflows/compose_performance_skill.yml`) is modified. - `workflow_dispatch` with an optional `pr_number` input (audits the PR's changed `.kt` files when provided, or audits all `**/*.kt` files across the repository when omitted). - **Workflow Steps**: 1. Checks out `android/compose-samples` with full history (`fetch-depth: 0`). 2. Installs the Android CLI and runs `android skills add --agent=gemini --project=. jetpack-compose-performance` to install the skill into `.agents/skills/jetpack-compose-performance`. 3. Collects the target `.kt` files into `.gemini/target_files.txt`. 4. Invokes `google-github-actions/run-gemini-cli` (`v0.1.22`) using `secrets.GEMINI_API_KEY` to audit the target Kotlin files against the skill and its `references/**/*.md` files. 5. Posts the structured Markdown review findings as a comment on the pull request (and outputs them to the GitHub Actions job summary). - Updates `.gitignore` to ignore `.gemini/` and `.agents/` directories.
2 parents a8712b8 + cf40aaa commit 0c2267c

1 file changed

Lines changed: 153 additions & 0 deletions

File tree

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
name: Jetpack Compose Performance Review
15+
16+
permissions:
17+
contents: read
18+
issues: write
19+
pull-requests: write
20+
21+
on:
22+
pull_request:
23+
branches: [ '*' ]
24+
paths:
25+
- '**/*.kt'
26+
- '.github/workflows/compose_performance_skill.yml'
27+
workflow_dispatch:
28+
inputs:
29+
pr_number:
30+
description: 'Pull request number to review (leave empty to review the latest commit)'
31+
required: false
32+
type: string
33+
34+
concurrency:
35+
group: ${{ github.workflow }}-${{ github.ref }}
36+
cancel-in-progress: true
37+
38+
jobs:
39+
compose-performance-review:
40+
runs-on: ubuntu-latest
41+
timeout-minutes: 30
42+
if: github.repository == 'android/compose-samples' && (github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.fork == false)
43+
44+
steps:
45+
- name: Checkout Repository
46+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
47+
with:
48+
token: ${{ secrets.PAT || github.token }}
49+
fetch-depth: 0
50+
persist-credentials: false
51+
52+
- name: Prepare Review Context
53+
id: context
54+
env:
55+
GH_TOKEN: ${{ secrets.PAT || github.token }}
56+
PR_NUMBER: ${{ inputs.pr_number || github.event.pull_request.number }}
57+
BASE_REF: ${{ github.base_ref }}
58+
run: |
59+
set -euo pipefail
60+
if [[ -n "${PR_NUMBER}" ]]; then
61+
if [[ -z "${BASE_REF}" ]]; then
62+
BASE_REF=$(gh pr view "${PR_NUMBER}" --json baseRefName --jq '.baseRefName')
63+
gh pr checkout "${PR_NUMBER}"
64+
git fetch origin "${BASE_REF}"
65+
fi
66+
DIFF_RANGE="origin/${BASE_REF}...HEAD"
67+
echo "mode=pr" >> "${GITHUB_OUTPUT}"
68+
echo "pr_number=${PR_NUMBER}" >> "${GITHUB_OUTPUT}"
69+
else
70+
DIFF_RANGE="HEAD~1...HEAD"
71+
echo "mode=commit" >> "${GITHUB_OUTPUT}"
72+
echo "pr_number=" >> "${GITHUB_OUTPUT}"
73+
fi
74+
if [[ -f .gitignore ]]; then
75+
sed -i '/^\.gemini\/$/d; /^\.agents\/$/d' .gitignore
76+
fi
77+
mkdir -p .gemini
78+
git diff --name-only --diff-filter=ACMRT "${DIFF_RANGE}" -- '*.kt' > .gemini/target_files.txt
79+
git diff -U5 --diff-filter=ACMRT "${DIFF_RANGE}" -- '*.kt' > .gemini/pr_diff.patch
80+
FILE_COUNT=$(grep -c '\.kt$' .gemini/target_files.txt || true)
81+
echo "file_count=${FILE_COUNT}" >> "${GITHUB_OUTPUT}"
82+
echo "Found ${FILE_COUNT} modified Kotlin file(s) to audit."
83+
84+
- name: Install Jetpack Compose Performance Skill
85+
if: steps.context.outputs.file_count != '0'
86+
run: |
87+
set -euo pipefail
88+
curl -fsSL https://dl.google.com/android/cli/latest/linux_x86_64/install.sh | bash
89+
export PATH="${HOME}/.local/bin:${PATH}"
90+
android skills add --agent=gemini --project=. jetpack-compose-performance
91+
92+
- name: Run Jetpack Compose Performance Skill
93+
if: steps.context.outputs.file_count != '0'
94+
id: gemini_review
95+
uses: google-github-actions/run-gemini-cli@f77273f4c914e4bf38440cf36a0369cb64a37489 # v0.1.22
96+
env:
97+
GEMINI_CLI_TRUST_WORKSPACE: 'true'
98+
GITHUB_TOKEN: ${{ secrets.PAT || github.token }}
99+
with:
100+
gemini_api_key: ${{ secrets.GEMINI_API_KEY }}
101+
github_pr_number: ${{ steps.context.outputs.pr_number }}
102+
upload_artifacts: 'true'
103+
settings: |
104+
{
105+
"model": {
106+
"maxSessionTurns": 50
107+
},
108+
"context": {
109+
"fileFiltering": {
110+
"respectGitIgnore": false,
111+
"respectGeminiIgnore": false
112+
}
113+
},
114+
"fileFiltering": {
115+
"respectGitIgnore": false,
116+
"respectGeminiIgnore": false
117+
}
118+
}
119+
prompt: |
120+
Use the `jetpack-compose-performance` skill located at `.agents/skills/jetpack-compose-performance/SKILL.md` to review the newly introduced or modified Kotlin code in `.gemini/pr_diff.patch`.
121+
122+
Follow these instructions strictly:
123+
1. Read `.agents/skills/jetpack-compose-performance/SKILL.md` first.
124+
2. Read `.gemini/pr_diff.patch` to identify the exact lines added or modified in this change (`+` lines in the diff hunks). The list of touched Kotlin files is also in `.gemini/target_files.txt`.
125+
3. You may read the touched Kotlin files listed in `.gemini/target_files.txt` ONLY to understand the surrounding context (such as enclosing `@Composable` functions, state declarations, parameters, or imports) of the changed lines.
126+
4. **Strict Diff Scope**: Only report Jetpack Compose performance findings on **newly introduced or modified code (`+` lines in `.gemini/pr_diff.patch`)**. Do NOT report findings on pre-existing, untouched code elsewhere in the same file or in other files.
127+
5. Whenever newly introduced or modified code matches a rule in Categories 1-7, you MUST open and read the corresponding `.agents/skills/jetpack-compose-performance/references/**/*.md` file for the approved fix pattern and scope guards before reporting a finding.
128+
6. Do NOT modify any files in the repository and do NOT run shell commands.
129+
7. Format your output as a Markdown review report:
130+
- Start your response with the single heading `## ⚡ Jetpack Compose Performance Review` (do not include any other top-level `#` or `##` title heading).
131+
- For each finding in the changed code, include the file path, line numbers, rule category, why it impacts Compose performance, and a concrete Kotlin `suggestion` or code snippet showing the recommended fix.
132+
- If the newly introduced or modified code follows Jetpack Compose performance best practices (or does not contain Jetpack Compose code), state clearly under the heading that no Jetpack Compose performance issues were found in the changed code.
133+
134+
- name: Post Findings on Pull Request
135+
if: steps.context.outputs.file_count != '0' && steps.context.outputs.pr_number != '' && steps.gemini_review.outputs.summary != ''
136+
env:
137+
GH_TOKEN: ${{ secrets.PAT || github.token }}
138+
PR_NUMBER: ${{ steps.context.outputs.pr_number }}
139+
REVIEW_SUMMARY: ${{ steps.gemini_review.outputs.summary }}
140+
run: |
141+
set -euo pipefail
142+
COMMENT_FILE="$(mktemp)"
143+
if [[ "${REVIEW_SUMMARY}" =~ ^[[:space:]]*# ]]; then
144+
printf '%s\n' "${REVIEW_SUMMARY}" > "${COMMENT_FILE}"
145+
else
146+
{
147+
echo "## ⚡ Jetpack Compose Performance Review"
148+
echo ""
149+
printf '%s\n' "${REVIEW_SUMMARY}"
150+
} > "${COMMENT_FILE}"
151+
fi
152+
gh pr comment "${PR_NUMBER}" --body-file "${COMMENT_FILE}"
153+
rm -f "${COMMENT_FILE}"

0 commit comments

Comments
 (0)