un-inception/scripts/generate-matrix.sh
russell@unturf.com cdb1be4b35 fix(ci): Cleanup orphaned test services before fan-out
Adds cleanup-services stage to child pipeline that destroys any
existing test services before the 42-language parallel test matrix
runs. Prevents concurrency limit failures from orphaned services.
2026-01-19 06:22:16 -05:00

133 lines
3.3 KiB
Bash
Executable file

#!/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 services before fan-out to avoid concurrency limits
cleanup-services:
stage: cleanup
needs:
- build-cli
script:
- echo "Cleaning up orphaned test services..."
- |
SERVICES=$(build/un service --list 2>/dev/null | grep -oE 'unsb-service-[a-f0-9]+' || true)
if [ -n "$SERVICES" ]; then
for SVC in $SERVICES; do
echo "Destroying orphan: $SVC"
build/un service --destroy "$SVC" || true
done
echo "Cleanup complete"
else
echo "No orphaned services found"
fi
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