feat: add hardened standalone container build - #624
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #624 +/- ##
=======================================
Coverage 92.94% 92.94%
=======================================
Files 35 35
Lines 1559 1559
Branches 392 392
=======================================
Hits 1449 1449
Misses 48 48
Partials 62 62 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Queued — the merge queue status continues in this comment ↓. |
There was a problem hiding this comment.
✨ PR Review
The PR introduces a well-structured two-stage standalone container build with a sensible .dockerignore allowlist and CI smoke checks. Two concrete issues were identified: a floating base-image tag that breaks reproducibility and risks a future runtime/compile-target mismatch, and a versioned changeset used for what the project's own rules classify as an internal-only change.
2 issues detected:
🧹 Maintainability - `node:lts-alpine` is a mutable tag; future LTS transitions will silently swap the runtime engine and break the node24 compile target.
Details: Both FROM node:lts-alpine stages use a mutable floating tag. When the Node.js LTS pointer moves to a new major (e.g., Node 26), both the build toolchain and the runtime will silently change. This also creates a hard mismatch with the target: "node24" value hardcoded in tsdown.config.ts: the standalone bundle is compiled for Node 24 APIs/syntax but will eventually be executed on a different engine version without any warning.
File: Dockerfile (3-14)
🧹 Maintainability - A `patch` version bump is emitted for a purely internal Docker/CI change, violating the project's own changeset guidelines.
Details: The project's own contribution rules state "use a versioned changeset only for user-facing, runtime-visible changes; use npx changeset --empty for docs, CI, tests, refactors, and other internal-only changes." Adding a Dockerfile, .dockerignore, and CI workflow is a build/ops change with no effect on the published npm package's runtime behaviour, so a versioned patch bump is incorrect here.
File: .changeset/calm-taxis-build.md (1-5)
Generated by LinearB AI and added by gitStream.
AI-generated content may contain inaccuracies. Please verify before using.
💡 Tip: You can customize your AI Review using Guidelines Learn how
Unit Test Results 1 files 32 suites 2s ⏱️ Results for commit b5dcbd7. ♻️ This comment has been updated with latest results. |
40b98a7 to
b5dcbd7
Compare
There was a problem hiding this comment.
✨ PR Review
The PR introduces a clean two-stage standalone Docker build. The allowlist .dockerignore, CI smoke checks, and bundling approach are well-structured. Two previously flagged issues (mutable lts-alpine tag and incorrect versioned changeset for a CI/ops change) remain unresolved and are not re-raised here. One new concrete bug was found in the tsdown configuration.
1 issues detected:
🐞 Bug - `clean: true` deletes the entire shared `dist/` folder before each build, so whichever build runs second erases the other's output.
Details: Both npm run build and npm run build:standalone use outDir: "dist" with clean: true. Running build:standalone wipes the entire dist/ directory and writes only standalone.mjs; a subsequent npm run build (or prepack) then wipes standalone.mjs and writes the library/CLI artefacts. The two build modes cannot coexist and will silently corrupt each other in any workflow that invokes both (e.g., a developer iterating locally, or a CI job that runs prepack after the Docker build step in the same workspace).
File: tsdown.config.ts (65-83)
Generated by LinearB AI and added by gitStream.
AI-generated content may contain inaccuracies. Please verify before using.
💡 Tip: You can customize your AI Review using Guidelines Learn how
Merge Queue Status
This pull request spent 2 minutes 47 seconds in the queue, including 1 minute 20 seconds running CI. Required conditions to merge
|
Summary
tsdownserver build for container deployment.node:lts-alpineimage with a non-root runtime and no applicationnode_modulesin the final image.Validation
npm run buildnpm run build:standalonenode dist/standalone.mjs --versionnode dist/standalone.mjs --helpnpm run check:typesnpm run checknpx vitest run --exclude tests/integration/**npm run check:changesetA local Docker engine was unavailable, so GitHub Actions performs the Docker build and runtime checks.
Resolves #618
✨ PR Description
Purpose: Convert Docker container build to hardened standalone Node.js bundle without application node_modules directory and run as non-root user.
Main changes:
Generated by LinearB AI and added by gitStream.
AI-generated content may contain inaccuracies. Please verify before using.
💡 Tip: You can customize your AI Description using Guidelines Learn how