-
Notifications
You must be signed in to change notification settings - Fork 77
236 lines (215 loc) · 10.4 KB
/
Copy pathbuild.yml
File metadata and controls
236 lines (215 loc) · 10.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
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