git-hooks/pre-push-fediverse

105 lines
2.7 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env bash
# Requires toot: https://github.com/ihabunek/toot
# This script posts git commit information to the Fediverse using the toot CLI
# To temperarily turn off posting, in project root:
# touch .git/ignorepost
# Check if .git/ignorepost exists - if so, exit silently
if [[ -f ".git/ignorepost" ]]; then
exit 0
fi
# Do not allow errors
set -e
remote="$1"
url="$2"
# Clean up the repository URL to create a web-friendly link
url="${url#*@}"
url="${url%.git}"
2023-05-26 10:08:56 -04:00
url="${url#*://}"
shopt -s extglob # Enable extended pattern matching
2023-05-26 10:20:38 -04:00
url="${url/:+([0-9])/}"
2023-05-26 10:08:56 -04:00
url="https://${url}"
# Extract project name from repository URL
project="${url##*/}"
project="${project%.git}"
# Get pusher's name from git config more safely
pusher="$(git config user.name)"
if [[ -z "$pusher" ]]; then
echo "Error: Could not determine user name from git config"
exit 1
fi
# Initialize message
message=""
tags=""
branches=""
# Read push information from stdin
while read localRef localSha remoteRef remoteSha; do
# Skip if no refs are being pushed
[[ -z "$localRef" ]] && continue
# Check if this is a tag push
if [[ "$localRef" == refs/tags/* ]]; then
tagName="${localRef#refs/tags/}"
if [[ -z "$tags" ]]; then
tags="$tagName"
else
tags="$tags, $tagName"
fi
else
# Get current branch name from ref
branch="${localRef#refs/heads/}"
# Verify we can access the commit
if ! git cat-file -e "$localSha"; then
echo "Error: Cannot access commit $localSha"
exit 1
fi
# Get latest commit message
commit="$(git log -1 --pretty=%B $localSha)"
if [[ -z "$branches" ]]; then
branches="$branch"
else
branches="$branches, $branch"
fi
fi
done
# Construct the final message
if [[ "${branches##*,}" != "${branches}" ]]; then
branches="${branches%, *} and ${branches##*, }"
fi
if [[ "${tags##*,}" != "${tags}" ]]; then
tags="${tags%, *} and ${tags##*, }"
fi
if [[ -n "$tags" ]]; then
message="$pusher tagged [$project project]($url) with: $tags"
elif [[ -n "$branches" ]]; then
if [[ "${branches% and }" != "${branches}" ]]; then
message="$pusher pushed changes to the $branches branches of the [$project project]($url)"
else
message="$pusher pushed changes to the $branches branch of the [$project project]($url)"
fi
if [[ "$branches" != *","* ]]; then
# Only add commit message if pushing to a single branch
message="$message
$commit"
fi
fi
# Only post if we have something to say
if [[ -n "$message" ]]; then
toot post -v public -p "$project" -t "text/markdown" "$message" &> /dev/null
fi
exit 0