Skip to content

build: migrate from bun to pnpm and upgrade semantic-release to v25 - #1321

Merged
chhoumann merged 4 commits into
masterfrom
chhoumann/upgrade-semantic-release-to-v25-blocked-by-buns
Jun 13, 2026
Merged

build: migrate from bun to pnpm and upgrade semantic-release to v25#1321
chhoumann merged 4 commits into
masterfrom
chhoumann/upgrade-semantic-release-to-v25-blocked-by-buns

Conversation

@chhoumann

@chhoumann chhoumann commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Summary

Migrates QuickAdd's package manager/toolchain from bun to pnpm and upgrades semantic-release to v25.

semantic-release v25 requires Node ^22.14.0 || >=24.10.0. The release job ran bunx semantic-release, and Bun 1.3.14 emulates Node 24.3.0, which fails that engine guard (bin/semantic-release.js) — so v25 couldn't run under bunx. Running every step under real Node via pnpm satisfies the guard and unblocks v25.

Closes #1240.

Changes

Toolchain

  • semantic-release ^24.2.9^25.0.5; added packageManager: pnpm@10.32.1.
  • Added pnpm.onlyBuiltDependencies (@codemirror/language, esbuild). pnpm 10 blocks build scripts by default; the git-hosted @codemirror/language fork pulled by obsidian-dataview must be prepared at install time (install hard-fails otherwise). It's externalized in esbuild.config.mjs, so it never enters our bundle.
  • Generated + committed pnpm-lock.yaml and docs/pnpm-lock.yaml; deleted bun.lock + docs/bun.lock. .gitignore now commits pnpm-lock.yaml and ignores foreign lockfiles (incl. bun.lock). docs/package.json gets packageManager too.

CI / release (ci.yml, release.yml)

  • oven-sh/setup-bunpnpm/action-setup@v6.0.8 (SHA-pinned) before setup-node.
  • check-latest: true on setup-node so a stale 24.x toolcache can't resolve below 24.10 and re-trip the engine guard.
  • All bun …pnpm …; bunx semantic-releasepnpm exec semantic-release. Added pnpm store caching.

Other

  • dependabot.yml: bunnpm ecosystem (pnpm is handled under npm).
  • version-docs.mjs docs snapshot shells pnpm run docusaurus.
  • docs/vercel.json → pnpm (non-frozen install, robust to whichever pnpm major the docs host resolves).
  • Updated AGENTS.md, CONTRIBUTING.md, README.md, docs/README.md, PR template, and .codex/environments/environment.toml.

Dependency Review / security cleanup

The bun→pnpm lockfile-format change makes Dependency Review re-scan the entire tree (it can't diff bun.lock against pnpm-lock.yaml), which surfaced several pre-existing high-severity advisories that already lived in bun.lock on master. Resolved them via real dependency hygiene (no allow-listing / suppression):

  • serialize-javascript@6.0.2 (GHSA-5c6j-r48x-rmvq, docs/webpack toolchain) → patched 7.0.5 via pnpm.overrides. Also moved the docs override block from npm's top-level overrides to pnpm.overrides, since pnpm doesn't read the former — the existing webpackbar override had silently stopped applying after the switch.
  • esbuild@0.28.0 (GHSA-gv7w-rqvm-qjhr) → 0.28.1. (Advisory is Deno-module-only; the Node/npm path we use already does SHA-256 integrity checks — bumped anyway to clear the version. Clean patch: security + bundler correctness fixes, no breaking changes, OIDC-published.)
  • lodash@4.17.21 + tmp (GHSA-r5fr-rjxr-66jc, GHSA-ph9p-34f9-6g65) → removed the unused cz-conventional-changelog/commitizen dev tool (no script, no docs; commits are PR-title-driven), which was their only source. Patched lodash@4.18.1 via @semantic-release/git is unaffected.
  • svelte 3.35 (GHSA-gw32-9rmw-qwww) → via obsidian-dataview → obsidian-calendar-ui. We only use dataview's getAPI accessor (calendar-ui is never invoked or bundled), and dataview is already on the latest 0.5.68, so a scoped pnpm.override puts calendar-ui on the patched svelte 3.59.2; our own svelte 5 is untouched.

Root high-severity pnpm audit is now clean.

Testing / validation

Verified locally (pnpm 10.32.1, Node 24.16) and green in CI on ubuntu:

  • pnpm install (root + docs) and --frozen-lockfile (both); cold-runner install builds the codemirror git dep and resolves the linux esbuild binary.
  • build, build-with-lint, check (846 files, 0 errors), test (1812 pass / 31 skip); docusaurus docs build.
  • semantic-release@25.0.5 engine guard passes under real Node; dry-run loads all release plugins — bundled @semantic-release/npm (the npmPublish:false version-bumper), @semantic-release/exec, the local docs-versioning-plugin.cjs, @semantic-release/git, @semantic-release/github — then correctly skips on the non-master branch.

This PR is build: so it does not itself cut a release; the next feat/fix/perf will, now running under v25.

Notes for review

  • .codex/environments/environment.toml is marked "AUTOGENERATED — DO NOT EDIT". I changed bun installpnpm install anyway, because leaving it would break the Codex cloud env and create a competing bun.lock. Worth confirming whatever regenerates it now emits pnpm.
  • Docs preview deploy is Cloudflare Pages (configured in the CF dashboard, not vercel.json); it auto-detects pnpm from the committed lockfile and passed in CI. The vercel.json edit is harmless but likely unused by CF.

semantic-release v25 requires Node `^22.14.0 || >=24.10.0`. The release job
ran `bunx semantic-release`, and Bun 1.3.14 emulates Node 24.3.0, which fails
that engine guard (bin/semantic-release.js). Switching the toolchain to pnpm
runs every step under real Node, so the guard passes and v25 is unblocked.

Toolchain:
- semantic-release ^24 -> ^25.0.5; add packageManager pnpm@10.32.1.
- Add pnpm.onlyBuiltDependencies (@codemirror/language, esbuild): pnpm 10
  blocks build scripts by default, and the git-hosted @codemirror/language
  fork pulled by obsidian-dataview must be prepared at install time.
- Generate + commit pnpm-lock.yaml and docs/pnpm-lock.yaml; delete bun.lock
  and docs/bun.lock; .gitignore now commits pnpm-lock.yaml and ignores foreign
  lockfiles (incl. bun.lock). docs/package.json gets packageManager too.

CI / release:
- oven-sh/setup-bun -> pnpm/action-setup (SHA-pinned) before setup-node.
- check-latest: true on setup-node so a stale 24.x toolcache can't resolve
  below 24.10 and re-trip the engine guard.
- All bun commands -> pnpm; `bunx semantic-release` -> `pnpm exec`.
- Add pnpm store caching.

Other:
- dependabot: bun -> npm ecosystem (pnpm is handled under npm).
- version-docs.mjs docs snapshot shells `pnpm run docusaurus`.
- docs/vercel.json -> pnpm (non-frozen, robust to Vercel's pnpm major).
- Update AGENTS.md/CONTRIBUTING.md/README.md/docs/README.md/PR template and
  .codex/environments/environment.toml.

Verified locally (pnpm 10.32.1, Node 24.16): install (root + docs), build,
build-with-lint, svelte-check, vitest (1812 pass / 31 skip), frozen-lockfile
installs, and a semantic-release v25 dry-run loading all release plugins.

Closes #1240
@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Replace Bun/yarn invocations with pnpm across configs, CI workflows, release scripts, package manifests, docs, and developer guidance; bump selected devDependencies.

Changes

Bun to pnpm Migration with devDependency updates

Layer / File(s) Summary
Package manager declaration & dependency config
.codex/environments/environment.toml, package.json, docs/package.json, .gitignore, .github/dependabot.yml
Root/docs declare pnpm and pnpm config/overrides; codex environment uses pnpm install; Dependabot entries switch to npm ecosystem; .gitignore updated for foreign lockfiles.
CI/CD workflows conversion
.github/workflows/ci.yml, .github/workflows/release.yml
Test and build-lint jobs replace Bun with Setup pnpm, Node.js 24 (check-latest: true), pnpm caching and pnpm install --frozen-lockfile; release workflow adds Setup pnpm and runs pnpm exec semantic-release.
Build & release script updates
package.json, scripts/release/version-docs.mjs
build-with-lint now uses pnpm lint; esbuild and semantic-release devDependencies bumped; docs versioning script invokes Docusaurus via pnpm run.
Docs deployment configuration
docs/vercel.json, docs/README.md
Vercel installCommand/buildCommand updated to use pnpm; docs deploy instructions use pnpm deploy.
Developer documentation and templates
.github/PULL_REQUEST_TEMPLATE.md, CONTRIBUTING.md, README.md, AGENTS.md, docs/README.md
PR template, contributing guide, main README, AGENTS playbook, and docs README updated to reference pnpm commands for setup, dev, test, build, and versioning.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

released

"🐰 I hopped the lockfile fence today,
swapped bun for pnpm along the way,
workflows trimmed, docs refined,
release and build now better aligned,
small bumps—big tidy hooray!"

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and concisely describes the main changes: migration from bun to pnpm and semantic-release upgrade to v25.
Linked Issues check ✅ Passed All requirements from issue #1240 are met: semantic-release upgraded to v25, toolchain migrated to pnpm, and release workflow now runs semantic-release under real Node via pnpm exec instead of bunx.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objective of migrating from bun to pnpm and upgrading semantic-release. No unrelated or extraneous modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chhoumann/upgrade-semantic-release-to-v25-blocked-by-buns

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 13, 2026

Copy link
Copy Markdown

Deploying quickadd with  Cloudflare Pages  Cloudflare Pages

Latest commit: 823b020
Status: ✅  Deploy successful!
Preview URL: https://21df2910.quickadd.pages.dev
Branch Preview URL: https://chhoumann-upgrade-semantic-r.quickadd.pages.dev

View logs

@github-actions

github-actions Bot commented Jun 13, 2026

Copy link
Copy Markdown

Dependency Review Summary

The full dependency review summary was too large to display here (3022KB, limit is 1024KB).

Please download the artifact named "dependency-review-summary" to view the complete report.

View full job summary

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 346b5cefe4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/README.md

```
$ USE_SSH=true yarn deploy
$ USE_SSH=true pnpm deploy

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use pnpm run for the deploy script

With this repo pinned to pnpm 10.x, these deployment examples do not run the Docusaurus deploy script: pnpm's 10.x docs say script shorthands only work for names that do not share an existing pnpm command, and deploy is an existing pnpm deploy workspace command. In docs/, that will fail or invoke the wrong command instead of publishing the site; both deployment examples should use pnpm run deploy so the package script receives USE_SSH/GIT_USER.

Useful? React with 👍 / 👎.

Dependency Review flagged docs serialize-javascript@6.0.2 (GHSA-5c6j-r48x-rmvq,
high, RCE; fixed in 7.0.3). It is a pre-existing transitive dep of the Docusaurus
webpack/terser toolchain (same version was in the old docs/bun.lock); the lockfile
format change just resurfaced it.

pnpm reads pnpm.overrides, not npm's top-level overrides field, so the existing
docs override block stopped applying after the bun->pnpm switch. Move it under
pnpm.overrides and add serialize-javascript ^7.0.3 (resolves to 7.0.5). Docs
build verified.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@package.json`:
- Line 10: Several lines in package.json use space indentation instead of the
repo's required tabs; update the affected JSON entries (notably the
"build-with-lint" script and the other modified JSON properties) to use tab
characters for indentation, ensure LF line endings per .editorconfig, and re-run
the formatter/lint for JSON to verify the changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a4d4ba59-b1b0-460a-8da1-21c58f5416be

📥 Commits

Reviewing files that changed from the base of the PR and between 72f1b91 and 346b5ce.

⛔ Files ignored due to path filters (4)
  • bun.lock is excluded by !**/*.lock
  • docs/bun.lock is excluded by !**/*.lock
  • docs/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • .codex/environments/environment.toml
  • .github/PULL_REQUEST_TEMPLATE.md
  • .github/dependabot.yml
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • .gitignore
  • AGENTS.md
  • CONTRIBUTING.md
  • README.md
  • docs/README.md
  • docs/package.json
  • docs/vercel.json
  • package.json
  • scripts/release/version-docs.mjs

Comment thread package.json
"lint": "eslint .",
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
"build-with-lint": "tsc -noEmit -skipLibCheck && bun lint && node esbuild.config.mjs production",
"build-with-lint": "tsc -noEmit -skipLibCheck && pnpm lint && node esbuild.config.mjs production",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use tab indentation in changed JSON lines.

Line 10, Line 39, Line 63, and Lines 69-74 are space-indented; this repo’s JSON guideline requires tabs.

As per coding guidelines, **/*.{ts,tsx,js,mjs,json} must use tab indentation and LF line endings as configured in .editorconfig.

Also applies to: 39-39, 63-63, 69-74

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` at line 10, Several lines in package.json use space indentation
instead of the repo's required tabs; update the affected JSON entries (notably
the "build-with-lint" script and the other modified JSON properties) to use tab
characters for indentation, ensure LF line endings per .editorconfig, and re-run
the formatter/lint for JSON to verify the changes.

Source: Coding guidelines

Dependency Review flagged root esbuild@0.28.0 (GHSA-gv7w-rqvm-qjhr, high).
Pre-existing (same version was in the old bun.lock); resurfaced by the lockfile
format change. The advisory is Deno-module-only (missing binary integrity check
when NPM_CONFIG_REGISTRY is attacker-controlled); the Node/npm path this project
uses already does SHA-256 binaryIntegrityCheck(), so it never affected us.

Bump to the patched 0.28.1 anyway to remove the flagged version. 0.28.1 is a
clean patch (security + minifier/bundling correctness fixes, no breaking
changes, OIDC trusted-published). Build + 1812 tests pass; main.js unchanged.

The local safe-chain min-release-age gate suppressed 0.28.1 (published 2 days
ago); committed the lockfile via --safe-chain-skip-minimum-package-age for this
reviewed security patch. CI installs frozen, so no min-age interaction there.
Resolve the remaining (pre-existing) high-severity advisories surfaced by the
whole-tree re-scan via dependency hygiene rather than allow-listing.

- Remove cz-conventional-changelog + the config.commitizen block. It was
  vestigial: no script, no docs, and commits are PR-title-driven (semantic-
  release reads the squash-merge title). Dropping it removes the entire
  commitizen tree, eliminating lodash@4.17.21 (GHSA-r5fr-rjxr-66jc) and tmp
  (GHSA-ph9p-34f9-6g65). The patched lodash@4.18.1 via @semantic-release/git
  is unaffected.
- obsidian-dataview (already on latest 0.5.68) pulls obsidian-calendar-ui ->
  svelte 3.35 (GHSA-gw32-9rmw-qwww). QuickAdd only uses dataview's getAPI
  accessor; calendar-ui is never invoked or bundled. No newer dataview exists,
  so scope a pnpm override to put calendar-ui on the patched svelte 3.59.2.
  Our own svelte 5 is untouched.

Root high-severity audit is now clean; build/lint/check/test all pass.
@chhoumann
chhoumann merged commit 4a76247 into master Jun 13, 2026
10 checks passed
@quickadd-release-bot

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 2.14.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upgrade semantic-release to v25 (blocked by Bun's emulated Node)

1 participant