Merge pom_dlineage.xml into pom.xml, and make CI run the jar it build… #26
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: Build and test | |
| # These demos used to be a vendored tree inside the gsp_java library repo, whose | |
| # CI ran their tests via `mvn test -pl gsp_demo_java`. That tree has been | |
| # retired, so this workflow keeps the tests running rather than letting the | |
| # signal disappear with it. | |
| # | |
| # The parser is resolved from Gudu's public Maven repository, declared in | |
| # pom.xml, so nothing here needs credentials. | |
| on: | |
| push: | |
| branches: [master] | |
| pull_request: | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # The parser jar is Java 8 bytecode and the POM pins source/target 1.8. | |
| # Building on both proves the demos stay consumable from an old JDK and | |
| # keep compiling on a current LTS. | |
| java: ["8", "21"] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up JDK ${{ matrix.java }} | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: ${{ matrix.java }} | |
| cache: maven | |
| # The parser version is written in four files: the root property, and the | |
| # three connector modules, which are separate builds with no parent to | |
| # inherit from. Nothing used to make them agree, so a bump that missed one | |
| # left a connector silently building against an older parser. Use | |
| # .github/scripts/set-parser-version.sh <version> to move them. | |
| - name: Parser version is consistent across all POMs | |
| run: .github/scripts/set-parser-version.sh --check | |
| - name: Build | |
| run: mvn -B package -DskipTests | |
| # This used to tolerate three failures in analyzespTest, believed to be | |
| # golden strings written for an older parser. They were something else: | |
| # gspCommon.BASE_SQL_DIR pointed one level short of the library's SQL | |
| # corpus, so the input file was never found and the comparison ran against | |
| # an empty string. Those four scripts are now checked in under | |
| # src/test/resources/, so the suite is self-contained: 144 tests, no | |
| # expected failures, nothing skipped. `continue-on-error` went with the | |
| # threshold -- a red test run is now a red build. | |
| - name: Test | |
| run: mvn -B test | |
| - name: Check the results | |
| run: .github/scripts/check-test-results.sh | |
| - name: Smoke test a demo | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| printf 'SELECT a.id, b.name FROM ta a JOIN tb b ON a.id = b.id WHERE a.x > 1;\n' > q.sql | |
| out=$(mvn -q exec:java \ | |
| -Dexec.mainClass=gudusoft.gsqlparser.demos.checksyntax.checksyntax \ | |
| -Dexec.args="/f q.sql /t oracle" -Dexec.classpathScope=compile) | |
| echo "$out" | |
| grep -q "syntax errors: 0" <<<"$out" | |
| # The standalone lineage tool. It used to be a second POM, | |
| # pom_dlineage.xml, and the step here only *built* it -- which is exactly | |
| # how it shipped broken twice. Building proves nothing about a program: | |
| # issue #47 was a missing JAXB dependency that compiles perfectly and dies | |
| # at runtime on any JDK past 8, and issue #46 was a documented run command | |
| # pointing at a directory the Maven route never creates. Both survived a | |
| # green build. So this runs it and checks the output; see the script for | |
| # why it asserts on the output rather than the exit status. | |
| # | |
| # It runs on both matrix JDKs for the same reason: #47 does not reproduce | |
| # on 8 at all, so a single-JDK check would have missed it. | |
| # | |
| # The issue-#39 guard that used to live here -- counting target/classes | |
| # before and after, because the second POM's incremental cleanup would | |
| # delete the root build's output -- is gone with the second POM. One POM | |
| # cannot collide with itself. | |
| - name: Run the standalone dlineage jar | |
| run: .github/scripts/smoke-dlineage-jar.sh | |
| # The .bat scripts are the original Windows, no-Maven workflow: edit | |
| # setenv\setenv.bat, cd into a demo folder, run compile_<demo>.bat then | |
| # run_<demo>.bat. They had been stale for years -- compiling | |
| # src\main\java\demos\<demo>\ and cd-ing up five levels, both correct only | |
| # before the demos moved under gudusoft\gsqlparser\demos\ -- and nothing ever | |
| # noticed, because nothing ran them. This job runs them. | |
| windows-bat: | |
| runs-on: windows-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| # The .bat scripts want a JDK 8 era toolchain, and setenv.bat now keeps | |
| # whatever JAVA_HOME it is given rather than hardcoding one. | |
| - name: Set up JDK 8 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: "8" | |
| cache: maven | |
| # No parser jar is committed, so setenv.bat fetches one into external_lib\ | |
| # on first use. This step only proves that bootstrap works from a clean | |
| # checkout; the demo steps below would trigger it anyway. | |
| - name: setenv.bat bootstraps the parser from Maven | |
| shell: cmd | |
| run: | | |
| if exist external_lib\gsqlparser-*.jar ( | |
| echo ::error::a parser jar is committed to this repository; it must be fetched, not vendored | |
| exit /b 1 | |
| ) | |
| call setenv\fetch-parser.bat | |
| dir external_lib | |
| for %%f in (external_lib\gsqlparser-*.jar) do exit /b 0 | |
| echo ::error::fetch-parser.bat produced no parser jar | |
| exit /b 1 | |
| # Phase 1: every compile_<demo>.bat must succeed. This is the check that | |
| # matters, and the one that would have caught the whole family going stale | |
| # when the demos moved directory. `pause` at the end of each script would | |
| # block forever on a runner with no keyboard, so stdin is fed from NUL. | |
| - name: Compile all 39 demos via compile_*.bat | |
| shell: cmd | |
| run: | | |
| setlocal enabledelayedexpansion | |
| set FAILED=0 | |
| set COUNT=0 | |
| for /r "%GITHUB_WORKSPACE%\src\main\java" %%s in (compile_*.bat) do ( | |
| set /a COUNT+=1 | |
| pushd "%%~dps" | |
| call "%%~nxs" < NUL > "%GITHUB_WORKSPACE%\c.txt" 2>&1 | |
| findstr /i /c:"error" /c:"file not found" /c:"no source files" "%GITHUB_WORKSPACE%\c.txt" >NUL && ( | |
| echo ::error::%%~nxs failed | |
| type "%GITHUB_WORKSPACE%\c.txt" | |
| set /a FAILED+=1 | |
| ) || echo ok %%~nxs | |
| popd | |
| ) | |
| echo. | |
| echo compiled !COUNT! demos, !FAILED! failed | |
| rem An explicit exit is required: a trailing `if` whose condition is | |
| rem false leaves whatever ERRORLEVEL the loop last set, and the step | |
| rem then fails despite reporting 0 failures. | |
| if !FAILED! GTR 0 exit /b 1 | |
| exit /b 0 | |
| # Phase 2: every run_<demo>.bat must at least start its class. Run with no | |
| # arguments, so most print their own usage line; what this proves is that | |
| # the class name in the script still resolves and the classpath is right. | |
| # A stale class name after a package move shows up here as | |
| # ClassNotFoundException, which is exactly what had happened. | |
| - name: Launch all 50 demos via run_*.bat | |
| shell: cmd | |
| run: | | |
| setlocal enabledelayedexpansion | |
| set FAILED=0 | |
| set COUNT=0 | |
| for /r "%GITHUB_WORKSPACE%\src\main\java" %%s in (run_*.bat) do ( | |
| set /a COUNT+=1 | |
| pushd "%%~dps" | |
| call "%%~nxs" < NUL > "%GITHUB_WORKSPACE%\r.txt" 2>&1 | |
| findstr /c:"ClassNotFoundException" /c:"NoClassDefFoundError" /c:"Main method not found" "%GITHUB_WORKSPACE%\r.txt" >NUL && ( | |
| echo ::error::%%~nxs could not launch its class | |
| type "%GITHUB_WORKSPACE%\r.txt" | |
| set /a FAILED+=1 | |
| ) || echo ok %%~nxs | |
| popd | |
| ) | |
| echo. | |
| echo launched !COUNT! demos, !FAILED! failed | |
| if !FAILED! GTR 0 exit /b 1 | |
| exit /b 0 | |
| # `pause` at the end of each script would block forever on a runner with | |
| # no keyboard, so stdin is fed from NUL. | |
| # | |
| # These four cover the shapes the scripts come in: a file+vendor demo, a | |
| # bare-filename demo, one that takes no arguments at all, and one nested a | |
| # directory deeper (so its cd depth differs). They are generated from one | |
| # template and go stale as a set, which is exactly what happened when the | |
| # demos moved directory, so this is a canary rather than full coverage. | |
| # Phase 3: a few demos driven with real arguments and checked against a | |
| # string their output must contain, so this is not only a smoke test. | |
| - name: Run four demos with real arguments | |
| shell: cmd | |
| run: | | |
| echo SELECT a.id FROM ta a; > "%GITHUB_WORKSPACE%\q.sql" | |
| rem dir compile script run script args expected in output | |
| call :demo checksyntax checksyntax checksyntax "/f %GITHUB_WORKSPACE%\q.sql /t oracle" "syntax errors: 0" || exit /b 1 | |
| call :demo formatsql formatsql formatsql "%GITHUB_WORKSPACE%\q.sql" "SELECT" || exit /b 1 | |
| call :demo listGSPInfo listGSPInfo listGSPInfo "" "Supported DBs" || exit /b 1 | |
| call :demo modifysql modifysql replaceTablename "" "output sql" || exit /b 1 | |
| echo All .bat demos passed. | |
| exit /b 0 | |
| :demo | |
| setlocal | |
| set DEMO=%~1 | |
| set CSCRIPT=%~2 | |
| set RSCRIPT=%~3 | |
| set ARGS=%~4 | |
| set EXPECT=%~5 | |
| echo. | |
| echo ==== %DEMO% : compile_%CSCRIPT%.bat / run_%RSCRIPT%.bat ==== | |
| cd /d "%GITHUB_WORKSPACE%\src\main\java\gudusoft\gsqlparser\demos\%DEMO%" | |
| call compile_%CSCRIPT%.bat < NUL > "%GITHUB_WORKSPACE%\c.txt" 2>&1 | |
| type "%GITHUB_WORKSPACE%\c.txt" | |
| findstr /i /c:"error" "%GITHUB_WORKSPACE%\c.txt" >NUL && ( | |
| echo ::error::compile_%CSCRIPT%.bat reported an error | |
| endlocal & exit /b 1 | |
| ) | |
| call run_%RSCRIPT%.bat %ARGS% < NUL > "%GITHUB_WORKSPACE%\r.txt" 2>&1 | |
| type "%GITHUB_WORKSPACE%\r.txt" | |
| findstr /c:"%EXPECT%" "%GITHUB_WORKSPACE%\r.txt" >NUL || ( | |
| echo ::error::run_%RSCRIPT%.bat did not print "%EXPECT%" | |
| endlocal & exit /b 1 | |
| ) | |
| endlocal & exit /b 0 |