Skip to content

release: prepare mds v0.1.0 (ready-state, no publish) - #37

Merged
dean0x merged 12 commits into
mainfrom
release-prep-v0.1.0
May 30, 2026
Merged

dean0x merged 12 commits into
mainfrom
release-prep-v0.1.0

Conversation

@dean0x

@dean0x dean0x commented May 29, 2026

Copy link
Copy Markdown
Owner

Summary

Brings the repo to a release-ready state for the first public v0.1.0 release
(crates.io + npm + GitHub), as a single coordinated, deferred release. Per
plan, this PR stops short of the release itself — no version tag, no
cargo publish, no npm publish
.

Implements the hardened release plan in phases:

  • Step 0 — commit/push prep (npm scope @mdscript/*, crates metadata, CI/CD
    scaffold, examples promotion, cross-dir scanner fixtures).
  • Phase A — native (napi) packaging: scoped @mdscript/mds-napi host +
    @mdscript/mds-napi-<triple> platform packages, napi v3 config, name↔loader
    verification gate, cross-compile matrix.
  • Phase B — WASM as a committed @mdscript/mds-wasm workspace wrapper.
  • Phase C — community health (SECURITY, CONTRIBUTING, CoC, issue/PR
    templates, dependabot), per-package LICENSE/README, README polish.
  • Phase D — release-engineering hardening: version/name gates, dry-run
    workflow_dispatch, provenance/OIDC, CHANGELOG → Unreleased, RELEASING.md runbook.

Baselines (regression floor)

  • Rust: 590 tests pass
  • JS: 224 tests pass
  • clippy -D warnings, cargo fmt --check: green
  • wasm artifact: 469531 bytes

Out of scope (deferred)

  • The actual v0.1.0 tag + publish (triggered later after review)
  • User account actions (npm org, GitHub PVR, repo secrets) — documented in RELEASING.md

Dean Sharon added 2 commits May 30, 2026 00:02
…I/CD, examples Consolidates the v0.1.0 release preparation: - npm scope rename @mds/* -> @mdscript/* - crates.io metadata + pinned path-dep versions - CHANGELOG consolidated to [0.1.0]; spec status; README install lines - ci.yml + partial release.yml - examples/ promoted from test_playground; rustfmt cleanup - cross-dir scanner fixtures (needed by U-SM8 on clean clone) Baselines: 590 Rust tests, 224 JS tests, clippy -D warnings, fmt all green.
…hase A — native (napi) packaging: - Rename host package to @mdscript/mds-napi; loader strings -> @mdscript/mds-napi-<triple> - napi v3 config (binaryName/packageName/7 targets) - node.ts requires the scoped package; mds optionalDep -> ^0.1.0 (kill file:) - A3 name<->loader gate (scripts/verify-napi-names.mjs) - Ship index.js/index.d.ts/LICENSE/README via files; metadata Phase B — WASM as committed workspace wrapper: - packages/mds-wasm (@mdscript/mds-wasm) building node+web targets into dist/ (strip wasm-pack's .gitignore so npm packs dist) - wasm.ts loader + browser import + error strings -> @mdscript/mds-wasm - @mdscript/mds depends on @mdscript/mds-wasm ^0.1.0 Release workflow (A6/A7/B4/D2/D3): - 7-target napi cross-compile matrix (--use-napi-cross for linux musl/arm) - stage+verify job runs A3 gate; workflow_dispatch dry-run publishes nothing - npm publishes with provenance (OIDC id-token); crates -> npm -> GitHub release - D1 version-consistency gate (scripts/verify-versions.mjs) Per-package LICENSE copies; napi README.
Dean Sharon added 10 commits May 30, 2026 00:24
…ot, README badges

Phase C community health (CODE_OF_CONDUCT deferred to #38 — see note):
- SECURITY.md: GitHub private vuln reporting, supported-versions table, the
  verified resource-limit table (call/loop/output/import/nesting/value/dot caps),
  and the debug-panics 'never ship enabled' warning
- CONTRIBUTING.md: real Rust/WASM/JS gates, MSRV 1.88, Node >=22, conventional commits
- .github/ISSUE_TEMPLATE/{bug_report,feature_request,config}.yml (security routed to
  the advisory page, blank issues disabled)
- .github/PULL_REQUEST_TEMPLATE.md (changelog/tests/conventional-commit checklist)
- .github/dependabot.yml: cargo + npm + github-actions, weekly
- README: CI/crates.io/npm/MIT badges + Contributing/Security sections

Refs #38
Phase D release-engineering hardening (no tag/publish):
- CHANGELOG: [0.1.0] -> [Unreleased] (drop hardcoded date; stamped at tag time)
- RELEASING.md: ordered runbook (version-gate -> build-napi -> stage+verify A3
  gate -> crates -> npm w/ provenance -> GitHub release), one-time maintainer
  prerequisites (npm org, OIDC/NPM_TOKEN, CARGO_REGISTRY_TOKEN, GitHub PVR, #38),
  local dry-run commands, and the A3 name-gate hard checkpoint
- Note: mds-cli dry-run requires mds-core on the index first (expected)

D1 version gate, D2 dry-run dispatch, D3 provenance/OIDC landed with the workflow.
native-backend.spec.mjs required crates/mds-napi/mds-napi.node directly. CI builds
the addon with `napi build --platform`, which names it mds-napi.<triple>.node, so
the bare path was MODULE_NOT_FOUND on every CI OS (it only worked locally where a
stale bare build happened to exist). Load through crates/mds-napi/index.js — the
same loader production uses — which resolves bare-or-suffixed names and returns the
identical raw addon. Reproduced the CI failure locally (suffixed-only) and verified
the fix: 6/6 pass.
Evaluator flagged the stale count; cargo test --workspace reports 590.
The 'Build WASM (nodejs)' CI step failed on macOS/windows with 'invalid type: map,
expected a string for key package.license' — those runners get an older wasm-pack
(ubuntu has a newer one preinstalled) that doesn't resolve Cargo workspace
inheritance for npm-metadata fields. Fix both ways:
- crates/mds-wasm/Cargo.toml: make license/repository/keywords explicit literals
  (mds-wasm isn't published to crates.io, so inheritance buys nothing)
- pin jetli/wasm-pack-action to version: latest on all 3 usages (ci x2, release)

Verified: cargo check + wrapper build OK, pkg package.json license=MIT.
… 'compiles file with imports' integration test asserted dep.startsWith('/'), a POSIX-only absolute-path check that fails on Windows where absolute paths are 'D:\…' or '\\?\D:\…'. Use node:path isAbsolute() instead. This was the sole remaining JS test failure on windows-latest (macOS was fixed by b3c78c3's wasm-pack manifest change; ubuntu was already green).
…Release workflow has never started successfully — GitHub displayed it by file path (not its 'Release' name) and produced an instant startup_failure run on every push, which means a real 'v0.1.0' tag push would fail to launch the release at all. Two YAML syntax errors: - step name 'Assert synchronized versions, no file: refs' — the unquoted ': ' parses as a nested mapping. Quoted the value. - 'with: { targets: ${{ matrix.settings.target }} }' — the expression's '}}' collides with the flow-mapping '}'. Converted to block style. Verified with actionlint 1.7.7: both workflows now lint clean (exit 0).
The module scanner rejected every compile on Windows with 'security: path
escapes project root' because the containment guards used POSIX-only string
prefixing — `absolutePath.startsWith(projectRoot + '/')` never matches a
backslash-separated Windows path like 'D:\\a\\mds\\mds\\...'.

- Add isWithinRoot() using path.relative (separator/drive/case aware); replace
  the two startsWith(projectRoot + '/') guards.
- Filesystem-root guard: dirname(root) === root instead of root === '/'.
- entryFilename: normalize separators to '/' so the entry virtual key matches
  the slash-based keys built by normalizeVirtualKey (mirrors Rust VirtualFs).
- realpath symlink fallback: compare case-insensitively on win32 (realpath can
  return a different drive-letter case than resolve()).

Verified on macOS: all 224 JS workspace tests pass (mds 122, bundler-utils 64,
rollup 10, vite 14, webpack 14).
… U-PF0 set the subprocess cwd to `new URL('.', import.meta.url).pathname`, which on Windows is '/D:/a/mds/...' — a non-existent path, so execFileSync failed with 'spawnSync node.exe ENOENT'. Use __dirname (fileURLToPath), matching backend.spec.mjs.
…e rollup/vite/webpack-loader test scripts used a POSIX-only inline env assignment, 'NODE_ENV=test node --test ...', which cmd.exe on Windows treats as a bogus command and fails before any test runs. rollup/vite gate _setTransformerForTesting behind NODE_ENV=test, so set it inside those two specs instead and drop the prefix from all three scripts (webpack's setter is ungated). No new dependency — keeps the zero-dependency root intact. Verified locally: rollup 10, vite 14, webpack 14 all pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant