Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions .github/workflows/compose_performance_skill.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: Jetpack Compose Performance Review

permissions:
contents: read
issues: write
pull-requests: write

on:
pull_request:
branches: [ '*' ]
paths:
- '**/*.kt'
- '.github/workflows/compose_performance_skill.yml'
workflow_dispatch:
inputs:
pr_number:
description: 'Pull request number to review (leave empty to review the latest commit)'
required: false
type: string

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
compose-performance-review:
runs-on: ubuntu-latest
timeout-minutes: 30
if: github.repository == 'android/compose-samples' && (github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.fork == false)

steps:
- name: Checkout Repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
token: ${{ secrets.PAT || github.token }}
fetch-depth: 0
persist-credentials: false

- name: Prepare Review Context
id: context
env:
GH_TOKEN: ${{ secrets.PAT || github.token }}
PR_NUMBER: ${{ inputs.pr_number || github.event.pull_request.number }}
BASE_REF: ${{ github.base_ref }}
run: |
set -euo pipefail
if [[ -n "${PR_NUMBER}" ]]; then
if [[ -z "${BASE_REF}" ]]; then
BASE_REF=$(gh pr view "${PR_NUMBER}" --json baseRefName --jq '.baseRefName')
gh pr checkout "${PR_NUMBER}"
git fetch origin "${BASE_REF}"
fi
DIFF_RANGE="origin/${BASE_REF}...HEAD"
echo "mode=pr" >> "${GITHUB_OUTPUT}"
echo "pr_number=${PR_NUMBER}" >> "${GITHUB_OUTPUT}"
else
DIFF_RANGE="HEAD~1...HEAD"
echo "mode=commit" >> "${GITHUB_OUTPUT}"
echo "pr_number=" >> "${GITHUB_OUTPUT}"
fi
if [[ -f .gitignore ]]; then
sed -i '/^\.gemini\/$/d; /^\.agents\/$/d' .gitignore
fi
mkdir -p .gemini
git diff --name-only --diff-filter=ACMRT "${DIFF_RANGE}" -- '*.kt' > .gemini/target_files.txt
git diff -U5 --diff-filter=ACMRT "${DIFF_RANGE}" -- '*.kt' > .gemini/pr_diff.patch
FILE_COUNT=$(grep -c '\.kt$' .gemini/target_files.txt || true)
echo "file_count=${FILE_COUNT}" >> "${GITHUB_OUTPUT}"
echo "Found ${FILE_COUNT} modified Kotlin file(s) to audit."

- name: Install Jetpack Compose Performance Skill
if: steps.context.outputs.file_count != '0'
run: |
set -euo pipefail
curl -fsSL https://dl.google.com/android/cli/latest/linux_x86_64/install.sh | bash
export PATH="${HOME}/.local/bin:${PATH}"
android skills add --agent=gemini --project=. jetpack-compose-performance

- name: Run Jetpack Compose Performance Skill
if: steps.context.outputs.file_count != '0'
id: gemini_review
uses: google-github-actions/run-gemini-cli@f77273f4c914e4bf38440cf36a0369cb64a37489 # v0.1.22
env:
GEMINI_CLI_TRUST_WORKSPACE: 'true'
GITHUB_TOKEN: ${{ secrets.PAT || github.token }}
with:
gemini_api_key: ${{ secrets.GEMINI_API_KEY }}
github_pr_number: ${{ steps.context.outputs.pr_number }}
upload_artifacts: 'true'
settings: |
{
"model": {
"maxSessionTurns": 50
},
"context": {
"fileFiltering": {
"respectGitIgnore": false,
"respectGeminiIgnore": false
}
},
"fileFiltering": {
"respectGitIgnore": false,
"respectGeminiIgnore": false
}
}
prompt: |
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`.

Follow these instructions strictly:
1. Read `.agents/skills/jetpack-compose-performance/SKILL.md` first.
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`.
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.
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.
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.
6. Do NOT modify any files in the repository and do NOT run shell commands.
7. Format your output as a Markdown review report:
- Start your response with the single heading `## ⚡ Jetpack Compose Performance Review` (do not include any other top-level `#` or `##` title heading).
- 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.
- 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.

- name: Post Findings on Pull Request
if: steps.context.outputs.file_count != '0' && steps.context.outputs.pr_number != '' && steps.gemini_review.outputs.summary != ''
env:
GH_TOKEN: ${{ secrets.PAT || github.token }}
PR_NUMBER: ${{ steps.context.outputs.pr_number }}
REVIEW_SUMMARY: ${{ steps.gemini_review.outputs.summary }}
run: |
set -euo pipefail
COMMENT_FILE="$(mktemp)"
if [[ "${REVIEW_SUMMARY}" =~ ^[[:space:]]*# ]]; then
printf '%s\n' "${REVIEW_SUMMARY}" > "${COMMENT_FILE}"
else
{
echo "## ⚡ Jetpack Compose Performance Review"
echo ""
printf '%s\n' "${REVIEW_SUMMARY}"
} > "${COMMENT_FILE}"
fi
gh pr comment "${PR_NUMBER}" --body-file "${COMMENT_FILE}"
rm -f "${COMMENT_FILE}"
Loading