GC-301h · Module 3

Pre-Merge Checks

3 min read

Pre-merge checks use Gemini CLI as a quality gate — the PR cannot merge until the AI analysis passes. This is implemented via GitHub required status checks: the Gemini workflow sets its conclusion to "success" or "failure" based on the analysis results, and branch protection rules require this check to pass. The critical design decision is the failure threshold: what level of issues blocks the merge? Block on critical security findings. Warn on medium-severity issues. Ignore low-severity style suggestions.

Quality gates must be fast and deterministic enough to earn developer trust. A gate that takes 10 minutes blocks the merge workflow. A gate that produces different results on the same code (LLM nondeterminism) frustrates developers who retry until it passes. Mitigate nondeterminism by using structured prompts with binary outputs ("Does this code have SQL injection? YES or NO"), temperature 0 if available, and conservative thresholds that only block on high-confidence findings.

#!/bin/bash
# Pre-merge quality gate
set -euo pipefail

DIFF=$(git diff origin/main...HEAD)
BLOCKERS=0
WARNINGS=0

# Security check
SECURITY=$(gemini -p "Scan this diff for security vulnerabilities. Be conservative — only flag definite issues. Output JSON: {findings: [{severity: \"critical\"|\"warning\", description: string, file: string}]}" \
  --output-format json 2>/dev/null)

CRITICAL=$(echo "$SECURITY" | jq '[.response.findings[]? | select(.severity == "critical")] | length')
WARN=$(echo "$SECURITY" | jq '[.response.findings[]? | select(.severity == "warning")] | length')

BLOCKERS=$((BLOCKERS + CRITICAL))
WARNINGS=$((WARNINGS + WARN))

# Architecture compliance check
ARCH=$(gemini -p "Does this diff violate any patterns in GEMINI.md? Answer with JSON: {compliant: true|false, violations: [string]}" \
  --output-format json 2>/dev/null)

COMPLIANT=$(echo "$ARCH" | jq -r '.response.compliant // true')
if [ "$COMPLIANT" = "false" ]; then
  ((BLOCKERS++))
fi

# Verdict
if [ $BLOCKERS -gt 0 ]; then
  echo "::error::Quality gate FAILED: $BLOCKERS critical issues"
  exit 1
elif [ $WARNINGS -gt 0 ]; then
  echo "::warning::Quality gate PASSED with $WARNINGS warnings"
  exit 0
else
  echo "Quality gate PASSED"
  exit 0
fi