Skip to content

Commit 2e6d48f

Browse files
Add GitHub Actions workflow for archive determinism testing
Builds archives on both Windows and Linux runners using a small checked-in test fixture and the full Server directory from the public MS2Community/MapleStory2-XML repo. Verifies same-platform determinism (hard fail) and cross-platform determinism (currently differs due to platform-native ZLib implementation differences). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 93b6b3f commit 2e6d48f

6 files changed

Lines changed: 170 additions & 0 deletions

File tree

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
###############################################################################
44
* text=auto
55

6+
# Test fixtures must be byte-identical across platforms
7+
test-fixture/** -text
8+
69
###############################################################################
710
# Set default behavior for command prompt diff.
811
#

.github/workflows/determinism.yml

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
name: Archive Determinism Check
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
branches: [master]
8+
workflow_dispatch:
9+
10+
jobs:
11+
build-archive:
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
os: [ubuntu-latest, windows-latest]
16+
runs-on: ${{ matrix.os }}
17+
steps:
18+
- uses: actions/checkout@v4
19+
with:
20+
submodules: recursive
21+
22+
- uses: actions/setup-dotnet@v4
23+
with:
24+
dotnet-version: '8.0.x'
25+
26+
- name: Clone test data
27+
run: git clone --depth 1 https://github.com/MS2Community/MapleStory2-XML.git test-data
28+
29+
- name: Diagnose test data
30+
shell: bash
31+
run: |
32+
echo "File count:"
33+
find test-data/Server -type f | wc -l
34+
echo "Sample file raw:"
35+
sha256sum test-data/Server/AI/AI_Anos.xml || true
36+
wc -c test-data/Server/AI/AI_Anos.xml || true
37+
echo "Sample file after CRLF strip:"
38+
tr -d '\r' < test-data/Server/AI/AI_Anos.xml | sha256sum
39+
tr -d '\r' < test-data/Server/AI/AI_Anos.xml | wc -c
40+
echo "All files combined hash after CRLF strip:"
41+
find test-data/Server -type f | sort | while read f; do tr -d '\r' < "$f"; done | sha256sum
42+
43+
- name: Build
44+
run: dotnet build MS2Tools.sln -c Release
45+
46+
- name: Run tests
47+
run: dotnet test MS2Lib/MS2Lib.Tests/MS2Lib.Tests.csproj -c Release --no-build
48+
49+
- name: Create archive from test-fixture (run 1)
50+
run: dotnet run --project MS2Create -c Release --no-build -- ./test-fixture ./out-fixture1 TestFixture MS2F
51+
52+
- name: Create archive from test-fixture (run 2)
53+
run: dotnet run --project MS2Create -c Release --no-build -- ./test-fixture ./out-fixture2 TestFixture MS2F
54+
55+
- name: Create archive from Server (run 1)
56+
run: dotnet run --project MS2Create -c Release --no-build -- ./test-data/Server ./out-server1 Server MS2F
57+
58+
- name: Create archive from Server (run 2)
59+
run: dotnet run --project MS2Create -c Release --no-build -- ./test-data/Server ./out-server2 Server MS2F
60+
61+
- name: Archive file sizes
62+
shell: bash
63+
run: |
64+
ls -la out-server1/Server.m2d out-server1/Server.m2h
65+
66+
- name: Hash outputs
67+
shell: bash
68+
run: |
69+
echo "=== Test Fixture ==="
70+
sha256sum out-fixture1/TestFixture.m2d out-fixture1/TestFixture.m2h
71+
sha256sum out-fixture2/TestFixture.m2d out-fixture2/TestFixture.m2h
72+
awk '{print $1}' <(sha256sum out-fixture1/TestFixture.m2d out-fixture1/TestFixture.m2h) > fixture-run1.txt
73+
awk '{print $1}' <(sha256sum out-fixture2/TestFixture.m2d out-fixture2/TestFixture.m2h) > fixture-run2.txt
74+
echo "=== Server ==="
75+
sha256sum out-server1/Server.m2d out-server1/Server.m2h
76+
sha256sum out-server2/Server.m2d out-server2/Server.m2h
77+
awk '{print $1}' <(sha256sum out-server1/Server.m2d out-server1/Server.m2h) > server-run1.txt
78+
awk '{print $1}' <(sha256sum out-server2/Server.m2d out-server2/Server.m2h) > server-run2.txt
79+
80+
- name: Verify same-platform determinism (test-fixture)
81+
shell: bash
82+
run: |
83+
if diff fixture-run1.txt fixture-run2.txt; then
84+
echo "PASS: Test fixture — same-platform runs are identical"
85+
else
86+
echo "FAIL: Test fixture — same-platform runs differ!"
87+
exit 1
88+
fi
89+
90+
- name: Verify same-platform determinism (Server)
91+
shell: bash
92+
run: |
93+
if diff server-run1.txt server-run2.txt; then
94+
echo "PASS: Server — same-platform runs are identical"
95+
else
96+
echo "FAIL: Server — same-platform runs differ!"
97+
exit 1
98+
fi
99+
100+
- name: Upload hashes
101+
uses: actions/upload-artifact@v4
102+
with:
103+
name: hashes-${{ matrix.os }}
104+
path: server-run1.txt
105+
106+
- name: Upload archive for comparison
107+
if: always()
108+
uses: actions/upload-artifact@v4
109+
with:
110+
name: archive-${{ matrix.os }}
111+
path: out-server1/
112+
113+
compare-platforms:
114+
needs: build-archive
115+
runs-on: ubuntu-latest
116+
steps:
117+
- name: Download Windows hashes
118+
uses: actions/download-artifact@v4
119+
with:
120+
name: hashes-windows-latest
121+
path: win
122+
123+
- name: Download Linux hashes
124+
uses: actions/download-artifact@v4
125+
with:
126+
name: hashes-ubuntu-latest
127+
path: linux
128+
129+
- name: Compare cross-platform hashes (Server)
130+
run: |
131+
echo "=== Windows ==="
132+
cat win/server-run1.txt
133+
echo "=== Linux ==="
134+
cat linux/server-run1.txt
135+
echo "=== Diff ==="
136+
if diff win/server-run1.txt linux/server-run1.txt; then
137+
echo "PASS: Cross-platform Server archives are byte-identical!"
138+
else
139+
echo "FAIL: Cross-platform Server archives differ"
140+
exit 1
141+
fi

test-fixture/a.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<ms2>
2+
<environment>
3+
<property name="test" value="determinism check" />
4+
<property name="id" value="1001" />
5+
<property name="description" value="This is a test fixture for verifying cross-platform archive determinism." />
6+
</environment>
7+
</ms2>

test-fixture/b.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<ms2>
2+
<npc id="2001" name="TestNPC">
3+
<stats hp="1000" mp="500" level="10" />
4+
<dialogue>
5+
<line id="1">Hello adventurer!</line>
6+
<line id="2">Welcome to MapleStory 2.</line>
7+
</dialogue>
8+
</npc>
9+
</ms2>

test-fixture/subdir/c.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<ms2>
2+
<item id="30000001" name="Sword of Testing">
3+
<stats attack="100" defense="0" speed="5" />
4+
<requirements level="1" job="knight" />
5+
<description>A trusty sword used for testing archive determinism.</description>
6+
</item>
7+
</ms2>

test-fixture/subdir/d.zlib

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Binary test content for zlib compression type detection.
2+
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
3+
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

0 commit comments

Comments
 (0)