diff --git a/configs/labels.registry b/configs/labels.registry new file mode 100644 index 0000000..65c49f0 --- /dev/null +++ b/configs/labels.registry @@ -0,0 +1,49 @@ +#!/bin/bash +# config/labels.registry +# Central Label Registry for Furt API Gateway Project +# Format: name:color:context:usage_contexts +# This file is the single source of truth for all labels + +# === CORE WORKFLOW LABELS === +service-request:7057ff:new_service:service_templates,status_updates +enhancement:84b6eb:improvement:all_templates +bug:d73a4a:error:bug_template,status_updates +question:d876e3:discussion:question_template + +# === COMPONENT CATEGORIES === +gateway:0052cc:gateway_core:architecture,performance,service_templates +performance:fbca04:optimization:performance_template,architecture +architecture:d4c5f9:design:architecture_template,gateway +security:28a745:security_review:security_template,gateway +configuration:f9d71c:config_management:deployment,architecture + +# === SERVICE-SPECIFIC LABELS === +service-formular2mail:1d76db:formular2mail:service_templates,integration +service-sagjan:1d76db:sagjan:service_templates,integration +service-newsletter:ff6b6b:newsletter:service_templates,integration + +# === WORKFLOW STATE LABELS === +work-in-progress:fbca04:active:status_updates +needs-review:0e8a16:review:status_updates +blocked:d73a4a:blocked:status_updates +ready-for-deployment:28a745:deploy_ready:status_updates + +# === INTEGRATION LABELS === +hugo-integration:ff7518:frontend:hugo_templates,integration +api-contract:5319e7:api_design:api_templates,service_templates +breaking-change:d73a4a:breaking:api_templates,architecture + +# === PRIORITY LABELS === +high-priority:d73a4a:urgent:all_templates +low-priority:0e8a16:nice_to_have:all_templates + +# === META LABELS === +low-tech:6f42c1:low_tech_principle:all_templates +digital-sovereignty:6f42c1:digital_sovereignty:all_templates +good-first-issue:7057ff:beginner_friendly:all_templates +help-wanted:159818:community_help:all_templates + +# === DEPLOYMENT LABELS === +deployment:ff7518:deployment:deployment_template +testing:f9d71c:testing:testing_template,integration +documentation:0366d6:docs:documentation_template \ No newline at end of file diff --git a/scripts/create_issue.sh b/scripts/create_issue.sh index 1de0f5c..773a5c0 100755 --- a/scripts/create_issue.sh +++ b/scripts/create_issue.sh @@ -1,19 +1,15 @@ #!/bin/bash +# scripts/create_issue.sh - Furt API Gateway Issue Creator +# FINAL VERSION with all fixes: HTTP 422, stdout-mixing, array handling, unknown labels -# Load environment -if [ -f .env ]; then - export $(cat .env | grep -v '^#' | xargs) -else - echo "❌ .env file not found!" - echo "📋 Copy .env.example to .env and configure it first" - exit 1 -fi +set -euo pipefail -# Validate required variables -if [ -z "$GITEA_URL" ] || [ -z "$REPO_OWNER" ] || [ -z "$REPO_NAME" ] || [ -z "$GITEA_TOKEN" ]; then - echo "❌ Missing required environment variables in .env" - echo "📋 Check .env.example for required variables" - exit 1 +# 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 @@ -28,320 +24,426 @@ log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } -# Get all labels with IDs (like update_issue.sh) +# 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 -get_labels() { - response=$(curl -s "$GITEA_URL/api/v1/repos/$REPO_OWNER/$REPO_NAME/labels" \ + +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 - name=$(echo "$line" | jq -r '.name') - id=$(echo "$line" | jq -r '.id') + 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" } -# Function to create issue with proper label ID handling -create_issue() { - local title="$1" - local body="$2" - local labels_string="$3" - local assignee="$4" +# 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}" - # Get label IDs first - get_labels + if [[ -n "${LABEL_IDS[$name]:-}" ]]; then + return 0 + fi - # Convert label names to IDs - local valid_label_ids=() - if [ -n "$labels_string" ]; then - IFS=',' read -ra LABEL_ARRAY <<< "$labels_string" + # 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" - for label in "${LABEL_ARRAY[@]}"; do - label=$(echo "$label" | xargs) # Trim whitespace - if [ -n "${LABEL_IDS[$label]}" ]; then - valid_label_ids+=("${LABEL_IDS[$label]}") - log_info "Using label '$label' (ID: ${LABEL_IDS[$label]})" - else - log_warning "Label '$label' not found, skipping" + # 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 - # Build labels array JSON with IDs - local labels_json="[" - for i in "${!valid_label_ids[@]}"; do - if [ $i -gt 0 ]; then - labels_json="${labels_json}," + # Show additional labels + for label in "${additional_labels[@]}"; do + if [[ -n "${LABEL_IDS[$label]:-}" ]]; then + log_info " ✅ $label (ID: ${LABEL_IDS[$label]}) [NEW!]" fi - labels_json="${labels_json}${valid_label_ids[$i]}" done - labels_json="${labels_json}]" - - # Build assignees array - local assignees_json="[]" - if [ -n "$assignee" ]; then - assignees_json="[\"$assignee\"]" - fi - - # Use jq for proper JSON encoding of body and payload - local json_payload=$(jq -n \ - --arg title "$title" \ - --arg body "$body" \ - --argjson labels "$labels_json" \ - --argjson assignees "$assignees_json" \ - '{ - title: $title, - body: $body, - labels: $labels, - assignees: $assignees - }') - - log_info "Creating issue: $title" - - 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 "$json_payload") - - http_code=$(echo "$response" | tail -n1) - response_body=$(echo "$response" | head -n -1) - - if [ "$http_code" = "201" ]; then - issue_number=$(echo "$response_body" | jq -r '.number') - issue_url="$GITEA_URL/$REPO_OWNER/$REPO_NAME/issues/$issue_number" - log_success "Issue #$issue_number created!" - echo "🔗 $issue_url" - echo "" - else - log_error "Failed to create issue (HTTP: $http_code)" - echo "$response_body" - fi } -# Predefined issue templates for Furt API Gateway -case "${1:-help}" in - "service") - service_name="${2:-newsletter}" - create_issue \ - "[SERVICE] $service_name für Furt Gateway" \ - "## 🏷️ Service-Details -**Name:** $service_name -**Port:** 808X (TBD) -**Zweck:** [Service-Beschreibung hier einfügen] +# 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 -- [ ] Grundfunktionalität implementieren -- [ ] Input-Validation für alle Endpunkte -- [ ] Error-Handling nach Furt-Standards -- [ ] Health-Check-Endpoint (\`/health\`) +- [ ] [Anforderung 1] +- [ ] [Anforderung 2] +- [ ] [Anforderung 3] ## 🔗 Gateway-Integration - [ ] **Routing:** \`/v1/$service_name/*\` -- [ ] **Authentication:** API-Key required -- [ ] **Rate-Limiting:** [X] requests/minute -- [ ] **Upstream:** \`http://127.0.0.1:808X\` -- [ ] **Timeout:** 15s default +- [ ] **Auth:** API-Key required +- [ ] **Rate-Limiting:** TBD req/min +- [ ] **Health-Check:** \`/health\` -## 🎯 API-Endpunkte (geplant) -\`\`\` -GET /v1/$service_name/ # List/Status -POST /v1/$service_name/create # Create new -PUT /v1/$service_name/{id} # Update existing -DELETE /v1/$service_name/{id} # Delete -\`\`\` - -## 🧪 Testing-Requirements -- [ ] Unit-Tests für Service-Logik -- [ ] Integration-Tests für Gateway ↔ Service -- [ ] API-Contract-Tests (OpenAPI-Compliance) -- [ ] Load-Tests für Performance-Baselines - -## 🌐 Hugo-Integration -- [ ] Shortcode: \`{{< furt-$service_name >}}\` -- [ ] JavaScript-Client-Library -- [ ] CSS-Styling für UI-Komponenten -- [ ] Dokumentation für Website-Integration - -## 📋 OpenAPI-Dokumentation -- [ ] \`docs/api/services/$service_name.yaml\` erstellen -- [ ] Request/Response-Schemas definieren -- [ ] Error-Codes dokumentieren -- [ ] Examples für alle Endpunkte +## 🎯 Hugo-Integration +- [ ] **Shortcode:** \`{{< furt-$service_name >}}\` +- [ ] **JavaScript-Client** +- [ ] **CSS-Styling** ## ⚡ Priorität -📊 Mittel - geplante Entwicklung +🔥 **Hoch** - benötigt für Website-Launch" -## 🔧 Implementation-Checklist -- [ ] Service-Generator ausführen: \`./scripts/service-generator.sh $service_name\` -- [ ] Service-Logik implementieren -- [ ] Gateway-Integration konfigurieren -- [ ] Tests schreiben und ausführen -- [ ] Deployment-Scripts anpassen -- [ ] Hugo-Integration entwickeln" \ - "service-request,enhancement" \ - "${DEFAULT_ASSIGNEE:-}" - ;; + # FIXED: Build labels JSON (clean, no stdout pollution) with additional service label + local labels_json=$(build_labels_json "service" "service-$service_name") - "architecture") - topic="${2:-middleware-optimization}" - create_issue \ - "[ARCH] Gateway $topic" \ - "## 🎯 Architektur-Thema -Gateway-$topic für bessere Performance/Maintainability + # 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 -**Current Implementation:** -- [Beschreibung des aktuellen Zustands] -- [Identifizierte Probleme oder Limitations] -- [Performance-Metrics wenn verfügbar] +- [Status Quo 1] +- [Status Quo 2] ## 💡 Vorgeschlagene Änderung -**Proposed Solution:** -- [Detaillierte Beschreibung der vorgeschlagenen Lösung] -- [Erwartete Verbesserungen] -- [Implementation-Approach] +- [Vorschlag 1] +- [Vorschlag 2] ## 🔄 Alternativen 1. **Option A:** [Beschreibung] - - Vorteile: [...] - - Nachteile: [...] - -2. **Option B:** [Beschreibung] - - Vorteile: [...] - - Nachteile: [...] +2. **Option B:** [Beschreibung] ## 📈 Betroffene Bereiche - [ ] Gateway-Performance -- [ ] Service-Integration -- [ ] Security (Auth/Rate-Limiting) -- [ ] Configuration-Management -- [ ] Monitoring/Logging -- [ ] Hugo-Integration +- [ ] Service-Integration +- [ ] Security +- [ ] Configuration-Management" -## 🧪 Testing-Impact -- [ ] Unit-Tests anpassen -- [ ] Integration-Tests erweitern -- [ ] Performance-Tests durchführen -- [ ] Backward-Compatibility prüfen - -## 📋 Implementation-Plan -1. **Phase 1:** [Erste Schritte] -2. **Phase 2:** [Hauptimplementierung] -3. **Phase 3:** [Testing und Optimization] -4. **Phase 4:** [Deployment und Monitoring] - -## ⚡ Priorität -🔥 Hoch - kritisch für Projekt-Erfolg" \ - "architecture,gateway,enhancement" \ - "${DEFAULT_ASSIGNEE:-}" - ;; + local labels_json=$(build_labels_json "architecture") - "performance") - component="${2:-gateway}" - create_issue \ - "[PERF] $component Performance-Optimierung" \ - "## 📊 Performance-Problem -**Component:** $component -**Issue:** [Beschreibung des Performance-Problems] + create_issue "$title" "$body" "$labels_json" +} -## 🔍 Gemessene Werte -**Current Performance:** -- **Response Time:** [X]ms average -- **Throughput:** [X] requests/second -- **Resource Usage:** [X]% CPU, [X]MB Memory -- **Error Rate:** [X]% under load - -**Target Performance:** -- **Response Time:** <[Y]ms -- **Throughput:** >[Y] requests/second -- **Resource Usage:** <[Y]% CPU, <[Y]MB Memory -- **Error Rate:** <[Y]% under normal load - -## 🎯 Performance-Ziele -- [ ] **Latency-Optimization:** Reduce response time by [X]% -- [ ] **Throughput-Increase:** Handle [X]x more concurrent requests -- [ ] **Resource-Efficiency:** Reduce CPU/Memory usage -- [ ] **Scalability:** Support [X] services without degradation - -## 🔍 Profiling-Results -**Current Bottlenecks:** -\`\`\` -[Paste go-pprof results oder performance measurements] -\`\`\` - -**Identified Issues:** -- [Issue 1]: [Description] -- [Issue 2]: [Description] -- [Issue 3]: [Description] - -## 🛠️ Optimization-Strategy -1. **Code-Optimization:** - - [Specific code changes] - - [Algorithm improvements] - -2. **Infrastructure-Optimization:** - - [Connection pooling] - - [Caching strategies] - -3. **Configuration-Tuning:** - - [Timeout adjustments] - - [Buffer size optimization] - -## 🧪 Performance-Testing-Plan -- [ ] **Baseline-Measurements:** Before optimization -- [ ] **Load-Testing:** Various traffic patterns -- [ ] **Stress-Testing:** Breaking point analysis -- [ ] **Endurance-Testing:** Long-running stability -- [ ] **Regression-Testing:** Ensure no functionality broken - -## 📋 Success-Criteria -- [ ] Target response time achieved -- [ ] Target throughput achieved -- [ ] Resource usage within limits -- [ ] No regressions in functionality -- [ ] Monitoring alerts configured - -## ⚡ Priorität -🔥 Hoch - Performance ist kritisch" \ - "performance,optimization,$component" \ - "${DEFAULT_ASSIGNEE:-}" - ;; +# Generic issue creation +create_issue() { + local title="$1" + local body="$2" + local labels_json="$3" - # Weitere templates hier... (gekürzt für Übersichtlichkeit) + log_info "Creating issue: $title" - "custom") - echo "🎯 Custom Furt Issue Creator" - echo "" - read -p "📝 Title: " title - echo "📋 Body (press Ctrl+D when finished):" - body=$(cat) - read -p "🏷️ Labels (comma separated): " labels - read -p "👤 Assignee (optional): " assignee + 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') - create_issue "$title" "$body" "$labels" "${assignee:-$DEFAULT_ASSIGNEE}" - ;; - - *) - 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" - ;; -esac + 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 diff --git a/scripts/update_script_labels.sh b/scripts/update_script_labels.sh new file mode 100755 index 0000000..730b295 --- /dev/null +++ b/scripts/update_script_labels.sh @@ -0,0 +1,451 @@ +#!/bin/bash +# scripts/update_script_labels.sh +# Auto-updates all scripts with current label definitions from registry +# COMPLETE VERSION with all integration fixes + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +REGISTRY_FILE="$PROJECT_ROOT/config/labels.registry" + +# Colors for logging +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"; } + +# Parse label registry into associative arrays +declare -A LABEL_COLORS +declare -A LABEL_CONTEXTS +declare -A LABEL_USAGES + +# Create registry file if it doesn't exist +create_registry_if_missing() { + if [[ ! -f "$REGISTRY_FILE" ]]; then + log_info "Creating label registry file..." + + mkdir -p "$(dirname "$REGISTRY_FILE")" + + cat > "$REGISTRY_FILE" << 'EOF' +# Central Label Registry for Furt API Gateway Project +# Format: name:color:context:usage_contexts +# This file is the single source of truth for all labels + +# === CORE WORKFLOW LABELS === +service-request:7057ff:new_service:service_templates,status_updates +enhancement:84b6eb:improvement:all_templates +bug:d73a4a:error:bug_template,status_updates +question:d876e3:discussion:question_template + +# === COMPONENT CATEGORIES === +gateway:0052cc:gateway_core:architecture,performance,service_templates +performance:fbca04:optimization:performance_template,architecture +architecture:d4c5f9:design:architecture_template,gateway +security:28a745:security_review:security_template,gateway +configuration:f9d71c:config_management:deployment,architecture + +# === SERVICE-SPECIFIC LABELS === +service-formular2mail:1d76db:formular2mail:service_templates,integration +service-sagjan:1d76db:sagjan:service_templates,integration +service-newsletter:ff6b6b:newsletter:service_templates,integration + +# === WORKFLOW STATE LABELS === +work-in-progress:fbca04:active:status_updates +needs-review:0e8a16:review:status_updates +blocked:d73a4a:blocked:status_updates +ready-for-deployment:28a745:deploy_ready:status_updates + +# === INTEGRATION LABELS === +hugo-integration:ff7518:frontend:hugo_templates,integration +api-contract:5319e7:api_design:api_templates,service_templates +breaking-change:d73a4a:breaking:api_templates,architecture + +# === PRIORITY LABELS === +high-priority:d73a4a:urgent:all_templates +low-priority:0e8a16:nice_to_have:all_templates + +# === META LABELS === +low-tech:6f42c1:low_tech_principle:all_templates +digital-sovereignty:6f42c1:digital_sovereignty:all_templates +good-first-issue:7057ff:beginner_friendly:all_templates +help-wanted:159818:community_help:all_templates + +# === DEPLOYMENT LABELS === +deployment:ff7518:deployment:deployment_template +testing:f9d71c:testing:testing_template,integration +documentation:0366d6:docs:documentation_template +EOF + + log_success "Created label registry: $REGISTRY_FILE" + fi +} + +parse_registry() { + create_registry_if_missing + + log_info "Parsing label registry..." + + while IFS= read -r line; do + # Skip comments and empty lines + [[ "$line" =~ ^#.*$ ]] && continue + [[ -z "$line" ]] && continue + + # Parse format: name:color:context:usage_contexts + if [[ "$line" =~ ^([^:]+):([^:]+):([^:]+):(.+)$ ]]; then + local name="${BASH_REMATCH[1]}" + local color="${BASH_REMATCH[2]}" + local context="${BASH_REMATCH[3]}" + local usage="${BASH_REMATCH[4]}" + + LABEL_COLORS["$name"]="$color" + LABEL_CONTEXTS["$name"]="$context" + LABEL_USAGES["$name"]="$usage" + + log_info "Loaded label: $name ($context)" + fi + done < "$REGISTRY_FILE" + + log_success "Loaded ${#LABEL_COLORS[@]} labels from registry" +} + +# Generate label definitions section for scripts +generate_label_definitions() { + cat << 'EOF' +# === 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=( +EOF + + for label in "${!LABEL_COLORS[@]}"; do + local color="${LABEL_COLORS[$label]}" + local context="${LABEL_CONTEXTS[$label]}" + local usage="${LABEL_USAGES[$label]}" + + echo " [\"$label\"]=\"color:$color;context:$context;usage:$usage\"" + done + + cat << 'EOF' +) + +# 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 === +EOF +} + +# Generate template-to-labels mapping +generate_template_mappings() { + cat << 'EOF' + +# === TEMPLATE LABEL MAPPINGS START === +# Auto-generated template to label mappings +declare -A TEMPLATE_LABELS=( +EOF + + # Generate mappings based on usage contexts + for template in "service_templates" "architecture" "performance_template" "bug_template" "security_template" "hugo_templates" "api_templates" "deployment_template"; do + local labels=() + for label in "${!LABEL_USAGES[@]}"; do + local usage="${LABEL_USAGES[$label]}" + if [[ "$usage" == *"$template"* ]] || [[ "$usage" == "all_templates" ]]; then + labels+=("$label") + fi + done + + if [[ ${#labels[@]} -gt 0 ]]; then + local label_list=$(IFS=','; echo "${labels[*]}") + echo " [\"${template%_*}\"]=\"$label_list\"" + fi + done + + cat << 'EOF' +) +# === TEMPLATE LABEL MAPPINGS END === +EOF +} + +# Generate filter options for get_issues.sh +generate_filter_options() { + cat << 'EOF' + +# === FILTER OPTIONS START === +# Auto-generated filter options for get_issues.sh +show_filter_help() { + echo "📋 Available filters:" +EOF + + # Group labels by context for better help display + declare -A context_labels + for label in "${!LABEL_CONTEXTS[@]}"; do + local context="${LABEL_CONTEXTS[$label]}" + if [[ -z "${context_labels[$context]}" ]]; then + context_labels[$context]="$label" + else + context_labels[$context]="${context_labels[$context]},$label" + fi + done + + for context in "${!context_labels[@]}"; do + echo " echo \" $context: ${context_labels[$context]}\"" + done + + cat << 'EOF' +} + +# Filter case statement +handle_filter() { + local filter="$1" + case "$filter" in +EOF + + for label in "${!LABEL_COLORS[@]}"; do + echo " $label) filter_by_label \"$label\" ;;" + done + + cat << 'EOF' + pipeline) show_pipeline_overview ;; + stats) show_statistics ;; + all) show_all_issues ;; + *) + log_error "Unknown filter: $filter" + show_filter_help + exit 1 + ;; + esac +} +# === FILTER OPTIONS END === +EOF +} + +# Update a single script file +update_script_file() { + local script_file="$1" + + if [[ ! -f "$script_file" ]]; then + log_warning "Script not found: $script_file" + return 1 + fi + + log_info "Updating $script_file..." + + # Create backup + cp "$script_file" "${script_file}.backup" + + # Check if script has label definition sections + if ! grep -q "# === LABEL DEFINITIONS START ===" "$script_file"; then + log_warning "$script_file has no label definitions section - skipping" + return 0 + fi + + # Find section boundaries + local start_line=$(grep -n "# === LABEL DEFINITIONS START ===" "$script_file" | cut -d: -f1) + local end_line=$(grep -n "# === LABEL DEFINITIONS END ===" "$script_file" | cut -d: -f1) + + if [[ -z "$start_line" ]] || [[ -z "$end_line" ]]; then + log_error "Malformed label definition section in $script_file" + return 1 + fi + + # Generate new content + local new_definitions=$(generate_label_definitions) + + # Handle template mappings if present + if grep -q "# === TEMPLATE LABEL MAPPINGS START ===" "$script_file"; then + new_definitions+="\n$(generate_template_mappings)" + fi + + # Handle filter options if present (for get_issues.sh) + if grep -q "# === FILTER OPTIONS START ===" "$script_file"; then + new_definitions+="\n$(generate_filter_options)" + fi + + # Create temporary file with updated content + local temp_file=$(mktemp) + + # Copy everything before label definitions + sed -n "1,$((start_line-1))p" "$script_file" > "$temp_file" + + # Add new definitions + echo -e "$new_definitions" >> "$temp_file" + + # Copy everything after label definitions (find new end line) + if grep -q "# === TEMPLATE LABEL MAPPINGS END ===" "$script_file"; then + local actual_end_line=$(grep -n "# === TEMPLATE LABEL MAPPINGS END ===" "$script_file" | cut -d: -f1) + elif grep -q "# === FILTER OPTIONS END ===" "$script_file"; then + local actual_end_line=$(grep -n "# === FILTER OPTIONS END ===" "$script_file" | cut -d: -f1) + else + local actual_end_line="$end_line" + fi + + sed -n "$((actual_end_line+1)),\$p" "$script_file" >> "$temp_file" + + # Replace original file + mv "$temp_file" "$script_file" + chmod +x "$script_file" + + log_success "Updated $script_file" +} + +# Add new label to registry +add_label_to_registry() { + local name="$1" + local color="${2:-ff6b6b}" + local context="${3:-auto_generated}" + local usage="${4:-all_templates}" + + # Skip if called during auto-update to prevent loops + if [[ "${FURT_AUTO_UPDATE:-}" == "true" ]]; then + return 0 + fi + + log_info "Adding new label to registry: $name" + + # Ensure registry exists + create_registry_if_missing + + # Check if label already exists + if grep -q "^$name:" "$REGISTRY_FILE"; then + log_warning "Label $name already exists in registry" + return 0 + fi + + # Add to appropriate section (determine by context) + local section_marker="# === CORE WORKFLOW LABELS ===" + if [[ "$context" == *"service"* ]]; then + section_marker="# === SERVICE-SPECIFIC LABELS ===" + elif [[ "$context" == *"workflow"* ]]; then + section_marker="# === WORKFLOW STATE LABELS ===" + elif [[ "$context" == *"component"* ]]; then + section_marker="# === COMPONENT CATEGORIES ===" + fi + + # Create backup + cp "$REGISTRY_FILE" "${REGISTRY_FILE}.backup" + + # Find section and add label + local temp_file=$(mktemp) + local added=false + + while IFS= read -r line; do + echo "$line" >> "$temp_file" + + if [[ "$line" == "$section_marker" ]] && [[ "$added" == false ]]; then + echo "$name:$color:$context:$usage" >> "$temp_file" + added=true + log_success "Added label $name to registry" + fi + done < "$REGISTRY_FILE" + + mv "$temp_file" "$REGISTRY_FILE" +} + +# Show current registry status +show_registry_status() { + echo "📊 Label Registry Status" + echo "========================" + echo "Registry file: $REGISTRY_FILE" + echo "Total labels: $(grep -c "^[^#]" "$REGISTRY_FILE" 2>/dev/null || echo 0)" + echo "" + echo "Labels by category:" + + local current_section="" + while IFS= read -r line; do + if [[ "$line" =~ ^#\ ===.*===\ $ ]]; then + current_section=$(echo "$line" | sed 's/# === \(.*\) ===/\1/') + echo " $current_section:" + elif [[ "$line" =~ ^[^#]+: ]] && [[ -n "$current_section" ]]; then + local label_name=$(echo "$line" | cut -d: -f1) + echo " - $label_name" + fi + done < "$REGISTRY_FILE" +} + +# Main function +main() { + local command="${1:-update}" + + case "$command" in + update) + log_info "Starting label synchronization..." + parse_registry + + # Update all script files + local scripts=( + "$PROJECT_ROOT/scripts/create_issue.sh" + "$PROJECT_ROOT/scripts/get_issues.sh" + "$PROJECT_ROOT/scripts/update_issue.sh" + ) + + for script in "${scripts[@]}"; do + update_script_file "$script" + done + + log_success "All scripts synchronized with label registry!" + ;; + + add) + local name="$2" + local color="${3:-ff6b6b}" + local context="${4:-auto_generated}" + local usage="${5:-all_templates}" + + if [[ -z "$name" ]]; then + log_error "Usage: $0 add [color] [context] [usage]" + exit 1 + fi + + add_label_to_registry "$name" "$color" "$context" "$usage" + parse_registry + main update + ;; + + status) + show_registry_status + ;; + + help) + echo "Usage: $0 [command] [options]" + echo "" + echo "Commands:" + echo " update Update all scripts with current registry" + echo " add Add new label to registry and update scripts" + echo " status Show registry status" + echo " help Show this help" + echo "" + echo "Examples:" + echo " $0 update" + echo " $0 add newsletter ff6b6b newsletter_service service_templates" + echo " $0 status" + ;; + + *) + log_error "Unknown command: $command" + main help + exit 1 + ;; + esac +} + +# Run if executed directly +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + main "$@" +fi +