fix: SWITCH task no longer falls through to defaultCase when matched case is empty #4310
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths-ignore: | |
| - "conductor-clients/**" | |
| pull_request: | |
| paths-ignore: | |
| - "conductor-clients/**" | |
| workflow_dispatch: | |
| inputs: | |
| redis_es8: | |
| description: "Redis + Elasticsearch 8" | |
| type: boolean | |
| default: true | |
| postgres: | |
| description: "PostgreSQL" | |
| type: boolean | |
| default: false | |
| mysql: | |
| description: "MySQL" | |
| type: boolean | |
| default: false | |
| redis_os3: | |
| description: "Redis + OpenSearch 3" | |
| type: boolean | |
| default: false | |
| redis_es7: | |
| description: "Redis + Elasticsearch 7" | |
| type: boolean | |
| default: false | |
| cassandra_es7: | |
| description: "Cassandra + Elasticsearch 7" | |
| type: boolean | |
| default: false | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| fetch-depth: 0 | |
| - name: Free disk space | |
| run: | | |
| sudo rm -rf /usr/share/dotnet | |
| sudo rm -rf /usr/local/lib/android | |
| sudo rm -rf /opt/ghc | |
| - name: Gradle wrapper validation | |
| uses: gradle/wrapper-validation-action@v3 | |
| - name: Set up Zulu JDK 21 | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: "zulu" | |
| java-version: "21" | |
| - name: Cache SonarCloud packages | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.sonar/cache | |
| key: ${{ runner.os }}-sonar | |
| restore-keys: ${{ runner.os }}-sonar | |
| - name: Cache Gradle packages | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.gradle/caches | |
| ~/.gradle/wrapper | |
| key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | |
| restore-keys: ${{ runner.os }}-gradle- | |
| - name: Force Docker API Version | |
| run: echo 'api.version=1.44' > ~/.docker-java.properties | |
| - name: Cache Docker images | |
| uses: actions/cache@v5 | |
| id: docker-cache | |
| with: | |
| path: /tmp/docker-images-build.tar | |
| key: docker-build-v2 | |
| - name: Load cached Docker images | |
| if: steps.docker-cache.outputs.cache-hit == 'true' | |
| run: docker load -i /tmp/docker-images-build.tar || true | |
| - name: Build with Gradle | |
| if: github.ref != 'refs/heads/main' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
| run: | | |
| ./gradlew build -x :conductor-test-harness:test --scan | |
| - name: Build and Publish snapshot | |
| if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' | |
| run: | | |
| echo "Running build for commit ${{ github.sha }}" | |
| ./gradlew build -x :conductor-test-harness:test | |
| - name: Save Docker images for cache | |
| if: steps.docker-cache.outputs.cache-hit != 'true' | |
| run: | | |
| set -euo pipefail | |
| docker image prune -f | |
| mapfile -t images < <((docker images --format '{{.Repository}}:{{.Tag}}' \ | |
| | grep -v '<none>' \ | |
| | grep -E '(^|/)(elasticsearch|redis|postgres|mysql|mongo|cassandra)(:|/)|mockserver/mockserver|opensearchproject/opensearch|testcontainers/|orkesio/') || true) | |
| if [ "${#images[@]}" -eq 0 ]; then | |
| echo "No Testcontainers-related images to cache; writing empty tar for cache action." | |
| tar -cf /tmp/docker-images-build.tar --files-from /dev/null | |
| exit 0 | |
| fi | |
| printf '%s\n' "${images[@]}" | |
| docker save -o /tmp/docker-images-build.tar "${images[@]}" | |
| - name: Generate aggregated coverage report | |
| if: always() | |
| run: ./gradlew jacocoAggregatedReport -x test || true | |
| - name: Publish Test Report | |
| uses: mikepenz/action-junit-report@v6 | |
| if: always() | |
| with: | |
| report_paths: "**/build/test-results/test/TEST-*.xml" | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: build-artifacts | |
| path: "**/build/reports" | |
| - name: Upload coverage report | |
| uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: coverage-report | |
| path: build/reports/jacoco/aggregated | |
| - name: Store Buildscan URL | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: build-scan | |
| path: "buildscan.log" | |
| test-harness: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| fetch-depth: 0 | |
| - name: Free disk space | |
| run: | | |
| sudo rm -rf /usr/share/dotnet | |
| sudo rm -rf /usr/local/lib/android | |
| sudo rm -rf /opt/ghc | |
| - name: Set up Zulu JDK 21 | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: "zulu" | |
| java-version: "21" | |
| - name: Cache Gradle packages | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.gradle/caches | |
| ~/.gradle/wrapper | |
| key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | |
| restore-keys: ${{ runner.os }}-gradle- | |
| - name: Force Docker API Version | |
| run: echo 'api.version=1.44' > ~/.docker-java.properties | |
| - name: Cache Docker images | |
| uses: actions/cache@v5 | |
| id: docker-cache | |
| with: | |
| path: /tmp/docker-images-test-harness.tar | |
| key: docker-test-harness-v2 | |
| - name: Load cached Docker images | |
| if: steps.docker-cache.outputs.cache-hit == 'true' | |
| run: docker load -i /tmp/docker-images-test-harness.tar || true | |
| - name: Run test-harness tests | |
| run: | | |
| ./gradlew :conductor-test-harness:test | |
| - name: Save Docker images for cache | |
| if: steps.docker-cache.outputs.cache-hit != 'true' | |
| run: | | |
| set -euo pipefail | |
| docker image prune -f | |
| mapfile -t images < <((docker images --format '{{.Repository}}:{{.Tag}}' \ | |
| | grep -v '<none>' \ | |
| | grep -E '(^|/)(elasticsearch|redis|postgres|mysql|mongo|cassandra)(:|/)|mockserver/mockserver|opensearchproject/opensearch|testcontainers/|orkesio/') || true) | |
| if [ "${#images[@]}" -eq 0 ]; then | |
| echo "No Testcontainers-related images to cache; writing empty tar for cache action." | |
| tar -cf /tmp/docker-images-test-harness.tar --files-from /dev/null | |
| exit 0 | |
| fi | |
| printf '%s\n' "${images[@]}" | |
| docker save -o /tmp/docker-images-test-harness.tar "${images[@]}" | |
| - name: Publish Test Report | |
| uses: mikepenz/action-junit-report@v6 | |
| if: always() | |
| with: | |
| report_paths: "test-harness/build/test-results/test/TEST-*.xml" | |
| - name: Upload test-harness reports | |
| uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: test-harness-reports | |
| path: "test-harness/build/reports" | |
| - name: Upload test-harness coverage report | |
| uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: test-harness-coverage-report | |
| path: "test-harness/build/reports/jacoco" | |
| generate-e2e-matrix: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.set-matrix.outputs.matrix }} | |
| steps: | |
| - id: set-matrix | |
| shell: bash | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| items="" | |
| [ "${{ inputs.redis_es8 }}" = "true" ] && items="${items}{\"name\":\"redis-es8\",\"script\":\"./e2e/run_tests-es8.sh\"}," | |
| [ "${{ inputs.postgres }}" = "true" ] && items="${items}{\"name\":\"postgres\",\"script\":\"./e2e/run_tests-postgres.sh\"}," | |
| [ "${{ inputs.mysql }}" = "true" ] && items="${items}{\"name\":\"mysql\",\"script\":\"./e2e/run_tests-mysql.sh\"}," | |
| [ "${{ inputs.redis_os3 }}" = "true" ] && items="${items}{\"name\":\"redis-os3\",\"script\":\"./e2e/run_tests-redis-os3.sh\"}," | |
| [ "${{ inputs.redis_es7 }}" = "true" ] && items="${items}{\"name\":\"redis-es7\",\"script\":\"./e2e/run_tests-redis-es7.sh\"}," | |
| [ "${{ inputs.cassandra_es7 }}" = "true" ] && items="${items}{\"name\":\"cassandra-es7\",\"script\":\"./e2e/run_tests-cassandra-es7.sh\"}," | |
| items="${items%,}" | |
| echo "matrix={\"include\":[${items}]}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo 'matrix={"include":[{"name":"redis-es8","script":"./e2e/run_tests-es8.sh"}]}' >> "$GITHUB_OUTPUT" | |
| fi | |
| e2e: | |
| needs: generate-e2e-matrix | |
| if: ${{ needs.generate-e2e-matrix.outputs.matrix != '{"include":[]}' }} | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJson(needs.generate-e2e-matrix.outputs.matrix) }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| fetch-depth: 0 | |
| - name: Free disk space | |
| run: | | |
| sudo rm -rf /usr/share/dotnet | |
| sudo rm -rf /usr/local/lib/android | |
| sudo rm -rf /opt/ghc | |
| - name: Set up Zulu JDK 21 | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: "zulu" | |
| java-version: "21" | |
| - name: Cache Gradle packages | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.gradle/caches | |
| ~/.gradle/wrapper | |
| key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} | |
| restore-keys: ${{ runner.os }}-gradle- | |
| - name: Run E2E tests (${{ matrix.name }}) | |
| run: ${{ matrix.script }} | |
| - name: Publish Test Report | |
| uses: mikepenz/action-junit-report@v6 | |
| if: always() | |
| with: | |
| report_paths: "e2e/build/test-results/test/TEST-*.xml" | |
| - name: Generate test summary table | |
| if: always() | |
| shell: python3 {0} | |
| run: | | |
| import os, glob, xml.etree.ElementTree as ET | |
| xml_files = glob.glob("e2e/build/test-results/test/TEST-*.xml") | |
| rows = [] | |
| totals = {"passed": 0, "failed": 0, "skipped": 0} | |
| for f in sorted(xml_files): | |
| try: | |
| root = ET.parse(f).getroot() | |
| except ET.ParseError: | |
| continue | |
| for tc in root.iter("testcase"): | |
| name = tc.get("name", "?") | |
| classname = tc.get("classname", "").split(".")[-1] | |
| duration = float(tc.get("time", 0)) | |
| if tc.find("skipped") is not None: | |
| status, totals["skipped"] = "⏭ skip", totals["skipped"] + 1 | |
| elif tc.find("failure") is not None or tc.find("error") is not None: | |
| node = tc.find("failure") if tc.find("failure") is not None else tc.find("error") | |
| msg = (node.get("message") or "")[:120] | |
| status, totals["failed"] = f"❌ `{msg}`", totals["failed"] + 1 | |
| else: | |
| status, totals["passed"] = "✅", totals["passed"] + 1 | |
| rows.append((classname, name, f"{duration:.1f}s", status)) | |
| backend = "${{ matrix.name }}" | |
| lines = [ | |
| f"## E2E results — {backend}", | |
| f"**✅ {totals['passed']} passed · ❌ {totals['failed']} failed · ⏭ {totals['skipped']} skipped**", | |
| "", | |
| "| Class | Test | Duration | Result |", | |
| "|-------|------|----------|--------|", | |
| ] | |
| for cls, name, dur, status in rows: | |
| lines.append(f"| {cls} | {name} | {dur} | {status} |") | |
| summary = os.environ.get("GITHUB_STEP_SUMMARY", "/dev/null") | |
| with open(summary, "a") as fh: | |
| fh.write("\n".join(lines) + "\n") | |
| - name: Upload E2E reports | |
| uses: actions/upload-artifact@v6 | |
| if: always() | |
| with: | |
| name: e2e-reports-${{ matrix.name }} | |
| path: "e2e/build/reports" | |
| build-ui: | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: ui | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" | |
| cache: "yarn" | |
| cache-dependency-path: ui/yarn.lock | |
| - name: Install Dependencies | |
| run: yarn install | |
| - name: Build UI | |
| run: yarn run build | |
| - name: Cache Playwright browsers | |
| uses: actions/cache@v4 | |
| id: playwright-cache | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: playwright-chromium-${{ hashFiles('ui/yarn.lock') }} | |
| - name: Install Playwright browsers | |
| if: steps.playwright-cache.outputs.cache-hit != 'true' | |
| run: npx playwright install --with-deps chromium | |
| - name: Install Playwright browser deps (cached) | |
| if: steps.playwright-cache.outputs.cache-hit == 'true' | |
| run: npx playwright install-deps chromium | |
| - name: Run Playwright E2E Tests | |
| run: yarn test:e2e | |
| - name: Upload Playwright report | |
| uses: actions/upload-artifact@v6 | |
| if: failure() | |
| with: | |
| name: playwright-report | |
| path: ui/playwright-report | |
| retention-days: 7 |