diff --git a/packages/mosaic/framework/tools/git/issue-assign.sh b/packages/mosaic/framework/tools/git/issue-assign.sh index f3a15cb..6151b0e 100755 --- a/packages/mosaic/framework/tools/git/issue-assign.sh +++ b/packages/mosaic/framework/tools/git/issue-assign.sh @@ -98,27 +98,32 @@ case "$PLATFORM" in ;; gitea) # tea issue edit syntax - REPO_ARGS=$(get_gitea_repo_args) || { - echo "Error: Could not resolve Gitea repo/login args for remote host" >&2 + REPO_SLUG=$(get_repo_slug) || { + echo "Error: Could not resolve Gitea repo slug from remote" >&2 exit 1 } - CMD="tea issue edit $ISSUE $REPO_ARGS" + REPO_LOGIN=$(get_gitea_login) || { + echo "Error: Could not resolve Gitea login for remote host" >&2 + exit 1 + } + REPO_ARGS=(--repo "$REPO_SLUG" --login "$REPO_LOGIN") + CMD=(tea issue edit "$ISSUE" "${REPO_ARGS[@]}") NEEDS_EDIT=false if [[ -n "$ASSIGNEE" ]]; then # tea uses --assignees flag - CMD="$CMD --assignees \"$ASSIGNEE\"" + CMD+=(--assignees "$ASSIGNEE") NEEDS_EDIT=true fi if [[ -n "$LABELS" ]]; then # tea uses --labels flag (replaces existing) - CMD="$CMD --labels \"$LABELS\"" + CMD+=(--labels "$LABELS") NEEDS_EDIT=true fi if [[ -n "$MILESTONE" ]]; then - MILESTONE_ID=$(tea milestones list $REPO_ARGS 2>/dev/null | grep -E "^\s*[0-9]+" | grep "$MILESTONE" | awk '{print $1}' | head -1) + MILESTONE_ID=$(tea milestones list "${REPO_ARGS[@]}" 2>/dev/null | grep -E "^\s*[0-9]+" | grep "$MILESTONE" | awk '{print $1}' | head -1) if [[ -n "$MILESTONE_ID" ]]; then - CMD="$CMD --milestone $MILESTONE_ID" + CMD+=(--milestone "$MILESTONE_ID") NEEDS_EDIT=true else echo "Warning: Could not find milestone '$MILESTONE'" >&2 @@ -126,7 +131,7 @@ case "$PLATFORM" in fi if [[ "$NEEDS_EDIT" == true ]]; then - eval "$CMD" + "${CMD[@]}" echo "Issue #$ISSUE updated successfully" else echo "No changes specified" diff --git a/packages/mosaic/framework/tools/git/issue-edit.sh b/packages/mosaic/framework/tools/git/issue-edit.sh index 0ffcc0b..865af4f 100755 --- a/packages/mosaic/framework/tools/git/issue-edit.sh +++ b/packages/mosaic/framework/tools/git/issue-edit.sh @@ -63,24 +63,28 @@ fi detect_platform >/dev/null if [[ "$PLATFORM" == "github" ]]; then - CMD="gh issue edit $ISSUE_NUMBER" - [[ -n "$TITLE" ]] && CMD="$CMD --title \"$TITLE\"" - [[ -n "$BODY" ]] && CMD="$CMD --body \"$BODY\"" - [[ -n "$LABELS" ]] && CMD="$CMD --add-label \"$LABELS\"" - [[ -n "$MILESTONE" ]] && CMD="$CMD --milestone \"$MILESTONE\"" - eval $CMD + CMD=(gh issue edit "$ISSUE_NUMBER") + [[ -n "$TITLE" ]] && CMD+=(--title "$TITLE") + [[ -n "$BODY" ]] && CMD+=(--body "$BODY") + [[ -n "$LABELS" ]] && CMD+=(--add-label "$LABELS") + [[ -n "$MILESTONE" ]] && CMD+=(--milestone "$MILESTONE") + "${CMD[@]}" echo "Updated GitHub issue #$ISSUE_NUMBER" elif [[ "$PLATFORM" == "gitea" ]]; then - REPO_ARGS=$(get_gitea_repo_args) || { - echo "Error: Could not resolve Gitea repo/login args for remote host" >&2 + REPO_SLUG=$(get_repo_slug) || { + echo "Error: Could not resolve Gitea repo slug from remote" >&2 exit 1 } - CMD="tea issue edit $ISSUE_NUMBER $REPO_ARGS" - [[ -n "$TITLE" ]] && CMD="$CMD --title \"$TITLE\"" - [[ -n "$BODY" ]] && CMD="$CMD --description \"$BODY\"" - [[ -n "$LABELS" ]] && CMD="$CMD --add-labels \"$LABELS\"" - [[ -n "$MILESTONE" ]] && CMD="$CMD --milestone \"$MILESTONE\"" - eval $CMD + REPO_LOGIN=$(get_gitea_login) || { + echo "Error: Could not resolve Gitea login for remote host" >&2 + exit 1 + } + CMD=(tea issue edit "$ISSUE_NUMBER" --repo "$REPO_SLUG" --login "$REPO_LOGIN") + [[ -n "$TITLE" ]] && CMD+=(--title "$TITLE") + [[ -n "$BODY" ]] && CMD+=(--description "$BODY") + [[ -n "$LABELS" ]] && CMD+=(--add-labels "$LABELS") + [[ -n "$MILESTONE" ]] && CMD+=(--milestone "$MILESTONE") + "${CMD[@]}" echo "Updated Gitea issue #$ISSUE_NUMBER" else echo "Error: Unknown platform" diff --git a/packages/mosaic/framework/tools/git/milestone-create.sh b/packages/mosaic/framework/tools/git/milestone-create.sh index c5ffb52..8f5c371 100755 --- a/packages/mosaic/framework/tools/git/milestone-create.sh +++ b/packages/mosaic/framework/tools/git/milestone-create.sh @@ -99,10 +99,15 @@ fi case "$PLATFORM" in github) # GitHub uses the API for milestone creation - JSON_PAYLOAD="{\"title\":\"$TITLE\"" - [[ -n "$DESCRIPTION" ]] && JSON_PAYLOAD="$JSON_PAYLOAD,\"description\":\"$DESCRIPTION\"" - [[ -n "$DUE_DATE" ]] && JSON_PAYLOAD="$JSON_PAYLOAD,\"due_on\":\"${DUE_DATE}T00:00:00Z\"" - JSON_PAYLOAD="$JSON_PAYLOAD}" + # Use jq to safely construct JSON so titles/descriptions containing + # quotes or special characters do not corrupt the payload (F-07). + JSON_PAYLOAD=$(jq -n \ + --arg t "$TITLE" \ + --arg d "$DESCRIPTION" \ + --arg due "${DUE_DATE}" \ + '{"title": $t} + + (if $d != "" then {"description": $d} else {} end) + + (if $due != "" then {"due_on": ($due + "T00:00:00Z")} else {} end)') gh api repos/:owner/:repo/milestones --method POST --input - <<< "$JSON_PAYLOAD" echo "Milestone '$TITLE' created successfully" diff --git a/packages/mosaic/framework/tools/git/pr-metadata.sh b/packages/mosaic/framework/tools/git/pr-metadata.sh index b6373bf..7e8d1fc 100755 --- a/packages/mosaic/framework/tools/git/pr-metadata.sh +++ b/packages/mosaic/framework/tools/git/pr-metadata.sh @@ -56,6 +56,8 @@ curl_gitea_pull() { local api_url="$1" local token basic_auth raw_code body_file http_code body_file=$(mktemp) + # Ensure the tmpfile is removed even on early exit (set -e, SIGINT, etc.) + trap 'rm -f "$body_file"' EXIT token=$(get_gitea_token "$HOST" || true) if [[ -n "$token" ]]; then