#!/usr/bin/env bash set -euo pipefail # Get the directory where this script is located SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" # Ensure access token exists ensure_token() { # Check if git-access-token exists, if not generate it if ! secret-mgr list 2>/dev/null | grep -q "git-access-token"; then echo "Access token not found, generating..." "$SCRIPT_DIR/generate-access-token" fi # Get the access token (extract actual token from "Access token was successfully created: ") GIT_TOKEN="$(secret-mgr get-secret --key git-access-token | awk '{print $NF}')" if [[ -z "$GIT_TOKEN" ]]; then echo "Error: Failed to get git-access-token" exit 1 fi echo "$GIT_TOKEN" } # Get owner and repo from local git repo get_repo_info() { local repo_path="$1" if [[ ! -d "$repo_path/.git" ]]; then echo "Error: Not a git repository: $repo_path" exit 1 fi REMOTE_URL="$(git -C "$repo_path" remote get-url origin)" if [[ "$REMOTE_URL" =~ https://git\.hangman-lab\.top/([^/]+)/([^/]+)\.git ]]; then OWNER="${BASH_REMATCH[1]}" REPO_NAME="${BASH_REMATCH[2]}" else echo "Error: Invalid remote URL format: $REMOTE_URL" echo "Expected: https://git.hangman-lab.top/\${owner}/\${repo-name}.git" exit 1 fi } # Subcommand: create cmd_create() { local repo_path="$1" local head_branch="$2" local base_branch="$3" local pr_title="${4:-untitled pull request}" local pr_body="${5:-}" get_repo_info "$repo_path" local token token="$(ensure_token)" echo "Creating PR: $OWNER/$REPO_NAME ($head_branch -> $base_branch)" RESPONSE=$(curl -s -X POST "https://git.hangman-lab.top/api/v1/repos/${OWNER}/${REPO_NAME}/pulls" \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -H "Authorization: token ${token}" \ -d "$(jq -n \ --arg head "$head_branch" \ --arg base "$base_branch" \ --arg title "$pr_title" \ --arg body "$pr_body" \ '{head: $head, base: $base, title: $title, body: $body}')") if echo "$RESPONSE" | jq -e '.message' >/dev/null 2>&1; then ERROR_MSG=$(echo "$RESPONSE" | jq -r '.message') echo "Error: $ERROR_MSG" exit 1 fi PR_URL=$(echo "$RESPONSE" | jq -r '.html_url // empty') if [[ -n "$PR_URL" ]]; then echo "Pull request created successfully!" echo "URL: $PR_URL" else echo "Error: Failed to create pull request" echo "Response: $RESPONSE" exit 1 fi } # Subcommand: list cmd_list() { local repo_path="$1" get_repo_info "$repo_path" local token token="$(ensure_token)" echo "Listing PRs for: $OWNER/$REPO_NAME" RESPONSE=$(curl -s -X GET "https://git.hangman-lab.top/api/v1/repos/${OWNER}/${REPO_NAME}/pulls/pinned" \ -H 'accept: application/json' \ -H "Authorization: token ${token}") if echo "$RESPONSE" | jq -e '.message' >/dev/null 2>&1; then ERROR_MSG=$(echo "$RESPONSE" | jq -r '.message') echo "Error: $ERROR_MSG" exit 1 fi echo "$RESPONSE" | jq -r '.[] | "\(.number)\t\(.title)\t\(.state)\t\(.html_url)"' 2>/dev/null || echo "$RESPONSE" } # Subcommand: commits cmd_commits() { local repo_path="$1" local pr_index="$2" get_repo_info "$repo_path" local token token="$(ensure_token)" echo "Fetching commits for PR #$pr_index in: $OWNER/$REPO_NAME" RESPONSE=$(curl -s -X GET "https://git.hangman-lab.top/api/v1/repos/${OWNER}/${REPO_NAME}/pulls/${pr_index}/commits" \ -H 'accept: application/json' \ -H "Authorization: token ${token}") if echo "$RESPONSE" | jq -e '.message' >/dev/null 2>&1; then ERROR_MSG=$(echo "$RESPONSE" | jq -r '.message') echo "Error: $ERROR_MSG" exit 1 fi echo "$RESPONSE" | jq -r '.[] | "\(.sha[0:7])\t\(.commit.message | split("\n")[0])"' 2>/dev/null || echo "$RESPONSE" } # Subcommand: merge cmd_merge() { local repo_path="$1" local pr_index="$2" local do="$3" local commit_id="${4:-}" local title="${5:-}" local message="${6:-}" get_repo_info "$repo_path" local token token="$(ensure_token)" echo "Merging PR #$pr_index in: $OWNER/$REPO_NAME (Do: $do)" # Get PR head sha first PR_INFO=$(curl -s -X GET "https://git.hangman-lab.top/api/v1/repos/${OWNER}/${REPO_NAME}/pulls/${pr_index}" \ -H 'accept: application/json' \ -H "Authorization: token ${token}") HEAD_SHA=$(echo "$PR_INFO" | jq -r '.head.sha') if [[ -z "$HEAD_SHA" || "$HEAD_SHA" == "null" ]]; then echo "Error: Failed to get PR head sha" exit 1 fi # Build JSON body local json json=$(jq -n \ --arg do "$do" \ --arg commit_id "$commit_id" \ --arg title "$title" \ --arg message "$message" \ --arg head_sha "$HEAD_SHA" \ '{ Do: $do, MergeCommitID: (if $commit_id != "" then $commit_id else null end), MergeMessageField: (if $message != "" then $message else null end), MergeTitleField: (if $title != "" then $title else null end), delete_branch_after_merge: true, force_merge: false, head_commit_id: $head_sha, merge_when_checks_succeed: true }') RESPONSE=$(curl -s -X POST "https://git.hangman-lab.top/api/v1/repos/${OWNER}/${REPO_NAME}/pulls/${pr_index}/merge" \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -H "Authorization: token ${token}" \ -d "$json") if echo "$RESPONSE" | jq -e '.message' >/dev/null 2>&1; then ERROR_MSG=$(echo "$RESPONSE" | jq -r '.message') echo "Error: $ERROR_MSG" exit 1 fi MERGED=$(echo "$RESPONSE" | jq -r '.merged') if [[ "$MERGED" == "true" ]]; then echo "Pull request merged successfully!" else echo "Error: Failed to merge pull request" echo "$RESPONSE" | jq '.' exit 1 fi } # Usage usage() { echo "Usage: $0 [options]" echo "" echo "Commands:" echo " create [pr-title] [pr-body]" echo " Create a pull request" echo " list List pull requests" echo " commits List commits in a PR" echo " merge [commit-id] [title] [message]" echo " Merge a pull request" echo "" echo " can be: merge, squash, rebase, manually-merged" exit 2 } # Main if [[ $# -lt 2 ]]; then usage fi COMMAND="$1" shift case "$COMMAND" in create) if [[ $# -lt 3 ]]; then echo "Error: create requires " exit 2 fi cmd_create "$@" ;; list) if [[ $# -lt 1 ]]; then echo "Error: list requires " exit 2 fi cmd_list "$@" ;; commits) if [[ $# -lt 2 ]]; then echo "Error: commits requires " exit 2 fi cmd_commits "$@" ;; merge) if [[ $# -lt 3 ]]; then echo "Error: merge requires " exit 2 fi cmd_merge "$@" ;; *) echo "Error: Unknown command: $COMMAND" usage ;; esac