Skip to content

chore: add rivetkit-native cross-platform builds to pkg-pr-new#4600

Merged
NathanFlurry merged 53 commits intomainfrom
pkg-pr-new-native-builds
Apr 13, 2026
Merged

chore: add rivetkit-native cross-platform builds to pkg-pr-new#4600
NathanFlurry merged 53 commits intomainfrom
pkg-pr-new-native-builds

Conversation

@NathanFlurry
Copy link
Copy Markdown
Member

Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Copy link
Copy Markdown
Member Author

NathanFlurry commented Apr 9, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@claude
Copy link
Copy Markdown

claude bot commented Apr 9, 2026

PR Review: chore: add rivetkit-native cross-platform builds to pkg-pr-new

This is a significant infrastructure PR that unifies the build and publish pipeline into a single publish.yaml workflow, adds cross-platform native build infrastructure, and introduces the @rivetkit/engine-cli npm package for distributing the engine binary. The design is solid overall. Notes below ordered by severity.


Issues

scripts/publish/src/local/cut-release.ts -- shell injection risk in git commit

shell: true is passed when running the git commit command with the version string interpolated into the command. If version ever contains shell metacharacters it would execute arbitrary commands. The version goes through semver validation upstream, but the defense-in-depth fix is trivial: drop shell: true and pass arguments as an array, letting execa handle quoting.


scripts/publish/src/lib/git.ts -- gh release list truncated at 200

createGhRelease fetches releases with --limit 200. If this repo ever exceeds 200 published releases, the function will silently fail to find an existing release and create a duplicate instead of updating it. Consider --limit 1000 or searching by tag name directly with gh release view.


rivetkit-typescript/packages/rivetkit/src/engine-process/mod.ts -- unbounded log file growth

Each call to ensureEngineProcess creates a new timestamped stdout/stderr log file with no rotation or cleanup. Over time (especially in dev with frequent restarts) this will silently fill ~/.rivetkit/var/logs/. Consider a startup cleanup that removes logs older than N days or caps the number of retained files.


scripts/publish/src/lib/npm.ts -- unreachable fallthrough

When attempt === opts.retries + 1, the attempt > opts.retries guard inside the loop fires and returns early, making the post-loop return { pkg, status: "failed" } dead code. Harmless but confusing.


rivetkit-typescript/packages/engine-cli/index.js -- misleading Windows error message

getPlatformPackageName() correctly returns @rivetkit/engine-cli-win32-x64 for Windows x64. The catch block says "Windows x64 is not yet supported via npm platform packages" -- this is only reached on preview builds where the optional package was intentionally not published, but the first sentence is confusing for release users who end up there. The version-string check below handles the preview case correctly; the opening sentence could be softened to "Windows x64 binaries are only available for release versions."


.github/workflows/publish.yaml -- no job-level timeouts

Long cross-compilation jobs (Windows MinGW, darwin via osxcross) can hang silently. Without timeout-minutes on the build jobs, a hung sccache connection or depot.dev outage could burn CI minutes indefinitely. Adding timeout-minutes: 60 (or per-job appropriate values) to the matrix jobs would bound the blast radius.


Minor Notes

  • findRepoRoot is duplicated in src/ci/bin.ts, src/local/cut-release.ts, and src/lib/context.ts with slightly different implementations. Worth extracting to a shared lib/repo-root.ts.

  • scripts/publish/src/lib/r2.ts -- module-level credential caching via let cached is fine for CI (fresh process per run) but worth a comment noting it is not safe for long-running server processes.

  • scripts/publish/src/lib/packages.ts -- assertDiscoverySanity is a great pattern. Explicitly validating that expected packages are present before publish guards against silent config drift.

  • docker/build/*.Dockerfile -- pinning syntax=docker/dockerfile:1.10.0 and the inline sccache health-check with fallback-to-no-cache are both good practices.

  • publish.yaml fork detection via github.event.pull_request.head.repo.fork to gate secrets is the correct standard approach.


Summary

The publish unification architecture is clean and well-thought-out. The PublishContext single-resolution pattern, the versionOnly vs full-bump split (commit-safe vs publish-time), and the platform meta-package injection design are all solid. The main actionable items are: the shell: true in the git commit (low-severity security hygiene), unbounded log file accumulation (UX/disk), and missing job timeouts (CI reliability).

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 10, 2026

More templates

@rivetkit/virtual-websocket

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/virtual-websocket@4600

@rivetkit/engine-runner

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@4600

@rivetkit/engine-runner-protocol

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@4600

@rivetkit/framework-base

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/framework-base@4600

@rivetkit/next-js

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/next-js@4600

@rivetkit/react

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/react@4600

rivetkit

pnpm add https://pkg.pr.new/rivet-dev/rivet/rivetkit@4600

@rivetkit/rivetkit-native

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/rivetkit-native@4600

@rivetkit/sql-loader

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sql-loader@4600

@rivetkit/sqlite-native

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sqlite-native@4600

@rivetkit/sqlite-wasm

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sqlite-wasm@4600

@rivetkit/traces

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/traces@4600

@rivetkit/workflow-engine

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/workflow-engine@4600

@rivetkit/engine-envoy-protocol

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-envoy-protocol@4600

commit: 2357d28

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 10, 2026

Preview packages published to npm

Install with:

npm install rivetkit@pr-4600

All packages published as 0.0.0-pr.4600.e13738f with tag pr-4600.

Engine binary is shipped via @rivetkit/engine-cli on linux-x64-musl, linux-arm64-musl, darwin-x64, and darwin-arm64. Windows users should use the release installer or set RIVET_ENGINE_BINARY.

Docker images:

docker pull rivetdev/engine:slim-e13738f
docker pull rivetdev/engine:full-e13738f
Individual packages
npm install rivetkit@pr-4600
npm install @rivetkit/react@pr-4600
npm install @rivetkit/rivetkit-native@pr-4600
npm install @rivetkit/sqlite-wasm@pr-4600
npm install @rivetkit/workflow-engine@pr-4600

@MasterPtato MasterPtato mentioned this pull request Apr 11, 2026
11 tasks
@NathanFlurry NathanFlurry force-pushed the pkg-pr-new-native-builds branch 4 times, most recently from 2fa64c6 to c8960f9 Compare April 12, 2026 05:29
@MasterPtato MasterPtato force-pushed the 04-09-do_not_merge_sandbox_benches branch from 04c63da to 42de8ce Compare April 12, 2026 19:42
@NathanFlurry NathanFlurry force-pushed the 04-09-do_not_merge_sandbox_benches branch from 42de8ce to 04c63da Compare April 12, 2026 22:30
@NathanFlurry NathanFlurry marked this pull request as ready for review April 12, 2026 22:30
…ackages

Adds @rivetkit/engine-cli meta package with per-platform optionalDependencies
(linux-x64/arm64-musl, darwin-x64/arm64) and rewires rivetkit's engine-process
to resolve the binary via @rivetkit/engine-cli getEnginePath() instead of
downloading from releases.rivet.dev. This lets preview publishes ship a usable
engine to npm under the pr-<num> dist-tag.

- CI workflow places engine build artifacts into engine-cli/npm/<platform>/
- bump-versions injects optionalDependencies for both rivetkit-native and
  engine-cli meta packages
- discover-packages scans both rivetkit-native/npm and engine-cli/npm
The rivet-engine binary is statically linked against musl, so the single
musl build runs on both glibc and musl hosts. With libc:[musl] set on the
platform package.json, npm was skipping the optionalDependency on glibc
hosts (Debian/Ubuntu/etc), leaving them with no engine binary. Drop the
libc constraint so every linux host installs the musl package, and
simplify the resolver to map linux -> musl unconditionally.
…vetkit-native jobs

The previous single build job with an 11-entry matrix mixed rivetkit-native
and engine rows into one flat list. Splitting into two jobs gives each group
its own matrix, its own UI expand/collapse in the Actions tab, and makes the
distinction between native-addon builds and engine-binary builds explicit.

The publish job now depends on both build jobs via needs: [build-rivetkit-native, build-engine].
Merge scripts/release/ and scripts/preview-publish/ into a single
scripts/publish/ package with src/lib (shared modules), src/ci (workflow
subcommands), and src/local (release cutter). Merge release.yaml and
preview-publish.yaml into a single publish.yaml with a context job that
resolves trigger/version/tag once and pins them as job outputs.

Shared code path for PRs, main pushes, and release cuts: build matrix,
per-arch Docker push, multi-arch manifest, R2 upload, npm publish. Release
tail adds R2 copy to version prefix, Docker retag, git tag, and GitHub
release. Windows engine binary is built only on release triggers via a
matrix gate.

Drops reuse_engine_version plumbing, the phase-based release orchestrator,
and @rivetkit/sqlite-native platform package publishing (the sqlite-native
Rust crate is now statically linked into @rivetkit/rivetkit-native via
libsqlite3-sys bundled feature, so the standalone npm package is redundant).

Preserves @rivetkit/devtools R2 upload under a release-only tail step
because rivetkit client code still lazy-loads it from releases.rivet.dev.
- Replace CJS require('node:fs') with a top-level import in context.ts
  (the file is ESM; require is not defined at runtime).
- Replace gh api -F body=@- (non-standard stdin file marker) with
  -f body=<string> which execa template-interpolates directly.
Root postinstall runs lefthook install which requires .git, but
.dockerignore excludes .git/ from the build context. Adding
--ignore-scripts skips the postinstall entirely. lefthook is a dev
git-hook manager and has no role inside the Docker image build.
Turbo's ^build graph pulls @rivetkit/rivetkit-native into
build:engine -F @rivetkit/engine-frontend, which tries to run napi
build inside the Docker context. cargo works in the rust:* image
but the cache-mounted CARGO_HOME breaks rustup toolchain resolution.

Add SKIP_NAPI_BUILD=1 honored by rivetkit-native/scripts/build.mjs
and set it in the Dockerfile. The engine-frontend only consumes the
TypeScript surface of rivetkit, not the runtime .node binary.
Turbo filters env vars by task-level allow-list; SKIP_NAPI_BUILD set
in the Docker build was being stripped before reaching rivetkit-native
build.mjs. Add it to the build task env list.
Preview Docker images push without the engine frontend UI. Release
images include the full frontend. Sidesteps a pre-existing code bug
in frontend/src/components/use-deployment-logs-stream.ts that imports
a missing RivetSse value from a pkg.pr.new-hosted @rivet-gg/cloud.
pnpm --filter=publish exec runs in scripts/publish/, so relative
args like 'engine-artifacts' and 'scripts/publish/static' resolved
against the wrong base. Use $GITHUB_WORKSPACE-prefixed absolute
paths for any --source/--scripts-dir args.
The previous base was read from rivetkit-native/package.json, which is
just whatever version happens to be committed at the time — no semantic
relationship to the PR being previewed. Hardcode 0.0.0 so previews are
obviously not real releases and always sort below any X.Y.Z.
GITHUB_TOKEN needs workflows:write when pushing a tag that references
a commit containing .github/workflows/ changes. Without it, GitHub
rejects the push.
@NathanFlurry NathanFlurry changed the base branch from 04-09-do_not_merge_sandbox_benches to graphite-base/4600 April 13, 2026 07:07
@NathanFlurry NathanFlurry force-pushed the pkg-pr-new-native-builds branch from 94419f9 to 0708022 Compare April 13, 2026 07:07
@NathanFlurry NathanFlurry changed the base branch from graphite-base/4600 to main April 13, 2026 07:07
Copy link
Copy Markdown
Member Author

NathanFlurry commented Apr 13, 2026

Merge activity

  • Apr 13, 7:08 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Apr 13, 7:08 AM UTC: @NathanFlurry merged this pull request with Graphite.

@NathanFlurry NathanFlurry merged commit d6a0ba8 into main Apr 13, 2026
20 of 37 checks passed
@NathanFlurry NathanFlurry deleted the pkg-pr-new-native-builds branch April 13, 2026 07:09
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