|
| 1 | +#!/bin/sh |
| 2 | + |
| 3 | +# Get the current branch name |
| 4 | +LOCAL_BRANCH=$(git rev-parse --abbrev-ref HEAD) |
| 5 | + |
| 6 | +# Get the remote URL to construct the PR URL |
| 7 | +REMOTE_URL=$(git config --get remote.origin.url) |
| 8 | + |
| 9 | +# Extract repo owner and name from remote URL |
| 10 | +# Handle both https://github.com/owner/repo.git and git@github.com:owner/repo.git |
| 11 | +if echo "$REMOTE_URL" | grep -q "github.com"; then |
| 12 | + REPO=$(echo "$REMOTE_URL" | sed -E 's|.*github.com[:/]([^/]+/[^/]+)(\.git)?$|\1|') |
| 13 | +else |
| 14 | + # If not a GitHub repo, exit silently |
| 15 | + exit 0 |
| 16 | +fi |
| 17 | + |
| 18 | +# Determine the base branch (main or master) |
| 19 | +BASE_BRANCH="main" |
| 20 | +if ! git rev-parse --verify "origin/$BASE_BRANCH" >/dev/null 2>&1; then |
| 21 | + BASE_BRANCH="master" |
| 22 | +fi |
| 23 | + |
| 24 | +# Get the range of commits being pushed |
| 25 | +# Pre-push hook receives: $1 = remote name, $2 = remote URL |
| 26 | +# We can also check what commits are being pushed |
| 27 | +REMOTE_REF="origin/$LOCAL_BRANCH" |
| 28 | +if git rev-parse --verify "$REMOTE_REF" >/dev/null 2>&1; then |
| 29 | + # Remote branch exists, compare with it |
| 30 | + COMMIT_RANGE="$REMOTE_REF..HEAD" |
| 31 | +else |
| 32 | + # No remote branch yet, compare with base branch |
| 33 | + COMMIT_RANGE="origin/$BASE_BRANCH..HEAD" |
| 34 | +fi |
| 35 | + |
| 36 | +# Check if we have any commits to push |
| 37 | +if ! git rev-list --count "$COMMIT_RANGE" >/dev/null 2>&1; then |
| 38 | + # No commits to compare, exit silently |
| 39 | + exit 0 |
| 40 | +fi |
| 41 | + |
| 42 | +# Get course.adoc files that were added or modified |
| 43 | +COURSE_FILES=$(git diff --name-only --diff-filter=AM "$COMMIT_RANGE" | grep "course\.adoc$" || true) |
| 44 | + |
| 45 | +if [ -z "$COURSE_FILES" ]; then |
| 46 | + # No course.adoc files modified, exit silently |
| 47 | + exit 0 |
| 48 | +fi |
| 49 | + |
| 50 | +# Check each course.adoc file for status changes |
| 51 | +FOUND_DRAFT=false |
| 52 | +FOUND_RELEASE=false |
| 53 | +FOUND_FIX=false |
| 54 | + |
| 55 | +for COURSE_FILE in $COURSE_FILES; do |
| 56 | + # Check if file exists (might be deleted in some commits) |
| 57 | + if [ ! -f "$COURSE_FILE" ]; then |
| 58 | + continue |
| 59 | + fi |
| 60 | + |
| 61 | + # Extract the base commit from the commit range (everything before ..) |
| 62 | + BASE_REF=$(echo "$COMMIT_RANGE" | sed 's/\.\..*//') |
| 63 | + BASE_COMMIT=$(git rev-parse "$BASE_REF" 2>/dev/null || echo "") |
| 64 | + |
| 65 | + # Check if :status: active was ADDED in the changes (release) |
| 66 | + # Look for additions of ":status: active" in the diff |
| 67 | + STATUS_ADDED=$(git diff "$COMMIT_RANGE" -- "$COURSE_FILE" | grep -c "^+.*:status:[[:space:]]*active" || echo "0") |
| 68 | + |
| 69 | + if [ "$STATUS_ADDED" -gt 0 ]; then |
| 70 | + # Status active was added in this change - it's a release |
| 71 | + FOUND_RELEASE=true |
| 72 | + elif [ -n "$BASE_COMMIT" ] && git cat-file -e "$BASE_COMMIT:$COURSE_FILE" 2>/dev/null; then |
| 73 | + # File existed before, check if it had active status |
| 74 | + BASE_HAS_ACTIVE=$(git show "$BASE_COMMIT:$COURSE_FILE" 2>/dev/null | grep -q "^:status:[[:space:]]*active" && echo "yes" || echo "no") |
| 75 | + CURRENT_HAS_ACTIVE=$(grep -q "^:status:[[:space:]]*active" "$COURSE_FILE" && echo "yes" || echo "no") |
| 76 | + |
| 77 | + if [ "$BASE_HAS_ACTIVE" = "yes" ] && [ "$CURRENT_HAS_ACTIVE" = "yes" ]; then |
| 78 | + # Status was already active and still is - this is a fix |
| 79 | + FOUND_FIX=true |
| 80 | + else |
| 81 | + # No active status, it's a draft |
| 82 | + FOUND_DRAFT=true |
| 83 | + fi |
| 84 | + else |
| 85 | + # File is new or we can't determine base, check current status |
| 86 | + if grep -q "^:status:[[:space:]]*active" "$COURSE_FILE"; then |
| 87 | + # New file with active status - treat as release |
| 88 | + FOUND_RELEASE=true |
| 89 | + else |
| 90 | + # New file without active status - it's a draft |
| 91 | + FOUND_DRAFT=true |
| 92 | + fi |
| 93 | + fi |
| 94 | +done |
| 95 | + |
| 96 | +# Construct the PR URL |
| 97 | +PR_URL="https://github.com/$REPO/compare/$BASE_BRANCH...$LOCAL_BRANCH" |
| 98 | + |
| 99 | +# Display appropriate message (this will show before push, but is informational) |
| 100 | +if [ "$FOUND_RELEASE" = true ]; then |
| 101 | + echo "" |
| 102 | + echo "✅ Course(s) with :status: active added - this looks like a release!" |
| 103 | + echo "" |
| 104 | + echo "💡 Open a PR with the Course Release Template:" |
| 105 | + echo "" |
| 106 | + echo " $PR_URL?template=course_release.md" |
| 107 | + echo "" |
| 108 | +elif [ "$FOUND_FIX" = true ]; then |
| 109 | + echo "" |
| 110 | + echo "🔧 Course fix detected (course already has :status: active)!" |
| 111 | + echo "" |
| 112 | + echo "💡 Open a PR with the Course Fix Template:" |
| 113 | + echo "" |
| 114 | + echo " $PR_URL?template=course_fix.md" |
| 115 | + echo "" |
| 116 | +elif [ "$FOUND_DRAFT" = true ]; then |
| 117 | + echo "" |
| 118 | + echo "📝 Course draft(s) detected!" |
| 119 | + echo "" |
| 120 | + echo "💡 Open a PR with the Course Draft Template:" |
| 121 | + echo "" |
| 122 | + echo " $PR_URL?template=course_draft.md" |
| 123 | + echo "" |
| 124 | +fi |
| 125 | + |
| 126 | +# Always exit 0 to allow the push to proceed (this is informational only) |
| 127 | +exit 0 |
| 128 | + |
0 commit comments