#!/bin/bash # Generate dynamic test matrix based on detected changes # Reads changes.json, outputs test-matrix.yml as a child pipeline config set -e # CRITICAL: Tags ALWAYS run full test matrix, no matter what if [ -n "$CI_COMMIT_TAG" ]; then echo "Tag detected ($CI_COMMIT_TAG) - forcing full test matrix" TEST_ALL="true" CHANGED_LANGS="" else # Read changes from detect-changes output CHANGES=$(cat changes.json) CHANGED_LANGS=$(echo "$CHANGES" | jq -r '.changed_langs[]' 2>/dev/null || echo "") TEST_ALL=$(echo "$CHANGES" | jq -r '.test_all' 2>/dev/null || echo "false") fi # Fetch ALL supported languages from the unsandbox API (the source of truth) ALL_SDKS=$(curl -s "https://api.unsandbox.com/languages" | jq -r '.languages[]' | tr '\n' ' ') if [ -z "$ALL_SDKS" ]; then # Fallback if API is unavailable ALL_SDKS="python javascript typescript ruby perl php lua bash go rust java kotlin c cpp" echo "Warning: Could not fetch languages from API, using fallback list" fi echo "Available SDKs from API: $ALL_SDKS" # Test ALL languages - the sandbox has compilers for compiled languages too! if [ "$TEST_ALL" = "true" ]; then LANGS="$ALL_SDKS" elif [ -z "$CHANGED_LANGS" ]; then # No changes - create minimal valid child pipeline that does nothing cat > test-matrix.yml << 'EOF' # No SDK changes detected - skip tests stages: - skip skip-tests: stage: skip tags: - build script: - echo "No SDK changes detected - skipping inception tests" EOF echo "No SDK changes - created skip pipeline" cat test-matrix.yml exit 0 else LANGS="$CHANGED_LANGS" fi # Count languages LANG_COUNT=$(echo $LANGS | wc -w) echo "Testing $LANG_COUNT languages: $LANGS" # Generate child pipeline config cat > test-matrix.yml << 'EOF' # Dynamically generated child pipeline - inception tests # Each test runs: build/un → unsandbox → SDK → unsandbox → test code stages: - build - cleanup - test default: tags: - build # CI variables inherited from parent pipeline build-cli: stage: build script: - bash scripts/build-clients.sh artifacts: paths: - build/ expire_in: 1 hour # Cleanup orphaned test resources before fan-out to avoid concurrency limits # ONLY targets resources with "test-" in the name to avoid destroying real services cleanup-services: stage: cleanup needs: - build-cli script: - echo "=== Cleaning up orphaned test resources ===" - | # Cleanup test services (test-python-*, test-javascript-*, etc.) echo "Checking for orphaned test services..." SERVICES=$(build/un service --list 2>/dev/null | grep -E "test-[a-z]+-[0-9]+" || true) if [ -n "$SERVICES" ]; then echo "$SERVICES" | while read -r line; do SVC=$(echo "$line" | grep -oE 'unsb-service-[a-f0-9]+' || true) if [ -n "$SVC" ]; then echo "Destroying test service: $SVC" build/un service --destroy "$SVC" || true fi done fi echo "Service cleanup complete" - | # Cleanup test sessions echo "Checking for orphaned test sessions..." SESSIONS=$(build/un session --list 2>/dev/null | grep -E "test-[a-z]+-[0-9]+" || true) if [ -n "$SESSIONS" ]; then echo "$SESSIONS" | while read -r line; do SESS=$(echo "$line" | grep -oE 'unsb-session-[a-f0-9-]+' || true) if [ -n "$SESS" ]; then echo "Killing test session: $SESS" build/un session --kill "$SESS" || true fi done fi echo "Session cleanup complete" - | # Cleanup test snapshots echo "Checking for orphaned test snapshots..." SNAPSHOTS=$(build/un snapshot --list 2>/dev/null | grep -E "test-[a-z]+-[0-9]+" || true) if [ -n "$SNAPSHOTS" ]; then echo "$SNAPSHOTS" | while read -r line; do SNAP=$(echo "$line" | grep -oE 'unsb-snapshot-[a-f0-9-]+' || true) if [ -n "$SNAP" ]; then echo "Deleting test snapshot: $SNAP" build/un snapshot --delete "$SNAP" || true fi done fi echo "Snapshot cleanup complete" - | # Cleanup test images echo "Checking for orphaned test images..." IMAGES=$(build/un image --list 2>/dev/null | grep -E "test-[a-z]+-[0-9]+" || true) if [ -n "$IMAGES" ]; then echo "$IMAGES" | while read -r line; do IMG=$(echo "$line" | grep -oE 'unsb-image-[a-f0-9-]+' || true) if [ -n "$IMG" ]; then echo "Deleting test image: $IMG" build/un image --delete "$IMG" || true fi done fi echo "Image cleanup complete" - echo "=== Cleanup complete ===" allow_failure: true test: stage: test needs: - build-cli - cleanup-services parallel: matrix: EOF # Add each language as a parallel job for LANG in $LANGS; do echo " - SDK_LANG: $LANG" >> test-matrix.yml done # Complete the test job template cat >> test-matrix.yml << 'EOF' script: - bash scripts/test-sdk.sh "$SDK_LANG" artifacts: reports: junit: "test-results-$SDK_LANG/test-results.xml" paths: - "test-results-$SDK_LANG/" expire_in: 30 days when: always allow_failure: true retry: 1 EOF echo "" echo "Generated test-matrix.yml with $LANG_COUNT parallel jobs:" cat test-matrix.yml