serialbench 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.github/scripts/push-to-data.sh +65 -0
  3. data/.github/workflows/benchmark.yml +98 -172
  4. data/.github/workflows/release.yml +68 -13
  5. data/Gemfile +1 -1
  6. data/config/benchmarks/full-json.yml +25 -0
  7. data/config/benchmarks/full-toml.yml +25 -0
  8. data/config/benchmarks/full-xml.yml +26 -0
  9. data/config/benchmarks/full-yaml.yml +25 -0
  10. data/config/benchmarks/full.yml +9 -4
  11. data/lib/serialbench/benchmark_runner.rb +32 -320
  12. data/lib/serialbench/cli/benchmark_cli.rb +1 -1
  13. data/lib/serialbench/cli.rb +0 -12
  14. data/lib/serialbench/models/benchmark_result.rb +2 -0
  15. data/lib/serialbench/models/result_store.rb +0 -38
  16. data/lib/serialbench/models.rb +0 -5
  17. data/lib/serialbench/serializers/base_serializer.rb +11 -3
  18. data/lib/serialbench/serializers/json/base_json_serializer.rb +8 -20
  19. data/lib/serialbench/serializers/json/json_serializer.rb +0 -16
  20. data/lib/serialbench/serializers/json/oj_serializer.rb +2 -17
  21. data/lib/serialbench/serializers/json/yajl_serializer.rb +2 -2
  22. data/lib/serialbench/serializers/toml/base_toml_serializer.rb +8 -29
  23. data/lib/serialbench/serializers/toml/toml_rb_serializer.rb +0 -16
  24. data/lib/serialbench/serializers/toml/tomlib_serializer.rb +0 -4
  25. data/lib/serialbench/serializers/toml/tomlrb_serializer.rb +2 -18
  26. data/lib/serialbench/serializers/xml/base_xml_serializer.rb +10 -26
  27. data/lib/serialbench/serializers/xml/leptris_serializer.rb +13 -10
  28. data/lib/serialbench/serializers/xml/libxml_serializer.rb +4 -9
  29. data/lib/serialbench/serializers/xml/nokogiri_serializer.rb +4 -9
  30. data/lib/serialbench/serializers/xml/oga_serializer.rb +6 -4
  31. data/lib/serialbench/serializers/xml/ox_serializer.rb +2 -2
  32. data/lib/serialbench/serializers/xml/rexml_serializer.rb +5 -12
  33. data/lib/serialbench/serializers/yaml/base_yaml_serializer.rb +1 -9
  34. data/lib/serialbench/serializers/yaml/syck_serializer.rb +0 -8
  35. data/lib/serialbench/test_data.rb +315 -0
  36. data/lib/serialbench/version.rb +1 -1
  37. data/lib/serialbench.rb +2 -1
  38. data/serialbench.gemspec +1 -2
  39. metadata +13 -59
  40. data/lib/serialbench/cli/resultset_cli.rb +0 -301
  41. data/lib/serialbench/models/result_set.rb +0 -79
  42. data/lib/serialbench/site_generator.rb +0 -337
  43. data/lib/serialbench/templates/assets/css/benchmark_report.css +0 -535
  44. data/lib/serialbench/templates/assets/css/format_based.css +0 -474
  45. data/lib/serialbench/templates/assets/css/themes.css +0 -589
  46. data/lib/serialbench/templates/assets/js/chart_helpers.js +0 -411
  47. data/lib/serialbench/templates/assets/js/dashboard.js +0 -795
  48. data/lib/serialbench/templates/assets/js/navigation.js +0 -142
  49. data/lib/serialbench/templates/base.liquid +0 -49
  50. data/lib/serialbench/templates/format_based.liquid +0 -507
  51. data/lib/serialbench/templates/partials/chart_section.liquid +0 -4
  52. data/site/.gitignore +0 -5
  53. data/site/README.md +0 -32
  54. data/site/astro.config.mjs +0 -12
  55. data/site/package-lock.json +0 -6160
  56. data/site/package.json +0 -22
  57. data/site/public/favicon.svg +0 -4
  58. data/site/scripts/gen-sample-data.mjs +0 -154
  59. data/site/src/components/AvailabilityMatrix.astro +0 -61
  60. data/site/src/components/CalibratedLeaderboard.vue +0 -134
  61. data/site/src/components/CitationBox.vue +0 -50
  62. data/site/src/components/DashboardConsole.vue +0 -193
  63. data/site/src/components/FeaturesTable.astro +0 -97
  64. data/site/src/components/MemoryPanel.vue +0 -44
  65. data/site/src/components/OpsChart.vue +0 -135
  66. data/site/src/config.ts +0 -18
  67. data/site/src/layouts/Layout.astro +0 -85
  68. data/site/src/lib/channels.ts +0 -24
  69. data/site/src/lib/dashboard.ts +0 -269
  70. data/site/src/pages/index.astro +0 -44
  71. data/site/src/pages/library/[slug].astro +0 -128
  72. data/site/src/pages/methodology.astro +0 -55
  73. data/site/src/styles/global.css +0 -103
  74. data/site/tsconfig.json +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff36b734da92061c2bbf271fd1e94f79f80d844f0b492c7f06a51aca5ed794aa
4
- data.tar.gz: 28aeb4041d3c1c04cdcfd4b5f5ad21757ed0616277bcf34b2db15c9d56a06b5a
3
+ metadata.gz: e90d8b6ebc8deebf308b1e02214b978597d0d2a9699c3845ebf6405953d733b7
4
+ data.tar.gz: 4cc9e46139f7054919657d66fd26ed6b40430856e0bdd317f2677451bc1bf715
5
5
  SHA512:
6
- metadata.gz: 9c497b089e84bc674bd444df875cc161ecf97b0d077d2ba9cb3c26cee91c27d8694cabc149b61f78c4fc0f9890b808a7604e6106e1d91aa04595c40a3cb6fa77
7
- data.tar.gz: 5a8eebcfe19699b5d9e1aed3caf1c65bec4937fe51199b8da0ef152e6145deab815621c354495279236f9b7c2e0eaa8e1c70eebdc1353ffb8ff6c89c900afeaa
6
+ metadata.gz: 38652e0714893c8ed9590fe1a7ef29c9c6e94cdbdcb0104d9190d12bad1c95f8635680b904d66b9edda72f55f7c037ce5e18894bf5fb66d5b88db21ba2dcaa3d
7
+ data.tar.gz: 728e8ee7c92138afdfd722cfb93ef7463c22e7d1c8882e5d83507dba7861637addd659e489df21c91a80a45680fc532eb0898f9ffed9ce48402a604962b73c85
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env bash
2
+ # Pushes one format's results.yaml to serialbench/data via the GitHub
3
+ # Contents API (atomic per-file, no merge conflicts from parallel legs).
4
+ # Called after each format's benchmark completes — the site rebuilds
5
+ # incrementally as data arrives.
6
+ set -euo pipefail
7
+
8
+ FMT="$1"
9
+ RUBY_VERSION="$2"
10
+ PLATFORM="$3"
11
+ RESULTS_FILE="results/runs/ci-ruby-${RUBY_VERSION}-${PLATFORM}/${FMT}/results.yaml"
12
+ DATA_TOKEN="${DATA_REPO_TOKEN:-}"
13
+
14
+ if [ -z "$DATA_TOKEN" ]; then
15
+ echo "::warning::DATA_REPO_TOKEN not set — skipping data push"
16
+ exit 0
17
+ fi
18
+
19
+ if [ ! -f "$RESULTS_FILE" ]; then
20
+ echo "::warning::No results at $RESULTS_FILE — skipping"
21
+ exit 0
22
+ fi
23
+
24
+ DATE=$(date -u +%Y-%m-%d)
25
+ TARGET_PATH="runs/${DATE}/${PLATFORM}-ruby-${RUBY_VERSION}.${FMT}.yaml"
26
+ CONTENT=$(base64 < "$RESULTS_FILE")
27
+
28
+ echo "Pushing ${TARGET_PATH} to serialbench/data..."
29
+
30
+ # Try create; if file exists (422), get sha and update
31
+ HTTP_CODE=$(curl -s -o /tmp/data-push-resp.json -w "%{http_code}" -X PUT \
32
+ -H "Authorization: Bearer ${DATA_TOKEN}" \
33
+ -H "Accept: application/vnd.github+json" \
34
+ "https://api.github.com/repos/serialbench/data/contents/${TARGET_PATH}" \
35
+ -d "{\"message\": \"${PLATFORM} ruby-${RUBY_VERSION} ${FMT}\", \"content\": \"${CONTENT}\", \"branch\": \"main\"}")
36
+
37
+ if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "201" ]; then
38
+ echo "Pushed ${TARGET_PATH}"
39
+ elif [ "$HTTP_CODE" = "422" ]; then
40
+ SHA=$(curl -sf \
41
+ -H "Authorization: Bearer ${DATA_TOKEN}" \
42
+ "https://api.github.com/repos/serialbench/data/contents/${TARGET_PATH}" \
43
+ | grep -oE '"sha":\s*"[a-f0-9]+"' | head -1 | grep -oE '[a-f0-9]{40}')
44
+ if [ -n "$SHA" ]; then
45
+ curl -sf -X PUT \
46
+ -H "Authorization: Bearer ${DATA_TOKEN}" \
47
+ -H "Accept: application/vnd.github+json" \
48
+ "https://api.github.com/repos/serialbench/data/contents/${TARGET_PATH}" \
49
+ -d "{\"message\": \"${PLATFORM} ruby-${RUBY_VERSION} ${FMT} (update)\", \"content\": \"${CONTENT}\", \"sha\": \"${SHA}\", \"branch\": \"main\"}" > /dev/null
50
+ echo "Updated existing ${TARGET_PATH}"
51
+ else
52
+ echo "::warning::422 but couldn't get sha for ${TARGET_PATH}"
53
+ fi
54
+ else
55
+ echo "::warning::Push failed (${HTTP_CODE}): $(cat /tmp/data-push-resp.json | head -c 200)"
56
+ fi
57
+
58
+ # Trigger site rebuild (debounced by concurrency group on the .io repo)
59
+ curl -sf -X POST \
60
+ -H "Authorization: Bearer ${DATA_TOKEN}" \
61
+ -H "Accept: application/vnd.github+json" \
62
+ "https://api.github.com/repos/serialbench/serialbench.github.io/dispatches" \
63
+ -d '{"event_type": "data-updated"}' \
64
+ && echo "Site rebuild triggered" \
65
+ || echo "::warning::Failed to trigger site rebuild"
@@ -16,13 +16,8 @@ on:
16
16
 
17
17
  permissions:
18
18
  contents: read
19
- pages: write
20
- id-token: write
21
19
 
22
20
  concurrency:
23
- # Renamed off "pages": that group's server-side state is wedged (a queued
24
- # run there returns 500 on cancel and blocks the single in-progress slot),
25
- # which starved every benchmark-weekly run after 2026-08-23 10:22Z.
26
21
  group: "site-deploy"
27
22
  cancel-in-progress: false
28
23
 
@@ -76,8 +71,6 @@ jobs:
76
71
  run: |
77
72
  vcpkg install libxml2:${{ steps.windows-arch.outputs.arch }} libxslt:${{ steps.windows-arch.outputs.arch }} 2>&1 || true
78
73
  vcpkg integrate install 2>&1 || true
79
- # vcpkg dynamic triplets put the DLLs in bin/; nokogiri's compiled
80
- # extension needs them on PATH at require time.
81
74
  echo "C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/bin" >> $GITHUB_PATH
82
75
  shell: bash
83
76
 
@@ -87,10 +80,6 @@ jobs:
87
80
  mkdir -p .bundle 2>&1 || true
88
81
  echo "---" > .bundle/config 2>&1 || true
89
82
  echo 'BUNDLE_BUILD__LIBXML___RUBY: "--with-xml2-dir=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }} --with-xml2-include=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/include/libxml2 --with-xml2-lib=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/lib"' >> .bundle/config 2>&1 || true
90
- # windows-11-arm has no precompiled nokogiri (pulled transitively via
91
- # moxml); build it against the vcpkg libxml2 instead of the vendored
92
- # source build that fails on ucrt/ARM64. Harmless on x64 Windows,
93
- # where the precompiled gem makes this config moot.
94
83
  echo 'BUNDLE_BUILD__NOKOGIRI: "--use-system-libraries --with-xml2-include=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/include/libxml2 --with-xml2-lib=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/lib --with-xslt-include=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/include/libxslt --with-xslt-lib=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/lib --with-zlib-dir=C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}"' >> .bundle/config 2>&1 || true
95
84
  shell: bash
96
85
 
@@ -100,14 +89,10 @@ jobs:
100
89
  ruby-version: ${{ matrix.ruby-version }}
101
90
  bundler-cache: true
102
91
 
103
- # The directory of ruby.exe is always in the DLL search path (unlike
104
- # PATH manipulation across step boundaries), so stage the vcpkg DLLs
105
- # there for the system-built nokogiri on Windows ARM.
106
92
  - name: Stage vcpkg DLLs beside ruby.exe (Windows)
107
93
  if: startsWith(matrix.platform, 'windows-')
108
94
  run: |
109
95
  RUBY_BIN="$(dirname "$(command -v ruby)")"
110
- echo "Staging vcpkg DLLs into $RUBY_BIN"
111
96
  ls "C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/bin/" || true
112
97
  cp -f "C:/vcpkg/installed/${{ steps.windows-arch.outputs.arch }}/bin/"*.dll "$RUBY_BIN/" 2>&1 || true
113
98
  shell: bash
@@ -123,48 +108,9 @@ jobs:
123
108
  run: |
124
109
  brew install libxml2 libxslt
125
110
 
126
- - name: Debug Ruby platform (Windows only)
127
- if: startsWith(matrix.platform, 'windows-')
128
- shell: ruby {0}
129
- run: |
130
- puts "=== Ruby Platform Debug Info ==="
131
- puts "RUBY_PLATFORM: #{RUBY_PLATFORM}"
132
- puts "Gem.win_platform?: #{Gem.win_platform?}"
133
- puts "RbConfig::CONFIG['host_os']: #{RbConfig::CONFIG['host_os']}"
134
- puts "RbConfig::CONFIG['host_cpu']: #{RbConfig::CONFIG['host_cpu']}"
135
- puts "RbConfig::CONFIG['arch']: #{RbConfig::CONFIG['arch']}"
136
- puts "================================"
137
-
138
111
  - name: Install gems
139
112
  run: bundle install
140
113
 
141
- # ubuntu-22.04's glibc (2.35) predates the precompiled leptris gem's
142
- # build host, so the gem's vendored libleptris.so fails to dlopen there
143
- # and the adapter reports leptris unavailable (empty availability dots
144
- # on the site). Leptris is pure C99 — build the lib from the gem's
145
- # tagged source and point the FFI loader at it; LEPTRIS_LIB_PATH is the
146
- # first candidate in the gem's ffi_lib list.
147
- - name: Build libleptris from source (Ubuntu 22.04)
148
- if: matrix.platform == 'ubuntu-22.04' || matrix.platform == 'ubuntu-22.04-arm'
149
- run: |
150
- LEPTRIS_VERSION=$(bundle exec ruby -e "require 'leptris'; print Leptris::VERSION")
151
- echo "Building libleptris ${LEPTRIS_VERSION}"
152
- curl -sL "https://github.com/leptris/leptris/archive/refs/tags/v${LEPTRIS_VERSION}.tar.gz" | tar xz
153
- cmake -S "leptris-${LEPTRIS_VERSION}" -B /tmp/leptris-build \
154
- -DLEPTRIS_BUILD_SHARED=ON -DLEPTRIS_BUILD_STATIC=OFF -DBUILD_TESTING=OFF \
155
- -DLEPTRIS_BUILD_CLI=OFF -DLEPTRIS_BUILD_BENCHMARKS=OFF -DLEPTRIS_BUILD_MAN_PAGES=OFF \
156
- -DLEPTRIS_ENABLE_UTF8PROC=OFF -DLEPTRIS_ENABLE_ICONV=OFF
157
- cmake --build /tmp/leptris-build -j"$(nproc)"
158
- LIBLEPTRIS=$(find /tmp/leptris-build -name 'libleptris.so*' -type f | head -1)
159
- echo "Built ${LIBLEPTRIS}"
160
- echo "LEPTRIS_LIB_PATH=${LIBLEPTRIS}" >> "$GITHUB_ENV"
161
- shell: bash
162
-
163
- - name: Update Ruby-Build cache
164
- run: bundle exec serialbench ruby-build update
165
- env:
166
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
167
-
168
114
  - name: Create environment config
169
115
  run: |
170
116
  mkdir -p config/environments
@@ -178,135 +124,124 @@ jobs:
178
124
  EOF
179
125
  shell: bash
180
126
 
181
- - name: Run benchmarks
127
+ # Each format is an independent checkpoint with its own upload.
128
+ # A failure in one format doesn't prevent the others from uploading.
129
+ - name: Benchmark xml
130
+ continue-on-error: true
131
+ shell: bash
182
132
  env:
183
133
  GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
184
134
  run: |
185
- bundle exec serialbench environment execute config/environments/ci-ruby-${{ matrix.ruby-version }}.yml config/benchmarks/full.yml results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}
135
+ bundle exec serialbench environment execute \
136
+ config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
137
+ config/benchmarks/full-xml.yml \
138
+ "results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/xml"
186
139
 
187
- - name: Verify benchmark results before upload
188
- run: |
189
- echo "=== Verifying benchmark results ==="
190
- RESULTS_FILE="results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/results.yaml"
191
-
192
- echo "📁 Checking file exists..."
193
- if [ ! -f "$RESULTS_FILE" ]; then
194
- echo "❌ ERROR: results.yaml not found at $RESULTS_FILE"
195
- exit 1
196
- fi
197
-
198
- echo "📊 Checking file size..."
199
- SIZE=$(wc -c < "$RESULTS_FILE" | tr -d ' ')
200
- echo " File size: $SIZE bytes"
201
-
202
- if [ "$SIZE" -lt 1000 ]; then
203
- echo "❌ ERROR: results.yaml is suspiciously small ($SIZE bytes)"
204
- echo " Expected at least 1000 bytes for valid benchmark results"
205
- echo "=== File contents ==="
206
- cat "$RESULTS_FILE"
207
- exit 1
208
- fi
140
+ - name: Upload xml
141
+ if: ${{ !cancelled() }}
142
+ uses: actions/upload-artifact@v4
143
+ with:
144
+ name: benchmark-results-${{ matrix.platform }}-ruby-${{ matrix.ruby-version }}-xml
145
+ path: results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/xml
146
+ retention-days: 30
147
+ if-no-files-found: warn
209
148
 
210
- echo "✅ File size OK: $SIZE bytes"
149
+ - name: Push xml to data repo
150
+ if: ${{ !cancelled() }}
151
+ continue-on-error: true
152
+ env:
153
+ DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
154
+ run: .github/scripts/push-to-data.sh xml ${{ matrix.ruby-version }} ${{ matrix.platform }}
211
155
  shell: bash
212
156
 
213
- - name: Validate YAML schema
157
+ - name: Benchmark json
158
+ continue-on-error: true
159
+ shell: bash
160
+ env:
161
+ GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
214
162
  run: |
215
- bundle exec serialbench validate result results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/results.yaml
163
+ bundle exec serialbench environment execute \
164
+ config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
165
+ config/benchmarks/full-json.yml \
166
+ "results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/json"
216
167
 
217
- - name: Upload benchmark results
168
+ - name: Upload json
169
+ if: ${{ !cancelled() }}
218
170
  uses: actions/upload-artifact@v4
219
171
  with:
220
- name: benchmark-results-${{ matrix.platform }}-ruby-${{ matrix.ruby-version }}
221
- path: results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}
172
+ name: benchmark-results-${{ matrix.platform }}-ruby-${{ matrix.ruby-version }}-json
173
+ path: results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/json
222
174
  retention-days: 30
175
+ if-no-files-found: warn
223
176
 
224
- # Aggregate results and deploy to GitHub Pages
225
- deploy-pages:
226
- if: github.ref == 'refs/heads/main'
227
- runs-on: ubuntu-latest
228
- needs: [setup, benchmark]
229
- environment:
230
- name: github-pages
231
- url: ${{ steps.deployment.outputs.page_url }}
232
-
233
- steps:
234
- - name: Checkout repository
235
- uses: actions/checkout@v4
236
-
237
- - name: Set up Ruby
238
- uses: ruby/setup-ruby@v1
239
- with:
240
- ruby-version: '3.3'
241
- bundler-cache: true
177
+ - name: Push json to data repo
178
+ if: ${{ !cancelled() }}
179
+ continue-on-error: true
180
+ env:
181
+ DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
182
+ run: .github/scripts/push-to-data.sh json ${{ matrix.ruby-version }} ${{ matrix.platform }}
183
+ shell: bash
242
184
 
243
- - name: Install system dependencies
185
+ - name: Benchmark yaml
186
+ continue-on-error: true
187
+ shell: bash
188
+ env:
189
+ GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
244
190
  run: |
245
- sudo apt-get update
246
- sudo apt-get install -y libxml2-dev libxslt1-dev build-essential
247
-
248
- - name: Install gems
249
- run: bundle install
191
+ bundle exec serialbench environment execute \
192
+ config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
193
+ config/benchmarks/full-yaml.yml \
194
+ "results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/yaml"
250
195
 
251
- - name: Download all benchmark artifacts
252
- uses: actions/download-artifact@v4
196
+ - name: Upload yaml
197
+ if: ${{ !cancelled() }}
198
+ uses: actions/upload-artifact@v4
253
199
  with:
254
- pattern: benchmark-results-*
255
- path: artifacts/
256
-
257
- - name: List downloaded artifacts structure
258
- run: |
259
- echo "=== Artifacts directory structure ==="
260
- ls -la artifacts/
261
- echo ""
262
- echo "=== Searching for results.yaml files ==="
263
- find artifacts/ -name "results.yaml" -type f
264
- echo ""
265
- echo "=== Directory tree (first 3 levels) ==="
266
- find artifacts/ -maxdepth 3 -type d | sort
267
-
268
- - name: Create resultset
269
- run: |
270
- mkdir -p results/sets
271
- bundle exec serialbench resultset create weekly-benchmark results/sets/weekly-benchmark
272
-
273
- - name: Add all results to resultset
274
- run: |
275
- bundle exec serialbench resultset add-result results/sets/weekly-benchmark artifacts/benchmark-results-*/
276
-
277
- - name: Export dashboard payload and raw data
278
- run: |
279
- bundle exec serialbench resultset export-data results/sets/weekly-benchmark site/src/data/sample.json --raw-data-dir site/public/data
200
+ name: benchmark-results-${{ matrix.platform }}-ruby-${{ matrix.ruby-version }}-yaml
201
+ path: results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/yaml
202
+ retention-days: 30
203
+ if-no-files-found: warn
280
204
 
281
- - name: Set up Node
282
- uses: actions/setup-node@v4
283
- with:
284
- node-version: '24'
285
- cache: npm
286
- cache-dependency-path: site/package-lock.json
205
+ - name: Push yaml to data repo
206
+ if: ${{ !cancelled() }}
207
+ continue-on-error: true
208
+ env:
209
+ DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
210
+ run: .github/scripts/push-to-data.sh yaml ${{ matrix.ruby-version }} ${{ matrix.platform }}
211
+ shell: bash
287
212
 
288
- - name: Build site
213
+ - name: Benchmark toml
214
+ continue-on-error: true
215
+ shell: bash
216
+ env:
217
+ GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
289
218
  run: |
290
- cd site
291
- npm ci
292
- npm run build
293
-
294
- - name: Setup Pages
295
- uses: actions/configure-pages@v4
219
+ bundle exec serialbench environment execute \
220
+ config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
221
+ config/benchmarks/full-toml.yml \
222
+ "results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/toml"
296
223
 
297
- - name: Upload to GitHub Pages
298
- uses: actions/upload-pages-artifact@v3
224
+ - name: Upload toml
225
+ if: ${{ !cancelled() }}
226
+ uses: actions/upload-artifact@v4
299
227
  with:
300
- path: site/dist
228
+ name: benchmark-results-${{ matrix.platform }}-ruby-${{ matrix.ruby-version }}-toml
229
+ path: results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/toml
230
+ retention-days: 30
231
+ if-no-files-found: warn
301
232
 
302
- - name: Deploy to GitHub Pages
303
- id: deployment
304
- uses: actions/deploy-pages@v4
233
+ - name: Push toml to data repo
234
+ if: ${{ !cancelled() }}
235
+ continue-on-error: true
236
+ env:
237
+ DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
238
+ run: .github/scripts/push-to-data.sh toml ${{ matrix.ruby-version }} ${{ matrix.platform }}
239
+ shell: bash
305
240
 
306
241
  # Summary job
307
242
  summary:
308
243
  runs-on: ubuntu-latest
309
- needs: [setup, benchmark, deploy-pages]
244
+ needs: [setup, benchmark]
310
245
  if: always()
311
246
  steps:
312
247
  - name: Generate workflow summary
@@ -314,28 +249,19 @@ jobs:
314
249
  echo "## Weekly Benchmark Summary" >> $GITHUB_STEP_SUMMARY
315
250
  echo "" >> $GITHUB_STEP_SUMMARY
316
251
  echo "**Benchmark Status**: ${{ needs.benchmark.result }}" >> $GITHUB_STEP_SUMMARY
317
- echo "**Deploy Status**: ${{ needs.deploy-pages.result }}" >> $GITHUB_STEP_SUMMARY
252
+ echo "**Incremental pushes**: each format pushes to data repo on completion" >> $GITHUB_STEP_SUMMARY
318
253
  echo "" >> $GITHUB_STEP_SUMMARY
319
254
  echo "### Platforms Tested" >> $GITHUB_STEP_SUMMARY
320
- echo "- Ubuntu Latest (Linux x86_64)" >> $GITHUB_STEP_SUMMARY
321
- echo "- Ubuntu 24.04 (Linux ARM64)" >> $GITHUB_STEP_SUMMARY
322
- echo "- Ubuntu 22.04 (Linux ARM64)" >> $GITHUB_STEP_SUMMARY
323
- echo "- macOS 14 (Apple Silicon ARM64)" >> $GITHUB_STEP_SUMMARY
324
- echo "- macOS 15 (Apple Silicon ARM64)" >> $GITHUB_STEP_SUMMARY
325
- echo "- macOS 15 Intel (Intel x86_64)" >> $GITHUB_STEP_SUMMARY
326
- echo "- macOS 26 (Apple Silicon ARM64)" >> $GITHUB_STEP_SUMMARY
327
- echo "- macOS 26 Intel (Intel x86_64)" >> $GITHUB_STEP_SUMMARY
255
+ echo "- Ubuntu 24.04 (x86_64 + ARM64)" >> $GITHUB_STEP_SUMMARY
256
+ echo "- Ubuntu 22.04 (x86_64 + ARM64)" >> $GITHUB_STEP_SUMMARY
257
+ echo "- macOS 14, 15, 26 (ARM64 + Intel)" >> $GITHUB_STEP_SUMMARY
258
+ echo "- Windows 2022, 2025, 11-ARM" >> $GITHUB_STEP_SUMMARY
328
259
  echo "" >> $GITHUB_STEP_SUMMARY
329
260
  echo "### Ruby Versions" >> $GITHUB_STEP_SUMMARY
330
261
  echo "- Ruby 3.2, 3.3, 3.4, 4.0" >> $GITHUB_STEP_SUMMARY
331
262
  echo "" >> $GITHUB_STEP_SUMMARY
332
- echo "### Serialization Libraries" >> $GITHUB_STEP_SUMMARY
333
- echo "- **XML**: REXML, Ox, Nokogiri, Oga, LibXML, Leptris" >> $GITHUB_STEP_SUMMARY
334
- echo "- **JSON**: JSON, Oj, RapidJSON, YAJL" >> $GITHUB_STEP_SUMMARY
335
- echo "- **YAML**: Psych" >> $GITHUB_STEP_SUMMARY
336
- echo "- **TOML**: TOML-RB, Tomlib, tomlrb" >> $GITHUB_STEP_SUMMARY
337
- echo "" >> $GITHUB_STEP_SUMMARY
338
263
  if [ "${{ github.ref }}" == "refs/heads/main" ]; then
339
264
  echo "### Results" >> $GITHUB_STEP_SUMMARY
340
- echo "📊 [View Interactive Dashboard](https://metanorma.github.io/serialbench/)" >> $GITHUB_STEP_SUMMARY
265
+ echo "📊 [View Dashboard](https://serialbench.github.io/serialbench/)" >> $GITHUB_STEP_SUMMARY
266
+ echo "📦 [Raw Data](https://github.com/serialbench/data)" >> $GITHUB_STEP_SUMMARY
341
267
  fi
@@ -1,5 +1,3 @@
1
- # Auto-generated by Cimas: Do not edit it manually!
2
- # See https://github.com/metanorma/cimas
3
1
  name: release
4
2
 
5
3
  on:
@@ -7,19 +5,76 @@ on:
7
5
  inputs:
8
6
  next_version:
9
7
  description: |
10
- Next release version. Possible values: x.y.z, major, minor, patch (or pre|rc|etc).
11
- Also, you can pass 'skip' to skip 'git tag' and do 'gem push' for the current version
8
+ Next release version. Possible values: x.y.z, major, minor, patch
9
+ (or pre|rc|etc).
12
10
  required: true
13
- default: 'skip'
14
- repository_dispatch:
15
- types: [ do-release ]
11
+ default: 'minor'
12
+ push:
13
+ tags: ['v*']
14
+
15
+ permissions:
16
+ contents: write
17
+ id-token: write
16
18
 
17
19
  jobs:
18
20
  release:
19
- uses: metanorma/ci/.github/workflows/rubygems-release.yml@main
20
- with:
21
- next_version: ${{ github.event.inputs.next_version }}
22
- secrets:
23
- rubygems-api-key: ${{ secrets.METANORMA_CI_RUBYGEMS_API_KEY }}
24
- pat_token: ${{ secrets.METANORMA_CI_PAT_TOKEN }}
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+
25
+ - uses: ruby/setup-ruby@v1
26
+ with:
27
+ ruby-version: '3.4'
28
+ bundler-cache: true
29
+
30
+ - name: Determine version
31
+ id: version
32
+ run: |
33
+ INPUT="${{ github.event.inputs.next_version }}"
34
+ if [ -z "$INPUT" ]; then
35
+ INPUT="${GITHUB_REF#refs/tags/v}"
36
+ echo "version=${INPUT}" >> "$GITHUB_OUTPUT"
37
+ elif echo "$INPUT" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+'; then
38
+ echo "version=${INPUT}" >> "$GITHUB_OUTPUT"
39
+ else
40
+ CURRENT=$(ruby -e "print Gem::Specification.load('serialbench.gemspec').version.to_s")
41
+ case "${INPUT}" in
42
+ major) NEW=$(echo "$CURRENT" | awk -F. '{print $1+1".0.0"}') ;;
43
+ minor) NEW=$(echo "$CURRENT" | awk -F. '{print $1"."$2+1".0"}') ;;
44
+ patch) NEW=$(echo "$CURRENT" | awk -F. '{print $1"."$2"."$3+1}') ;;
45
+ *) NEW="${INPUT}" ;;
46
+ esac
47
+ echo "version=${NEW}" >> "$GITHUB_OUTPUT"
48
+ fi
49
+
50
+ - name: Update version
51
+ run: |
52
+ VERSION=${{ steps.version.outputs.version }}
53
+ sed -i.bak "s/VERSION = .*/VERSION = '${VERSION}'/" lib/serialbench/version.rb
54
+ rm -f lib/serialbench/version.rb.bak
55
+ git config user.name "release-bot"
56
+ git config user.email "release-bot@users.noreply.github.com"
57
+ git add lib/serialbench/version.rb
58
+ git commit -m "Bump serialbench to ${VERSION}" || exit 0
59
+ git push origin HEAD:main
60
+
61
+ - name: Tag
62
+ run: |
63
+ VERSION=${{ steps.version.outputs.version }}
64
+ git tag "v${VERSION}" 2>/dev/null || true
65
+ git push origin "v${VERSION}" 2>/dev/null || true
66
+
67
+ - name: Build gem
68
+ run: gem build serialbench.gemspec
69
+
70
+ - name: Push to RubyGems
71
+ run: gem push serialbench-*.gem
72
+ env:
73
+ GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
25
74
 
75
+ - name: Create GitHub Release
76
+ run: |
77
+ VERSION=${{ steps.version.outputs.version }}
78
+ gh release create "v${VERSION}" --title "serialbench ${VERSION}" --generate-notes 2>/dev/null || true
79
+ env:
80
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
data/Gemfile CHANGED
@@ -12,7 +12,7 @@ unless Gem.win_platform? && RUBY_PLATFORM.include?('aarch64')
12
12
  gem 'libxml-ruby'
13
13
  end
14
14
 
15
- gem 'leptris' # Needs the libleptris shared library (LEPTRIS_LIB_PATH or system install)
15
+ gem 'leptris', '1.9.35' # precompiled platform gems bundle libleptris (darwin/linux/mingw)
16
16
  gem 'benchmark' # Removed from stdlib in Ruby 4.0
17
17
  gem 'base64' # Required for Ruby 3.4+
18
18
  gem 'lutaml-model', '~> 0.7'
@@ -0,0 +1,25 @@
1
+ # Per-format split of full.yml: each format runs in its own process so
2
+ # memory profiling of large documents cannot compound across formats
3
+ # (windows runners OOMed with all four formats in one process).
4
+ name: full-json
5
+
6
+ data_sizes:
7
+ - small
8
+ - medium
9
+ - large
10
+
11
+ formats:
12
+ - json
13
+
14
+ iterations:
15
+ small: 10
16
+ medium: 3
17
+ large: 1
18
+
19
+ operations:
20
+ - parse
21
+ - generate
22
+ - streaming
23
+ - memory
24
+
25
+ warmup: 2
@@ -0,0 +1,25 @@
1
+ # Per-format split of full.yml: each format runs in its own process so
2
+ # memory profiling of large documents cannot compound across formats
3
+ # (windows runners OOMed with all four formats in one process).
4
+ name: full-toml
5
+
6
+ data_sizes:
7
+ - small
8
+ - medium
9
+ - large
10
+
11
+ formats:
12
+ - toml
13
+
14
+ iterations:
15
+ small: 10
16
+ medium: 3
17
+ large: 1
18
+
19
+ operations:
20
+ - parse
21
+ - generate
22
+ - streaming
23
+ - memory
24
+
25
+ warmup: 2
@@ -0,0 +1,26 @@
1
+ # Per-format split of full.yml: each format runs in its own process so
2
+ # memory profiling of large documents cannot compound across formats
3
+ # (windows runners OOMed with all four formats in one process).
4
+ name: full-xml
5
+
6
+ data_sizes:
7
+ - small
8
+ - medium
9
+ - large
10
+
11
+ formats:
12
+ - xml
13
+
14
+ iterations:
15
+ small: 10
16
+ medium: 3
17
+ large: 1
18
+
19
+ operations:
20
+ - parse
21
+ - generate
22
+ - streaming
23
+ - xpath
24
+ - memory
25
+
26
+ warmup: 2
@@ -0,0 +1,25 @@
1
+ # Per-format split of full.yml: each format runs in its own process so
2
+ # memory profiling of large documents cannot compound across formats
3
+ # (windows runners OOMed with all four formats in one process).
4
+ name: full-yaml
5
+
6
+ data_sizes:
7
+ - small
8
+ - medium
9
+ - large
10
+
11
+ formats:
12
+ - yaml
13
+
14
+ iterations:
15
+ small: 10
16
+ medium: 3
17
+ large: 1
18
+
19
+ operations:
20
+ - parse
21
+ - generate
22
+ - streaming
23
+ - memory
24
+
25
+ warmup: 2