Skip to content

chore: migrate pnpm to Bun in deploy-docs and Dockerfile#858

Open
djdembeck wants to merge 6 commits intodevelopfrom
chore/migrate-pnpm-to-bun
Open

chore: migrate pnpm to Bun in deploy-docs and Dockerfile#858
djdembeck wants to merge 6 commits intodevelopfrom
chore/migrate-pnpm-to-bun

Conversation

@djdembeck
Copy link
Copy Markdown
Collaborator

@djdembeck djdembeck commented Apr 7, 2026

Why

The migration from pnpm to Bun was completed in previous commits, but some pnpm references were missed.

What

  • Update deploy-docs.yml workflow to use Bun instead of pnpm
  • Update Dockerfile.prod to use Bun instead of pnpm
  • Delete orphaned pnpm-lock.yaml file

Spirit/Intent

Complete the pnpm to Bun migration by removing all remaining pnpm artifacts and configurations. This ensures consistency across the codebase and removes unused files.

Summary by CodeRabbit

  • Chores
    • Switched CI and container build tooling to a new JavaScript runtime/package manager, streamlining install and build steps.
    • Simplified dependency installation and reduced multi-stage install complexity for container images.
    • Reorganized how build artifacts and production dependencies are assembled into the runtime image.
    • No changes to runtime behavior, public APIs, or end-user functionality; experience unchanged.

Clean up remaining pnpm usage that was missed during main migration to Bun:

- Update deploy-docs.yml workflow to use Bun

- Update Dockerfile.prod to use Bun

- Delete orphaned pnpm-lock.yaml
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 7, 2026

📝 Walkthrough

Walkthrough

Switched JavaScript tooling from pnpm+Node.js to Bun in the docs CI workflow and the production Docker build; replaced setup actions and install/build commands with Bun equivalents and added a dedicated deps stage to produce production node_modules for the runtime image.

Changes

Cohort / File(s) Summary
CI Docs Workflow
/.github/workflows/deploy-docs.yml
Replaced pnpm/action-setup and actions/setup-node with oven-sh/setup-bun@v1 pinned to Bun v1.3.9; changed pnpm install --frozen-lockfilebun install --frozen-lockfile; changed pnpm run build-docsbun run build-docs. No other job logic, artifact upload, or OpenAPI sync steps modified.
Production Docker Build
Dockerfile.prod
Build stage switched to a Bun base image; replaced pnpm install/build with bun install --frozen-lockfile and bun run build. Added a deps stage running bun install --frozen-lockfile --production --ignore-scripts to produce production node_modules. Final runtime copies dist and package.json from build stage and node_modules from deps stage; runtime user, port, healthcheck, and entrypoint unchanged.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer/PR
    participant GH as GitHub Actions
    participant Bun as oven-sh/setup-bun
    participant Art as Artifacts
    Dev->>GH: push PR triggers workflow
    GH->>Bun: setup Bun v1.3.9
    GH->>Bun: bun install --frozen-lockfile
    GH->>Bun: bun run build-docs
    Bun->>Art: produce docs build artifacts
    GH->>Art: upload artifacts
Loading
sequenceDiagram
    participant Docker as Docker build
    participant Build as Builder (Bun image)
    participant Deps as Deps stage (Bun)
    participant Runtime as Final runtime image
    Docker->>Build: bun install --frozen-lockfile
    Build->>Build: bun run build -> generates /dist and package.json
    Docker->>Deps: bun install --frozen-lockfile --production --ignore-scripts -> produces prod node_modules
    Runtime->>Build: copy /dist and package.json
    Runtime->>Deps: copy production node_modules
    Runtime->>Runtime: set entrypoint `node ./dist/server.js`
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • ci: add docs deployment workflow #850: Previously added a pnpm/Node-based docs deployment workflow; directly related because this PR replaces that setup with oven-sh/setup-bun and Bun install/build commands.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Follow Agents.Md Standards ✅ Passed PR follows conventional commit format for infrastructure-only changes; code quality standards don't apply to non-TypeScript modifications.
Title check ✅ Passed The title follows the conventional commits format (chore: description) and accurately describes the main changes: migrating from pnpm to Bun in the deploy-docs workflow and Dockerfile.

✏️ 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 chore/migrate-pnpm-to-bun

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

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@Dockerfile.prod`:
- Around line 10-11: The Dockerfile currently installs all dependencies
(including devDependencies) in the build stage using "bun install" and then
copies node_modules into the final image; update the Dockerfile so the build
stage runs "bun install" (without --ignore-scripts) and "bun run build" as now,
but in the final production stage reinstall only production deps (e.g., run "bun
install --production --frozen-lockfile --ignore-scripts" or the equivalent Bun
flag) so devDependencies are excluded and lifecycle scripts are ignored in
production; ensure the production-stage command replaces the copied node_modules
or runs in an isolated layer so only production deps end up in the runtime image
and keep the --ignore-scripts flag only on the production install step.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 565ef96f-6db3-46a2-b07c-d03dbf42e202

📥 Commits

Reviewing files that changed from the base of the PR and between ccd7425 and 7236118.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • .github/workflows/deploy-docs.yml
  • Dockerfile.prod
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*

⚙️ CodeRabbit configuration file

**/*: Please review focusing on:

  • Code quality and consistency with existing patterns
  • Adherence to TypeScript best practices
  • Test coverage for any new code
  • Security implications of changes
  • Performance considerations
  • Documentation updates where needed

This project follows the AGENTS.md repository standards. Please ensure:

  • Conventional commit format is followed
  • Unit tests are included with proper coverage
  • No breaking changes are introduced without proper discussion

Files:

  • Dockerfile.prod
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: laxamentumtech/audnexus PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-16T18:11:20.542Z
Learning: CI runs linting, tests, and builds on push to main/develop/renovate branches and PRs to main/develop, with matrix testing for Node.js LTS and current versions
🔇 Additional comments (4)
.github/workflows/deploy-docs.yml (3)

28-31: LGTM! Bun setup is properly configured.

The action is correctly pinned by SHA, and the Bun version (1.3.9) aligns with the @types/bun version in package.json.


34-34: LGTM!

The --frozen-lockfile flag is correctly retained to ensure reproducible CI builds.


46-46: LGTM!

The bun run build-docs invocation is compatible with the existing script in package.json which simply runs the redocly CLI.

Dockerfile.prod (1)

2-2: LGTM!

Using oven/bun:alpine as the build stage base image is appropriate for the Bun migration.

- Remove --ignore-scripts from build stage to allow lifecycle scripts

- Install fresh production deps in final stage with --production flag

- Skip copying node_modules from build stage
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@Dockerfile.prod`:
- Around line 25-30: The Dockerfile production stage uses the nonexistent
bun.lockb and invokes the bun CLI in an image (node:lts-alpine) that doesn't
include Bun; update the COPY and install steps: change the copy source from
"bun.lockb" to the actual lockfile name "bun.lock" and either (a) install Bun in
the production stage before the "RUN bun install..." command so the bun CLI is
available, or (b) avoid running bun in prod by performing a production install
in the build stage (installing production deps there and copying node_modules
into the final image) and remove the "RUN bun install --production
--frozen-lockfile --ignore-scripts" line; adjust the COPY and RUN lines
accordingly to reference the corrected lockfile and chosen approach.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 62d077bf-e2d0-46c5-8ed0-bf461dbc70b8

📥 Commits

Reviewing files that changed from the base of the PR and between 7236118 and 96fea97.

📒 Files selected for processing (1)
  • Dockerfile.prod
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*

⚙️ CodeRabbit configuration file

**/*: Please review focusing on:

  • Code quality and consistency with existing patterns
  • Adherence to TypeScript best practices
  • Test coverage for any new code
  • Security implications of changes
  • Performance considerations
  • Documentation updates where needed

This project follows the AGENTS.md repository standards. Please ensure:

  • Conventional commit format is followed
  • Unit tests are included with proper coverage
  • No breaking changes are introduced without proper discussion

Files:

  • Dockerfile.prod
🔇 Additional comments (1)
Dockerfile.prod (1)

2-2: Build stage migration to Bun looks correct.

Using oven/bun:alpine for the build stage with bun install --frozen-lockfile and bun run build is appropriate. The removal of --ignore-scripts allows lifecycle scripts to run during build as needed.

Also applies to: 10-11

…ation

- Remove nonexistent bun.lockb reference from production stage
- Remove bun install from production stage (Bun not available in node:lts-alpine)
- Copy node_modules from build stage instead to use pre-installed dependencies
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
Dockerfile.prod (1)

10-11: ⚠️ Potential issue | 🟠 Major

Production image still carries devDependencies from the build stage.

Lines 10-11 install full deps, and Line 29 copies that full node_modules into runtime. This bloats the image and increases runtime attack surface.

Proposed fix
 RUN bun install --frozen-lockfile \
-    && bun run build
+    && bun run build \
+    && rm -rf node_modules \
+    && bun install --production --frozen-lockfile --ignore-scripts
#!/bin/bash
set -euo pipefail

echo "== Dev dependency count =="
jq '.devDependencies | length' package.json

echo "== Dockerfile dependency install/copy steps =="
rg -n 'bun install|COPY --from=build /app/node_modules' Dockerfile.prod

echo "== Check for production-only install/prune command =="
rg -n --pcre2 'bun install.*(--production|-p)\b|npm prune --omit=dev|pnpm install.*--prod' Dockerfile.prod || true

As per coding guidelines, please review focusing on security implications and performance considerations.

Also applies to: 28-29

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile.prod` around lines 10 - 11, The Dockerfile currently runs a full
dependency install (RUN bun install --frozen-lockfile && bun run build) and then
copies /app/node_modules from the build stage into the runtime, which pulls
devDependencies into the final image; change the build-stage install to a
production-only install (e.g., replace RUN bun install --frozen-lockfile with
RUN bun install --frozen-lockfile --production or equivalent bun prune/omit-dev
step after install) so devDependencies are never installed, and keep the COPY
--from=build /app/node_modules into the runtime but only after the
production-only install; update any build-stage steps that rely on devDeps to
run in a separate intermediate stage if needed so the final image contains only
production deps.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Dockerfile.prod`:
- Line 2: Replace the floating base image reference "FROM oven/bun:alpine AS
build" with a pinned Bun image (include the 1.x tag and the image manifest
digest) so production builds are reproducible; update the FROM line to use the
form "oven/bun:1-alpine@sha256:<manifest_digest>" by fetching the correct sha256
manifest for the chosen tag from the registry and commit that exact digest.

---

Duplicate comments:
In `@Dockerfile.prod`:
- Around line 10-11: The Dockerfile currently runs a full dependency install
(RUN bun install --frozen-lockfile && bun run build) and then copies
/app/node_modules from the build stage into the runtime, which pulls
devDependencies into the final image; change the build-stage install to a
production-only install (e.g., replace RUN bun install --frozen-lockfile with
RUN bun install --frozen-lockfile --production or equivalent bun prune/omit-dev
step after install) so devDependencies are never installed, and keep the COPY
--from=build /app/node_modules into the runtime but only after the
production-only install; update any build-stage steps that rely on devDeps to
run in a separate intermediate stage if needed so the final image contains only
production deps.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: aab54920-5391-4d59-a3da-1a82370192d4

📥 Commits

Reviewing files that changed from the base of the PR and between 96fea97 and 10a0a44.

📒 Files selected for processing (1)
  • Dockerfile.prod
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*

⚙️ CodeRabbit configuration file

**/*: Please review focusing on:

  • Code quality and consistency with existing patterns
  • Adherence to TypeScript best practices
  • Test coverage for any new code
  • Security implications of changes
  • Performance considerations
  • Documentation updates where needed

This project follows the AGENTS.md repository standards. Please ensure:

  • Conventional commit format is followed
  • Unit tests are included with proper coverage
  • No breaking changes are introduced without proper discussion

Files:

  • Dockerfile.prod
🔇 Additional comments (1)
Dockerfile.prod (1)

25-26: Good explicit runtime metadata copy.

Copying package.json explicitly from the build stage keeps runtime artifact inputs clear and consistent.

Changes:
- Pin oven/bun base image to specific SHA for reproducibility
- Add dedicated deps stage to install production-only dependencies
- Modify prod stage to copy from deps stage, excluding devDependencies

This reduces final container size by not including build-time dependencies.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
Dockerfile.prod (1)

21-22: ⚠️ Potential issue | 🟡 Minor

Skip project install hooks in the deps stage.

Line 22 will rerun the root install/prepare hooks because Bun executes the project’s {pre|post}install and {pre|post}prepare scripts during bun install, and this repo’s package.json defines a preinstall hook. In the production-deps stage those scripts do not contribute to the runtime image, so they only add another avoidable failure point during image build; --ignore-scripts is the supported way to skip them. (bun.sh)

Suggested hardening
-RUN bun install --frozen-lockfile --production
+RUN bun install --frozen-lockfile --production --ignore-scripts

Run this to show the project hooks and the current deps-stage install command:

#!/bin/bash
set -euo pipefail

echo "=== package.json install/prepare hooks ==="
python - <<'PY'
import json
with open("package.json") as f:
    scripts = json.load(f).get("scripts", {})
for key in ("preinstall", "postinstall", "preprepare", "postprepare"):
    if key in scripts:
        print(f"{key}: {scripts[key]}")
PY

echo
echo "=== deps stage install command ==="
sed -n '18,23p' Dockerfile.prod

Expected result: if any root install/prepare hooks are present, add --ignore-scripts on Line 22 so they are not rerun in the production-deps layer.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile.prod` around lines 21 - 22, The production-deps stage runs "RUN
bun install --frozen-lockfile --production" which will execute project
{pre|post}install and prepare hooks; change that command to skip project
install/prepare scripts by adding Bun's --ignore-scripts flag so hooks in
package.json are not re-run in the deps stage (update the RUN bun install
--frozen-lockfile --production invocation to include --ignore-scripts).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@Dockerfile.prod`:
- Around line 21-22: The production-deps stage runs "RUN bun install
--frozen-lockfile --production" which will execute project {pre|post}install and
prepare hooks; change that command to skip project install/prepare scripts by
adding Bun's --ignore-scripts flag so hooks in package.json are not re-run in
the deps stage (update the RUN bun install --frozen-lockfile --production
invocation to include --ignore-scripts).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 327b4f18-e344-41d8-8e28-e9eefe535f56

📥 Commits

Reviewing files that changed from the base of the PR and between 10a0a44 and 98af301.

📒 Files selected for processing (1)
  • Dockerfile.prod
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*

⚙️ CodeRabbit configuration file

**/*: Please review focusing on:

  • Code quality and consistency with existing patterns
  • Adherence to TypeScript best practices
  • Test coverage for any new code
  • Security implications of changes
  • Performance considerations
  • Documentation updates where needed

This project follows the AGENTS.md repository standards. Please ensure:

  • Conventional commit format is followed
  • Unit tests are included with proper coverage
  • No breaking changes are introduced without proper discussion

Files:

  • Dockerfile.prod
🧠 Learnings (1)
📚 Learning: 2026-02-16T18:11:20.542Z
Learnt from: CR
Repo: laxamentumtech/audnexus PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-16T18:11:20.542Z
Learning: Docker publish workflow builds and pushes images to ghcr.io on schedule (daily 05:15 UTC), push to develop/main/semver tags, and PRs to main. Only publishes images—does not deploy (use Coolify for deployment)

Applied to files:

  • Dockerfile.prod
🪛 GitHub Check: SonarCloud Code Analysis
Dockerfile.prod

[warning] 2-2: Use either the version tag or the digest for the image instead of both.

See more on https://sonarcloud.io/project/issues?id=laxamentumtech_audnexus&issues=AZ1pSZq8f8TpJOiaZyhO&open=AZ1pSZq8f8TpJOiaZyhO&pullRequest=858


[warning] 14-14: Use either the version tag or the digest for the image instead of both.

See more on https://sonarcloud.io/project/issues?id=laxamentumtech_audnexus&issues=AZ1pSZq8f8TpJOiaZyhP&open=AZ1pSZq8f8TpJOiaZyhP&pullRequest=858

🔇 Additional comments (1)
Dockerfile.prod (1)

18-19: Verify the deps stage is copying the active Bun lockfile.

Line 19 hardcodes bun.lockb. Bun 1.2+ defaults to bun.lock, and bun.lockb is only the legacy format unless the repo explicitly opts back into it. If this repo has already migrated to the text lockfile, this COPY will fail before the production-deps install runs. (bun.sh)

Run this to confirm the committed lockfile/config matches Dockerfile.prod:

#!/bin/bash
set -euo pipefail

echo "=== Bun lockfiles present ==="
find . -maxdepth 2 \( -name 'bun.lock' -o -name 'bun.lockb' \) -print | sort

echo
echo "=== bunfig lockfile settings ==="
if [ -f bunfig.toml ]; then
  rg -n 'saveTextLockfile|lockfile' bunfig.toml
else
  echo "bunfig.toml not present"
fi

echo
echo "=== Dockerfile reference ==="
grep -nE 'bun\.lockb?' Dockerfile.prod

Expected result: the filename copied on Line 19 should match the Bun lockfile actually committed/configured in the repo.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Dockerfile.prod`:
- Around line 18-22: The Dockerfile's COPY instruction references the wrong
lockfile name; update the COPY line that currently says COPY package.json
bun.lockb ./ to use the repository's actual lockfile name (bun.lock) so it reads
COPY package.json bun.lock ./; leave the subsequent RUN bun install
--frozen-lockfile --production --ignore-scripts unchanged.
- Around line 24-25: Replace the unpinned base image line "FROM node:lts-alpine
AS prod" with a pinned Node.js image (either a specific version tag like
node:18.19.0-alpine or the corresponding digested image) to ensure reproducible
builds; update the Dockerfile's Stage 3 base image declaration (the FROM line
referencing node:lts-alpine AS prod) to use the chosen pinned tag or digest and
verify the digest/tag matches your CI/build environment.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 45cdacf3-73b3-4a29-a682-1e6b8c1552fd

📥 Commits

Reviewing files that changed from the base of the PR and between 98af301 and 2ae35b6.

📒 Files selected for processing (1)
  • Dockerfile.prod
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*

⚙️ CodeRabbit configuration file

**/*: Please review focusing on:

  • Code quality and consistency with existing patterns
  • Adherence to TypeScript best practices
  • Test coverage for any new code
  • Security implications of changes
  • Performance considerations
  • Documentation updates where needed

This project follows the AGENTS.md repository standards. Please ensure:

  • Conventional commit format is followed
  • Unit tests are included with proper coverage
  • No breaking changes are introduced without proper discussion

Files:

  • Dockerfile.prod
🔇 Additional comments (2)
Dockerfile.prod (2)

1-11: Build stage is well-structured.

The pinned oven/bun:1-alpine@sha256:... image ensures reproducible builds. Using --frozen-lockfile without --ignore-scripts is correct here since lifecycle scripts may be needed during the build phase.


36-54: Production stage assembly is well-designed.

The three-stage build pattern correctly addresses the previous concern about devDependencies being included in the production image:

  • node_modules from the deps stage contains only production dependencies
  • dist from the build stage contains compiled output
  • Non-root user and healthcheck follow security best practices

As per coding guidelines, the Node runtime is appropriate here since the compiled output is pure ESM that Node can execute without Bun-specific APIs.

- Add build stage using bun to compile the application
- Add deps stage for production-only dependencies
- Add prod stage with non-root user (nodejs:1001)
- Set up HEALTHCHECK with curl on port 3000
- Improve security by running as non-root user
@djdembeck djdembeck changed the title chore: remove leftover pnpm references chore: migrate pnpm to Bun in deploy-docs and Dockerfile Apr 7, 2026
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