Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions .github/workflows/js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ jobs:
with:
node-version: "24.22.1"
- name: Install dependencies
run: cd crates/markkit-js && npm install
run: cd crates/markkit-js && npm install --ignore-scripts --audit=false --fund=false
- name: Build
run: cd crates/markkit-js && npx napi build --release
run: cd crates/markkit-js && npx --no-install napi build --release --platform
- name: Verify build preserved the patched lockfile
run: git diff --exit-code -- Cargo.lock
- name: Verify installed npm package
run: |
cd crates/markkit-js
npm pack --ignore-scripts --json > "$RUNNER_TEMP/markkit-pack.json"
node -e 'const p=require(process.argv[1])[0]; const files=p.files.map(f=>f.path); if(!files.includes("index.js") || !files.some(f=>f.endsWith(".node"))) throw Error("npm package must contain its loader and native binary")' "$RUNNER_TEMP/markkit-pack.json"
TARBALL=$(node -e 'console.log(require(process.argv[1])[0].filename)' "$RUNNER_TEMP/markkit-pack.json")
npm install --prefix "$RUNNER_TEMP/markkit-npm-smoke" --ignore-scripts --audit=false --fund=false "$PWD/$TARBALL"
node -e 'const m=require(process.argv[1]); if(m.extractHtmlSync("<h1>Smoke</h1>").trim()!=="# Smoke") throw Error("native extraction smoke failed")' "$RUNNER_TEMP/markkit-npm-smoke/node_modules/@everruns/markkit"
25 changes: 22 additions & 3 deletions .github/workflows/publish-js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,31 @@ jobs:
with:
node-version: "24.22.1"
registry-url: "https://registry.npmjs.org"
- name: Require npm publisher credential
if: inputs.dry_run != 'true'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
if [ -z "$NODE_AUTH_TOKEN" ]; then
echo "::error::NPM_TOKEN is unavailable for this publisher"
exit 1
fi
- name: Install dependencies
run: cd crates/markkit-js && npm install
run: cd crates/markkit-js && npm install --ignore-scripts --audit=false --fund=false
- name: Build
run: cd crates/markkit-js && npx napi build --release
run: cd crates/markkit-js && npx --no-install napi build --release --platform
- name: Verify build preserved the patched lockfile
run: git diff --exit-code -- Cargo.lock
- name: Verify installed npm package
run: |
cd crates/markkit-js
npm pack --ignore-scripts --json > "$RUNNER_TEMP/markkit-pack.json"
node -e 'const p=require(process.argv[1])[0]; const files=p.files.map(f=>f.path); if(!files.includes("index.js") || !files.some(f=>f.endsWith(".node"))) throw Error("npm package must contain its loader and native binary")' "$RUNNER_TEMP/markkit-pack.json"
TARBALL=$(node -e 'console.log(require(process.argv[1])[0].filename)' "$RUNNER_TEMP/markkit-pack.json")
npm install --prefix "$RUNNER_TEMP/markkit-npm-smoke" --ignore-scripts --audit=false --fund=false "$PWD/$TARBALL"
node -e 'const m=require(process.argv[1]); if(m.extractHtmlSync("<h1>Smoke</h1>").trim()!=="# Smoke") throw Error("native extraction smoke failed")' "$RUNNER_TEMP/markkit-npm-smoke/node_modules/@everruns/markkit"
- name: Publish
if: inputs.dry_run != 'true'
run: cd crates/markkit-js && npm publish
run: cd crates/markkit-js && npm publish --ignore-scripts
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
17 changes: 17 additions & 0 deletions .github/workflows/publish-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,27 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Require PyPI publisher credential
if: inputs.dry_run != 'true'
env:
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
if [ -z "$TWINE_PASSWORD" ]; then
echo "::error::PYPI_API_TOKEN is unavailable for this publisher"
exit 1
fi
- name: Install maturin
run: pip install maturin twine
- name: Build wheels
run: cd crates/markkit-python && maturin build --release
- name: Verify build preserved the patched lockfile
run: git diff --exit-code -- Cargo.lock
- name: Verify wheel metadata and native import
run: |
twine check target/wheels/*.whl
python -m venv "$RUNNER_TEMP/markkit-wheel-smoke"
"$RUNNER_TEMP/markkit-wheel-smoke/bin/python" -m pip install --no-deps target/wheels/*.whl
"$RUNNER_TEMP/markkit-wheel-smoke/bin/python" -c 'import markkit_python; assert markkit_python.extract_html_sync("<h1>Smoke</h1>").strip() == "# Smoke"'
- name: Publish
if: inputs.dry_run != 'true'
run: twine upload target/wheels/*.whl
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,10 @@ node_modules/

# WASM build artifacts
*.wasm

# Generated NAPI package artifacts
crates/markkit-js/*.node
crates/markkit-js/index.js
crates/markkit-js/index.d.ts
crates/markkit-js/package-lock.json
crates/markkit-js/*.tgz
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

## [0.1.1] - 2026-10-22

### Security

- Upgrade the HTTP, spreadsheet and ZIP dependency graph to patched TLS and archive releases.
- Track the workspace lockfile so CI audits the same resolution used by CLI and binding builds.
Library consumers must refresh their application lockfiles to receive transitive TLS fixes;
a dependency library's lockfile is not inherited.
- Run JavaScript build and packaging workflows on Node.js 24.22.1.
- Include the generated JavaScript loader and native binary in npm packages and verify installed package loading.
- Scope npm native artifacts explicitly to Linux x64/glibc; other platforms are not included in this release.
- Verify Python wheel metadata and native extraction before upload; the wheel publisher targets Linux x64/CPython 3.12.

### Changed

Expand Down
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ members = [
]

[workspace.package]
version = "0.1.0"
version = "0.1.1"
edition = "2024"
license = "MIT"
authors = ["Everruns <oss@everruns.com>"]
Expand Down
2 changes: 1 addition & 1 deletion crates/markkit-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ docx = ["markkit/docx"]
spreadsheet = ["markkit/spreadsheet"]

[dependencies]
markkit = { path = "../markkit", version = "0.1.0", features = ["http_client"] }
markkit = { path = "../markkit", version = "0.1.1", features = ["http_client"] }
tokio = { workspace = true, features = ["macros", "net", "rt", "rt-multi-thread", "time", "fs"] }
clap.workspace = true
anyhow.workspace = true
Expand Down
17 changes: 17 additions & 0 deletions crates/markkit-js/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# @everruns/markkit

Native Node.js bindings for Markkit HTML-to-Markdown extraction.

This npm release supports **Linux x64 with glibc**. It does not include binaries for
macOS, Windows, ARM64 or musl Linux. Other platforms require a separate future
native release; Rust and Python package availability is independent.

The package contains its JavaScript loader and native binary. CI verifies a clean
installation and extraction smoke on Node.js 24.22.1 before publication. Use a
currently supported Node.js release with its security patches installed.

```js
const { extractHtmlSync } = require('@everruns/markkit');
console.log(extractHtmlSync('<h1>Hello</h1>'));
// # Hello
```
19 changes: 16 additions & 3 deletions crates/markkit-js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@everruns/markkit",
"version": "0.1.0",
"version": "0.1.1",
"description": "Extract clean markdown from any format – Node.js bindings",
"main": "index.js",
"types": "index.d.ts",
Expand All @@ -17,9 +17,22 @@
},
"files": [
"index.js",
"index.d.ts"
"index.d.ts",
"*.node"
],
"devDependencies": {
"@napi-rs/cli": "^3"
}
},
"publishConfig": {
"access": "public"
},
"os": [
"linux"
],
"cpu": [
"x64"
],
"libc": [
"glibc"
]
}
17 changes: 17 additions & 0 deletions crates/markkit-python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# markkit-python

Native Python bindings for Markkit HTML-to-Markdown extraction.

The current wheel publisher builds for **Linux x64 and CPython 3.12**. It does not
publish macOS, Windows, ARM64 or other Python-version wheels. Other wheel targets
require a separate future release; Rust and npm availability is independent.

```python
import markkit_python

print(markkit_python.extract_html_sync("<h1>Hello</h1>"))
# # Hello
```

Publication verifies wheel metadata, installs the actual wheel into a clean
virtual environment and exercises native extraction before upload.
14 changes: 14 additions & 0 deletions specs/release-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,17 @@ version from `Cargo.toml`. Python and npm packages are published separately with
| Rust crate | `cargo publish` | crates.io |
| Python wheel | `maturin build` | PyPI |
| npm package | `napi build` | npm |

## Native package scope and verification

Run the Python and npm publishers from the same verified release tag as Rust.
The initial npm artifact supports Linux x64/glibc only, and the current Python
wheel publisher targets Linux x64/CPython 3.12 only. Other platforms and interpreters
are not claimed as available; a future native release can expand coverage.

Both publishers default to a credential-free dry run. Actual publication requires
an existing publisher credential before building; missing credentials fail without
printing values. Do not create credentials or alter permissions to complete a release.
Before upload, npm installs and loads its packed tarball (loader plus native binary),
and Python checks metadata and imports the built wheel in a clean virtual environment.
Both builds must preserve the patched Cargo.lock.
Loading