# 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: Automation on: push: branches: [main] pull_request_target: types: [opened, synchronize, reopened] pull_request_review: types: [submitted] permissions: contents: write issues: write pull-requests: write jobs: format: name: Format if: github.event_name == 'push' runs-on: ubuntu-latest steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: token: ${{ secrets.GOOGLEWORKSPACE_BOT_TOKEN }} - name: Install Rust uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable with: components: rustfmt - name: Run cargo fmt run: cargo fmt --all - name: Commit and push run: | git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git add -A git diff --cached --quiet || git commit -m "style: cargo fmt" && git push file-labeler: name: File Labeler if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5 with: repo-token: ${{ secrets.GOOGLEWORKSPACE_BOT_TOKEN }} sync-labels: true gemini-review: name: Gemini Review if: >- github.event_name == 'pull_request_target' && github.event.action == 'synchronize' runs-on: ubuntu-latest concurrency: group: gemini-review-${{ github.event.pull_request.number }} cancel-in-progress: true steps: - name: Remove reviewed label uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | try { await github.rest.issues.removeLabel({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.pull_request.number, name: 'gemini: reviewed', }); } catch (e) { // Label not present — ignore } - name: Debounce run: sleep 60 - name: Trigger Gemini Code Assist review uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 with: github-token: ${{ secrets.GOOGLEWORKSPACE_BOT_TOKEN }} script: | await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.pull_request.number, body: '/gemini review', }); gemini-reviewed: name: Gemini Reviewed if: >- github.event_name == 'pull_request_review' && github.event.review.user.login == 'gemini-code-assist[bot]' runs-on: ubuntu-latest steps: - name: Add reviewed label if review matches HEAD uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const pr = await github.rest.pulls.get({ owner: context.repo.owner, repo: context.repo.repo, pull_number: context.payload.pull_request.number, }); if (context.payload.review.commit_id !== pr.data.head.sha) { console.log(`Review is for ${context.payload.review.commit_id} but HEAD is ${pr.data.head.sha} — skipping label`); return; } try { await github.rest.issues.addLabels({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.pull_request.number, labels: ['gemini: reviewed'], }); } catch (e) { if (e.status === 403) { console.log(`Token cannot add labels for this review event (${e.message}) — skipping`); return; } throw e; }