mirror of
https://github.com/DeBrosOfficial/network.git
synced 2025-12-11 08:18:49 +00:00
feat: add pre-commit hook for automatic changelog updates
- Introduced a pre-commit hook that updates the changelog if there are code changes, excluding commits that only modify the changelog or Makefile. - Added user confirmation for proceeding with the commit after displaying the changelog preview. - Enhanced the update_changelog.sh script to differentiate between pre-commit and pre-push contexts for better change analysis.
This commit is contained in:
parent
d3543ac3ab
commit
11ce4f2a53
89
.githooks/pre-commit
Normal file
89
.githooks/pre-commit
Normal file
@ -0,0 +1,89 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Colors for output
|
||||
CYAN='\033[0;36m'
|
||||
YELLOW='\033[1;33m'
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
NOCOLOR='\033[0m'
|
||||
|
||||
# Get the directory where this hook is located
|
||||
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# Go up from .git/hooks/ to repo root
|
||||
REPO_ROOT="$(cd "$HOOK_DIR/../.." && pwd)"
|
||||
CHANGELOG_SCRIPT="$REPO_ROOT/scripts/update_changelog.sh"
|
||||
PREVIEW_FILE="$REPO_ROOT/.changelog_preview.tmp"
|
||||
VERSION_FILE="$REPO_ROOT/.changelog_version.tmp"
|
||||
|
||||
# Only run changelog update if there are actual code changes (not just changelog files)
|
||||
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
|
||||
if [ -z "$STAGED_FILES" ]; then
|
||||
# No staged files, exit
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check if only CHANGELOG.md and/or Makefile are being committed
|
||||
OTHER_FILES=$(echo "$STAGED_FILES" | grep -v "^CHANGELOG.md$" | grep -v "^Makefile$")
|
||||
if [ -z "$OTHER_FILES" ]; then
|
||||
# Only changelog files are being committed, skip update
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Update changelog before commit
|
||||
if [ -f "$CHANGELOG_SCRIPT" ]; then
|
||||
echo -e "\n${CYAN}Updating changelog...${NOCOLOR}"
|
||||
|
||||
# Set environment variable to indicate we're running from pre-commit
|
||||
export CHANGELOG_CONTEXT=pre-commit
|
||||
|
||||
bash "$CHANGELOG_SCRIPT"
|
||||
changelog_status=$?
|
||||
if [ $changelog_status -ne 0 ]; then
|
||||
echo -e "${RED}Commit aborted: changelog update failed.${NOCOLOR}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Show preview if changelog was updated
|
||||
if [ -f "$PREVIEW_FILE" ] && [ -f "$VERSION_FILE" ]; then
|
||||
NEW_VERSION=$(cat "$VERSION_FILE")
|
||||
PREVIEW_CONTENT=$(cat "$PREVIEW_FILE")
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}========================================================================${NOCOLOR}"
|
||||
echo -e "${CYAN} CHANGELOG PREVIEW${NOCOLOR}"
|
||||
echo -e "${BLUE}========================================================================${NOCOLOR}"
|
||||
echo ""
|
||||
echo -e "${GREEN}New Version: ${YELLOW}$NEW_VERSION${NOCOLOR}"
|
||||
echo ""
|
||||
echo -e "${CYAN}Changelog Entry:${NOCOLOR}"
|
||||
echo -e "${BLUE}────────────────────────────────────────────────────────────────────────${NOCOLOR}"
|
||||
echo -e "$PREVIEW_CONTENT"
|
||||
echo -e "${BLUE}────────────────────────────────────────────────────────────────────────${NOCOLOR}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Do you want to proceed with the commit? (yes/no):${NOCOLOR} "
|
||||
# Read from /dev/tty to ensure we can read from terminal even in git hook context
|
||||
read -r confirmation < /dev/tty
|
||||
|
||||
if [ "$confirmation" != "yes" ]; then
|
||||
echo -e "${RED}Commit aborted by user.${NOCOLOR}"
|
||||
echo -e "${YELLOW}To revert changes, run:${NOCOLOR}"
|
||||
echo -e " git checkout CHANGELOG.md Makefile"
|
||||
# Clean up temp files
|
||||
rm -f "$PREVIEW_FILE" "$VERSION_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Proceeding with commit...${NOCOLOR}"
|
||||
|
||||
# Add the updated CHANGELOG.md and Makefile to the current commit
|
||||
echo -e "${CYAN}Staging CHANGELOG.md and Makefile...${NOCOLOR}"
|
||||
git add CHANGELOG.md Makefile
|
||||
|
||||
# Clean up temp files
|
||||
rm -f "$PREVIEW_FILE" "$VERSION_FILE"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}Warning: changelog update script not found at $CHANGELOG_SCRIPT${NOCOLOR}"
|
||||
fi
|
||||
|
||||
@ -2,81 +2,11 @@
|
||||
|
||||
# Colors for output
|
||||
CYAN='\033[0;36m'
|
||||
YELLOW='\033[1;33m'
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
NOCOLOR='\033[0m'
|
||||
|
||||
# Get the directory where this hook is located
|
||||
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# Go up from .git/hooks/ to repo root
|
||||
REPO_ROOT="$(cd "$HOOK_DIR/../.." && pwd)"
|
||||
CHANGELOG_SCRIPT="$REPO_ROOT/scripts/update_changelog.sh"
|
||||
PREVIEW_FILE="$REPO_ROOT/.changelog_preview.tmp"
|
||||
VERSION_FILE="$REPO_ROOT/.changelog_version.tmp"
|
||||
|
||||
# Update changelog before push
|
||||
if [ -f "$CHANGELOG_SCRIPT" ]; then
|
||||
echo -e "\n${CYAN}Updating changelog...${NOCOLOR}"
|
||||
bash "$CHANGELOG_SCRIPT"
|
||||
changelog_status=$?
|
||||
if [ $changelog_status -ne 0 ]; then
|
||||
echo -e "${RED}Push aborted: changelog update failed.${NOCOLOR}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Show preview if changelog was updated
|
||||
if [ -f "$PREVIEW_FILE" ] && [ -f "$VERSION_FILE" ]; then
|
||||
NEW_VERSION=$(cat "$VERSION_FILE")
|
||||
PREVIEW_CONTENT=$(cat "$PREVIEW_FILE")
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}========================================================================${NOCOLOR}"
|
||||
echo -e "${CYAN} CHANGELOG PREVIEW${NOCOLOR}"
|
||||
echo -e "${BLUE}========================================================================${NOCOLOR}"
|
||||
echo ""
|
||||
echo -e "${GREEN}New Version: ${YELLOW}$NEW_VERSION${NOCOLOR}"
|
||||
echo ""
|
||||
echo -e "${CYAN}Changelog Entry:${NOCOLOR}"
|
||||
echo -e "${BLUE}────────────────────────────────────────────────────────────────────────${NOCOLOR}"
|
||||
echo -e "$PREVIEW_CONTENT"
|
||||
echo -e "${BLUE}────────────────────────────────────────────────────────────────────────${NOCOLOR}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Do you want to proceed with the push? (yes/no):${NOCOLOR} "
|
||||
# Read from /dev/tty to ensure we can read from terminal even in git hook context
|
||||
read -r confirmation < /dev/tty
|
||||
|
||||
if [ "$confirmation" != "yes" ]; then
|
||||
echo -e "${RED}Push aborted by user.${NOCOLOR}"
|
||||
echo -e "${YELLOW}To revert changes, run:${NOCOLOR}"
|
||||
echo -e " git checkout CHANGELOG.md Makefile"
|
||||
# Clean up temp files
|
||||
rm -f "$PREVIEW_FILE" "$VERSION_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Proceeding with push...${NOCOLOR}"
|
||||
|
||||
# Commit the updated CHANGELOG.md and Makefile
|
||||
cd "$REPO_ROOT"
|
||||
echo -e "${CYAN}Staging CHANGELOG.md and Makefile...${NOCOLOR}"
|
||||
git add CHANGELOG.md Makefile
|
||||
|
||||
echo -e "${CYAN}Committing changes...${NOCOLOR}"
|
||||
NEW_VERSION=$(cat "$VERSION_FILE")
|
||||
git commit -m "chore: update changelog and version to $NEW_VERSION" || {
|
||||
# If commit fails (e.g., no changes to commit), continue anyway
|
||||
echo -e "${YELLOW}Note: Could not commit changes (may already be committed)${NOCOLOR}"
|
||||
}
|
||||
|
||||
# Clean up temp files
|
||||
rm -f "$PREVIEW_FILE" "$VERSION_FILE"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}Warning: changelog update script not found at $CHANGELOG_SCRIPT${NOCOLOR}"
|
||||
fi
|
||||
|
||||
# Run tests before push
|
||||
echo -e "\n${CYAN}Running tests...${NOCOLOR}"
|
||||
go test ./... # Runs all tests in your repo
|
||||
status=$?
|
||||
|
||||
15
CHANGELOG.md
15
CHANGELOG.md
@ -13,6 +13,21 @@ The format is based on [Keep a Changelog][keepachangelog] and adheres to [Semant
|
||||
### Deprecated
|
||||
|
||||
### Fixed
|
||||
## [0.53.17] - 2025-11-03
|
||||
|
||||
### Added
|
||||
- Added a new Git `pre-commit` hook to automatically update the changelog and version before committing, ensuring version consistency.
|
||||
|
||||
### Changed
|
||||
- Refactored the `update_changelog.sh` script to support different execution contexts (pre-commit vs. pre-push), allowing it to analyze only staged changes during commit.
|
||||
- The Git `pre-push` hook was simplified by removing the changelog update logic, which is now handled by the `pre-commit` hook.
|
||||
|
||||
### Deprecated
|
||||
|
||||
### Removed
|
||||
|
||||
### Fixed
|
||||
\n
|
||||
## [0.53.16] - 2025-11-03
|
||||
|
||||
### Added
|
||||
|
||||
2
Makefile
2
Makefile
@ -21,7 +21,7 @@ test-e2e:
|
||||
|
||||
.PHONY: build clean test run-node run-node2 run-node3 run-example deps tidy fmt vet lint clear-ports install-hooks
|
||||
|
||||
VERSION := 0.53.16
|
||||
VERSION := 0.53.17
|
||||
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
||||
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
LDFLAGS := -X 'main.version=$(VERSION)' -X 'main.commit=$(COMMIT)' -X 'main.date=$(DATE)'
|
||||
|
||||
@ -93,47 +93,76 @@ fi
|
||||
# Gather all git diffs
|
||||
log "Collecting git diffs..."
|
||||
|
||||
# Unstaged changes
|
||||
UNSTAGED_DIFF=$(git diff 2>/dev/null || echo "")
|
||||
UNSTAGED_COUNT=$(echo "$UNSTAGED_DIFF" | grep -c "^diff\|^index" 2>/dev/null || echo "0")
|
||||
[ -z "$UNSTAGED_COUNT" ] && UNSTAGED_COUNT="0"
|
||||
|
||||
# Staged changes
|
||||
STAGED_DIFF=$(git diff --cached 2>/dev/null || echo "")
|
||||
STAGED_COUNT=$(echo "$STAGED_DIFF" | grep -c "^diff\|^index" 2>/dev/null || echo "0")
|
||||
[ -z "$STAGED_COUNT" ] && STAGED_COUNT="0"
|
||||
|
||||
# Unpushed commits
|
||||
UNPUSHED_DIFF=$(git diff "$REMOTE_BRANCH"..HEAD 2>/dev/null || echo "")
|
||||
UNPUSHED_COMMITS=$(git rev-list --count "$REMOTE_BRANCH"..HEAD 2>/dev/null || echo "0")
|
||||
[ -z "$UNPUSHED_COMMITS" ] && UNPUSHED_COMMITS="0"
|
||||
|
||||
# Check if the only unpushed commit is a changelog update commit
|
||||
# If so, exclude it from the diff to avoid infinite loops
|
||||
if [ "$UNPUSHED_COMMITS" -gt 0 ]; then
|
||||
LATEST_COMMIT_MSG=$(git log -1 --pretty=%B HEAD 2>/dev/null || echo "")
|
||||
if echo "$LATEST_COMMIT_MSG" | grep -q "chore: update changelog and version"; then
|
||||
# If the latest commit is a changelog commit, check if there are other commits
|
||||
if [ "$UNPUSHED_COMMITS" -eq 1 ]; then
|
||||
log "Latest commit is a changelog update. No other changes detected. Skipping changelog update."
|
||||
# Clean up any old preview files
|
||||
rm -f "$REPO_ROOT/.changelog_preview.tmp" "$REPO_ROOT/.changelog_version.tmp"
|
||||
exit 0
|
||||
else
|
||||
# Multiple commits, exclude the latest changelog commit from diff
|
||||
log "Multiple unpushed commits detected. Excluding latest changelog commit from analysis."
|
||||
# Get all commits except the latest one
|
||||
UNPUSHED_DIFF=$(git diff "$REMOTE_BRANCH"..HEAD~1 2>/dev/null || echo "")
|
||||
UNPUSHED_COMMITS=$(git rev-list --count "$REMOTE_BRANCH"..HEAD~1 2>/dev/null || echo "0")
|
||||
[ -z "$UNPUSHED_COMMITS" ] && UNPUSHED_COMMITS="0"
|
||||
# Check if running from pre-commit context
|
||||
if [ "$CHANGELOG_CONTEXT" = "pre-commit" ]; then
|
||||
log "Running in pre-commit context - analyzing staged changes only"
|
||||
|
||||
# Unstaged changes (usually none in pre-commit, but check anyway)
|
||||
UNSTAGED_DIFF=$(git diff 2>/dev/null || echo "")
|
||||
UNSTAGED_COUNT=$(echo "$UNSTAGED_DIFF" | grep -c "^diff\|^index" 2>/dev/null || echo "0")
|
||||
[ -z "$UNSTAGED_COUNT" ] && UNSTAGED_COUNT="0"
|
||||
|
||||
# Staged changes (these are what we're committing)
|
||||
STAGED_DIFF=$(git diff --cached 2>/dev/null || echo "")
|
||||
STAGED_COUNT=$(echo "$STAGED_DIFF" | grep -c "^diff\|^index" 2>/dev/null || echo "0")
|
||||
[ -z "$STAGED_COUNT" ] && STAGED_COUNT="0"
|
||||
|
||||
# No unpushed commits analysis in pre-commit context
|
||||
UNPUSHED_DIFF=""
|
||||
UNPUSHED_COMMITS="0"
|
||||
|
||||
log "Found: $UNSTAGED_COUNT unstaged file(s), $STAGED_COUNT staged file(s)"
|
||||
else
|
||||
# Pre-push context - analyze everything
|
||||
# Unstaged changes
|
||||
UNSTAGED_DIFF=$(git diff 2>/dev/null || echo "")
|
||||
UNSTAGED_COUNT=$(echo "$UNSTAGED_DIFF" | grep -c "^diff\|^index" 2>/dev/null || echo "0")
|
||||
[ -z "$UNSTAGED_COUNT" ] && UNSTAGED_COUNT="0"
|
||||
|
||||
# Staged changes
|
||||
STAGED_DIFF=$(git diff --cached 2>/dev/null || echo "")
|
||||
STAGED_COUNT=$(echo "$STAGED_DIFF" | grep -c "^diff\|^index" 2>/dev/null || echo "0")
|
||||
[ -z "$STAGED_COUNT" ] && STAGED_COUNT="0"
|
||||
|
||||
# Unpushed commits
|
||||
UNPUSHED_DIFF=$(git diff "$REMOTE_BRANCH"..HEAD 2>/dev/null || echo "")
|
||||
UNPUSHED_COMMITS=$(git rev-list --count "$REMOTE_BRANCH"..HEAD 2>/dev/null || echo "0")
|
||||
[ -z "$UNPUSHED_COMMITS" ] && UNPUSHED_COMMITS="0"
|
||||
|
||||
# Check if the only unpushed commit is a changelog update commit
|
||||
# If so, exclude it from the diff to avoid infinite loops
|
||||
if [ "$UNPUSHED_COMMITS" -gt 0 ]; then
|
||||
LATEST_COMMIT_MSG=$(git log -1 --pretty=%B HEAD 2>/dev/null || echo "")
|
||||
if echo "$LATEST_COMMIT_MSG" | grep -q "chore: update changelog and version"; then
|
||||
# If the latest commit is a changelog commit, check if there are other commits
|
||||
if [ "$UNPUSHED_COMMITS" -eq 1 ]; then
|
||||
log "Latest commit is a changelog update. No other changes detected. Skipping changelog update."
|
||||
# Clean up any old preview files
|
||||
rm -f "$REPO_ROOT/.changelog_preview.tmp" "$REPO_ROOT/.changelog_version.tmp"
|
||||
exit 0
|
||||
else
|
||||
# Multiple commits, exclude the latest changelog commit from diff
|
||||
log "Multiple unpushed commits detected. Excluding latest changelog commit from analysis."
|
||||
# Get all commits except the latest one
|
||||
UNPUSHED_DIFF=$(git diff "$REMOTE_BRANCH"..HEAD~1 2>/dev/null || echo "")
|
||||
UNPUSHED_COMMITS=$(git rev-list --count "$REMOTE_BRANCH"..HEAD~1 2>/dev/null || echo "0")
|
||||
[ -z "$UNPUSHED_COMMITS" ] && UNPUSHED_COMMITS="0"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
log "Found: $UNSTAGED_COUNT unstaged file(s), $STAGED_COUNT staged file(s), $UNPUSHED_COMMITS unpushed commit(s)"
|
||||
fi
|
||||
|
||||
log "Found: $UNSTAGED_COUNT unstaged file(s), $STAGED_COUNT staged file(s), $UNPUSHED_COMMITS unpushed commit(s)"
|
||||
|
||||
# Combine all diffs
|
||||
ALL_DIFFS="${UNSTAGED_DIFF}
|
||||
if [ "$CHANGELOG_CONTEXT" = "pre-commit" ]; then
|
||||
ALL_DIFFS="${UNSTAGED_DIFF}
|
||||
---
|
||||
STAGED CHANGES:
|
||||
---
|
||||
${STAGED_DIFF}"
|
||||
else
|
||||
ALL_DIFFS="${UNSTAGED_DIFF}
|
||||
---
|
||||
STAGED CHANGES:
|
||||
---
|
||||
@ -142,13 +171,23 @@ ${STAGED_DIFF}
|
||||
UNPUSHED COMMITS:
|
||||
---
|
||||
${UNPUSHED_DIFF}"
|
||||
fi
|
||||
|
||||
# Check if there are any changes
|
||||
if [ -z "$(echo "$UNSTAGED_DIFF$STAGED_DIFF$UNPUSHED_DIFF" | tr -d '[:space:]')" ]; then
|
||||
log "No changes detected (unstaged, staged, or unpushed). Skipping changelog update."
|
||||
# Clean up any old preview files
|
||||
rm -f "$REPO_ROOT/.changelog_preview.tmp" "$REPO_ROOT/.changelog_version.tmp"
|
||||
exit 0
|
||||
if [ "$CHANGELOG_CONTEXT" = "pre-commit" ]; then
|
||||
# In pre-commit, only check staged changes
|
||||
if [ -z "$(echo "$STAGED_DIFF" | tr -d '[:space:]')" ]; then
|
||||
log "No staged changes detected. Skipping changelog update."
|
||||
rm -f "$REPO_ROOT/.changelog_preview.tmp" "$REPO_ROOT/.changelog_version.tmp"
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
# In pre-push, check all changes
|
||||
if [ -z "$(echo "$UNSTAGED_DIFF$STAGED_DIFF$UNPUSHED_DIFF" | tr -d '[:space:]')" ]; then
|
||||
log "No changes detected (unstaged, staged, or unpushed). Skipping changelog update."
|
||||
rm -f "$REPO_ROOT/.changelog_preview.tmp" "$REPO_ROOT/.changelog_version.tmp"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Get current version from Makefile
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user