Skip to content

Commit 985b919

Browse files
Merge pull request #28 from raphaelmansuy/bench/ooda-score-improvement-2026-03-25
feat: ship benchmark frontier and full release automation
2 parents f7e702e + d00b176 commit 985b919

602 files changed

Lines changed: 41713 additions & 16024 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,23 @@ jobs:
1111
name: Rust — build & test
1212
runs-on: ${{ matrix.os }}
1313
strategy:
14+
fail-fast: false
1415
matrix:
1516
os: [ubuntu-latest, macos-14, windows-latest]
1617
steps:
1718
- uses: actions/checkout@v4
19+
- name: Install Poppler (Ubuntu)
20+
if: runner.os == 'Linux'
21+
run: |
22+
sudo apt-get update
23+
sudo apt-get install -y poppler-utils
24+
- name: Install Poppler (macOS)
25+
if: runner.os == 'macOS'
26+
run: brew install poppler
27+
- name: Install Poppler (Windows)
28+
if: runner.os == 'Windows'
29+
shell: pwsh
30+
run: choco install poppler -y
1831
- uses: dtolnay/rust-toolchain@stable
1932
- uses: Swatinem/rust-cache@v2
2033
- run: cargo build
@@ -55,10 +68,28 @@ jobs:
5568
# Install the platform binary into the local package directory
5669
cp ../../target/release/libedgeparse_node.so npm/linux-x64-gnu/edgeparse-node.linux-x64-gnu.node
5770
# Install the local platform package so require('edgeparse-linux-x64-gnu') resolves
58-
npm install --save-dev file:./npm/linux-x64-gnu
71+
npm install --no-save file:./npm/linux-x64-gnu
5972
npm run build:ts
6073
npm test
6174
75+
wasm:
76+
name: WASM SDK — build
77+
runs-on: ubuntu-latest
78+
steps:
79+
- uses: actions/checkout@v4
80+
- uses: dtolnay/rust-toolchain@stable
81+
with:
82+
targets: wasm32-unknown-unknown
83+
- uses: Swatinem/rust-cache@v2
84+
- run: cargo check -p edgeparse-wasm --target wasm32-unknown-unknown
85+
86+
docker:
87+
name: Docker — smoke build
88+
runs-on: ubuntu-latest
89+
steps:
90+
- uses: actions/checkout@v4
91+
- run: docker build -f docker/Dockerfile .
92+
6293
security:
6394
name: Security audit
6495
runs-on: ubuntu-latest

.github/workflows/release-node.yml

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ on:
66
workflow_dispatch:
77
inputs:
88
tag_name:
9-
description: 'Tag name to publish (e.g. v0.2.0) — used for version sync'
9+
description: 'Tag name to publish (e.g. v0.2.1) — used for version sync'
1010
required: true
11-
default: 'v0.2.0'
11+
default: 'v0.2.1'
1212

1313
permissions:
1414
contents: read
@@ -133,12 +133,26 @@ jobs:
133133
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
134134
run: |
135135
for dir in sdks/node/npm/*/; do
136-
(cd "$dir" && npm publish --access public) || echo "::warning::Failed to publish $dir"
136+
OUTPUT=$((cd "$dir" && npm publish --access public) 2>&1) && echo "$OUTPUT" || {
137+
echo "$OUTPUT"
138+
if echo "$OUTPUT" | grep -Eq "cannot publish over the previously published versions|You cannot publish over the previously published version"; then
139+
echo "::warning::Package already published for $dir — skipping."
140+
else
141+
exit 1
142+
fi
143+
}
137144
done
138145
139146
- name: Publish edgeparse (main package)
140147
env:
141148
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
142149
run: |
143150
cd sdks/node
144-
npm publish --access public
151+
OUTPUT=$(npm publish --access public 2>&1) && echo "$OUTPUT" || {
152+
echo "$OUTPUT"
153+
if echo "$OUTPUT" | grep -Eq "cannot publish over the previously published versions|You cannot publish over the previously published version"; then
154+
echo "edgeparse already published at this version — skipping."
155+
else
156+
exit 1
157+
fi
158+
}

.github/workflows/release-wasm.yml

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
name: Release — WASM SDK (npm)
2+
3+
on:
4+
push:
5+
tags: ['v[0-9]+.[0-9]+.[0-9]+']
6+
workflow_dispatch:
7+
inputs:
8+
tag_name:
9+
description: 'Tag name to publish (e.g. v0.2.1) — used for version sync'
10+
required: true
11+
default: 'v0.2.1'
12+
13+
permissions:
14+
contents: write
15+
16+
jobs:
17+
publish-wasm:
18+
name: Publish WASM package
19+
runs-on: ubuntu-latest
20+
environment: npm
21+
steps:
22+
- uses: actions/checkout@v4
23+
- uses: actions/setup-node@v4
24+
with:
25+
node-version: '20'
26+
registry-url: 'https://registry.npmjs.org'
27+
- uses: dtolnay/rust-toolchain@stable
28+
with:
29+
targets: wasm32-unknown-unknown
30+
- uses: Swatinem/rust-cache@v2
31+
- uses: taiki-e/install-action@wasm-pack
32+
33+
- name: Verify version consistency
34+
env:
35+
INPUT_TAG_NAME: ${{ inputs.tag_name }}
36+
run: |
37+
TAG_NAME="${INPUT_TAG_NAME:-$GITHUB_REF_NAME}"
38+
TAG_VERSION="${TAG_NAME#v}"
39+
CARGO_VERSION=$(cargo metadata --no-deps --format-version 1 \
40+
| jq -r '.packages[] | select(.name=="edgeparse-wasm") | .version')
41+
if [[ "$TAG_VERSION" != "$CARGO_VERSION" ]]; then
42+
echo "ERROR: tag $TAG_VERSION ≠ Cargo.toml $CARGO_VERSION"
43+
exit 1
44+
fi
45+
46+
- name: Build WASM package
47+
run: |
48+
cd crates/edgeparse-wasm
49+
wasm-pack build --target web --release
50+
51+
- name: Sync npm metadata
52+
env:
53+
INPUT_TAG_NAME: ${{ inputs.tag_name }}
54+
run: |
55+
node -e "
56+
const fs = require('fs');
57+
const refName = process.env.INPUT_TAG_NAME || process.env.GITHUB_REF_NAME;
58+
const version = refName.replace(/^v/, '');
59+
const path = 'crates/edgeparse-wasm/pkg/package.json';
60+
const pkg = JSON.parse(fs.readFileSync(path, 'utf8'));
61+
pkg.name = '@edgeparse/edgeparse-wasm';
62+
pkg.version = version;
63+
pkg.description = 'EdgeParse PDF parser — WebAssembly build for browsers';
64+
pkg.repository = {
65+
type: 'git',
66+
url: 'https://github.com/raphaelmansuy/edgeparse'
67+
};
68+
pkg.files = [
69+
'edgeparse_wasm_bg.wasm',
70+
'edgeparse_wasm.js',
71+
'edgeparse_wasm.d.ts'
72+
];
73+
fs.writeFileSync(path, JSON.stringify(pkg, null, 2) + '\n');
74+
console.log('Version synced to: ' + version);
75+
"
76+
77+
- name: Pack npm tarball
78+
run: |
79+
cd crates/edgeparse-wasm/pkg
80+
npm pack
81+
82+
- uses: actions/upload-artifact@v4
83+
with:
84+
name: wasm-package
85+
path: crates/edgeparse-wasm/pkg/*.tgz
86+
87+
- name: Publish WASM package to npm
88+
env:
89+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
90+
run: |
91+
cd crates/edgeparse-wasm/pkg
92+
OUTPUT=$(npm publish --access public 2>&1) && echo "$OUTPUT" || {
93+
echo "$OUTPUT"
94+
if echo "$OUTPUT" | grep -Eq "cannot publish over the previously published versions|You cannot publish over the previously published version"; then
95+
echo "@edgeparse/edgeparse-wasm already published at this version — skipping."
96+
else
97+
exit 1
98+
fi
99+
}
100+
101+
- name: Upload npm tarball to GitHub Release
102+
env:
103+
GH_TOKEN: ${{ github.token }}
104+
INPUT_TAG_NAME: ${{ inputs.tag_name }}
105+
run: |
106+
TAG_NAME="${INPUT_TAG_NAME:-$GITHUB_REF_NAME}"
107+
gh release upload "$TAG_NAME" crates/edgeparse-wasm/pkg/*.tgz \
108+
--repo "${{ github.repository }}" --clobber

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,25 @@ this project adheres to [Semantic Versioning](https://semver.org/).
77

88
---
99

10+
## [0.2.1] — 2026-03-26
11+
12+
### Added
13+
- Dedicated `release-wasm.yml` workflow to publish `@edgeparse/edgeparse-wasm` on tagged releases and attach the npm tarball to the GitHub Release
14+
- CI coverage for the WASM target and Docker image smoke builds so every shipped artifact is validated before release
15+
- Release-channel documentation in the README covering crates, SDKs, CLI archives, Homebrew, and container images
16+
17+
### Changed
18+
- Bumped the workspace and published SDK manifests to `0.2.1`
19+
- Local release helpers now publish `pdf-cos` before `edgeparse-core`, matching the crates.io CI workflow
20+
- `make publish-all` now includes the WASM SDK release path
21+
- README benchmark results updated to the latest 200-document `opendataloader.org` comparison, where EdgeParse leads the published field on every reported metric
22+
23+
### Fixed
24+
- Removed stale release documentation that still described five workflows and partial manual workarounds for older releases
25+
- Updated install guidance to reflect Linux `glibc >= 2.17` compatibility for release binaries
26+
27+
---
28+
1029
## [0.2.0] — 2026-03-24
1130

1231
### Added

Cargo.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ default-members = [
1515
]
1616

1717
[workspace.package]
18-
version = "0.2.0"
18+
version = "0.2.1"
1919
edition = "2021"
2020
rust-version = "1.85"
2121
license = "Apache-2.0"

Makefile

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919
bench-engines bench-non-ocr bench-ocr bench-compare-all bench-report \
2020
run demo \
2121
publish-rust publish-rust-dry publish-python publish-python-dry \
22-
publish-node publish-node-dry \
22+
publish-node publish-node-dry publish-wasm publish-wasm-dry \
2323
publish-cli publish-cli-dry \
2424
publish-brew publish-brew-dry \
25+
wasm-build wasm-check wasm-size wasm-clean \
2526
publish-all \
2627
clean clean-bench clean-all
2728

@@ -221,14 +222,28 @@ bench-report: bench-setup ## Regenerate HTML report from existing results (no r
221222
# ══════════════════════════════════════════════════════════════════════════════
222223

223224
# ── Rust / crates.io ──────────────────────────────────────────────────────────
224-
publish-rust-dry: ## Dry-run: verify edgeparse-core + edgeparse-cli can be published
225+
publish-rust-dry: ## Dry-run: verify pdf-cos + edgeparse-core publish cleanly and edgeparse-cli packages cleanly
226+
$(call log,cargo publish --dry-run [pdf-cos])
227+
@cargo publish -p pdf-cos --dry-run --allow-dirty
225228
$(call log,cargo publish --dry-run [edgeparse-core])
226-
@cargo publish -p edgeparse-core --dry-run
227-
$(call log,cargo publish --dry-run [edgeparse-cli])
228-
@cargo publish -p edgeparse-cli --dry-run
229+
@cargo publish -p edgeparse-core --dry-run --allow-dirty
230+
$(call log,cargo package --allow-dirty [edgeparse-cli])
231+
@OUTPUT=$$(cargo package -p edgeparse-cli --allow-dirty 2>&1) && echo "$$OUTPUT" || { \
232+
echo "$$OUTPUT"; \
233+
if echo "$$OUTPUT" | grep -q 'location searched: crates.io index' \
234+
&& echo "$$OUTPUT" | grep -q 'required by package `edgeparse-cli'; then \
235+
printf "$(BOLD)$(YELLOW)$(RESET) $(YELLOW)edgeparse-cli package dry-run requires edgeparse-core $(VERSION) to already exist on crates.io; the tagged CI release handles that publish order.$(RESET)\n"; \
236+
else \
237+
exit 1; \
238+
fi; \
239+
}
229240
$(call ok,Rust dry-run passed — ready for crates.io)
230241

231-
publish-rust: ## Publish edgeparse-core then edgeparse-cli to crates.io
242+
publish-rust: ## Publish pdf-cos, edgeparse-core, then edgeparse-cli to crates.io
243+
$(call log,Publishing pdf-cos to crates.io ...)
244+
@cargo publish -p pdf-cos
245+
$(call log,Waiting 30 s for crates.io index to propagate ...)
246+
@sleep 30
232247
$(call log,Publishing edgeparse-core to crates.io ...)
233248
@cargo publish -p edgeparse-core
234249
$(call log,Waiting 30 s for crates.io index to propagate ...)
@@ -502,9 +517,36 @@ publish-brew: ## Generate Homebrew formula and push to $(BREW_TAP_REPO)
502517
rm -rf "$$TAPDIR"
503518
$(call ok,Homebrew formula v$(VERSION) pushed to $(BREW_TAP_REPO))
504519

520+
# ── WASM / npm ────────────────────────────────────────────────────────────────
521+
publish-wasm-dry: ## Dry-run: build the WASM package and preview the npm tarball
522+
$(call log,Building WebAssembly package [dry-run] ...)
523+
@command -v wasm-pack >/dev/null 2>&1 || { \
524+
$(call err,wasm-pack not found — install: cargo install wasm-pack); \
525+
exit 1; }
526+
@cd crates/edgeparse-wasm && wasm-pack build --target web --release
527+
@node -e "const fs=require('fs');const p='crates/edgeparse-wasm/pkg/package.json';const pkg=JSON.parse(fs.readFileSync(p,'utf8'));pkg.name='@edgeparse/edgeparse-wasm';pkg.version='$(VERSION)';fs.writeFileSync(p,JSON.stringify(pkg,null,2)+'\n');"
528+
@cd crates/edgeparse-wasm/pkg && npm pack --dry-run
529+
$(call ok,WASM dry-run passed — ready for npm)
530+
531+
publish-wasm: ## Build and publish the WASM npm package (@edgeparse/edgeparse-wasm)
532+
ifndef NPM_TOKEN
533+
$(call err,NPM_TOKEN is required. Usage: NPM_TOKEN=<token> make publish-wasm)
534+
@exit 1
535+
endif
536+
$(call log,Publishing @edgeparse/edgeparse-wasm to npm ...)
537+
@command -v wasm-pack >/dev/null 2>&1 || { \
538+
$(call err,wasm-pack not found — install: cargo install wasm-pack); \
539+
exit 1; }
540+
@printf "//registry.npmjs.org/:_authToken=%s\n" "$(NPM_TOKEN)" > ~/.npmrc
541+
@cd crates/edgeparse-wasm && wasm-pack build --target web --release
542+
@node -e "const fs=require('fs');const p='crates/edgeparse-wasm/pkg/package.json';const pkg=JSON.parse(fs.readFileSync(p,'utf8'));pkg.name='@edgeparse/edgeparse-wasm';pkg.version='$(VERSION)';fs.writeFileSync(p,JSON.stringify(pkg,null,2)+'\n');"
543+
@cd crates/edgeparse-wasm/pkg && npm publish --access public
544+
@rm -f ~/.npmrc
545+
$(call ok,WASM package published to npm)
546+
505547
# ── Combined ──────────────────────────────────────────────────────────────────
506-
publish-all: publish-rust publish-python publish-node publish-cli publish-brew ## Publish everything: Rust crates + Python wheels + Node.js packages + CLI binaries + Homebrew formula
507-
$(call ok,All SDKs + CLI + Homebrew tap published)
548+
publish-all: publish-rust publish-python publish-node publish-wasm publish-cli publish-brew ## Publish everything: crates + Python + Node + WASM + CLI + Homebrew
549+
$(call ok,All publish targets completed)
508550

509551
# ══════════════════════════════════════════════════════════════════════════════
510552
## WASM
@@ -513,12 +555,12 @@ publish-all: publish-rust publish-python publish-node publish-cli publish-brew #
513555
WASM_CRATE := crates/edgeparse-wasm
514556

515557
wasm-build: ## Build WASM package (release, --target web)
516-
$(call info,Building WASM package...)
558+
$(call log,Building WASM package...)
517559
@cd $(WASM_CRATE) && wasm-pack build --target web --release --scope edgeparse
518560
$(call ok,WASM package built → $(WASM_CRATE)/pkg/)
519561

520562
wasm-check: ## Check WASM compilation (fast, no codegen)
521-
$(call info,Checking WASM compilation...)
563+
$(call log,Checking WASM compilation...)
522564
@cargo check --target wasm32-unknown-unknown -p edgeparse-wasm
523565
$(call ok,WASM check passed)
524566

0 commit comments

Comments
 (0)