Files
games-server-scripts/gitea_push.sh
2025-04-17 20:44:56 +02:00

284 lines
7.2 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/zsh
# Script Version: 19
# Description: Pushes the current folder (e.g. /etc) to a nested Gitea repo using provided nesting arguments. Auto-creates the remote repo via Gitea API if missing.
# Set variables
# ========
# Try to extract GITEA_API_TOKEN from ~/.gitea_token if not set
if [ -z "$GITEA_API_TOKEN" ] && [ -f "$HOME/.gitea_token" ]; then
GITEA_API_TOKEN=$(<"$HOME/.gitea_token")
export GITEA_API_TOKEN
fi
GITEA_USER=$(awk '{for(i=1;i<=NF;i++) if($i=="login") print $(i+1)}' ~/.netrc | head -n1)
if [ -z "$GITEA_USER" ]; then
echo "[ERROR] No login found in ~/.netrc"
exit 1
fi
GITEA_URL="https://$(awk '{for(i=1;i<=NF;i++) if($i=="machine") print $(i+1)}' ~/.netrc | head -n1)"
if [ -z "$GITEA_URL" ]; then
echo "[ERROR] No URL found in ~/.netrc"
exit 1
fi
GITEA_API_URL="$GITEA_URL/api/v1"
PRIVATE=false
DEBUG=false
COMMIT_MESSAGE="Update $(date +"%F_%T")"
# Logging function
# ========
log() {
local level="$1"; shift
if [[ "$level" == "DEBUG" && "$DEBUG" != true ]]; then return; fi
local color_reset="$(tput sgr0)"
local color=""
case "$level" in
INFO) color="$(tput setaf 6)" ;; # cyan
WARNING) color="$(tput setaf 3)" ;; # yellow
ERROR) color="$(tput setaf 1)" ;; # red
DEBUG) color="$(tput bold; tput setaf 4)" ;; # bold blue
esac
echo "${color}[$level] $*${color_reset}"
}
# Functions
# ========
create_repo() {
log INFO "Repository does not exist. Creating via API: $REMOTE_PATH"
log DEBUG "POST $GITEA_API_URL/user/repos with name=$REMOTE_PATH and private=$PRIVATE"
RESPONSE=$(curl -s -X POST \
-H "Authorization: token $GITEA_API_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"name\": \"$FOLDER_NAME\", \"private\": $PRIVATE}" \
"$GITEA_API_URL/user/repos")
if echo "$RESPONSE" | grep -q '"clone_url"'; then
log INFO "Remote repository created successfully."
HTTP_STATUS=200
else
log ERROR "Failed to create remote repository: $RESPONSE"
exit 1
fi
}
prepare_commit() {
git add .
log INFO "Committing changes"
git commit -m "$COMMIT_MESSAGE" || log INFO "Nothing to commit"
}
setup_remote() {
if git remote | grep -q '^origin$'; then
log INFO "Updating remote origin URL"
git remote set-url origin "$GIT_REMOTE"
else
log INFO "Adding remote origin"
git remote add origin "$GIT_REMOTE"
fi
}
push_changes() {
log INFO "Pushing to $GIT_REMOTE"
git push -u origin main
}
# Show help if no arguments are given
# ========
if [ $# -eq 0 ]; then
echo "GITEA_API_TOKEN=<your token>"
echo "Usage: $0 [--private] [--debug] [--message \"your commit message\"] <host_group>"
echo "Example: $0 server"
echo " $0 --private workstation"
echo " $0 --debug server"
echo " $0 --message \"minor update\" server"
echo
echo "Note: You must cd into the target folder before running this script."
echo "For example:"
echo " cd /etc && $0 server"
echo
echo "Authentication:"
echo " Git operations (clone, push, pull) use ~/.netrc with your Git password:"
echo " machine \$(echo \"$GITEA_URL\" | sed 's|https\?://||') login $GITEA_USER password \"<your Git password>\""
echo " chmod 600 ~/.netrc"
echo
echo " API operations (e.g. creating repos) use a Personal Access Token stored in ~/.gitea_token"
echo " echo \"<your_token>\" > ~/.gitea_token && chmod 600 ~/.gitea_token"
exit 0
fi
# Parse arguments
# ========
POSITIONAL_ARGS=()
while [[ $# -gt 0 ]]; do
case "$1" in
--private)
PRIVATE=true
shift
;;
--debug)
DEBUG=true
shift
;;
--message)
COMMIT_MESSAGE="$2"
shift 2
;;
*)
POSITIONAL_ARGS+=("$1")
shift
;;
esac
done
set -- "${POSITIONAL_ARGS[@]}"
if [[ $# -ne 1 ]]; then
echo "Usage: $0 [--private] [--debug] [--message \"your commit message\"] <host_group>"
exit 1
fi
HOST_GROUP=$(echo "$1" | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9-')
HOST_NAME=$(hostname -s | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9-')
FOLDER_NAME="${HOST_NAME}-${HOST_GROUP}-$(basename "$PWD")"
REPO_PATH="$PWD"
REMOTE_PATH="$FOLDER_NAME"
GIT_REMOTE="$GITEA_URL/$GITEA_USER/$FOLDER_NAME.git"
# Git authentication hint
log DEBUG "Ensure ~/.netrc has: machine <host> login $GITEA_USER password <your Git password>"
# Check or create remote repo
check_or_create_repo() {
if [ -z "$GITEA_API_TOKEN" ]; then
log WARNING "GITEA_API_TOKEN is not set. Skipping API repo creation."
return
fi
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: token $GITEA_API_TOKEN" \
"$GITEA_API_URL/repos/$GITEA_USER/$FOLDER_NAME")
if [ "$HTTP_STATUS" -ne 200 ]; then
create_repo
else
log INFO "Remote repository already exists."
fi
}
check_or_create_repo
# Main Process
# ========
# Add safe.directory for current repo if needed
if [ -n "$GIT_REMOTE" ]; then
SAFE_DIR="$(pwd)"
git config --global --add safe.directory "$SAFE_DIR"
log DEBUG "Added safe.directory: $SAFE_DIR"
fi
# Create default .gitignore if not present
if [ ! -f .gitignore ]; then
log INFO "Creating default .gitignore"
cat > .gitignore <<EOF
# Bytecode-Dateien
__pycache__/
*.py[cod]
# Virtuelle Umgebungen
.venv/
venv/
# Betriebssystem-Dateien
.DS_Store
Thumbs.db
# Logfiles und Dumps
*.log
*.bak
*.swp
*.tmp
# IDEs und Editoren
.vscode/
.idea/
EOF
fi
# Ensure Git user identity is configured
log DEBUG "Checking Git user configuration..."
if ! git config user.name >/dev/null 2>&1; then
git config --global user.name "$(whoami)"
log DEBUG "Set Git user.name to $(whoami)"
else
log DEBUG "Git user.name already set to $(git config --show-origin user.name)"
fi
if ! git config user.email >/dev/null 2>&1; then
git config --global user.email "$(whoami)@$(hostname -f)"
log DEBUG "Set Git user.email to $(whoami)@$(hostname -f)"
else
log DEBUG "Git user.email already set to $(git config --show-origin user.email)"
fi
# Safety check against pushing from / or $HOME
if [[ "$PWD" == "$HOME" || "$PWD" == "/" ]]; then
log ERROR "Refusing to run inside \$PWD=$PWD"
exit 1
fi
log INFO "Pushing $REPO_PATH to $GIT_REMOTE"
cd "$REPO_PATH" || { log ERROR "Directory $REPO_PATH not found"; exit 1; }
# Initialize git if needed
# Branch is fixed to 'main' for simplicity and consistency
if [ ! -d .git ]; then
log INFO "Initializing Git repo"
git init
git config init.defaultBranch main
git checkout -b main
else
CURRENT_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)
if [ "$CURRENT_BRANCH" != "main" ]; then
log WARNING "Current branch is '$CURRENT_BRANCH', renaming to 'main'"
if ! git rev-parse HEAD >/dev/null 2>&1; then
git checkout -b main
else
git branch -m main
fi
fi
log DEBUG ".git directory already present"
fi
# Ensure at least one commit exists
# Create placeholder file if no untracked files exist
if [ -z "$(git ls-files)" ]; then
touch .gitkeep
git add .gitkeep
log DEBUG "Added .gitkeep to ensure initial commit"
fi
prepare_commit
# Set or update remote
if [ "$HTTP_STATUS" -eq 200 ]; then
setup_remote
else
log WARNING "Skipping remote setup repository does not exist."
fi
# Push to remote
if [ "$HTTP_STATUS" -eq 200 ]; then
push_changes
else
log WARNING "Skipping push repository does not exist."
fi