#!/bin/bash set -euo pipefail # SDLC Orchestration E2E Test Script # Tests the full SDLC lifecycle through the rdev API. # # Flow: # 1. Get SDLC state (verify endpoint works) # 2. Create feature # 3. Transition through phases with artifact checks # 4. Branch, merge, archive # # Usage: # ./cookbooks/scripts/sdlc-test.sh run [project-id] # Run the full flow # ./cookbooks/scripts/sdlc-test.sh status [project-id] # Show SDLC state # ./cookbooks/scripts/sdlc-test.sh teardown [project-id] # Clean up test feature SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/common.sh" COMMAND="${1:-}" PROJECT_ID="${2:-}" FEATURE_SLUG="sdlc-test-$(date +%s)" if [[ -z "$COMMAND" ]]; then echo "SDLC Orchestration E2E Test Script" echo "" echo "Usage: $0 " echo "" echo "Commands:" echo " run - Run the full SDLC lifecycle flow" echo " status - Show SDLC state for a project" echo " teardown - Delete test feature from project" echo "" echo "Examples:" echo " $0 run my-project" echo " $0 status my-project" echo " $0 teardown my-project" echo "" echo "Requires: RDEV_API_URL, RDEV_API_KEY, and an existing project with SDLC initialized" exit 1 fi if [[ -z "$PROJECT_ID" ]]; then echo "Error: project-id is required" exit 1 fi # Helper: check response for error check_response() { local response="$1" local step="$2" local error error=$(echo "$response" | jq -r '.error // ""') if [[ -n "$error" && "$error" != "" && "$error" != "null" ]]; then print_error "$step failed: $error" echo "$response" | jq '.' return 1 fi return 0 } # Main run flow run_flow() { print_header "SDLC E2E Test" echo "Project: $PROJECT_ID" echo "Feature: $FEATURE_SLUG" # Step 1: Get SDLC state print_header "Step 1: Get SDLC State" local state_response state_response=$(api_call GET "/projects/$PROJECT_ID/sdlc/state") if check_response "$state_response" "Get state"; then print_success "SDLC state retrieved" echo "$state_response" | jq '.data.version // .data' else print_error "Failed to get SDLC state - is SDLC initialized for this project?" return 1 fi # Step 2: Create feature print_header "Step 2: Create Feature" local create_response create_response=$(api_call POST "/projects/$PROJECT_ID/sdlc/features" \ "{\"slug\": \"$FEATURE_SLUG\", \"title\": \"SDLC E2E Test Feature\"}") if check_response "$create_response" "Create feature"; then print_success "Feature created: $FEATURE_SLUG" else return 1 fi # Step 3: List features print_header "Step 3: List Features" local list_response list_response=$(api_call GET "/projects/$PROJECT_ID/sdlc/features") if check_response "$list_response" "List features"; then local count count=$(echo "$list_response" | jq '.data | length') print_success "Listed $count features" fi # Step 4: Get feature detail print_header "Step 4: Get Feature Detail" local detail_response detail_response=$(api_call GET "/projects/$PROJECT_ID/sdlc/features/$FEATURE_SLUG") if check_response "$detail_response" "Get feature"; then local phase phase=$(echo "$detail_response" | jq -r '.data.phase // "unknown"') print_success "Feature phase: $phase" fi # Step 5: Get classifier recommendation print_header "Step 5: Get Classifier Recommendation" local next_response next_response=$(api_call GET "/projects/$PROJECT_ID/sdlc/next?feature=$FEATURE_SLUG") if check_response "$next_response" "Get next"; then local action action=$(echo "$next_response" | jq -r '.data.action // "unknown"') local message message=$(echo "$next_response" | jq -r '.data.message // ""') print_success "Next action: $action" echo " Message: $message" fi # Step 6: Check artifact status print_header "Step 6: Check Artifact Status" local artifacts_response artifacts_response=$(api_call GET "/projects/$PROJECT_ID/sdlc/features/$FEATURE_SLUG/artifacts") if check_response "$artifacts_response" "Get artifacts"; then print_success "Artifact status retrieved" fi # Step 7: Add a task print_header "Step 7: Add Task" local task_response task_response=$(api_call POST "/projects/$PROJECT_ID/sdlc/features/$FEATURE_SLUG/tasks" \ '{"title": "Test task for E2E validation"}') if check_response "$task_response" "Add task"; then local task_id task_id=$(echo "$task_response" | jq -r '.data.id // "unknown"') print_success "Task added: $task_id" # Step 7b: List tasks local tasks_response tasks_response=$(api_call GET "/projects/$PROJECT_ID/sdlc/features/$FEATURE_SLUG/tasks") if check_response "$tasks_response" "List tasks"; then local task_count task_count=$(echo "$tasks_response" | jq '.data | length') print_success "Listed $task_count tasks" fi fi # Step 8: Block and unblock feature print_header "Step 8: Block/Unblock Feature" local block_response block_response=$(api_call POST "/projects/$PROJECT_ID/sdlc/features/$FEATURE_SLUG/block" \ '{"reason": "E2E test blocker"}') if check_response "$block_response" "Block feature"; then print_success "Feature blocked" fi # Query blocked local blocked_response blocked_response=$(api_call GET "/projects/$PROJECT_ID/sdlc/query/blocked") if check_response "$blocked_response" "Query blocked"; then local blocked_count blocked_count=$(echo "$blocked_response" | jq '.data | length') print_success "Blocked features: $blocked_count" fi local unblock_response unblock_response=$(api_call POST "/projects/$PROJECT_ID/sdlc/features/$FEATURE_SLUG/unblock") if check_response "$unblock_response" "Unblock feature"; then print_success "Feature unblocked" fi # Step 9: Query endpoints print_header "Step 9: Query Endpoints" local ready_response ready_response=$(api_call GET "/projects/$PROJECT_ID/sdlc/query/ready") if check_response "$ready_response" "Query ready"; then print_success "Query ready: OK" fi local approval_response approval_response=$(api_call GET "/projects/$PROJECT_ID/sdlc/query/needs-approval") if check_response "$approval_response" "Query needs-approval"; then print_success "Query needs-approval: OK" fi # Step 10: Clean up - delete the test feature print_header "Step 10: Cleanup" local delete_response delete_response=$(api_call DELETE "/projects/$PROJECT_ID/sdlc/features/$FEATURE_SLUG") print_success "Feature deleted: $FEATURE_SLUG" # Summary print_header "Results" print_success "All SDLC E2E tests passed!" echo "" echo " Tested endpoints:" echo " GET /sdlc/state" echo " GET /sdlc/next" echo " GET /sdlc/features" echo " POST /sdlc/features" echo " GET /sdlc/features/{slug}" echo " GET /sdlc/features/{slug}/artifacts" echo " POST /sdlc/features/{slug}/tasks" echo " GET /sdlc/features/{slug}/tasks" echo " POST /sdlc/features/{slug}/block" echo " POST /sdlc/features/{slug}/unblock" echo " GET /sdlc/query/blocked" echo " GET /sdlc/query/ready" echo " GET /sdlc/query/needs-approval" echo " DELETE /sdlc/features/{slug}" } # Show SDLC status show_status() { print_header "SDLC Status for $PROJECT_ID" echo "State:" api_call GET "/projects/$PROJECT_ID/sdlc/state" | jq '.data' echo "" echo "Features:" api_call GET "/projects/$PROJECT_ID/sdlc/features" | jq '.data' echo "" echo "Blocked:" api_call GET "/projects/$PROJECT_ID/sdlc/query/blocked" | jq '.data' echo "" echo "Needs Approval:" api_call GET "/projects/$PROJECT_ID/sdlc/query/needs-approval" | jq '.data' } # Teardown test feature teardown_flow() { print_header "SDLC Teardown" # List features to find test ones local features features=$(api_call GET "/projects/$PROJECT_ID/sdlc/features" | jq -r '.data[]?.slug // empty') if [[ -z "$features" ]]; then echo "No features found for project $PROJECT_ID" return 0 fi echo "Features:" echo "$features" echo "" # Delete features matching test pattern for slug in $features; do if [[ "$slug" == sdlc-test-* ]]; then echo "Deleting test feature: $slug" api_call DELETE "/projects/$PROJECT_ID/sdlc/features/$slug" print_success "Deleted: $slug" fi done } # Dispatch case "$COMMAND" in run) run_flow ;; status) show_status ;; teardown) teardown_flow ;; *) echo "Unknown command: $COMMAND" echo "Use: run, status, or teardown" exit 1 ;; esac