Created
November 25, 2025 17:16
-
-
Save nickfloyd/76da274a9904b35439ab09eeaabf8245 to your computer and use it in GitHub Desktop.
Verify PRs for the GitHub Terraform Provider
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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