-
Notifications
You must be signed in to change notification settings - Fork 77
355 lines (309 loc) · 14.7 KB
/
Copy pathnightly.yml
File metadata and controls
355 lines (309 loc) · 14.7 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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
name: Nightly
# build.yml runs on push and pull_request, so it only tells you about changes
# made HERE. This repository's other moving part is outside it: the parser
# artifact published to https://www.sqlparser.com/maven/. A release there can
# change demo output or drop an API without a single commit landing in this
# repo, and nothing would notice until someone ran a demo by hand.
#
# So this workflow runs on a timer and covers both:
# pinned -- ${gsp.core.version} from pom.xml, the version the README
# documents, on the two JDKs the demos claim to support.
# latest -- whatever is newest on sqlparser.com right now. This is the job
# that earns the nightly. When it goes red and `pinned` stays
# green, a new parser release broke the demos.
#
# Both jobs do the same four things: prove no parser jar is committed, compile
# everything, run the whole test suite, and then actually run the demos --
# every one of them for launch, and a table of them with real arguments checked
# against expected output.
on:
schedule:
# 03:17 UTC. Not on the hour: GitHub drops scheduled runs when too many
# repositories ask for the same popular minute.
- cron: "17 3 * * *"
workflow_dispatch:
inputs:
parser_version:
description: "Parser version for the 'latest' job (blank = resolve newest from sqlparser.com)"
required: false
type: string
permissions:
contents: read
jobs:
pinned:
name: "pinned parser (JDK ${{ matrix.java }})"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# The parser jar is Java 8 bytecode and the POM pins source/target 1.8.
java: ["8", "21"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: ${{ matrix.java }}
cache: maven
# A vendored parser is what once let these demos compile against a build
# years older than their own source, so its absence is an invariant worth
# asserting rather than a convention worth documenting.
- name: No parser jar is committed
run: |
set -euo pipefail
if git ls-files | grep -E '(^|/)(gsqlparser|gudusoft\.gsqlparser)[^/]*\.jar$'; then
echo "::error::a parser jar is committed; it must be resolved from Gudu's Maven repository"
exit 1
fi
echo "ok: no parser jar in the index"
- name: Parser version is consistent across all POMs
run: .github/scripts/set-parser-version.sh --check
- name: Report the parser being used
run: |
set -euo pipefail
v=$(mvn -B -q help:evaluate -Dexpression=gsp.core.version -DforceStdout)
echo "pinned parser version: $v"
echo "### Pinned parser \`$v\` (JDK ${{ matrix.java }})" >> "$GITHUB_STEP_SUMMARY"
- name: Compile everything
run: mvn -B package -DskipTests
- name: Test
run: mvn -B test
- name: Check the results
run: .github/scripts/check-test-results.sh
# The standalone lineage tool, run rather than merely built. It was its own
# POM until 2026-07-28, and only ever compiled here, which is how it
# shipped a missing JAXB dependency (issue #47) and an unrunnable
# documented command (issue #46) through green builds.
- name: Run the standalone dlineage jar
run: .github/scripts/smoke-dlineage-jar.sh
- name: Every demo starts
run: .github/scripts/run-all-demos.sh --timeout 90
- name: Demos produce their expected output
run: .github/scripts/run-demo-cases.sh --timeout 180
latest:
name: "latest published parser"
runs-on: ubuntu-latest
# Needed only by the last step, which opens the bump PR. Everything above it
# is read-only.
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "21"
cache: maven
# <release> is the newest non-snapshot; fall back to <latest>, then to the
# last <version> listed. Failing to resolve is an error rather than a
# silent fallback to the pinned version: a job that quietly re-tests what
# `pinned` already covers looks green while testing nothing new.
- name: Resolve the newest published parser
id: ver
run: |
set -euo pipefail
if [ -n "${{ inputs.parser_version }}" ]; then
v="${{ inputs.parser_version }}"
echo "using the version supplied to workflow_dispatch: $v"
else
url=https://www.sqlparser.com/maven/com/gudusoft/gsqlparser/maven-metadata.xml
curl -sSf --retry 3 --retry-delay 5 -o meta.xml "$url"
v=$(sed -n 's:.*<release>\(.*\)</release>.*:\1:p' meta.xml | head -1)
[ -n "$v" ] || v=$(sed -n 's:.*<latest>\(.*\)</latest>.*:\1:p' meta.xml | head -1)
[ -n "$v" ] || v=$(sed -n 's:.*<version>\(.*\)</version>.*:\1:p' meta.xml | tail -1)
if [ -z "$v" ]; then
echo "::error::could not read a version out of $url"
cat meta.xml
exit 1
fi
fi
pinned=$(mvn -B -q help:evaluate -Dexpression=gsp.core.version -DforceStdout)
echo "version=$v" >> "$GITHUB_OUTPUT"
echo "newest published: $v / pinned in pom.xml: $pinned"
{
echo "### Latest published parser \`$v\`"
if [ "$v" = "$pinned" ]; then
echo "Same as the pinned version, so this job duplicates \`pinned\`."
else
echo "Pinned version is \`$pinned\`. If this job is red and \`pinned\` is green,"
echo "release \`$v\` broke the demos. If it is green, \`gsp.core.version\`"
echo "can be bumped to \`$v\`."
fi
} >> "$GITHUB_STEP_SUMMARY"
- name: Compile everything
run: mvn -B package -DskipTests -Dgsp.core.version=${{ steps.ver.outputs.version }}
- name: Test
run: mvn -B test -Dgsp.core.version=${{ steps.ver.outputs.version }}
- name: Check the results
run: .github/scripts/check-test-results.sh
# Same smoke run as the pinned job, against the jar "Compile everything"
# just built with -Dgsp.core.version=<newest release>. This is the check
# that would notice a new parser breaking data lineage at runtime while
# still compiling, which is precisely the failure mode a build-only step
# cannot see.
- name: Run the standalone dlineage jar against the newest release
run: .github/scripts/smoke-dlineage-jar.sh
- name: Every demo starts
env:
MVN_ARGS: -Dgsp.core.version=${{ steps.ver.outputs.version }}
run: .github/scripts/run-all-demos.sh --timeout 90
- name: Demos produce their expected output
env:
MVN_ARGS: -Dgsp.core.version=${{ steps.ver.outputs.version }}
run: .github/scripts/run-demo-cases.sh --timeout 180
# Everything above passed against this version, so the bump is already
# proven rather than proposed on faith: full suite, every demo started,
# and the demo cases checked against expected output. Opening a PR instead
# of committing keeps a human in the loop and gives the push-triggered
# build.yml a chance to disagree.
#
# Deliberately the LAST step in the job: any earlier failure means the new
# release broke something, and then no PR is what we want.
- name: Propose the bump when the newest release is green
if: github.ref == 'refs/heads/master'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NEW: ${{ steps.ver.outputs.version }}
run: |
set -euo pipefail
pinned=$(mvn -B -q help:evaluate -Dexpression=gsp.core.version -DforceStdout)
if [ "$NEW" = "$pinned" ]; then
echo "already on $NEW, nothing to propose"
exit 0
fi
branch="bump-parser-$NEW"
if gh pr list --head "$branch" --state open --json number \
--jq 'length' | grep -qv '^0$'; then
echo "a PR for $branch is already open"
exit 0
fi
if git ls-remote --exit-code --heads origin "$branch" >/dev/null 2>&1; then
echo "branch $branch already exists on origin; leaving it alone"
exit 0
fi
.github/scripts/set-parser-version.sh "$NEW"
.github/scripts/set-parser-version.sh --check
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -b "$branch"
git commit -aqm "Bump the parser from $pinned to $NEW
The nightly ran the newest published release through the same checks
the pinned version gets, and it passed all of them:
- full test suite, no failures
- every demo starts
- the demo cases in .github/scripts/demo-cases.tsv produce their
expected output
Opened automatically by .github/workflows/nightly.yml. Merge it if you
want the demos on $NEW; close it to stay on $pinned, and the nightly
will keep testing $NEW without asking again until a newer release
appears."
git push -q origin "$branch"
gh pr create --base master --head "$branch" \
--title "Bump the parser from $pinned to $NEW" \
--body "\`$NEW\` is the newest release on sqlparser.com. Tonight's nightly ran it through the same checks the pinned \`$pinned\` gets, and it passed all of them: the full test suite with no failures, every demo starting, and every case in \`.github/scripts/demo-cases.tsv\` producing its expected output.
This touches the four places the version is written -- \`pom.xml\` and the three \`connector/*/pom.xml\` -- via \`.github/scripts/set-parser-version.sh\`, so they cannot drift apart.
Merge to move the demos to \`$NEW\`. Close to stay on \`$pinned\`; the nightly will go on testing \`$NEW\` and will not reopen this until a newer release appears.
Opened by [\`nightly.yml\`](https://github.com/${{ github.repository }}/actions/workflows/nightly.yml)."
# The .bat family is the original Windows, no-Maven workflow. It went stale
# for years because nothing ran it; build.yml runs it per push and this runs
# it nightly, against a parser fetched fresh rather than a cached one.
windows-bat:
name: "Windows .bat scripts"
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "8"
cache: maven
- 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
- name: Compile every demo 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.
if !FAILED! GTR 0 exit /b 1
exit /b 0
- name: Launch every demo 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
- name: Run four demos with real arguments
shell: cmd
run: |
echo SELECT a.id FROM ta a; > "%GITHUB_WORKSPACE%\q.sql"
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