Skip to content

Commit 3d5f21a

Browse files
chore: publish edgeparse-wasm to npm + GitHub Packages (v0.2.4)
Enables edgeparse-wasm publication on npm and GitHub Packages. Adds CDN examples, framework quick-starts, and NPM_TOKEN setup docs. Bumps workspace to v0.2.4.
1 parent b04309b commit 3d5f21a

7 files changed

Lines changed: 463 additions & 94 deletions

File tree

.github/workflows/release-wasm.yml

Lines changed: 106 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,47 @@
1-
name: Release — WASM SDK (npm)
1+
name: Release — WASM SDK (npm + GitHub Packages)
22

33
on:
44
push:
55
tags: ['v[0-9]+.[0-9]+.[0-9]+']
66
workflow_dispatch:
77
inputs:
88
tag_name:
9-
description: 'Tag name to publish (e.g. v0.2.2) — used for version sync'
9+
description: 'Tag name to publish (e.g. v0.2.4) — used for version sync'
1010
required: true
11-
default: 'v0.2.2'
11+
default: 'v0.2.4'
1212

1313
permissions:
14-
contents: write
14+
contents: write # upload GitHub Release assets
15+
packages: write # publish to GitHub Packages npm registry
1516

1617
jobs:
1718
publish-wasm:
18-
name: Publish WASM package
19+
name: Build & publish WASM package
1920
runs-on: ubuntu-latest
2021
environment: npm
22+
2123
steps:
2224
- uses: actions/checkout@v4
25+
26+
# Node.js is needed for npm pack / publish and wasm-pack post-processing.
27+
# Registry URL is overridden per-publish step via .npmrc; the value here
28+
# merely ensures `NODE_AUTH_TOKEN` is wired into the environment.
2329
- uses: actions/setup-node@v4
2430
with:
2531
node-version: '20'
2632
registry-url: 'https://registry.npmjs.org'
33+
2734
- uses: dtolnay/rust-toolchain@stable
2835
with:
2936
targets: wasm32-unknown-unknown
37+
3038
- uses: Swatinem/rust-cache@v2
39+
3140
- uses: taiki-e/install-action@wasm-pack
3241

42+
# ─────────────────────────────────────────────────────────────────────
43+
# 1. Verify that the Git tag matches the Cargo workspace version.
44+
# ─────────────────────────────────────────────────────────────────────
3345
- name: Verify version consistency
3446
env:
3547
INPUT_TAG_NAME: ${{ inputs.tag_name }}
@@ -42,79 +54,145 @@ jobs:
4254
echo "ERROR: tag $TAG_VERSION ≠ Cargo.toml $CARGO_VERSION"
4355
exit 1
4456
fi
57+
echo "VERSION=$TAG_VERSION" >> "$GITHUB_ENV"
58+
echo "TAG_NAME=$TAG_NAME" >> "$GITHUB_ENV"
4559
60+
# ─────────────────────────────────────────────────────────────────────
61+
# 2. Compile the Rust crate to WebAssembly and generate JS/TS glue.
62+
# ─────────────────────────────────────────────────────────────────────
4663
- name: Build WASM package
4764
run: |
4865
cd crates/edgeparse-wasm
4966
wasm-pack build --target web --release
5067
51-
- name: Sync npm metadata
52-
env:
53-
INPUT_TAG_NAME: ${{ inputs.tag_name }}
68+
# ─────────────────────────────────────────────────────────────────────
69+
# 3. Patch pkg/package.json with release metadata (shared across both
70+
# registries; the name/scope is adjusted per publish step below).
71+
# ─────────────────────────────────────────────────────────────────────
72+
- name: Sync package metadata
5473
run: |
5574
node -e "
5675
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-wasm';
62-
pkg.version = version;
76+
const version = process.env.VERSION;
77+
const pkgPath = 'crates/edgeparse-wasm/pkg/package.json';
78+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
79+
pkg.version = version;
6380
pkg.description = 'EdgeParse PDF parser — WebAssembly build for browsers';
64-
pkg.homepage = 'https://edgeparse.io/docs/api/wasm/';
65-
pkg.repository = {
81+
pkg.homepage = 'https://edgeparse.io/docs/api/wasm/';
82+
pkg.keywords = ['pdf', 'parser', 'wasm', 'webassembly', 'browser', 'extraction', 'markdown'];
83+
pkg.repository = {
6684
type: 'git',
6785
url: 'git+https://github.com/raphaelmansuy/edgeparse.git',
6886
directory: 'crates/edgeparse-wasm'
6987
};
70-
pkg.publishConfig = { access: 'public' };
88+
pkg.exports = {
89+
'.': { import: './edgeparse_wasm.js', types: './edgeparse_wasm.d.ts' }
90+
};
7191
pkg.files = [
7292
'edgeparse_wasm_bg.wasm',
7393
'edgeparse_wasm.js',
7494
'edgeparse_wasm.d.ts',
95+
'edgeparse_wasm_bg.wasm.d.ts',
7596
'README.md',
7697
'LICENSE'
7798
];
78-
fs.writeFileSync(path, JSON.stringify(pkg, null, 2) + '\n');
79-
console.log('Version synced to: ' + version);
99+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
100+
console.log('Metadata synced to version: ' + version);
80101
"
81102
82-
- name: Stage package docs
103+
- name: Stage README and LICENSE
83104
run: |
84105
cp README.md crates/edgeparse-wasm/pkg/README.md
85-
cp LICENSE crates/edgeparse-wasm/pkg/LICENSE
106+
cp LICENSE crates/edgeparse-wasm/pkg/LICENSE
86107
108+
# ─────────────────────────────────────────────────────────────────────
109+
# 4. Pack the tarball once (reused by both registries and the Release).
110+
# ─────────────────────────────────────────────────────────────────────
87111
- name: Pack npm tarball
88112
run: |
113+
node -e "
114+
const fs = require('fs');
115+
const pkgPath = 'crates/edgeparse-wasm/pkg/package.json';
116+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
117+
pkg.name = 'edgeparse-wasm';
118+
pkg.publishConfig = { access: 'public', registry: 'https://registry.npmjs.org' };
119+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
120+
"
89121
cd crates/edgeparse-wasm/pkg
90122
npm pack
91123
92124
- uses: actions/upload-artifact@v4
93125
with:
94126
name: wasm-package
95127
path: crates/edgeparse-wasm/pkg/*.tgz
128+
retention-days: 30
129+
130+
# ─────────────────────────────────────────────────────────────────────
131+
# 5a. Publish to npm (primary registry — enables jsDelivr & unpkg CDNs).
132+
# Uses NPM_TOKEN Classic Automation token stored as a repository
133+
# secret. "already-published" is treated as idempotent.
134+
# ─────────────────────────────────────────────────────────────────────
135+
- name: Publish to npm registry
136+
env:
137+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
138+
run: |
139+
node -e "
140+
const fs = require('fs');
141+
const pkgPath = 'crates/edgeparse-wasm/pkg/package.json';
142+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
143+
pkg.name = 'edgeparse-wasm';
144+
pkg.publishConfig = { access: 'public', registry: 'https://registry.npmjs.org' };
145+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
146+
"
147+
cd crates/edgeparse-wasm/pkg
148+
npm publish --access public --registry https://registry.npmjs.org \
149+
|| { CODE=$?; [ "$CODE" -eq 1 ] && npm info edgeparse-wasm@${{ env.VERSION }} >/dev/null 2>&1 && echo "Already published — skipping." || exit $CODE; }
96150
97-
- name: Skip WASM npm publication
151+
# ─────────────────────────────────────────────────────────────────────
152+
# 5b. Publish to GitHub Packages (secondary registry — useful for
153+
# enterprise / GitHub-native consumers).
154+
# The package is scoped as @raphaelmansuy/edgeparse-wasm.
155+
# Uses the built-in GITHUB_TOKEN — no extra secret required.
156+
# ─────────────────────────────────────────────────────────────────────
157+
- name: Publish to GitHub Packages
158+
env:
159+
NODE_AUTH_TOKEN: ${{ github.token }}
98160
run: |
99-
echo "::warning::WASM npm publication is disabled. The package tarball will still be uploaded to the GitHub Release."
161+
node -e "
162+
const fs = require('fs');
163+
const pkgPath = 'crates/edgeparse-wasm/pkg/package.json';
164+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
165+
pkg.name = '@raphaelmansuy/edgeparse-wasm';
166+
pkg.publishConfig = {
167+
access: 'public',
168+
registry: 'https://npm.pkg.github.com'
169+
};
170+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
171+
"
172+
# Write a scoped .npmrc so npm uses the right registry for this scope.
173+
echo "@raphaelmansuy:registry=https://npm.pkg.github.com" >> ~/.npmrc
174+
echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}" >> ~/.npmrc
175+
cd crates/edgeparse-wasm/pkg
176+
npm publish --registry https://npm.pkg.github.com \
177+
|| { CODE=$?; echo "GitHub Packages publish exited $CODE — may already exist for this version." ; }
100178
179+
# ─────────────────────────────────────────────────────────────────────
180+
# 6. Attach the tarball to the GitHub Release.
181+
# ─────────────────────────────────────────────────────────────────────
101182
- name: Ensure GitHub Release exists
102183
env:
103184
GH_TOKEN: ${{ github.token }}
104-
INPUT_TAG_NAME: ${{ inputs.tag_name }}
105185
run: |
106-
TAG_NAME="${INPUT_TAG_NAME:-$GITHUB_REF_NAME}"
107186
gh release view "$TAG_NAME" --repo "${{ github.repository }}" \
108187
|| gh release create "$TAG_NAME" \
109188
--repo "${{ github.repository }}" \
110189
--title "$TAG_NAME" \
111190
--generate-notes
112191
113-
- name: Upload npm tarball to GitHub Release
192+
- name: Upload tarball to GitHub Release
114193
env:
115194
GH_TOKEN: ${{ github.token }}
116-
INPUT_TAG_NAME: ${{ inputs.tag_name }}
117195
run: |
118-
TAG_NAME="${INPUT_TAG_NAME:-$GITHUB_REF_NAME}"
119196
gh release upload "$TAG_NAME" crates/edgeparse-wasm/pkg/*.tgz \
120197
--repo "${{ github.repository }}" --clobber
198+

CHANGELOG.md

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

88
---
99

10+
## [0.2.4] — 2026-04-13
11+
12+
### Added
13+
- **WASM npm publication**`edgeparse-wasm` is now published to the npm public registry on every tagged release; jsDelivr and unpkg CDNs become available automatically
14+
- **GitHub Packages secondary registry**`@raphaelmansuy/edgeparse-wasm` is published to `npm.pkg.github.com` alongside the npm release, providing a GitHub-native install path for enterprise users
15+
- **CDN quick-start**`docs/09-wasm-sdk.md` now includes copy-pasteable `<script type="module">` examples for jsDelivr and unpkg (no build tool required)
16+
- **Framework quick-starts** — Vite + React, Next.js App Router, Webpack 5, and Service Worker PWA examples added to the WASM SDK docs
17+
- **`exports` field in `pkg/package.json`** — adds a proper ESM exports map for bundler interop
18+
19+
### Changed
20+
- `release-wasm.yml` now publishes to npm (primary) and GitHub Packages (secondary) instead of skipping publication; both steps treat "already published" as non-fatal
21+
- `release-wasm.yml` requires `packages: write` permission (for GitHub Packages) and existing `contents: write` (for GitHub Releases)
22+
- `pkg/package.json` carries full metadata (keywords, exports, publishConfig) so it is ready to publish without CI patching the file from scratch
23+
- `docs/09-wasm-sdk.md` consolidated installation and distribution section with all four channels (npm, jsDelivr, unpkg, GitHub Packages)
24+
- `docs/07-cicd-publishing.md` updated with WASM npm rows in the artifacts table, `NPM_TOKEN` scope note, and step-by-step token setup instructions
25+
26+
### Fixed
27+
- `INPUT_TAG_NAME` env variable now written to `$GITHUB_ENV` so downstream steps in `release-wasm.yml` can reference `${{ env.TAG_NAME }}` without re-reading inputs
28+
29+
---
30+
1031
## [0.2.3] — 2026-03-28
1132

1233
### 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.3"
18+
version = "0.2.4"
1919
edition = "2021"
2020
rust-version = "1.85"
2121
license = "Apache-2.0"
Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,46 @@
11
{
2-
"name": "@edgeparse/edgeparse-wasm",
2+
"name": "edgeparse-wasm",
33
"type": "module",
44
"description": "EdgeParse PDF parser — WebAssembly build for browsers",
5-
"version": "0.2.3",
5+
"version": "0.2.4",
66
"license": "Apache-2.0",
7+
"homepage": "https://edgeparse.io/docs/api/wasm/",
78
"repository": {
89
"type": "git",
9-
"url": "https://github.com/raphaelmansuy/edgeparse"
10+
"url": "git+https://github.com/raphaelmansuy/edgeparse.git",
11+
"directory": "crates/edgeparse-wasm"
1012
},
13+
"keywords": [
14+
"pdf",
15+
"parser",
16+
"wasm",
17+
"webassembly",
18+
"browser",
19+
"extraction",
20+
"markdown"
21+
],
1122
"files": [
1223
"edgeparse_wasm_bg.wasm",
1324
"edgeparse_wasm.js",
14-
"edgeparse_wasm.d.ts"
25+
"edgeparse_wasm.d.ts",
26+
"edgeparse_wasm_bg.wasm.d.ts",
27+
"README.md",
28+
"LICENSE"
1529
],
1630
"main": "edgeparse_wasm.js",
31+
"module": "edgeparse_wasm.js",
1732
"types": "edgeparse_wasm.d.ts",
33+
"exports": {
34+
".": {
35+
"import": "./edgeparse_wasm.js",
36+
"types": "./edgeparse_wasm.d.ts"
37+
}
38+
},
1839
"sideEffects": [
1940
"./snippets/*"
20-
]
41+
],
42+
"publishConfig": {
43+
"access": "public",
44+
"registry": "https://registry.npmjs.org"
45+
}
2146
}

0 commit comments

Comments
 (0)