Automation & Scripting

Streamline your development workflow by automating repetitive tasks with intelligent AI assistance.

Why Automate with Gemini CLI?

Gemini CLI reads from stdin, writes to stdout, and returns standard exit codes — making it a first-class citizen in any Unix shell pipeline. Every automation pattern you already know works out of the box: find feeds it file lists, xargs parallelises it, cron schedules it, and GitHub Actions orchestrates it in CI/CD.

The practical payoff is substantial. Tasks that previously required manual attention — reviewing overnight log summaries, adding docstrings to new functions before code review, translating error messages into user-friendly copy, generating release notes from git history — all become zero-touch automated steps.

This page covers four real-world automation scenarios with complete, runnable scripts. Each example is production-tested and includes error handling, rate-limit awareness, and safe file-writing patterns. Copy them directly or adapt them to your workflow.

Scenario 1: CI/CD Integration

Adding Gemini CLI to a GitHub Actions workflow gives every pull request an AI-assisted code quality report. The workflow below triggers on every push and pull request. It installs Gemini CLI, runs a code analysis step against the changed files, and uploads the report as a build artifact so reviewers can read it inline in the GitHub UI.

The critical security detail is passing the API key as a GitHub Actions secret (secrets.GEMINI_API_KEY). Never hard-code the key in the workflow YAML file or echo it to the log.

# .github/workflows/ai-review.yml

name: AI Code Review

on: [push, pull_request]

 

jobs:

ai_review:

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v4

with:

fetch-depth: 0 # full history for git diff

 

- uses: actions/setup-node@v4

with:

node-version: "20"

 

- name: Install Gemini CLI

run: npm install -g @google/gemini-cli

 

- name: Run AI Code Analysis

env:

GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}

run: |

DIFF=$(git diff origin/main...HEAD -- '*.ts' '*.js')

if [ -n "$DIFF" ]; then

echo "$DIFF" | gemini \

"Review this diff for bugs, security issues, and improvements. \

Format the report in Markdown with sections for each concern." \

> ai-review.md

else

echo "No TypeScript/JavaScript changes to review." > ai-review.md

fi

 

- name: Upload Review Report

uses: actions/upload-artifact@v4

with:

name: ai-review-report

path: ai-review.md

Scenario 2: Pre-Commit AI Review Hook

A Git pre-commit hook runs every time you execute git commit and before the commit object is created. It is the ideal place to enforce AI-assisted code standards: security checks, naming conventions, or documentation requirements.

The hook below extracts only the staged diff (lines you actually intend to commit), sends it to Gemini with a focused security review prompt, and blocks the commit if Gemini detects a critical issue. Non-critical feedback is printed as a warning but does not block the commit.

Install it by copying the script to .git/hooks/pre-commit and making it executable. To share the hook with your team, use a hook manager like husky or pre-commit and commit the script to your repository.

#!/bin/bash

# .git/hooks/pre-commit

# chmod +x .git/hooks/pre-commit

 

set -euo pipefail

 

DIFF=$(git diff --cached --no-color)

 

if [ -z "$DIFF" ]; then

exit 0 # nothing staged, skip review

fi

 

echo "Running AI security review on staged changes..."

 

REVIEW=$(echo "$DIFF" | gemini \

"Review this git diff for security vulnerabilities only (hardcoded secrets, \

SQL injection, XSS, insecure deserialization). \

If you find a critical vulnerability, end with: BLOCK. \

If no critical issues, end with: PASS." 2>&1 || echo "GEMINI_ERROR")

 

if echo "$REVIEW" | grep -q "GEMINI_ERROR"; then

echo "WARN: Gemini review unavailable, committing without AI check."

exit 0

fi

 

echo "-------- Gemini Review --------"

echo "$REVIEW"

echo "-------------------------------"

 

if echo "$REVIEW" | tail -3 | grep -q "^BLOCK$"; then

echo "Commit BLOCKED: critical security issue detected." >&2

exit 1

fi

 

exit 0

Scenario 3: Batch File Processing

Batch processing applies the same AI transformation to many files. Common use cases include adding type annotations to a legacy JavaScript codebase, extracting metadata from a large collection of log files, translating documentation into another language, or generating unit test stubs for every untested module.

The script below processes every Python file under a target directory, asking Gemini to add Google-style docstrings to each public function and class. It writes output to a temporary file and only replaces the original if the output is non-empty and the Gemini call succeeded. A configurable delay between requests keeps you within the free-tier RPM limit.

#!/bin/bash

# batch-docstrings.sh — add Google docstrings to Python files

# Usage: bash batch-docstrings.sh ./src

 

set -euo pipefail

 

TARGET="${1:-.}"

DELAY=4 # seconds between requests (free tier: 15 RPM)

ERRORS=0

PROCESSED=0

 

find "$TARGET" -name "*.py" \

-not -path "*/node_modules/*" \

-not -path "*/__pycache__/*" \

-not -path "*/venv/*" | while read -r file; do

 

echo "Processing: $file"

tmpfile=$(mktemp --suffix=.py)

 

if gemini \

"Add Google-style docstrings to every public function and class. \

Do not change any logic. Return the complete file contents only, \

with no additional explanation." \

< "$file" > "$tmpfile" 2>&1; then

 

if [ -s "$tmpfile" ]; then

cp "$file" "$file.bak" # keep backup

mv "$tmpfile" "$file"

PROCESSED=$(( PROCESSED + 1 ))

echo " OK: $file"

else

echo " WARN: empty response for $file"

rm -f "$tmpfile"

fi

else

echo " ERROR: $file"

rm -f "$tmpfile"

ERRORS=$(( ERRORS + 1 ))

fi

 

sleep "$DELAY"

done

 

echo "Done. Processed: $PROCESSED, Errors: $ERRORS"

Backup files are written with a .bak extension. After reviewing the output, remove them with find . -name "*.bak" -delete.

Scenario 4: Scheduled Log Summarisation

Cron jobs are perfect for recurring AI tasks: summarising error logs every morning, generating weekly progress reports from git history, or monitoring a directory for new files and processing them automatically.

The script below reads yesterday's application error log, asks Gemini to group the errors by root cause and prioritise them, and emails the summary. Add it to your crontab to run every morning at 07:00:

#!/bin/bash

# daily-log-summary.sh — summarise yesterday's errors

# crontab: 0 7 * * * /home/user/scripts/daily-log-summary.sh

 

set -euo pipefail

 

LOG_DIR="/var/log/myapp"

REPORT_DIR="/home/$USER/reports"

YESTERDAY=$(date -d "yesterday" +'%Y-%m-%d' 2>/dev/null \

|| date -v -1d +'%Y-%m-%d') # macOS fallback

LOG_FILE="$LOG_DIR/error-$YESTERDAY.log"

REPORT_FILE="$REPORT_DIR/summary-$YESTERDAY.md"

 

mkdir -p "$REPORT_DIR"

 

if [ ! -f "$LOG_FILE" ]; then

echo "No log file found for $YESTERDAY" > "$REPORT_FILE"

exit 0

fi

 

echo "Generating summary for $YESTERDAY..."

 

gemini \

"Analyse these application error logs from $YESTERDAY. \

Group errors by root cause. For each group: count occurrences, \

show a representative stack trace, and suggest a fix priority \

(critical/high/medium/low). Format as Markdown." \

< "$LOG_FILE" > "$REPORT_FILE"

 

# Optional: email the report

if command -v mail &>/dev/null; then

mail -s "Daily Error Summary $YESTERDAY" team@example.com < "$REPORT_FILE"

fi

 

echo "Report saved: $REPORT_FILE"

Add to crontab with crontab -e and insert: 0 7 * * * /path/to/daily-log-summary.sh

Quick Automation Examples

Batch Processing

find . -name "*.js" | xargs -I {} bash -c 'gemini "Add error handling to this file" < "$1" > "$1.patched"' _ {}

Build Automation

gemini "Generate a Makefile for this project" . > Makefile

Test Generation

gemini "Generate unit tests for every exported function" < utils.js > tests/utils.test.js

Frequently Asked Questions

Can Gemini CLI run in headless or non-interactive mode for CI/CD?

Yes. Set the GEMINI_API_KEY environment variable as a CI secret, then call gemini directly in your pipeline steps. Output is written to stdout and can be redirected to files or piped to other commands with no interactive prompts.

How do I prevent Gemini CLI from modifying files unintentionally?

Always write AI output to a temporary file first, verify it is non-empty, then replace the original. Use set -euo pipefail at the top of every script so any error causes an immediate exit before any file gets overwritten.

What is the best way to handle long-running batch jobs?

Add a sleep between requests to stay within your RPM limit, log each operation to a file so you can resume from where you left off if interrupted, and implement exponential backoff for 429 errors. Process files sequentially unless your plan allows high concurrency.

Can I use Gemini CLI in a pre-commit hook?

Yes. Extract the staged diff with git diff --cached, pipe it to gemini with a focused review prompt, and exit non-zero to block the commit if critical issues are found. Always add a fallback that allows the commit if the API is unavailable to avoid blocking your team during outages.