hive-forge: fix assign endpoint + surface API errors via --fail-with-body (#353)

This commit is contained in:
damocles 2026-05-23 15:53:06 +02:00
parent b3e94760e1
commit 8e5112aa27

View file

@ -27,21 +27,28 @@ pkgs.writeShellApplication {
_token=$(cat "$_token_file")
FORGE_API="$HIVE_FORGE_URL/api/v1"
# `-sS --fail-with-body` makes curl quiet on success, print errors to
# stderr on transport failures, AND surface the response body for HTTP
# error codes (4xx/5xx) before exiting non-zero. Without this, a 500 /
# 404 from forge silently returned an empty stdout — combined with the
# script's `set -o pipefail` + the `| jq ...` consumer, the failure
# propagated as "no output" with no clue about what went wrong (closes
# #353).
forge_get() {
${pkgs.curl}/bin/curl -sf \
${pkgs.curl}/bin/curl -sS --fail-with-body \
-H "Authorization: token $_token" \
-H "Accept: application/json" \
"$1"
}
forge_post() {
${pkgs.curl}/bin/curl -sf -X POST \
${pkgs.curl}/bin/curl -sS --fail-with-body -X POST \
-H "Authorization: token $_token" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d "$2" "$1"
}
forge_patch() {
${pkgs.curl}/bin/curl -sf -X PATCH \
${pkgs.curl}/bin/curl -sS --fail-with-body -X PATCH \
-H "Authorization: token $_token" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
@ -51,13 +58,13 @@ pkgs.writeShellApplication {
local _url="$1"
local _body="''${2:-}"
if [ -n "$_body" ]; then
${pkgs.curl}/bin/curl -sf -X DELETE \
${pkgs.curl}/bin/curl -sS --fail-with-body -X DELETE \
-H "Authorization: token $_token" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d "$_body" "$_url"
else
${pkgs.curl}/bin/curl -sf -X DELETE \
${pkgs.curl}/bin/curl -sS --fail-with-body -X DELETE \
-H "Authorization: token $_token" \
-H "Accept: application/json" \
"$_url"
@ -189,17 +196,29 @@ pkgs.writeShellApplication {
cmd_assign() {
# assign <number> <user> [--remove]
# Assign or unassign a user on an issue or PR.
#
# The Forgejo API has no dedicated `POST /issues/{n}/assignees`
# endpoint (closes #353) — assignees are an EditIssueOption field
# on the issue itself. We patch the full assignee list:
# - add: GET current assignees, append `_user`, PATCH back
# - remove: GET current assignees, drop `_user`, PATCH back
# The PATCH is idempotent: re-adding an existing assignee or
# removing one that's not on the list is a no-op (the resulting
# assignee list is unchanged).
if [ $# -lt 2 ]; then echo "usage: hive-forge assign <number> <user> [--remove]" >&2; exit 1; fi
local _n="$1" _user="$2" _remove="''${3:-}"
local _payload
_payload=$(jq -n --arg u "$_user" '{assignees:[$u]}')
local _current _payload
_current=$(forge_get "$FORGE_API/repos/$HIVE_FORGE_REPO/issues/$_n" \
| jq -c '[.assignees[]?.login]')
if [ "$_remove" = "--remove" ]; then
forge_delete "$FORGE_API/repos/$HIVE_FORGE_REPO/issues/$_n/assignees" "$_payload" \
| jq '{number,assignees:[.assignees[]?.login]}'
_payload=$(jq -n --argjson cur "$_current" --arg u "$_user" \
'{assignees: ($cur - [$u])}')
else
forge_post "$FORGE_API/repos/$HIVE_FORGE_REPO/issues/$_n/assignees" "$_payload" \
| jq '{number,assignees:[.assignees[]?.login]}'
_payload=$(jq -n --argjson cur "$_current" --arg u "$_user" \
'{assignees: (($cur + [$u]) | unique)}')
fi
forge_patch "$FORGE_API/repos/$HIVE_FORGE_REPO/issues/$_n" "$_payload" \
| jq '{number,assignees:[.assignees[]?.login]}'
}
cmd_close() {