Skip to content

fix(release): lint native packages before publish - #1073

Merged
ryoppippi merged 1 commit into
mainfrom
codex/subpackage-publish-lint
May 19, 2026
Merged

ryoppippi merged 1 commit into
mainfrom
codex/subpackage-publish-lint

Conversation

@ryoppippi

@ryoppippi ryoppippi commented May 19, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Runs clean-pkg-json and publint from each native optional package prepack hook after native binary verification.
  • Adds package-local catalog devDependencies so the publish lifecycle can resolve both CLIs for every native subpackage.
  • Marks native packages as commonjs to keep publint output clean for packages without JavaScript entrypoints.

Testing

  • pnpm run format
  • pnpm typecheck
  • pnpm --filter ./packages/ccusage-darwin-arm64 exec publint
  • env NIX_CONFIG="access-tokens = github.com=$(gh auth token)" nix develop --command pnpm run test

Summary by cubic

Lint and clean native @ccusage/* subpackages during publish to catch manifest issues and match the main package’s checks. prepack now runs clean-pkg-json and publint after verifying the native binary, and packages are marked as CommonJS to reduce lint noise.

  • Bug Fixes
    • Run clean-pkg-json and publint in each native subpackage prepack after binary verification.
    • Add catalog devDependencies for both CLIs so lifecycle scripts resolve per subpackage.
    • Set "type": "commonjs" to avoid publint warnings for packages without JS entrypoints.

Written for commit 484a7da. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • Chores
    • Updated package configurations for all platform-specific native builds (Darwin, Linux, Windows).
    • Standardized CommonJS module type declaration across native packages.
    • Enhanced pre-release validation with additional package integrity and linting checks.
    • Added supporting development tools to ensure consistent package quality standards.

Review Change Stack

Native optional packages previously only verified that the staged binary existed during prepack. The publish path now also runs clean-pkg-json and publint so the subpackage manifests receive the same cleanup and package validation as the main ccusage package before npm publish.

Each native package declares the release and lint CLIs as devDependencies through the existing catalogs so pnpm can resolve the lifecycle commands from the package itself. The manifests also set type=commonjs to keep publint output clean for packages that do not ship JavaScript entrypoints.
@ryoppippi

Copy link
Copy Markdown
Member Author

@coderabbitai please review this PR.

This updates the native optional package publish lifecycle so each subpackage runs clean-pkg-json and publint after verifying its staged binary.

@coderabbitai

coderabbitai Bot commented May 19, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e019aa5c-da1c-42bf-a869-eca03d5338c1

📥 Commits

Reviewing files that changed from the base of the PR and between 5f6410c and 484a7da.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • packages/ccusage-darwin-arm64/package.json
  • packages/ccusage-darwin-x64/package.json
  • packages/ccusage-linux-arm64/package.json
  • packages/ccusage-linux-x64/package.json
  • packages/ccusage-win32-arm64/package.json
  • packages/ccusage-win32-x64/package.json

📝 Walkthrough

Walkthrough

Six native packages for different platforms (darwin-arm64/x64, linux-arm64/x64, win32-arm64/x64) are updated identically to declare CommonJS module type and extend their prepack build pipeline with package cleanup and linting tools.

Changes

Native Packages CommonJS and Prepack Configuration

Layer / File(s) Summary
CommonJS type declaration and prepack tooling
packages/ccusage-darwin-arm64/package.json, packages/ccusage-darwin-x64/package.json, packages/ccusage-linux-arm64/package.json, packages/ccusage-linux-x64/package.json, packages/ccusage-win32-arm64/package.json, packages/ccusage-win32-x64/package.json
All six platform-specific native packages add "type": "commonjs" to declare their module system. The prepack script is extended to run clean-pkg-json && publint after the native package verification step. Corresponding devDependencies for clean-pkg-json and publint are added to each package to support the extended prepack pipeline.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes


🐰 Six packages hop in sync,
With CommonJS type they link,
Clean and lint before they ship,
Every platform takes the trip! 📦✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(release): lint native packages before publish' clearly and concisely summarizes the main change: adding linting steps to the prepack script for native packages before publishing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/subpackage-publish-lint

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

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
ccusage-guide 484a7da Commit Preview URL

Branch Preview URL
May 19 2026, 08:00 PM

@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

I'll fetch the PR details and examine the changes before giving a thorough review.


🏁 Script executed:

#!/bin/bash
# Get the PR diff and details
gh pr view 1073 --repo ryoppippi/ccusage --json title,body,files,additions,deletions,changedFiles

echo "=== PR diff ==="
gh pr diff 1073 --repo ryoppippi/ccusage

Length of output: 8610


🏁 Script executed:

#!/bin/bash
# Look at the catalog configuration in pnpm-workspace.yaml
cat pnpm-workspace.yaml 2>/dev/null || echo "pnpm-workspace.yaml not found"

echo "=== One full native package.json for context ==="
cat packages/ccusage-darwin-arm64/package.json

echo "=== verify-native-package.mjs script ==="
cat apps/ccusage/scripts/verify-native-package.mjs

echo "=== Main package prepack for comparison ==="
cat apps/ccusage/package.json | python3 -c "import sys, json; d=json.load(sys.stdin); print(json.dumps(d.get('scripts', {}), indent=2))"

Length of output: 5318


@ryoppippi This is a clean, well-structured improvement to the native package publish lifecycle. Here's my review:


Review Summary

All 6 native packages (darwin-arm64, darwin-x64, linux-arm64, linux-x64, win32-arm64, win32-x64) receive identical, consistent changes. No issues found — everything looks correct.

✅ What looks good

prepack script ordering

verify-native-package.mjs && clean-pkg-json && publint

The order is logical and intentional:

  1. Verify binary first — fail-fast if the staged binary isn't present or isn't executable.
  2. clean-pkg-json — strips devDependencies and other dev-only fields from the manifest in-place.
  3. publint — validates the cleaned manifest (i.e., exactly what will be published). This is the correct order.

Catalog references are valid
Both "clean-pkg-json": "catalog:release" and "publint": "catalog:lint" correctly map to entries already defined in pnpm-workspace.yaml. The lockfile is updated accordingly.

"type": "commonjs" is the right call
These packages only ship a binary (bin/ccusage) with no JavaScript entrypoints. Without a type field, publint emits noise about ambiguous module type. Setting commonjs cleanly silences those warnings without misrepresenting anything.

Windows compatibility
The && chain is safe because shellEmulator: true is set in the workspace config, which pnpm uses to emulate POSIX shell syntax on Windows.

devDependencies won't leak into published packages
clean-pkg-json strips them before the tarball is packed, so the added devDependencies block serves only the local lifecycle and won't appear on npm.

Consistent with the main package's pattern
The main apps/ccusage prepack already uses clean-pkg-json. This PR brings the native subpackages in line — and goes a step further by adding publint as well.


No issues found. This is a solid, minimal, and well-reasoned improvement to the release pipeline. ✅

[approve]

@pkg-pr-new

pkg-pr-new Bot commented May 19, 2026

Copy link
Copy Markdown

Open in StackBlitz

ccusage

npx https://pkg.pr.new/ryoppippi/ccusage@1073

@ccusage/ccusage-darwin-arm64

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/ccusage-darwin-arm64@1073

@ccusage/ccusage-darwin-x64

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/ccusage-darwin-x64@1073

@ccusage/ccusage-linux-arm64

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/ccusage-linux-arm64@1073

@ccusage/ccusage-linux-x64

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/ccusage-linux-x64@1073

@ccusage/ccusage-win32-arm64

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/ccusage-win32-arm64@1073

@ccusage/ccusage-win32-x64

npx https://pkg.pr.new/ryoppippi/ccusage/@ccusage/ccusage-win32-x64@1073

commit: 484a7da

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 484a7da30b72
Base SHA: 5f6410cef124

This compares the Rust PR release binary against the configured base package on the same CI runner.

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new 5f6410cef124 659.6ms 483.7ms 33.4ms 3
PR pkg.pr.new 484a7da30b72 702.1ms 538.5ms 34.2ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: 5f6410cef124; PR package: 484a7da30b72. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, measured by hyperfine with 0 warmups and 1 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 691.6ms 691.4ms 1.00x 1.46 GiB/s 1.46 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 851.7ms 827.3ms 1.03x 1.18 GiB/s 1.22 GiB/s

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 682.9ms 1.47 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 646.9ms 1.56 GiB/s 1
claude --offline --json Workspace release binary 1.01 GiB 710.9ms 1.42 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 816.2ms 1.23 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 791.7ms 1.27 GiB/s 1
codex --offline --json Workspace release binary 1.01 GiB 806.4ms 1.25 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
claude daily --offline --json 0.00 MiB 31.9ms 4.5ms 7.11x 0.05 MiB/s 0.34 MiB/s
claude session --offline --json 0.00 MiB 31.0ms 4.6ms 6.71x 0.05 MiB/s 0.33 MiB/s
codex daily --offline --json 0.00 MiB 30.8ms 4.2ms 7.25x 0.03 MiB/s 0.20 MiB/s
codex session --offline --json 0.00 MiB 30.0ms 4.2ms 7.10x 0.03 MiB/s 0.20 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs rust/target/release/ccusage directly. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
claude --offline --json 1.01 GiB 680.2ms 706.2ms 0.96x 1.48 GiB/s 1.43 GiB/s
codex --offline --json 1.01 GiB 820.2ms 806.3ms 1.02x 1.23 GiB/s 1.25 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 9.45 KiB 9.45 KiB +0.00 KiB 1.00x
installed native package binary 3288.24 KiB 3288.24 KiB +0.00 KiB 1.00x
Rust release binary rust/target/release/ccusage - 2955.68 KiB - -

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: 484a7da30b72
Base SHA: 5f6410cef124

This compares the PR package against the configured base package on the same CI runner.

Package runner startup

Execution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one bunx -p <url> ccusage --version run with an empty Bun install cache. Warm reuses that cache and reports the median of repeated runs.

Package SHA Execution setup Bunx temp cache Bunx warm median Warm samples
Base pkg.pr.new 5f6410cef124 630.9ms 510.3ms 33.7ms 3
PR pkg.pr.new 484a7da30b72 591.9ms 686.1ms 33.0ms 3

Cached bunx execution performance

Runs the same large fixture through bunx -p <pkg.pr.new URL> ccusage after the Bun install cache has already been populated by the startup measurement. This separates cached package-runner execution from first-fetch package materialization.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base package: 5f6410cef124; PR package: 484a7da30b72. Both run through bunx -p <pkg.pr.new URL> ccusage using the warmed Bun install cache from package runner startup, measured by hyperfine with 0 warmups and 1 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
bunx -p <pkg> ccusage claude --offline --json 1.01 GiB 693.0ms 695.0ms 1.00x 1.45 GiB/s 1.45 GiB/s
bunx -p <pkg> ccusage codex --offline --json 1.01 GiB 861.8ms 854.2ms 1.01x 1.17 GiB/s 1.18 GiB/s

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 678.6ms 1.48 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 656.5ms 1.53 GiB/s 1
claude --offline --json Workspace release binary 1.01 GiB 718.4ms 1.40 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 852.9ms 1.18 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 817.1ms 1.23 GiB/s 1
codex --offline --json Workspace release binary 1.01 GiB 816.4ms 1.23 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
claude daily --offline --json 0.00 MiB 32.0ms 32.0ms 1.00x 0.05 MiB/s 0.05 MiB/s
claude session --offline --json 0.00 MiB 32.3ms 31.9ms 1.01x 0.05 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 31.9ms 31.3ms 1.02x 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 31.5ms 31.4ms 1.00x 0.03 MiB/s 0.03 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/work/_temp/ccusage-large-fixture (1.01 GiB, 2,597 files), Codex /home/runner/work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2,597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.

Command Input Base median PR median PR vs base Base throughput PR throughput
claude --offline --json 1.01 GiB 686.9ms 713.0ms 0.96x 1.47 GiB/s 1.41 GiB/s
codex --offline --json 1.01 GiB 891.3ms 860.8ms 1.04x 1.13 GiB/s 1.17 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 9.45 KiB 9.45 KiB +0.00 KiB 1.00x
installed native package binary 3288.24 KiB 3288.24 KiB +0.00 KiB 1.00x
Rust release binary rust/target/release/ccusage - 2955.68 KiB - -

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@ryoppippi
ryoppippi merged commit 8378395 into main May 19, 2026
39 checks passed
@ryoppippi
ryoppippi deleted the codex/subpackage-publish-lint branch May 19, 2026 21:42
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