Formatting #78
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, mvp-0.0.1-snapshot ] | |
| pull_request: | |
| branches: [ main, mvp-0.0.1-snapshot ] | |
| env: | |
| JAVA_OPTS: -Xmx4G -XX:+UseG1GC | |
| SBT_OPTS: -Xmx4G -XX:+UseG1GC | |
| jobs: | |
| build: | |
| strategy: | |
| matrix: | |
| include: | |
| - module: core | |
| commands: > | |
| scalafmtCheckAll "scalafixAll --check" core/test compile-fail-tests/test | |
| paths: | | |
| target | |
| modules/core/target | |
| modules/compile-fail-tests/target | |
| - module: connectors | |
| commands: > | |
| scalafmtCheckAll "scalafixAll --check" connectors/test connectors-gcs/test | |
| paths: | | |
| target | |
| modules/connectors/target | |
| modules/connectors-gcs/target | |
| - module: engines | |
| commands: > | |
| scalafmtCheckAll "scalafixAll --check" engines-spark/test engines-flink/test "engines-spark/testOnly *StreamingCDCSpec" "engines-flink/testOnly *EngineAbstractionSpec" | |
| paths: | | |
| target | |
| modules/engines-spark/target | |
| modules/engines-flink/target | |
| name: ${{ matrix.module }} | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: '21' | |
| - name: Cache SBT and dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.ivy2/cache | |
| ~/.cache/coursier | |
| ~/.sbt | |
| ${{ matrix.paths }} | |
| key: ${{ runner.os }}-sbt-${{ matrix.module }}-${{ hashFiles('**/build.sbt', '**/project/**/*.sbt', format('modules/{0}/**', matrix.module)) }} | |
| restore-keys: | | |
| ${{ runner.os }}-sbt-${{ matrix.module }}- | |
| - name: Build module | |
| run: sbt -batch ${{ matrix.commands }} | |
| refactor-lint: | |
| name: Refactor lint & Unsafe cast gate | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: '21' | |
| - name: Cache Ivy and Coursier | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.ivy2/cache | |
| ~/.cache/coursier | |
| ~/.sbt | |
| key: ${{ runner.os }}-sbt-${{ hashFiles('**/build.sbt', '**/project/**/*.sbt', '**/.scalafix.conf') }} | |
| restore-keys: | | |
| ${{ runner.os }}-sbt- | |
| - name: Scalafix check (no rewrites) | |
| continue-on-error: true | |
| run: sbt -batch "scalafixAll --check" | |
| - name: Scalafmt check | |
| run: sbt -batch "scalafmtCheckAll" | |
| - name: Cast/Any CI gate | |
| shell: bash | |
| run: | | |
| echo "🔍 Enforcing no asInstanceOf/Any in main sources (with whitelist)" | |
| # Whitelist files where reflective casts are intentionally localized | |
| WHITELIST=( | |
| "modules/engines-spark/src/main/scala/com/flowforge/engines/spark/SparkDataAlgebra.scala" | |
| "modules/core/src/main/scala/com/flowforge/core/contracts/internal/SchemaConformsMacros.scala" | |
| ) | |
| is_whitelisted() { | |
| local f="$1" | |
| for w in "${WHITELIST[@]}"; do | |
| if [[ "$f" == "$w" ]]; then return 0; fi | |
| done | |
| return 1 | |
| } | |
| FAILURES=() | |
| while IFS= read -r -d '' file; do | |
| if is_whitelisted "$file"; then continue; fi | |
| if rg -n "\\basInstanceOf\\b" "$file" >/dev/null; then | |
| FAILURES+=("$file: asInstanceOf usage") | |
| fi | |
| # Explicit Any in type positions (heuristic, avoids matching 'any' words) | |
| if rg -n "(:|\bval\b|\bdef\b|\btype\b)[^\n]*\bAny\b" "$file" >/dev/null; then | |
| FAILURES+=("$file: explicit Any type") | |
| fi | |
| done < <(find modules -type f -path "*/src/main/*" -name "*.scala" -print0) | |
| if ((${#FAILURES[@]} > 0)); then | |
| echo "❌ FAIL: Unsafe patterns detected outside whitelist:" >&2 | |
| printf '%s\n' "${FAILURES[@]}" >&2 | |
| exit 1 | |
| fi | |
| echo "✅ PASS: No unsafe asInstanceOf/Any found outside whitelist" | |
| - name: Try/Try-catch/unsafeRunSync bans (main sources only) | |
| shell: bash | |
| run: | | |
| echo "🔍 Enforcing ADR-022 try/Try bans and unsafeRunSync in main sources" | |
| set -euo pipefail | |
| FAIL=0 | |
| # Search only in main sources; allow tests/examples | |
| MAPFILE=() | |
| while IFS= read -r -d '' f; do MAPFILE+=("$f"); done < <(find modules -type f -path "*/src/main/scala/*" -name "*.scala" -print0) | |
| # Whitelist specific files that may reference scala.util.Try for API surface | |
| WHITELIST=( | |
| "modules/core/src/main/scala/com/flowforge/core/safety/Safety.scala" | |
| "modules/core/src/main/scala/com/flowforge/core/package.scala" | |
| ) | |
| is_whitelisted() { | |
| local f="$1" | |
| for w in "${WHITELIST[@]}"; do [[ "$f" == "$w" ]] && return 0; done | |
| return 1 | |
| } | |
| if rg -n "\btry\s*\{" "${MAPFILE[@]}"; then echo "❌ try { found in main sources"; FAIL=1; fi | |
| # Scan for scala.util.Try excluding whitelist | |
| while IFS= read -r line; do | |
| file=$(echo "$line" | awk -F: '{print $1}') | |
| if is_whitelisted "$file"; then continue; fi | |
| echo "❌ scala.util.Try found in $file"; FAIL=1 | |
| done < <(rg -n "\\bscala\\.util\\.Try\\b" "${MAPFILE[@]}" || true) | |
| if rg -n "unsafeRunSync" "${MAPFILE[@]}"; then echo "❌ unsafeRunSync found in main sources"; FAIL=1; fi | |
| if [[ "$FAIL" -ne 0 ]]; then exit 1; fi | |
| echo "✅ PASS: No banned patterns in main sources" | |
| spark-it: | |
| if: github.event_name == 'workflow_dispatch' | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: '21' | |
| - name: Cache Ivy and Coursier | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.ivy2/cache | |
| ~/.cache/coursier | |
| ~/.sbt | |
| key: ${{ runner.os }}-sbt-${{ hashFiles('**/build.sbt', '**/project/**/*.sbt', '**/project/**/Dependencies.scala') }} | |
| restore-keys: | | |
| ${{ runner.os }}-sbt- | |
| - name: Run opt-in Spark/Delta ITs | |
| run: | | |
| sbt -batch -DwithSparkIT=true "enginesSpark/testOnly *SparkDeltaSCD2IT" |