Files
dotfiles/bin/gitea-pr
T

153 lines
5.1 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
GITEA_SSH_HOST="gitbox.bradina.localdomain"
GITEA_API="https://gitbox.branderson.io/api/v1"
function usage() {
echo "Usage: gitea-pr create [--title TITLE] [--body BODY] [--base BRANCH]"
echo " gitea-pr comments PR_NUMBER"
echo " gitea-pr merge PR_NUMBER"
}
function require_token() {
if [ -z "${GITEA_TOKEN:-}" ]; then
echo "GITEA_TOKEN is not set. Generate a token in the Gitea web UI" \
"(Settings > Applications, scopes write:repository + write:issue)" \
"and add 'export GITEA_TOKEN=...' to ~/.profile.local" >&2
exit 1
fi
}
function gitea_owner_repo() {
local remote_url host owner_repo
remote_url=$(git remote get-url origin 2>/dev/null) || {
echo "No 'origin' remote found in this repository" >&2
exit 1
}
host=$(echo "$remote_url" | sed -E 's#^[^@]+@([^:]+):.*#\1#')
if [ "$host" != "$GITEA_SSH_HOST" ]; then
echo "origin remote ($remote_url) is not on $GITEA_SSH_HOST; gitea-pr only supports this host" >&2
exit 1
fi
owner_repo=$(echo "$remote_url" | sed -E 's#^[^@]+@[^:]+:##; s#\.git$##')
echo "$owner_repo"
}
if [ "$#" -lt 1 ]; then
usage
exit 1
fi
subcommand="$1"
shift
case "$subcommand" in
create|comments|merge)
require_token
owner_repo=$(gitea_owner_repo)
owner="${owner_repo%%/*}"
repo="${owner_repo##*/}"
;;
*)
usage
exit 1
;;
esac
case "$subcommand" in
create)
title=""
body=""
base=""
while [ "$#" -gt 0 ]; do
case "$1" in
--title) title="$2"; shift 2 ;;
--body) body="$2"; shift 2 ;;
--base) base="$2"; shift 2 ;;
*) echo "Unknown option: $1" >&2; usage; exit 1 ;;
esac
done
current_branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$current_branch" = "HEAD" ]; then
echo "Detached HEAD: check out the feature branch before creating a PR" >&2
exit 1
fi
if [ -z "$base" ]; then
base=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's#refs/remotes/origin/##' || true)
base="${base:-main}"
fi
if [ -z "$title" ]; then
title="$current_branch"
fi
response=$(curl -sS -w '\n%{http_code}' -X POST "${GITEA_API}/repos/${owner}/${repo}/pulls" \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg head "$current_branch" --arg base "$base" --arg title "$title" --arg body "$body" \
'{head: $head, base: $base, title: $title, body: $body}')")
http_code=$(echo "$response" | tail -1)
json=$(echo "$response" | sed '$d')
if [ "$http_code" -lt 200 ] || [ "$http_code" -ge 300 ]; then
echo "Failed to create PR (HTTP $http_code):" >&2
echo "$json" >&2
exit 1
fi
echo "$json" | jq -r '.html_url'
;;
comments)
pr_number="${1:-}"
if [ -z "$pr_number" ]; then
echo "Usage: gitea-pr comments PR_NUMBER" >&2
exit 1
fi
echo "=== Issue comments ==="
response=$(curl -sS -w '\n%{http_code}' "${GITEA_API}/repos/${owner}/${repo}/issues/${pr_number}/comments" \
-H "Authorization: token ${GITEA_TOKEN}")
http_code=$(echo "$response" | tail -1)
json=$(echo "$response" | sed '$d')
if [ "$http_code" -lt 200 ] || [ "$http_code" -ge 300 ]; then
echo "Failed to fetch issue comments (HTTP $http_code):" >&2
echo "$json" >&2
exit 1
fi
echo "$json" | jq -r '.[] | "[\(.user.login) @ \(.created_at)]\n\(.body)\n"'
echo "=== Reviews ==="
response=$(curl -sS -w '\n%{http_code}' "${GITEA_API}/repos/${owner}/${repo}/pulls/${pr_number}/reviews" \
-H "Authorization: token ${GITEA_TOKEN}")
http_code=$(echo "$response" | tail -1)
json=$(echo "$response" | sed '$d')
if [ "$http_code" -lt 200 ] || [ "$http_code" -ge 300 ]; then
echo "Failed to fetch reviews (HTTP $http_code):" >&2
echo "$json" >&2
exit 1
fi
echo "$json" | jq -r '.[] | select(.body != "") | "[\(.user.login) @ \(.submitted_at) — \(.state)]\n\(.body)\n"'
;;
merge)
pr_number="${1:-}"
if [ -z "$pr_number" ]; then
echo "Usage: gitea-pr merge PR_NUMBER" >&2
exit 1
fi
response=$(curl -sS -w '\n%{http_code}' -X POST "${GITEA_API}/repos/${owner}/${repo}/pulls/${pr_number}/merge" \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"Do": "merge"}')
http_code=$(echo "$response" | tail -1)
json=$(echo "$response" | sed '$d')
if [ "$http_code" -lt 200 ] || [ "$http_code" -ge 300 ]; then
echo "Failed to merge PR #${pr_number} (HTTP $http_code):" >&2
echo "$json" >&2
exit 1
fi
echo "Merged PR #${pr_number}"
;;
esac