#!/bin/bash # scripts/create_issue.sh - Furt API Gateway Issue Creator # FINAL VERSION with all fixes: HTTP 422, stdout-mixing, array handling, unknown labels set -euo pipefail # Standard environment setup SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" if [ -f "$PROJECT_ROOT/.env" ]; then export $(cat "$PROJECT_ROOT/.env" | grep -v '^#' | xargs) fi # Colors GREEN='\033[0;32m' BLUE='\033[0;34m' RED='\033[0;31m' YELLOW='\033[1;33m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } # Track new labels for auto-update (FIXED: Safe initialization) declare -A NEW_LABELS_CREATED=() # === LABEL DEFINITIONS START === # This section is auto-maintained by update_script_labels.sh # DO NOT EDIT MANUALLY - Changes will be overwritten declare -A LABEL_DEFINITIONS=( ["service-request"]="color:7057ff;context:new_service;usage:service_templates,status_updates" ["enhancement"]="color:84b6eb;context:improvement;usage:all_templates" ["bug"]="color:d73a4a;context:error;usage:bug_template,status_updates" ["gateway"]="color:0052cc;context:gateway_core;usage:architecture,performance,service_templates" ["performance"]="color:fbca04;context:optimization;usage:performance_template,architecture" ["architecture"]="color:d4c5f9;context:design;usage:architecture_template,gateway" ["security"]="color:28a745;context:security_review;usage:security_template,gateway" ["service-formular2mail"]="color:1d76db;context:formular2mail;usage:service_templates,integration" ["service-sagjan"]="color:1d76db;context:sagjan;usage:service_templates,integration" ["service-newsletter"]="color:ff6b6b;context:newsletter;usage:service_templates,integration" ["work-in-progress"]="color:fbca04;context:active;usage:status_updates" ["needs-review"]="color:0e8a16;context:review;usage:status_updates" ["hugo-integration"]="color:ff7518;context:frontend;usage:hugo_templates,integration" ["api-contract"]="color:5319e7;context:api_design;usage:api_templates,service_templates" ["breaking-change"]="color:d73a4a;context:breaking;usage:api_templates,architecture" ["high-priority"]="color:d73a4a;context:urgent;usage:all_templates" ["low-tech"]="color:6f42c1;context:low_tech_principle;usage:all_templates" ["digital-sovereignty"]="color:6f42c1;context:digital_sovereignty;usage:all_templates" ) # Extract label info get_label_color() { echo "${LABEL_DEFINITIONS[$1]}" | cut -d';' -f1 | cut -d':' -f2; } get_label_context() { echo "${LABEL_DEFINITIONS[$1]}" | cut -d';' -f2 | cut -d':' -f2; } get_label_usage() { echo "${LABEL_DEFINITIONS[$1]}" | cut -d';' -f3 | cut -d':' -f2; } # Check if label is valid for context is_label_valid_for_context() { local label="$1" local context="$2" local usage=$(get_label_usage "$label") [[ "$usage" == *"$context"* ]] || [[ "$usage" == "all_templates" ]] } # === LABEL DEFINITIONS END === # === TEMPLATE LABEL MAPPINGS START === # Auto-generated template to label mappings declare -A TEMPLATE_LABELS=( ["service"]="service-request,enhancement,gateway,service-formular2mail,service-sagjan,service-newsletter,api-contract,high-priority,low-tech,digital-sovereignty" ["architecture"]="enhancement,gateway,performance,architecture,security,breaking-change,high-priority,low-tech,digital-sovereignty" ["performance"]="enhancement,gateway,performance,architecture,high-priority,low-tech,digital-sovereignty" ["bug"]="bug,enhancement,gateway,service-formular2mail,service-sagjan,service-newsletter,work-in-progress,needs-review,high-priority,low-tech,digital-sovereignty" ["security"]="security,gateway,enhancement,high-priority,low-tech,digital-sovereignty" ["hugo"]="hugo-integration,enhancement,gateway,service-formular2mail,service-sagjan,service-newsletter,api-contract,high-priority,low-tech,digital-sovereignty" ["api"]="api-contract,service-request,enhancement,gateway,service-formular2mail,service-sagjan,service-newsletter,breaking-change,high-priority,low-tech,digital-sovereignty" ["deployment"]="enhancement,gateway,service-formular2mail,service-sagjan,service-newsletter,high-priority,low-tech,digital-sovereignty" ) # === TEMPLATE LABEL MAPPINGS END === # Load existing labels from repository declare -A LABEL_IDS load_existing_labels() { if [[ -z "${GITEA_URL:-}" ]] || [[ -z "${GITEA_TOKEN:-}" ]]; then log_error "GITEA_URL and GITEA_TOKEN must be set" exit 1 fi log_info "Loading existing labels from repository..." local response=$(curl -s "$GITEA_URL/api/v1/repos/$REPO_OWNER/$REPO_NAME/labels" \ -H "Authorization: token $GITEA_TOKEN") if [[ $? -ne 0 ]]; then log_error "Failed to fetch labels from repository" exit 1 fi while IFS= read -r line; do local name=$(echo "$line" | jq -r '.name') local id=$(echo "$line" | jq -r '.id') LABEL_IDS["$name"]="$id" done < <(echo "$response" | jq -c '.[]') log_info "Loaded ${#LABEL_IDS[@]} existing labels" } # FIXED: Silent version of ensure_label_exists (no stdout pollution!) ensure_label_exists_silent() { local name="$1" local color="${2:-ff6b6b}" local description="${3:-Auto-generated label}" if [[ -n "${LABEL_IDS[$name]:-}" ]]; then return 0 fi # Create label (redirect output to prevent stdout mixing) local response=$(curl -s -w "\n%{http_code}" -X POST \ "$GITEA_URL/api/v1/repos/$REPO_OWNER/$REPO_NAME/labels" \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"name\": \"$name\", \"color\": \"$color\", \"description\": \"$description\" }" 2>/dev/null) local http_code=$(echo "$response" | tail -n1) local response_body=$(echo "$response" | head -n -1) if [[ "$http_code" == "201" ]]; then local new_id=$(echo "$response_body" | jq -r '.id') LABEL_IDS["$name"]="$new_id" # FIXED: Track for auto-update (but don't log here!) NEW_LABELS_CREATED["$name"]="$color:auto_generated:all_templates" return 0 else return 1 fi } # FIXED: Build labels JSON for API calls (handles unknown labels!) build_labels_json() { local template="$1" shift local additional_labels=("$@") # Get template labels local template_labels_string="${TEMPLATE_LABELS[$template]:-}" local all_labels=() # Add template labels if [[ -n "$template_labels_string" ]]; then IFS=',' read -ra template_labels <<< "$template_labels_string" all_labels+=("${template_labels[@]}") fi # Add additional labels all_labels+=("${additional_labels[@]}") # FIXED: Ensure all labels exist and collect IDs (handles unknown labels!) local label_ids=() for label in "${all_labels[@]}"; do # Process both known and unknown labels if [[ -n "${LABEL_DEFINITIONS[$label]:-}" ]]; then # Known label - use defined color and context local color=$(get_label_color "$label") local context=$(get_label_context "$label") ensure_label_exists_silent "$label" "$color" "Furt: $context" else # FIXED: Unknown label - auto-create with smart defaults local default_color="ff6b6b" local default_context="auto_generated" # Smart defaults based on label pattern if [[ "$label" == service-* ]]; then default_color="1d76db" default_context="service_integration" elif [[ "$label" == *-priority ]]; then default_color="d73a4a" default_context="priority_level" elif [[ "$label" == hugo-* ]]; then default_color="ff7518" default_context="frontend_integration" fi ensure_label_exists_silent "$label" "$default_color" "Furt: $default_context" fi # Collect ID if label was created/exists if [[ -n "${LABEL_IDS[$label]:-}" ]]; then label_ids+=("${LABEL_IDS[$label]}") fi done # Build JSON array (clean output only!) if [[ ${#label_ids[@]} -gt 0 ]]; then printf '[%s]' "$(IFS=','; echo "${label_ids[*]}")" else echo "[]" fi } # Show which labels are being used (AFTER JSON building to avoid stdout pollution) show_labels_used() { local template="$1" shift local additional_labels=("$@") log_info "Labels used for this issue:" # Show template labels local template_labels_string="${TEMPLATE_LABELS[$template]:-}" if [[ -n "$template_labels_string" ]]; then IFS=',' read -ra template_labels <<< "$template_labels_string" for label in "${template_labels[@]}"; do if [[ -n "${LABEL_IDS[$label]:-}" ]]; then log_info " โœ… $label (ID: ${LABEL_IDS[$label]})" fi done fi # Show additional labels for label in "${additional_labels[@]}"; do if [[ -n "${LABEL_IDS[$label]:-}" ]]; then log_info " โœ… $label (ID: ${LABEL_IDS[$label]}) [NEW!]" fi done } # FIXED: AUTO-UPDATE with safe array handling auto_update_scripts_if_needed() { # FIXED: Safe check for empty associative array local new_labels_count=0 if [[ "${#NEW_LABELS_CREATED[@]}" -gt 0 ]] 2>/dev/null; then new_labels_count=${#NEW_LABELS_CREATED[@]} fi if [[ $new_labels_count -eq 0 ]]; then return 0 # No new labels, no update needed fi log_info "๐Ÿ”„ Auto-updating scripts with $new_labels_count new labels..." # Add new labels to registry for label_name in "${!NEW_LABELS_CREATED[@]}"; do local label_info="${NEW_LABELS_CREATED[$label_name]}" local color=$(echo "$label_info" | cut -d':' -f1) local context=$(echo "$label_info" | cut -d':' -f2) local usage=$(echo "$label_info" | cut -d':' -f3) log_info "Adding '$label_name' to registry..." # Add to registry (suppressing output to avoid noise) FURT_AUTO_UPDATE=true "$SCRIPT_DIR/update_script_labels.sh" add "$label_name" "$color" "$context" "$usage" >/dev/null 2>&1 || true done # Update all scripts with new labels log_info "Synchronizing all scripts..." "$SCRIPT_DIR/update_script_labels.sh" update >/dev/null 2>&1 || true log_success "โœ… All scripts automatically synchronized with new labels!" # Show what was added echo "" echo "๐Ÿ†• New labels created and synchronized:" for label_name in "${!NEW_LABELS_CREATED[@]}"; do echo " - $label_name (ID: ${LABEL_IDS[$label_name]})" done echo "" } # Create issue templates create_service_issue() { local service_name="${1:-newsletter}" local title="[SERVICE] $service_name fรผr Furt Gateway" local body="# Service-Request: $service_name ## ๐Ÿท๏ธ Service-Details **Name:** $service_name **Port:** TBD **Zweck:** [Service-Beschreibung] ## ๐Ÿ“ Funktionsanforderungen - [ ] [Anforderung 1] - [ ] [Anforderung 2] - [ ] [Anforderung 3] ## ๐Ÿ”— Gateway-Integration - [ ] **Routing:** \`/v1/$service_name/*\` - [ ] **Auth:** API-Key required - [ ] **Rate-Limiting:** TBD req/min - [ ] **Health-Check:** \`/health\` ## ๐ŸŽฏ Hugo-Integration - [ ] **Shortcode:** \`{{< furt-$service_name >}}\` - [ ] **JavaScript-Client** - [ ] **CSS-Styling** ## โšก Prioritรคt ๐Ÿ”ฅ **Hoch** - benรถtigt fรผr Website-Launch" # FIXED: Build labels JSON (clean, no stdout pollution) with additional service label local labels_json=$(build_labels_json "service" "service-$service_name") # Show which labels are being used (AFTER JSON building) show_labels_used "service" "service-$service_name" create_issue "$title" "$body" "$labels_json" } create_architecture_issue() { local topic="${1:-middleware-optimization}" local title="[ARCH] Gateway $topic" local body="# Architektur-Diskussion: $topic ## ๐ŸŽฏ Architektur-Thema [Beschreibung des Architektur-Themas] ## ๐Ÿ“Š Aktuelle Situation - [Status Quo 1] - [Status Quo 2] ## ๐Ÿ’ก Vorgeschlagene ร„nderung - [Vorschlag 1] - [Vorschlag 2] ## ๐Ÿ”„ Alternativen 1. **Option A:** [Beschreibung] 2. **Option B:** [Beschreibung] ## ๐Ÿ“ˆ Betroffene Bereiche - [ ] Gateway-Performance - [ ] Service-Integration - [ ] Security - [ ] Configuration-Management" local labels_json=$(build_labels_json "architecture") create_issue "$title" "$body" "$labels_json" } # Generic issue creation create_issue() { local title="$1" local body="$2" local labels_json="$3" log_info "Creating issue: $title" local response=$(curl -s -w "\n%{http_code}" -X POST \ "$GITEA_URL/api/v1/repos/$REPO_OWNER/$REPO_NAME/issues" \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"title\": $(echo "$title" | jq -R .), \"body\": $(echo "$body" | jq -R -s .), \"labels\": $labels_json }") local http_code=$(echo "$response" | tail -n1) local response_body=$(echo "$response" | head -n -1) if [[ "$http_code" == "201" ]]; then local issue_number=$(echo "$response_body" | jq -r '.number') local issue_url=$(echo "$response_body" | jq -r '.html_url') log_success "Issue #$issue_number created!" echo "๐Ÿ”— $issue_url" else log_error "Failed to create issue (HTTP: $http_code)" log_error "Response: $response_body" exit 1 fi } # Show usage information show_usage() { echo "๐ŸŽฏ Furt API-Gateway Issue Creator" echo "" echo "Usage: $0 [TEMPLATE] [OPTIONS]" echo "" echo "๐Ÿ“‹ Available Templates:" echo " service [name] New service for gateway (default: newsletter)" echo " architecture [topic] Gateway architecture discussion (default: middleware-optimization)" echo " performance [comp] Performance optimization (default: gateway)" echo " api [service] API contract update (default: formular2mail)" echo " security [comp] Security review/issue (default: gateway)" echo " bug [comp] [desc] Bug report (default: gateway)" echo " hugo [feature] Hugo integration (default: shortcode)" echo " deployment [comp] Deployment issue (default: gateway)" echo " custom Custom issue (interactive)" echo "" echo "๐Ÿš€ Examples:" echo " $0 service newsletter # Create newsletter service request" echo " $0 architecture rate-limiting # Discuss rate limiting architecture" echo " $0 performance gateway # Gateway performance optimization" echo " $0 custom # Interactive custom issue" } # Main function main() { local template="${1:-help}" if [[ "$template" == "help" ]] || [[ "$template" == "--help" ]] || [[ "$template" == "-h" ]]; then show_usage exit 0 fi # Load existing labels load_existing_labels case "$template" in service) create_service_issue "${2:-newsletter}" ;; architecture) create_architecture_issue "${2:-middleware-optimization}" ;; performance) local component="${2:-gateway}" local title="[PERF] $component Performance-Optimierung" local body="# Performance-Optimierung: $component" local labels_json=$(build_labels_json "performance") create_issue "$title" "$body" "$labels_json" ;; *) log_error "Unknown template: $template" show_usage exit 1 ;; esac # FIXED: AUTO-UPDATE: Automatically sync scripts if new labels were created auto_update_scripts_if_needed } # Run if executed directly if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi