kammer/.claude/scripts/create-pr.sh

100 lines
2.8 KiB
Bash
Executable file

#!/usr/bin/env bash
# Create a PR on Forgejo via tea and record it in the request log.
#
# Usage:
# .claude/scripts/create-pr.sh <title> [body] [base]
#
# Environment:
# FORGEJO_BASE_BRANCH — override default base branch (default: main)
set -euo pipefail
TITLE="${1:-}"
BODY="${2:-}"
BASE="${3:-${FORGEJO_BASE_BRANCH:-main}}"
LOG_FILE=".claude/request-log.jsonl"
if [ -z "$TITLE" ]; then
echo "Usage: create-pr.sh <title> [body] [base-branch]" >&2
exit 1
fi
if ! command -v tea &>/dev/null; then
cat >&2 <<'MSG'
Error: 'tea' CLI not found.
Install options:
nix develop path:~/.claude/workflows/forgejo # recommended
brew install gitea/tap/tea # macOS
go install gitea.com/gitea/tea@latest # Go
Then configure: tea login add
MSG
exit 1
fi
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "$CURRENT_BRANCH" = "$BASE" ]; then
echo "Error: currently on base branch '$BASE'. Create a feature branch first." >&2
exit 1
fi
echo "Creating PR: '$TITLE'"
echo " head: $CURRENT_BRANCH → base: $BASE"
echo ""
# Build tea args
TEA_ARGS=(pr create
--title "$TITLE"
--head "$CURRENT_BRANCH"
--base "$BASE"
)
if [ -n "$BODY" ]; then
TEA_ARGS+=(--description "$BODY")
fi
PR_OUTPUT=$(tea "${TEA_ARGS[@]}" 2>&1)
echo "$PR_OUTPUT"
# Extract URL — tea prints something like: "Created pull request #42"
# and/or a URL line
PR_URL=$(echo "$PR_OUTPUT" | grep -oE 'https?://[^[:space:]]+/pulls/[0-9]+' | head -1 || true)
PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$' || true)
if [ -z "$PR_NUMBER" ]; then
# Fallback: parse "Created pull request #N"
PR_NUMBER=$(echo "$PR_OUTPUT" | grep -oE '#[0-9]+' | grep -oE '[0-9]+' | head -1 || true)
fi
# Update most recent pending entry in the log
if [ -n "$PR_NUMBER" ] && [ -f "$LOG_FILE" ] && [ -s "$LOG_FILE" ]; then
TMPFILE=$(mktemp)
# Find and update the last entry that matches current branch & is pending
awk -v branch="$CURRENT_BRANCH" -v pr_num="$PR_NUMBER" -v pr_url="$PR_URL" '
BEGIN { updated = 0 }
{
lines[NR] = $0
}
END {
# Walk backwards to find last matching entry
for (i = NR; i >= 1; i--) {
if (!updated && lines[i] ~ ("\"branch\":\"" branch "\"") && lines[i] ~ "\"status\":\"pending\"") {
# Use a simple substitution — jq would be cleaner but we avoid a subshell per line
cmd = "echo " lines[i] " | jq --arg pn \"" pr_num "\" --arg pu \"" pr_url "\" \".pr_number = ($pn | tonumber) | .pr_url = $pu | .status = \\\"open\\\"\""
cmd | getline updated_line
close(cmd)
lines[i] = updated_line
updated = 1
}
}
for (i = 1; i <= NR; i++) print lines[i]
}
' "$LOG_FILE" > "$TMPFILE"
mv "$TMPFILE" "$LOG_FILE"
echo ""
echo "Request log updated with PR #$PR_NUMBER"
fi