- Add AUTO_TEARDOWN env var and --auto-teardown flag to cookbook scripts - Scripts automatically delete created projects on exit (including Ctrl+C) - Add DELETE /projects/cleanup API endpoint for bulk cleanup - Supports shell-style glob patterns (e.g., "tree-test-*") - Includes dry_run mode and older_than_hours filter for safety - Requires admin scope for actual deletion - Update cookbook scripts: landing-test, composable-test, template-validation, feature-test, tree-runner Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
214 lines
6.1 KiB
Bash
Executable File
214 lines
6.1 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Landing Page Cookbook Test Script
|
|
# Tests the composable landing page flow from cookbooks/landing-page.md
|
|
#
|
|
# Flow:
|
|
# 1. Create project (monorepo skeleton)
|
|
# 2. Add app-astro component
|
|
# 3. Wait for CI pipeline
|
|
# 4. Verify site is live
|
|
#
|
|
# Usage:
|
|
# ./cookbooks/scripts/landing-test.sh run [name] # Run the full flow
|
|
# ./cookbooks/scripts/landing-test.sh status [name] # Check current status
|
|
# ./cookbooks/scripts/landing-test.sh diagnose [name] # Deep diagnostic analysis
|
|
# ./cookbooks/scripts/landing-test.sh teardown [name] # Clean up test resources
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
source "$SCRIPT_DIR/common.sh"
|
|
|
|
# Parse --auto-teardown flag from args
|
|
ARGS=("$@")
|
|
for i in "${!ARGS[@]}"; do
|
|
if [[ "${ARGS[$i]}" == "--auto-teardown" ]]; then
|
|
AUTO_TEARDOWN="true"
|
|
unset 'ARGS[$i]'
|
|
fi
|
|
done
|
|
ARGS=("${ARGS[@]}") # Re-index array
|
|
|
|
COMMAND="${ARGS[0]:-}"
|
|
PROJECT_NAME="${ARGS[1]:-landing-test-$(date +%s)}"
|
|
|
|
# Register cleanup trap for auto-teardown
|
|
register_cleanup_trap
|
|
|
|
if [[ -z "$COMMAND" ]]; then
|
|
echo "Landing Page E2E Test Script"
|
|
echo ""
|
|
echo "Usage: $0 <command> [project-name]"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " run - Run the full composable landing page flow"
|
|
echo " status - Check project and component status"
|
|
echo " diagnose - Deep diagnostic of pipeline and site issues"
|
|
echo " teardown - Delete project (preserves git repo)"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " $0 run my-landing"
|
|
echo " $0 status my-landing"
|
|
echo " $0 diagnose my-landing"
|
|
echo " $0 teardown my-landing"
|
|
echo ""
|
|
exit 1
|
|
fi
|
|
|
|
# Main run flow
|
|
run_flow() {
|
|
print_header "Landing Page E2E Test (Composable)"
|
|
echo "Project: $PROJECT_NAME"
|
|
|
|
# Step 1: Create project (monorepo skeleton)
|
|
print_header "Step 1: Creating project skeleton"
|
|
|
|
local create_response
|
|
create_response=$(api_call POST "/project" "{\"name\": \"$PROJECT_NAME\", \"description\": \"Landing page E2E test\"}")
|
|
echo "$create_response" | jq '.'
|
|
|
|
local domain
|
|
domain=$(echo "$create_response" | jq -r '.data.domain // ""')
|
|
|
|
if [[ -z "$domain" || "$domain" == "null" ]]; then
|
|
print_error "Failed to create project"
|
|
exit 1
|
|
fi
|
|
|
|
# Track project for auto-cleanup
|
|
CLEANUP_PROJECT="$PROJECT_NAME"
|
|
|
|
print_success "Project created: $PROJECT_NAME"
|
|
echo " Domain: $domain"
|
|
echo " Git: https://git.threesix.ai/$(get_git_owner)/$PROJECT_NAME"
|
|
|
|
# Step 2: Add app-astro component
|
|
print_header "Step 2: Adding landing page component (app-astro)"
|
|
|
|
local component_response
|
|
component_response=$(api_call POST "/projects/$PROJECT_NAME/components" '{"type": "app-astro", "name": "landing", "template": "app-astro"}')
|
|
|
|
local component_path
|
|
component_path=$(echo "$component_response" | jq -r '.data.path // ""')
|
|
|
|
if [[ -z "$component_path" || "$component_path" == "null" ]]; then
|
|
print_error "Failed to add component"
|
|
echo "$component_response" | jq '.'
|
|
exit 1
|
|
fi
|
|
|
|
local component_port
|
|
component_port=$(echo "$component_response" | jq -r '.data.port // "N/A"')
|
|
|
|
print_success "Component added: $component_path (port: $component_port)"
|
|
|
|
# Step 3: Wait for pipeline (auto-diagnoses on failure)
|
|
print_header "Step 3: Waiting for CI pipeline"
|
|
if ! wait_for_pipeline "$PROJECT_NAME"; then
|
|
print_warning "Pipeline failed, continuing to check site..."
|
|
fi
|
|
|
|
# Step 4: Wait for site (auto-diagnoses on timeout)
|
|
print_header "Step 4: Verifying site is accessible"
|
|
if ! wait_for_site "$domain" 30 5 "$PROJECT_NAME"; then
|
|
print_error "Site not accessible"
|
|
exit 1
|
|
fi
|
|
|
|
# Summary
|
|
print_header "Test Complete"
|
|
print_success "Project created: $PROJECT_NAME"
|
|
print_success "Landing page deployed"
|
|
echo ""
|
|
echo "Site URL: https://$domain"
|
|
echo "Git repo: https://git.threesix.ai/$(get_git_owner)/$PROJECT_NAME"
|
|
echo "CI: https://ci.threesix.ai/$(get_git_owner)/$PROJECT_NAME"
|
|
echo ""
|
|
echo "To customize: POST /projects/$PROJECT_NAME/builds with a prompt"
|
|
echo "To teardown: $0 teardown $PROJECT_NAME"
|
|
}
|
|
|
|
# Check status
|
|
check_status() {
|
|
print_header "Project Status: $PROJECT_NAME"
|
|
|
|
echo "Project:"
|
|
api_call GET "/project/$PROJECT_NAME" | jq '.data // .'
|
|
echo ""
|
|
|
|
echo "Components:"
|
|
api_call GET "/projects/$PROJECT_NAME/components" | jq '.data // .'
|
|
echo ""
|
|
|
|
echo "Latest Pipelines:"
|
|
api_call GET "/projects/$PROJECT_NAME/pipelines" | jq '.data[:3] // .'
|
|
}
|
|
|
|
# Deep diagnostic
|
|
diagnose() {
|
|
print_header "Diagnostic: $PROJECT_NAME"
|
|
|
|
# Get project info for domain
|
|
local project
|
|
project=$(api_call GET "/project/$PROJECT_NAME")
|
|
|
|
local domain
|
|
domain=$(echo "$project" | jq -r '.data.domain // ""')
|
|
|
|
if [[ -z "$domain" || "$domain" == "null" ]]; then
|
|
print_error "Project not found or no domain assigned"
|
|
echo "$project" | jq '.'
|
|
return 1
|
|
fi
|
|
|
|
echo "Project: $PROJECT_NAME"
|
|
echo "Domain: https://$domain"
|
|
echo "Git: https://git.threesix.ai/$(get_git_owner)/$PROJECT_NAME"
|
|
echo "CI: https://ci.threesix.ai/$(get_git_owner)/$PROJECT_NAME"
|
|
|
|
# Run pipeline diagnostics
|
|
diagnose_pipeline_failure "$PROJECT_NAME"
|
|
|
|
# Run site diagnostics
|
|
diagnose_site_failure "$domain" "$PROJECT_NAME"
|
|
|
|
print_header "Summary"
|
|
echo "To retry the pipeline:"
|
|
print_cmd "Push a commit to trigger CI, or manually trigger from Woodpecker UI"
|
|
echo ""
|
|
echo "To check real-time logs:"
|
|
print_cmd "kubectl logs -n projects -l app=$PROJECT_NAME -f"
|
|
}
|
|
|
|
# Teardown
|
|
teardown() {
|
|
print_header "Tearing down: $PROJECT_NAME"
|
|
|
|
local result
|
|
result=$(api_call DELETE "/project/$PROJECT_NAME")
|
|
echo "$result" | jq '.'
|
|
|
|
echo ""
|
|
print_success "Project deleted. Gitea repo preserved."
|
|
}
|
|
|
|
case "$COMMAND" in
|
|
run)
|
|
run_flow
|
|
;;
|
|
status)
|
|
check_status
|
|
;;
|
|
diagnose)
|
|
diagnose
|
|
;;
|
|
teardown)
|
|
teardown
|
|
;;
|
|
*)
|
|
echo "Unknown command: $COMMAND"
|
|
echo "Valid commands: run, status, diagnose, teardown"
|
|
exit 1
|
|
;;
|
|
esac
|