Repository navigation
447 lines (405 loc) · 22.9 KB
/
Copy pathci.yml
File metadata and controls
447 lines (405 loc) · 22.9 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
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
name: FundsXML CI
# Validates every committed sample against the official released XSD and the
# Schematron ruleset, runs the XSLT transforms as a smoke test, and asserts the
# negative fixtures still fail. Positive samples must stay green.
#
# Security note: no untrusted GitHub event data (issue/PR/commit text) is used
# in any run: step, so there is no workflow-injection surface here.
on:
push:
branches: ["**"]
pull_request:
workflow_dispatch:
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install tooling
run: sudo apt-get update -qq && sudo apt-get install -y -qq libxml2-utils xsltproc xmlsec1
- uses: actions/setup-java@v5
with:
distribution: temurin
java-version: "21"
- uses: actions/setup-python@v6
with:
python-version: "3.11"
- uses: actions/setup-node@v6
with:
node-version: "20"
- uses: actions/setup-dotnet@v5
with:
dotnet-version: "8.0"
# One idiomatic, OS-agnostic Python install (venv + editable pyproject).
# Dependency-only manifest — nothing is packaged/importable.
- name: Python - venv & install (pyproject)
run: |
python -m venv .venv
.venv/bin/pip install --quiet --upgrade pip
.venv/bin/pip install --quiet -e .
.venv/bin/python -c "import lxml, saxonche; print('python deps OK')"
# The examples no longer resolve any schema: each validator takes a
# schema path (or URL) + the XML file. This step is CI plumbing only —
# a plain curl of the official releases into ci-schemas/ so the many
# raw-xmllint steps below have a local schema path to point at. (The
# validators' own remote-URL handling is exercised separately.)
- name: Fetch official schemas for CI (plain curl, no resolver)
run: |
set -e
for v in 4.2.9 4.1.0 4.0.0; do
mkdir -p "ci-schemas/$v"
curl -sSL --fail -o "ci-schemas/$v/FundsXML.xsd" \
"https://github.com/fundsxml/schema/releases/download/$v/FundsXML.xsd"
if grep -q 'xmldsig-core-schema\.xsd' "ci-schemas/$v/FundsXML.xsd"; then
curl -sSL --fail -o "ci-schemas/$v/xmldsig-core-schema.xsd" \
"https://github.com/fundsxml/schema/releases/download/$v/xmldsig-core-schema.xsd"
fi
done
- name: XSD - all positive samples must validate
run: |
set -e
declare -A S=(
["4.2.9"]="positions/Mixed-Fund_Positions transactions/Fund_Transactions documents/Fund_Documents regulatory/EFT_Regulatory signed/Signed_Fund_Skeleton"
["4.1.0"]="positions/Equity-Fund_Positions"
["4.0.0"]="positions/Equity-Fund_Positions"
)
for v in "${!S[@]}"; do
for f in ${S[$v]}; do
echo "XSD $v/$f"
xmllint --noout --nonet --schema "ci-schemas/$v/FundsXML.xsd" \
"FundsXML_Files/$v/$f.xml"
done
done
- name: XSD - negative fixture must FAIL
run: |
if xmllint --noout --nonet --schema ci-schemas/4.2.9/FundsXML.xsd \
tests/fixtures/invalid/xsd-invalid_Positions.xml 2>/dev/null; then
echo "::error::xsd-invalid fixture unexpectedly validated"; exit 1
fi
echo "xsd-invalid correctly rejected"
- name: Python - XSD validation (schema path + remote URL)
run: |
set -e
V=".venv/bin/python XSD_Validation/python/validate.py"
# Local schema path (two versions) ...
$V ci-schemas/4.2.9/FundsXML.xsd FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml
$V ci-schemas/4.1.0/FundsXML.xsd FundsXML_Files/4.1.0/positions/Equity-Fund_Positions.xml
# ... and a remote schema URL (the official release, fetched by the
# validator itself — exercises the URL path + the relative xmldsig
# sibling fetch).
$V https://github.com/fundsxml/schema/releases/download/4.2.9/FundsXML.xsd \
FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml
if $V ci-schemas/4.2.9/FundsXML.xsd tests/fixtures/invalid/xsd-invalid_Positions.xml; then
echo "::error::xsd-invalid unexpectedly validated (Python)"; exit 1
fi
echo "Python validate.py: path + URL ok, negative correctly rejected"
- name: .NET - XSD validation (schema path + remote URL)
run: |
set -e
D="dotnet run --project XSD_Validation/dotnet --"
$D ci-schemas/4.2.9/FundsXML.xsd FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml
$D ci-schemas/4.1.0/FundsXML.xsd FundsXML_Files/4.1.0/positions/Equity-Fund_Positions.xml
# Remote schema URL: .NET resolves it (and the relative xmldsig
# import) natively via the schema-set URL resolver.
$D https://github.com/fundsxml/schema/releases/download/4.2.9/FundsXML.xsd \
FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml
if $D ci-schemas/4.2.9/FundsXML.xsd tests/fixtures/invalid/xsd-invalid_Positions.xml; then
echo "::error::xsd-invalid unexpectedly validated (.NET)"; exit 1
fi
echo ".NET XsdValidate: path + URL ok, negative correctly rejected"
- name: CLI - validate.sh (schema path + remote URL)
run: |
set -e
XSD_Validation/cli/validate.sh ci-schemas/4.2.9/FundsXML.xsd \
FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml
# Remote schema URL: validate.sh fetches it (and the xmldsig
# sibling) into a temp dir, then validates offline with --nonet.
XSD_Validation/cli/validate.sh \
https://github.com/fundsxml/schema/releases/download/4.2.9/FundsXML.xsd \
FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml
if XSD_Validation/cli/validate.sh ci-schemas/4.2.9/FundsXML.xsd \
tests/fixtures/invalid/xsd-invalid_Positions.xml; then
echo "::error::xsd-invalid unexpectedly validated (CLI)"; exit 1
fi
echo "CLI validate.sh: path + URL ok, negative correctly rejected"
# ---------------------------------------------------------------------
# Java examples — built & run via the committed Maven Wrapper. The first
# ./mvnw bootstraps Maven itself, then resolves all deps from Central.
# A repo-wide `compile` builds every module once so later `exec:java`
# steps need no `compile` goal (keeps stdout clean for the XQuery step,
# which serializes its result to stdout).
# ---------------------------------------------------------------------
- name: Java - build all modules (Maven Wrapper)
run: ./mvnw -q -B compile
- name: Java - XSD validation (schema path + remote URL)
run: |
set -e
M="./mvnw -q -B -pl XSD_Validation/java exec:java"
$M -Dexec.args="ci-schemas/4.2.9/FundsXML.xsd FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml"
$M -Dexec.args="ci-schemas/4.1.0/FundsXML.xsd FundsXML_Files/4.1.0/positions/Equity-Fund_Positions.xml"
# Remote schema URL: the validator fetches it (and the xmldsig
# sibling) into a temp dir, then validates locally.
$M -Dexec.args="https://github.com/fundsxml/schema/releases/download/4.2.9/FundsXML.xsd FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml"
if $M -Dexec.args="ci-schemas/4.2.9/FundsXML.xsd tests/fixtures/invalid/xsd-invalid_Positions.xml"; then
echo "::error::xsd-invalid unexpectedly validated (Java)"; exit 1
fi
echo "Java XsdValidate: path + URL ok, negative correctly rejected"
- name: Schematron - canonical sample passes, fixture fails
run: |
set -e
SCH=Schematron_DataQuality_Checks/Basic_Checks/basic_checks.sch
M="./mvnw -q -B -pl Schematron_DataQuality_Checks/Basic_Checks/invocation exec:java"
$M -Dexec.args="$SCH FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml"
if $M -Dexec.args="$SCH tests/fixtures/invalid/schematron-invalid_Positions.xml"; then
echo "::error::schematron-invalid fixture unexpectedly passed"; exit 1
fi
echo "schematron-invalid correctly failed"
- name: Schematron - .NET variant (drives the SchXslt CLI jar from the Maven local repo)
run: |
set -e
SCH=Schematron_DataQuality_Checks/Basic_Checks/basic_checks.sch
D="dotnet run --project Schematron_DataQuality_Checks/Basic_Checks/invocation --"
$D $SCH FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml
if $D $SCH tests/fixtures/invalid/schematron-invalid_Positions.xml; then
echo "::error::schematron-invalid fixture unexpectedly passed (.NET)"; exit 1
fi
echo ".NET SchematronValidate: sample ok, fixture correctly failed"
- name: Smoke - XSLT transforms produce non-empty output
run: |
set -e
M="./mvnw -q -B -pl XSLT_Transformations/invocation exec:java"
SRC=FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml
$M -Dexec.args="XSLT_DataQuality_Checks/Custom_Internal_Checks/custom_internal_checks.xslt $SRC out_dq.html"
$M -Dexec.args="XSLT_Transformations/Factsheet/factsheet_html.xslt $SRC out_fs.html"
$M -Dexec.args="XSLT_Transformations/Factsheet/factsheet_fo.xslt $SRC out_fs.fo"
$M -Dexec.args="XSLT_Transformations/CSV_Export/positions_csv.xslt $SRC out_pos.csv"
xmllint --noout out_fs.fo
for f in out_dq.html out_fs.html out_pos.csv; do
test -s "$f" || { echo "::error::$f is empty"; exit 1; }
done
test "$(wc -l < out_pos.csv)" -ge 2
- name: Smoke - XQuery examples run and produce XML
run: |
set -e
M="./mvnw -q -B -pl XQuery_Examples/invocation exec:java"
SRC=FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml
# RunXQuery serializes to stdout; -q keeps Maven silent so the
# redirect captures pure XML.
$M -Dexec.args="XQuery_Examples/aggregate-by-assettype.xq $SRC" > out_agg.xml
$M -Dexec.args="XQuery_Examples/top-holdings.xq $SRC n=5" > out_top.xml
$M -Dexec.args="XQuery_Examples/fund-summary.xq $SRC" > out_sum.xml
$M -Dexec.args="XQuery_Examples/look-through.xq $SRC" > out_lt.xml
for f in out_agg.xml out_top.xml out_sum.xml out_lt.xml; do
xmllint --noout "$f"
done
test "$(xmllint --xpath 'count(//Holding)' out_top.xml)" = "5"
- name: XML signature - Apache Santuario sign/verify/tamper roundtrip
run: |
set -e
M="./mvnw -q -B -pl XML_Signature/java exec:java"
SRC=FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml
# In-language key generation (JDK keytool, no openssl).
$M -Dexec.mainClass=GenerateTestKey
$M -Dexec.mainClass=SignFundsXml \
-Dexec.args="$SRC signed.xml XML_Signature/keys/test-signing.p12 changeit fundsxml"
$M -Dexec.mainClass=VerifyFundsXml \
-Dexec.args="signed.xml XML_Signature/keys/test-signing-cert.pem"
xmllint --noout --nonet --schema ci-schemas/4.2.9/FundsXML.xsd signed.xml
sed 's/<TotalPercentage>8.33</<TotalPercentage>9.33</' signed.xml > tampered.xml
if $M -Dexec.mainClass=VerifyFundsXml \
-Dexec.args="tampered.xml XML_Signature/keys/test-signing-cert.pem"; then
echo "::error::tampered file unexpectedly verified"; exit 1
fi
echo "tamper correctly detected"
- name: XML signature - xmlsec1 CLI signs the skeleton template, cross-verifies with Java
run: |
set -e
SH=XML_Signature/cli/sign-verify-xmlsec1.sh
SKEL=FundsXML_Files/4.2.9/signed/Signed_Fund_Skeleton.xml
M="./mvnw -q -B -pl XML_Signature/java exec:java"
# sign the committed template in place (keys from the GenerateTestKey step above)
$SH sign "$SKEL" xs-signed.xml
xmllint --noout --nonet --schema ci-schemas/4.2.9/FundsXML.xsd xs-signed.xml
$SH verify xs-signed.xml
# Java verifies the xmlsec1 output: pinned cert AND embedded certificate
$M -Dexec.mainClass=VerifyFundsXml \
-Dexec.args="xs-signed.xml XML_Signature/keys/test-signing-cert.pem"
$M -Dexec.mainClass=VerifyFundsXml -Dexec.args="xs-signed.xml"
# xmlsec1 verifies the Java-signed file from the previous step
$SH verify signed.xml
sed 's/<Amount ccy="EUR">125000000</<Amount ccy="EUR">125000001</' xs-signed.xml > xs-tampered.xml
if $SH verify xs-tampered.xml; then
echo "::error::xmlsec1-signed tampered file unexpectedly verified"; exit 1
fi
echo "xmlsec1: sign/verify/tamper ok, cross-verified with Java"
- name: DB integration - multi-fund import+export in 4 languages
run: |
set -e
PY=.venv/bin/python
FX=FundsXML_Files/4.2.9/positions/Multi-Fund_Positions.xml
MX=FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml
DOC=FUNDSXML_MULTI_1
EQ="$PY Database_Integration/tools/xml_equiv.py"
XSD="ci-schemas/4.2.9/FundsXML.xsd"
# The multi-fund fixture must itself be schema-valid.
xmllint --noout --nonet --schema "$XSD" "$FX"
# Each language: separate import then export, then prove
# exported file == input file (and is schema-valid).
# Python
$PY Database_Integration/python/import_fundsxml.py py.db "$FX"
$PY Database_Integration/python/export_fundsxml.py py.db "$DOC" py.xml
xmllint --noout --nonet --schema "$XSD" py.xml
$EQ "$FX" py.xml
# Java (sqlite-jdbc via Maven; classes already built above)
MJ="./mvnw -q -B -pl Database_Integration/java exec:java"
$MJ -Dexec.mainClass=ImportFundsXml -Dexec.args="java.db $FX"
$MJ -Dexec.mainClass=ExportFundsXml -Dexec.args="java.db $DOC java.xml"
xmllint --noout --nonet --schema "$XSD" java.xml
$EQ "$FX" java.xml
# JavaScript (sql.js)
( cd Database_Integration/javascript && npm install --no-audit --no-fund )
node Database_Integration/javascript/import_fundsxml.mjs js.db "$FX"
node Database_Integration/javascript/export_fundsxml.mjs js.db "$DOC" js.xml
xmllint --noout --nonet --schema "$XSD" js.xml
$EQ "$FX" js.xml
# C# (.NET): separate import and export projects
dotnet run --project Database_Integration/csharp/import -- cs.db "$FX"
dotnet run --project Database_Integration/csharp/export -- cs.db "$DOC" cs.xml
xmllint --noout --nonet --schema "$XSD" cs.xml
$EQ "$FX" cs.xml
# Cross-language: every export identical to Python's.
$EQ py.xml java.xml && $EQ py.xml js.xml && $EQ py.xml cs.xml
# Single-fund sample still imports+exports (lossy -> XSD-valid only).
$PY Database_Integration/python/import_fundsxml.py mx.db "$MX"
$PY Database_Integration/python/export_fundsxml.py mx.db FUNDSXML_FILE_1 mx.xml
xmllint --noout --nonet --schema "$XSD" mx.xml
echo "multi-fund import+export equivalent in python/java/javascript/csharp"
- name: Large-file - streaming aggregate / split / delta (constant memory)
run: |
set -e
PY=.venv/bin/python
P=Large_File_Processing/python
$PY $P/make_large_sample.py big.xml 30000
xmllint --noout --nonet --schema ci-schemas/4.2.9/FundsXML.xsd big.xml
$PY $P/stream_aggregate.py big.xml | tee agg.txt
grep -q '^positions : 30000$' agg.txt
grep -q '^sum value (EUR): 30000000.00$' agg.txt
# Java StreamAggregate (pure JDK) under a small heap proves the
# constant-memory claim; MAVEN_OPTS bounds the in-process JVM.
MAVEN_OPTS=-Xmx64m ./mvnw -q -B -pl Large_File_Processing/java exec:java \
-Dexec.args="big.xml" | tee aggj.txt
grep -q '^positions : 30000$' aggj.txt
$PY $P/split.py big.xml chunks/ 10000
test "$(ls chunks/chunk-*.xml | wc -l)" = "3"
xmllint --noout --nonet --schema ci-schemas/4.2.9/FundsXML.xsd chunks/chunk-0001.xml
$PY $P/delta_diff.py big.xml big.xml # identical -> exit 0
- name: Data binding / JSON - round-trip + native Java binding
run: |
set -e
PY=.venv/bin/python
SRC=FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml
$PY Data_Binding_JSON/python/fundsxml_json.py roundtrip "$SRC" rj.xml
xmllint --noout --nonet --schema ci-schemas/4.2.9/FundsXML.xsd rj.xml
# Multi-fund JSON round-trip is lossless -> must be xml_equiv-equal.
MF=FundsXML_Files/4.2.9/positions/Multi-Fund_Positions.xml
$PY Data_Binding_JSON/python/fundsxml_json.py roundtrip "$MF" rjm.xml
xmllint --noout --nonet --schema ci-schemas/4.2.9/FundsXML.xsd rjm.xml
$PY Database_Integration/tools/xml_equiv.py "$MF" rjm.xml
$PY - "$SRC" rj.xml <<'PY'
import re, sys
o, r = (open(p).read() for p in sys.argv[1:3])
nav = lambda x: re.search(r'<TotalNetAssetValue>\s*<Amount ccy="EUR">([0-9.]+)', x).group(1)
npos = lambda x: len(re.findall(r'<Position>', x))
assert abs(float(nav(o)) - float(nav(r))) < 0.01, (nav(o), nav(r))
assert npos(o) == npos(r), (npos(o), npos(r))
print("JSON round-trip preserved:", nav(r), npos(r))
PY
./mvnw -q -B -pl Data_Binding_JSON/java exec:java -Dexec.args="$SRC" | tee nb.txt
grep -q '^Positions : 21$' nb.txt
- name: Regression - legacy XSLT 1.0 report still runs
run: |
xsltproc XSLT_DataQuality_Checks/Enhanced_Check/FundsXML_CompleteDQReport_HTML.xsl \
FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml > out_enh.html
test -s out_enh.html
# =======================================================================
# Windows smoke — proves the examples are genuinely cross-platform and
# standalone (the whole point of this work): every stack runs with no bash,
# no prior tool step, on a clean Windows box, taking a schema URL + the XML
# file directly. A focused subset (Python / Java / .NET XSD + one XSLT + a
# DB round-trip + the PowerShell CLI), not the full bash-heavy matrix.
# =======================================================================
windows-smoke:
runs-on: windows-latest
defaults:
run:
shell: pwsh
steps:
- uses: actions/checkout@v6
- uses: actions/setup-java@v5
with:
distribution: temurin
java-version: "21"
- uses: actions/setup-python@v6
with:
python-version: "3.11"
- uses: actions/setup-dotnet@v5
with:
dotnet-version: "8.0"
- name: Python - venv & install (pyproject)
run: |
python -m venv .venv
.venv\Scripts\python -m pip install --quiet --upgrade pip
.venv\Scripts\pip install --quiet -e .
.venv\Scripts\python -c "import lxml, saxonche; print('python deps OK')"
- name: Python - XSD validation (remote schema URL on Windows)
run: |
$src = "FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml"
$xsd = "https://github.com/fundsxml/schema/releases/download/4.2.9/FundsXML.xsd"
.venv\Scripts\python XSD_Validation/python/validate.py $xsd $src
if ($LASTEXITCODE -ne 0) { throw "positive failed" }
.venv\Scripts\python XSD_Validation/python/validate.py $xsd tests/fixtures/invalid/xsd-invalid_Positions.xml
if ($LASTEXITCODE -eq 0) { throw "negative unexpectedly validated (Python)" }
Write-Host "Python OK on Windows"
exit 0 # reset $LASTEXITCODE (the negative case left it at 1)
- name: Java - XSD validate + one XSLT (Maven Wrapper, mvnw.cmd)
run: |
$src = "FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml"
$xsd = "https://github.com/fundsxml/schema/releases/download/4.2.9/FundsXML.xsd"
.\mvnw.cmd -q -B -pl XSD_Validation/java compile exec:java "-Dexec.args=$xsd $src"
if ($LASTEXITCODE -ne 0) { throw "Java XSD positive failed" }
.\mvnw.cmd -q -B -pl XSD_Validation/java exec:java "-Dexec.args=$xsd tests/fixtures/invalid/xsd-invalid_Positions.xml"
if ($LASTEXITCODE -eq 0) { throw "Java negative unexpectedly validated" }
.\mvnw.cmd -q -B -pl XSLT_Transformations/invocation compile exec:java "-Dexec.args=XSLT_Transformations/CSV_Export/positions_csv.xslt $src out_pos.csv"
if (-not (Test-Path out_pos.csv)) { throw "XSLT produced no output" }
Write-Host "Java OK on Windows"
exit 0 # reset $LASTEXITCODE (the negative case left it at 1)
- name: .NET - XSD validation (remote schema URL on Windows)
run: |
$src = "FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml"
$xsd = "https://github.com/fundsxml/schema/releases/download/4.2.9/FundsXML.xsd"
dotnet run --project XSD_Validation/dotnet -- $xsd $src
if ($LASTEXITCODE -ne 0) { throw ".NET XSD positive failed" }
dotnet run --project XSD_Validation/dotnet -- $xsd tests/fixtures/invalid/xsd-invalid_Positions.xml
if ($LASTEXITCODE -eq 0) { throw ".NET negative unexpectedly validated" }
Write-Host ".NET OK on Windows"
exit 0 # reset $LASTEXITCODE (the negative case left it at 1)
- name: CLI - validate.ps1 (remote URL, .NET fallback when no xmllint)
run: |
$xsd = "https://github.com/fundsxml/schema/releases/download/4.2.9/FundsXML.xsd"
pwsh XSD_Validation/cli/validate.ps1 $xsd FundsXML_Files/4.2.9/positions/Mixed-Fund_Positions.xml
if ($LASTEXITCODE -ne 0) { throw "validate.ps1 positive failed" }
pwsh XSD_Validation/cli/validate.ps1 $xsd tests/fixtures/invalid/xsd-invalid_Positions.xml
if ($LASTEXITCODE -eq 0) { throw "validate.ps1 negative unexpectedly validated" }
Write-Host "PowerShell CLI OK on Windows"
exit 0 # reset $LASTEXITCODE (the negative case left it at 1)
- name: DB round-trip (Python) on Windows
run: |
$fx = "FundsXML_Files/4.2.9/positions/Multi-Fund_Positions.xml"
.venv\Scripts\python Database_Integration/python/import_fundsxml.py fx.db $fx
if ($LASTEXITCODE -ne 0) { throw "import failed" }
.venv\Scripts\python Database_Integration/python/export_fundsxml.py fx.db FUNDSXML_MULTI_1 out.xml
if ($LASTEXITCODE -ne 0) { throw "export failed" }
.venv\Scripts\python Database_Integration/tools/xml_equiv.py $fx out.xml
if ($LASTEXITCODE -ne 0) { throw "round-trip not equivalent" }
Write-Host "DB round-trip OK on Windows"
exit 0