Skip to content

Instantly share code, notes, and snippets.

@nickfloyd
Created November 25, 2025 17:16
Show Gist options
  • Select an option

  • Save nickfloyd/76da274a9904b35439ab09eeaabf8245 to your computer and use it in GitHub Desktop.

Select an option

Save nickfloyd/76da274a9904b35439ab09eeaabf8245 to your computer and use it in GitHub Desktop.
Verify PRs for the GitHub Terraform Provider
#!/usr/bin/env bash
# THIS WAS GENERATED BY COPILOT
set -uo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Script configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
PR_NUMBER="${1:-}"
# Health check results
CHECKS_PASSED=0
CHECKS_FAILED=0
CHECKS_TOTAL=0
# Helper functions
log_info() {
echo -e "${BLUE}ℹ${NC} $1"
}
log_success() {
echo -e "${GREEN}✓${NC} $1"
((CHECKS_PASSED++))
((CHECKS_TOTAL++))
}
log_error() {
echo -e "${RED}✗${NC} $1"
((CHECKS_FAILED++))
((CHECKS_TOTAL++))
}
log_warning() {
echo -e "${YELLOW}⚠${NC} $1"
}
print_separator() {
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
}
print_header() {
print_separator
echo -e "${BLUE}$1${NC}"
print_separator
}
# Usage function
usage() {
cat <<EOF
Usage: $0 <pr-number>
Check the health of a GitHub Pull Request by:
1. Fetching and checking out the PR locally
2. Building the provider
3. Running linting checks
4. Running tests
Example:
$0 2941
EOF
exit 1
}
# Validate PR number
if [[ -z "$PR_NUMBER" ]]; then
log_error "PR number is required"
usage
fi
if ! [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then
log_error "PR number must be a positive integer"
usage
fi
# Save current branch
ORIGINAL_BRANCH=$(git rev-parse --abbrev-ref HEAD)
log_info "Current branch: $ORIGINAL_BRANCH"
# Cleanup function
cleanup() {
local exit_code=$?
print_separator
log_info "Cleaning up..."
# Return to original branch
if [[ -n "${ORIGINAL_BRANCH:-}" ]]; then
log_info "Returning to branch: $ORIGINAL_BRANCH"
git checkout "$ORIGINAL_BRANCH" 2>/dev/null || true
fi
# Delete PR branch if it exists
if git rev-parse --verify "pr-$PR_NUMBER" >/dev/null 2>&1; then
log_info "Deleting temporary branch: pr-$PR_NUMBER"
git branch -D "pr-$PR_NUMBER" 2>/dev/null || true
fi
exit $exit_code
}
trap cleanup EXIT INT TERM
# Start health check
print_header "PR Health Check for PR #$PR_NUMBER"
cd "$REPO_ROOT"
# Step 1: Fetch PR
print_header "Step 1: Fetching PR #$PR_NUMBER"
# First, get PR information from GitHub API
log_info "Fetching PR information from GitHub API..."
PR_INFO=$(curl -s "https://api.github.com/repos/integrations/terraform-provider-github/pulls/$PR_NUMBER")
if echo "$PR_INFO" | grep -q '"message": "Not Found"'; then
log_error "PR #$PR_NUMBER not found"
exit 1
fi
# Extract PR details using jq if available, otherwise use grep
if command -v jq &> /dev/null; then
PR_HEAD_REF=$(echo "$PR_INFO" | jq -r '.head.ref')
PR_HEAD_REPO=$(echo "$PR_INFO" | jq -r '.head.repo.clone_url')
PR_TITLE=$(echo "$PR_INFO" | jq -r '.title')
PR_USER=$(echo "$PR_INFO" | jq -r '.user.login')
PR_HEAD_REPO_FULL=$(echo "$PR_INFO" | jq -r '.head.repo.full_name')
else
# Fallback to grep parsing
PR_HEAD_REF=$(echo "$PR_INFO" | grep '"ref"' | grep -v '"base"' | head -1 | sed 's/.*"ref": "\([^"]*\)".*/\1/')
PR_HEAD_REPO=$(echo "$PR_INFO" | grep '"clone_url"' | head -2 | tail -1 | sed 's/.*"clone_url": "\([^"]*\)".*/\1/')
PR_TITLE=$(echo "$PR_INFO" | grep '"title"' | head -1 | sed 's/.*"title": "\([^"]*\)".*/\1/')
PR_USER=$(echo "$PR_INFO" | grep '"login"' | head -1 | sed 's/.*"login": "\([^"]*\)".*/\1/')
PR_HEAD_REPO_FULL=$(echo "$PR_INFO" | grep '"full_name"' | head -2 | tail -1 | sed 's/.*"full_name": "\([^"]*\)".*/\1/')
fi
# Determine if it's a fork
if [[ "$PR_HEAD_REPO_FULL" == "integrations/terraform-provider-github" ]]; then
PR_IS_FORK="false"
else
PR_IS_FORK="true"
fi
log_info "PR #$PR_NUMBER: $PR_TITLE"
log_info "Author: $PR_USER"
log_info "Branch: $PR_HEAD_REF"
if [[ "$PR_IS_FORK" == "true" ]]; then
log_info "PR is from a fork: $PR_HEAD_REPO"
log_info "Fetching from fork..."
# Add fork as a temporary remote if needed
TEMP_REMOTE="pr-$PR_NUMBER-remote"
# Remove existing remote if it exists
git remote remove "$TEMP_REMOTE" 2>/dev/null || true
if git remote add "$TEMP_REMOTE" "$PR_HEAD_REPO"; then
log_info "Added temporary remote: $TEMP_REMOTE"
else
log_error "Failed to add remote for fork"
exit 1
fi
# Fetch from the fork
if git fetch "$TEMP_REMOTE" "$PR_HEAD_REF:pr-$PR_NUMBER"; then
log_success "Successfully fetched PR #$PR_NUMBER from fork"
# Clean up the temporary remote after successful fetch
git remote remove "$TEMP_REMOTE" 2>/dev/null || true
else
log_error "Failed to fetch PR #$PR_NUMBER from fork"
git remote remove "$TEMP_REMOTE" 2>/dev/null || true
exit 1
fi
else
log_info "PR is from the main repository"
log_info "Fetching from origin..."
if git fetch origin "pull/$PR_NUMBER/head:pr-$PR_NUMBER"; then
log_success "Successfully fetched PR #$PR_NUMBER"
else
log_error "Failed to fetch PR #$PR_NUMBER"
exit 1
fi
fi
# Step 2: Checkout PR
print_header "Step 2: Checking out PR #$PR_NUMBER"
log_info "Switching to PR branch..."
# Checkout the PR branch
git checkout "pr-$PR_NUMBER" >/dev/null 2>&1
if git rev-parse --verify "pr-$PR_NUMBER" >/dev/null 2>&1 && [[ "$(git rev-parse --abbrev-ref HEAD)" == "pr-$PR_NUMBER" ]]; then
log_success "Successfully checked out PR #$PR_NUMBER"
# Show PR details
log_info "Current commit: $(git rev-parse --short HEAD)"
log_info "Commit message: $(git log -1 --pretty=%B | head -n 1)"
log_info "Author: $(git log -1 --pretty=%an)"
else
log_error "Failed to checkout PR #$PR_NUMBER"
exit 1
fi
# Step 3: Build
print_header "Step 3: Building Provider"
log_info "Running build..."
if make build 2>&1 | tee /tmp/pr-check-build.log; then
log_success "Build successful"
else
log_error "Build failed"
log_warning "See /tmp/pr-check-build.log for details"
cat /tmp/pr-check-build.log
fi
# Step 4: Format Check
print_header "Step 4: Checking Code Formatting"
log_info "Running format check..."
if make fmtcheck 2>&1 | tee /tmp/pr-check-fmt.log; then
log_success "Format check passed"
else
log_error "Format check failed"
log_warning "See /tmp/pr-check-fmt.log for details"
log_info "Run 'make fmt' to fix formatting issues"
fi
# Step 5: Linting
print_header "Step 5: Running Linter"
log_info "Running golangci-lint..."
if make lint 2>&1 | tee /tmp/pr-check-lint.log; then
log_success "Linting passed"
else
log_error "Linting failed"
log_warning "See /tmp/pr-check-lint.log for details"
fi
# Step 6: Unit Tests
print_header "Step 6: Running Unit Tests"
log_info "Running unit tests (non-acceptance tests)..."
if make test 2>&1 | tee /tmp/pr-check-test.log; then
log_success "Unit tests passed"
else
log_error "Unit tests failed"
log_warning "See /tmp/pr-check-test.log for details"
fi
# Step 7: Acceptance Tests
print_header "Step 7: Running Acceptance Tests"
if [[ -n "${GITHUB_TOKEN:-}" ]] && [[ -n "${GITHUB_OWNER:-}" ]]; then
log_info "Acceptance test environment detected"
log_info "Running acceptance tests (this may take several minutes)..."
log_warning "Note: This will create/modify resources in your GitHub organization"
if make testacc 2>&1 | tee /tmp/pr-check-testacc.log; then
log_success "Acceptance tests passed"
else
log_error "Acceptance tests failed"
log_warning "See /tmp/pr-check-testacc.log for details"
fi
else
log_warning "Acceptance test environment not configured - skipping"
log_info "To enable acceptance tests, set:"
echo " export GITHUB_OWNER=<your-org>"
echo " export GITHUB_TOKEN=<your-token>"
log_info "Then run: ./scripts/check-pr.sh $PR_NUMBER"
fi
# Final Report
print_header "PR Health Check Summary"
echo "PR #$PR_NUMBER Health Report:"
echo ""
echo "Total Checks: $CHECKS_TOTAL"
echo -e "${GREEN}Passed: $CHECKS_PASSED${NC}"
echo -e "${RED}Failed: $CHECKS_FAILED${NC}"
echo ""
if [[ $CHECKS_FAILED -eq 0 ]]; then
log_success "PR #$PR_NUMBER is HEALTHY ✓"
echo ""
echo "All checks passed! This PR is ready for review."
exit 0
else
log_error "PR #$PR_NUMBER has ISSUES ✗"
echo ""
echo "Some checks failed. Please review the logs above."
echo ""
echo "Log files:"
echo " - Build: /tmp/pr-check-build.log"
echo " - Format: /tmp/pr-check-fmt.log"
echo " - Lint: /tmp/pr-check-lint.log"
echo " - Test: /tmp/pr-check-test.log"
echo " - Testacc: /tmp/pr-check-testacc.log"
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment