GC-301h · Module 1

Artifact Handling & Caching

3 min read

Gemini CLI analysis produces artifacts — review JSON files, generated documentation, test stubs, audit reports. GitHub Actions' actions/upload-artifact persists these across workflow runs and makes them downloadable from the Actions UI. For PR workflows, the more useful pattern is posting results directly as PR comments using the GitHub API or actions like peter-evans/create-or-update-comment. A review JSON artifact that nobody downloads is less valuable than a review comment that appears inline on the PR.

Caching reduces redundant Gemini calls. If a file has not changed since the last analysis, there is no reason to re-analyze it. The pattern: hash the file content, check if a cached result exists for that hash, skip the Gemini call if it does. actions/cache with a content-based key (hashFiles("src/**")) provides this at the workflow level. For file-level caching within a batch, maintain a content-addressed cache directory where the filename is the SHA-256 of the input file.

# Cache Gemini analysis results by content hash
- name: Cache analysis results
  uses: actions/cache@v4
  with:
    path: .gemini-cache
    key: gemini-analysis-${{ hashFiles('src/**/*.ts') }}
    restore-keys: |
      gemini-analysis-

- name: Run Gemini analysis (skips cached files)
  env:
    GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
  run: |
    mkdir -p .gemini-cache
    for file in $(git diff --name-only origin/main...HEAD -- '*.ts'); do
      hash=$(sha256sum "$file" | cut -d' ' -f1)
      if [ -f ".gemini-cache/$hash.json" ]; then
        echo "CACHED: $file"
        continue
      fi
      gemini -p "Review $file for issues" --output-format json \
        > ".gemini-cache/$hash.json" 2>/dev/null
    done

- name: Post review to PR
  uses: peter-evans/create-or-update-comment@v4
  with:
    issue-number: ${{ github.event.pull_request.number }}
    body-path: review-summary.md