-
-
Notifications
You must be signed in to change notification settings - Fork 989
fix(cli-v3): detect package manager (yarn/pnpm/npm) and lockfile for correct deploy builds #2988
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix(cli-v3): detect package manager (yarn/pnpm/npm) and lockfile for correct deploy builds #2988
Conversation
…correct deploy builds (triggerdotdev#2914)
🦋 Changeset detectedLatest commit: 4621b9c The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughThis pull request implements package manager and lockfile detection for container builds. The system now detects the active package manager (npm, yarn, or pnpm) and its corresponding lockfile, copies the lockfile into the build output, and generates appropriate install commands in the generated Containerfile. Four files are modified: a changeset entry documenting the fix, the build worker script to handle package manager detection and lockfile copying, the container image generation logic to support multiple package managers, and a new test file validating the behavior across different package manager scenarios. Estimated code review effort🎯 3 (Moderate) | ⏱️ ~30 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return ` | ||
| RUN corepack enable | ||
| RUN pnpm install | ||
| `; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 pnpm install command generates inconsistent Dockerfile formatting with extra whitespace
The getInstallCommand function for pnpm returns a template literal with leading newlines and 6 spaces of indentation before each RUN command.
Click to expand
Issue
The pnpm case at buildImage.ts:1176-1180 returns:
return `
RUN corepack enable
RUN pnpm install
`;This produces output with leading/trailing newlines and inconsistent indentation:
COPY --chown=node:node package.json ./
# No lockfile path provided
RUN corepack enable
RUN pnpm install
# Now copy all the files
Comparison
The npm and yarn cases return clean single-line strings without extra whitespace:
"RUN yarn install"(line 1174)"RUN npm i --no-audit --no-fund --no-save --no-package-lock"(line 1184)
Impact
While Docker technically accepts indented RUN commands, this produces messy Dockerfile output that is inconsistent with the rest of the generated file. The extra blank lines and indentation make the Dockerfile harder to read and debug.
Recommendation: Use consistent formatting without extra whitespace:
case "pnpm": {
return "RUN corepack enable\nRUN pnpm install";
}Was this helpful? React with 👍 or 👎 to provide feedback.
Review CompleteYour review story is ready! Comment !reviewfast on this PR to re-generate the story. |
There was a problem hiding this 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
🤖 Fix all issues with AI agents
In `@packages/cli-v3/src/deploy/buildImage.ts`:
- Around line 1171-1187: getInstallCommand currently prevents reproducible
installs and creates extra Docker layers; update it so npm uses "npm ci" (not
"npm i"), yarn uses a frozen/CI mode (e.g., "yarn install --frozen-lockfile"),
and pnpm runs corepack enable and install in a single RUN with pnpm's
frozen-lockfile flag (e.g., "corepack enable && pnpm install --frozen-lockfile")
to avoid multiple layers; modify the switch in getInstallCommand (check
packageManager?.name) to return these CI/immutable install commands and remove
the "--no-package-lock/--no-audit" pattern that disables lockfile enforcement.
🧹 Nitpick comments (2)
packages/cli-v3/src/build/buildWorker.ts (1)
212-233: Consider warning users when lockfile copy fails.The current implementation silently fails (debug-level log only) when the lockfile cannot be copied. This could lead to non-reproducible builds without the user's awareness, especially if they expect the lockfile to be used.
💡 Proposed enhancement to warn users on lockfile copy failure
if (lockFile) { try { await copyFile( join(resolvedConfig.workingDir, lockFile), join(outputPath, lockFile) ); } catch (e) { - logger.debug("Failed to copy lockfile", { + logger.warn("Failed to copy lockfile - build may not be reproducible", { lockFile, error: e instanceof Error ? e.message : e, }); } }packages/cli-v3/src/deploy/buildImage.test.ts (1)
1-4: Minor: Remove leading empty line.There's an unnecessary empty line at the start of the file.
✨ Proposed fix
- import { describe, it, expect } from "vitest"; import { generateContainerfile, GenerateContainerfileOptions } from "./buildImage.js";
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
.changeset/fix-cli-deploy-yarn-workspaces.mdpackages/cli-v3/src/build/buildWorker.tspackages/cli-v3/src/deploy/buildImage.test.tspackages/cli-v3/src/deploy/buildImage.ts
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead
**/*.{ts,tsx}: Always import tasks from@trigger.dev/sdk, never use@trigger.dev/sdk/v3or deprecatedclient.defineJobpattern
Every Trigger.dev task must be exported and have a uniqueidproperty with no timeouts in the run function
Files:
packages/cli-v3/src/deploy/buildImage.test.tspackages/cli-v3/src/deploy/buildImage.tspackages/cli-v3/src/build/buildWorker.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function declarations instead of default exports
Import from
@trigger.dev/coreusing subpaths only, never import from root
Files:
packages/cli-v3/src/deploy/buildImage.test.tspackages/cli-v3/src/deploy/buildImage.tspackages/cli-v3/src/build/buildWorker.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use vitest for all tests in the Trigger.dev repository
Files:
packages/cli-v3/src/deploy/buildImage.test.ts
**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/otel-metrics.mdc)
**/*.ts: When creating or editing OTEL metrics (counters, histograms, gauges), ensure metric attributes have low cardinality by using only enums, booleans, bounded error codes, or bounded shard IDs
Do not use high-cardinality attributes in OTEL metrics such as UUIDs/IDs (envId, userId, runId, projectId, organizationId), unbounded integers (itemCount, batchSize, retryCount), timestamps (createdAt, startTime), or free-form strings (errorMessage, taskName, queueName)
When exporting OTEL metrics via OTLP to Prometheus, be aware that the exporter automatically adds unit suffixes to metric names (e.g., 'my_duration_ms' becomes 'my_duration_ms_milliseconds', 'my_counter' becomes 'my_counter_total'). Account for these transformations when writing Grafana dashboards or Prometheus queries
Files:
packages/cli-v3/src/deploy/buildImage.test.tspackages/cli-v3/src/deploy/buildImage.tspackages/cli-v3/src/build/buildWorker.ts
**/*.{js,ts,jsx,tsx,json,md,yaml,yml}
📄 CodeRabbit inference engine (AGENTS.md)
Format code using Prettier before committing
Files:
packages/cli-v3/src/deploy/buildImage.test.tspackages/cli-v3/src/deploy/buildImage.tspackages/cli-v3/src/build/buildWorker.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.test.{ts,tsx,js,jsx}: Test files should live beside the files under test and use descriptivedescribeanditblocks
Tests should avoid mocks or stubs and use the helpers from@internal/testcontainerswhen Redis or Postgres are needed
Use vitest for running unit tests
**/*.test.{ts,tsx,js,jsx}: Use vitest exclusively for testing and never mock anything - use testcontainers instead
Place test files next to source files with naming pattern: source file (e.g.,MyService.ts) →MyService.test.ts
Files:
packages/cli-v3/src/deploy/buildImage.test.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use testcontainers helpers (
redisTest,postgresTest,containerTest) from@internal/testcontainersfor Redis/PostgreSQL testing instead of mocks
Files:
packages/cli-v3/src/deploy/buildImage.test.ts
{packages,integrations}/**/*
📄 CodeRabbit inference engine (CLAUDE.md)
Add a changeset when modifying any public package in
packages/*orintegrations/*usingpnpm run changeset:add
Files:
packages/cli-v3/src/deploy/buildImage.test.tspackages/cli-v3/src/deploy/buildImage.tspackages/cli-v3/src/build/buildWorker.ts
🧠 Learnings (20)
📓 Common learnings
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Use build extensions in trigger.config.ts (additionalFiles, additionalPackages, aptGet, prismaExtension, etc.) to customize the build
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-15T11:50:06.067Z
Learning: Applies to {packages,integrations}/**/* : Add a changeset when modifying any public package in `packages/*` or `integrations/*` using `pnpm run changeset:add`
📚 Learning: 2026-01-15T11:50:06.067Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-15T11:50:06.067Z
Learning: Applies to {packages,integrations}/**/* : Add a changeset when modifying any public package in `packages/*` or `integrations/*` using `pnpm run changeset:add`
Applied to files:
.changeset/fix-cli-deploy-yarn-workspaces.mdpackages/cli-v3/src/build/buildWorker.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Use build extensions in trigger.config.ts (additionalFiles, additionalPackages, aptGet, prismaExtension, etc.) to customize the build
Applied to files:
.changeset/fix-cli-deploy-yarn-workspaces.mdpackages/cli-v3/src/build/buildWorker.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `trigger.dev/sdk/v3` for all imports in Trigger.dev tasks
Applied to files:
.changeset/fix-cli-deploy-yarn-workspaces.md
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Applies to apps/webapp/**/*.{ts,tsx} : When importing from `trigger.dev/core` in the webapp, use subpath exports from the package.json instead of importing from the root path
Applied to files:
.changeset/fix-cli-deploy-yarn-workspaces.md
📚 Learning: 2026-01-15T11:50:06.067Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-15T11:50:06.067Z
Learning: Applies to **/*.{ts,tsx} : Always import tasks from `trigger.dev/sdk`, never use `trigger.dev/sdk/v3` or deprecated `client.defineJob` pattern
Applied to files:
.changeset/fix-cli-deploy-yarn-workspaces.md
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `schemaTask()` from `trigger.dev/sdk/v3` with Zod schema for payload validation
Applied to files:
.changeset/fix-cli-deploy-yarn-workspaces.md
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use the `task()` function from `trigger.dev/sdk/v3` to define tasks with id and run properties
Applied to files:
.changeset/fix-cli-deploy-yarn-workspaces.md
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Configure build process in trigger.config.ts using `build` object with external packages, extensions, and JSX settings
Applied to files:
.changeset/fix-cli-deploy-yarn-workspaces.mdpackages/cli-v3/src/build/buildWorker.ts
📚 Learning: 2025-11-27T16:26:44.496Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/executing-commands.mdc:0-0
Timestamp: 2025-11-27T16:26:44.496Z
Learning: For running tests, navigate into the package directory and run `pnpm run test --run` to enable single-file test execution (e.g., `pnpm run test ./src/engine/tests/ttl.test.ts --run`)
Applied to files:
packages/cli-v3/src/deploy/buildImage.test.ts
📚 Learning: 2026-01-15T11:50:06.067Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-15T11:50:06.067Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Use vitest exclusively for testing and never mock anything - use testcontainers instead
Applied to files:
packages/cli-v3/src/deploy/buildImage.test.ts
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to **/*.{test,spec}.{ts,tsx} : Use vitest for all tests in the Trigger.dev repository
Applied to files:
packages/cli-v3/src/deploy/buildImage.test.ts
📚 Learning: 2026-01-15T10:48:02.687Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-15T10:48:02.687Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Use vitest for running unit tests
Applied to files:
packages/cli-v3/src/deploy/buildImage.test.ts
📚 Learning: 2026-01-15T10:48:02.687Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-15T10:48:02.687Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Test files should live beside the files under test and use descriptive `describe` and `it` blocks
Applied to files:
packages/cli-v3/src/deploy/buildImage.test.ts
📚 Learning: 2026-01-15T11:50:06.067Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-15T11:50:06.067Z
Learning: Applies to **/*.test.{ts,tsx} : Use testcontainers helpers (`redisTest`, `postgresTest`, `containerTest`) from `internal/testcontainers` for Redis/PostgreSQL testing instead of mocks
Applied to files:
packages/cli-v3/src/deploy/buildImage.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use logger methods (debug, log, info, warn, error) from `trigger.dev/sdk/v3` for structured logging in tasks
Applied to files:
packages/cli-v3/src/deploy/buildImage.ts
📚 Learning: 2026-01-15T11:50:06.067Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-15T11:50:06.067Z
Learning: Run commands from root with `pnpm run` in this pnpm 10.23.0 monorepo using Turborepo
Applied to files:
packages/cli-v3/src/deploy/buildImage.ts
📚 Learning: 2026-01-15T10:48:02.687Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-15T10:48:02.687Z
Learning: Use pnpm as the package manager (version 10.23.0 or later) and Node.js 20.20.0
Applied to files:
packages/cli-v3/src/deploy/buildImage.ts
📚 Learning: 2025-11-27T16:26:44.496Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/executing-commands.mdc:0-0
Timestamp: 2025-11-27T16:26:44.496Z
Learning: Execute most monorepo commands using `pnpm run` from the root directory, with `--filter` flag for specific packages (e.g., `pnpm run dev --filter webapp`)
Applied to files:
packages/cli-v3/src/deploy/buildImage.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Configure Trigger.dev project in `trigger.config.ts` using `defineConfig()` with project ref and task directories
Applied to files:
packages/cli-v3/src/build/buildWorker.ts
🧬 Code graph analysis (2)
packages/cli-v3/src/deploy/buildImage.ts (1)
packages/cli-v3/e2e/utils.ts (1)
PackageManager(13-13)
packages/cli-v3/src/build/buildWorker.ts (1)
packages/cli-v3/e2e/utils.ts (1)
PackageManager(13-13)
🔇 Additional comments (7)
.changeset/fix-cli-deploy-yarn-workspaces.md (1)
1-5: LGTM!The changeset is correctly formatted, targets the appropriate package with a patch-level change, and provides a clear description of the fix referencing the issue.
packages/cli-v3/src/deploy/buildImage.ts (3)
2-2: LGTM!The
PackageManagertype import fromnypmand the new optional fields inGenerateContainerfileOptionsare well-designed for the feature's needs.Also applies to: 686-687
554-559: LGTM!The cache options formatting is reorganized but preserves the original behavior.
874-878: LGTM!The conditional lockfile copy logic is well-implemented with a helpful comment fallback for debugging when no lockfile is provided.
packages/cli-v3/src/build/buildWorker.ts (2)
3-3: LGTM!The new imports for
detectPackageManager,PackageManager, andcopyFileare appropriate for the package manager detection and lockfile handling features.Also applies to: 14-14
245-263: LGTM!The updated
writeContainerfilefunction signature correctly accepts and propagates the package manager and lockfile path to the container file generation.packages/cli-v3/src/deploy/buildImage.test.ts (1)
5-50: Good test coverage for the new functionality.The tests adequately cover the main scenarios: default npm behavior, yarn installation, pnpm installation with corepack, and lockfile copying. Consider adding tests for edge cases in a follow-up:
- npm with
package-lock.jsonlockfile- Verifying the comment appears when no lockfile is provided
- Bun runtime behavior (if applicable)
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| function getInstallCommand(packageManager?: PackageManager | null) { | ||
| switch (packageManager?.name) { | ||
| case "yarn": { | ||
| return "RUN yarn install"; | ||
| } | ||
| case "pnpm": { | ||
| return ` | ||
| RUN corepack enable | ||
| RUN pnpm install | ||
| `; | ||
| } | ||
| case "npm": | ||
| default: { | ||
| return "RUN npm i --no-audit --no-fund --no-save --no-package-lock"; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
npm ci yarn pnpm --frozen-lockfile reproducible builds best practices
💡 Result:
Goal: “fail the build if the lockfile would change”
Use the package manager’s CI / immutable install mode so dependency resolution is taken from the lockfile and the install aborts if the lockfile and manifests are out of sync.
npm (package-lock.json / npm-shrinkwrap.json)
- CI command:
npm ci - Key properties: requires an existing lockfile, errors if lockfile doesn’t match
package.json, removes existingnode_modules, and never writes package.json / lockfiles. [1]
Yarn
Yarn 1 (Classic)
- CI command:
yarn install --frozen-lockfile(fails ifyarn.lockwould need changes). [2]
Yarn 2+ (Berry / modern Yarn)
- CI command:
yarn install --immutable - Notes:
--immutabledefaults to true on CI, fails if the lockfile would be modified;--frozen-lockfileexists as an alias for backward compatibility (planned removal in a later release). [3] - For stricter reproducibility in “Zero-Installs” setups:
yarn install --immutable --immutable-cache(and optionally--check-cache). [3]
pnpm (pnpm-lock.yaml)
- CI command:
pnpm install --frozen-lockfile - Notes:
--frozen-lockfiledefaults to true on CI (when a lockfile is present) and fails if the lockfile is out of sync / would need updates. [4]
Reproducible-build best practices (works across npm/Yarn/pnpm)
- Commit exactly one lockfile (package-lock.json or yarn.lock or pnpm-lock.yaml) and don’t mix package managers in the same repo.
- Pin the package manager version (so the same lockfile semantics/resolver are used everywhere), and use the pinned version in CI.
- Pin Node.js (major/minor) for CI and releases; native addons and resolution edge-cases can vary by Node version.
- Keep install flags/config consistent between lockfile generation and CI (example: npm notes that flags like
--legacy-peer-depsused duringnpm installshould also be used fornpm ci, otherwise CI may fail). [1] - Treat lockfile updates as code changes: update via the package manager, review diffs, and avoid manual edits.
Quick “CI install” command cheat-sheet
# npm
npm ci
# Yarn 1
yarn install --frozen-lockfile
# Yarn 2+
yarn install --immutable
# pnpm
pnpm install --frozen-lockfileSources: npm ci docs [1]; Yarn classic --frozen-lockfile docs [2]; Yarn modern --immutable / CI behavior docs [3]; pnpm --frozen-lockfile / CI default docs [4].
🏁 Script executed:
# Search for issue `#2914` reference in the repo
rg "2914" --type ts --type md --type json
# Look for context in buildImage.ts around the install command generation
fd buildImage.ts -x cat -n {} | head -100Repository: triggerdotdev/trigger.dev
Length of output: 3348
🏁 Script executed:
# Check if there are any GitHub issue links or comments in the relevant files
rg "frozen-lockfile|npm ci|reproducible.*build" packages/cli-v3/src/deploy/ -A 2 -B 2Repository: triggerdotdev/trigger.dev
Length of output: 51
🏁 Script executed:
# Find and examine buildImage.ts more carefully
fd buildImage.ts -x wc -l {}Repository: triggerdotdev/trigger.dev
Length of output: 116
🏁 Script executed:
# Look at lines around 1171-1187 in buildImage.ts
fd buildImage.ts -x sed -n '1150,1200p' {}Repository: triggerdotdev/trigger.dev
Length of output: 892
🏁 Script executed:
# Search for any issue/PR references related to reproducible builds or frozen-lockfile
rg "issue|PR|frozen.*lock|reproducible" packages/cli-v3/src/deploy/buildImage.ts -B 2 -A 2Repository: triggerdotdev/trigger.dev
Length of output: 3565
🏁 Script executed:
# Check if there's a .yarn-version or .node-version or similar to understand which Yarn version is used
fd -e "versions" -e "npmrc" -e "yarnrc" -e "pnpmfile" packages/cli-v3/Repository: triggerdotdev/trigger.dev
Length of output: 438
🏁 Script executed:
# Check package.json for packageManager field to see which version is pinned
rg '"packageManager"' packages/cli-v3/package.jsonRepository: triggerdotdev/trigger.dev
Length of output: 51
🏁 Script executed:
# Check root package.json for packageManager field
cat package.json | grep -A 2 -B 2 "packageManager"Repository: triggerdotdev/trigger.dev
Length of output: 184
🏁 Script executed:
# Check what lockfiles exist in repo to determine package manager versions
git ls-files | rg -E "yarn\.lock|pnpm-lock\.yaml|package-lock\.json" | head -5Repository: triggerdotdev/trigger.dev
Length of output: 465
🏁 Script executed:
# Check for lockfiles to understand which package managers are used
git ls-files | grep -E "yarn\.lock|pnpm-lock\.yaml|package-lock\.json"Repository: triggerdotdev/trigger.dev
Length of output: 956
🏁 Script executed:
# Check if there's any yarn version specification
cat .yarnrc.yml 2>/dev/null || cat .yarnrc 2>/dev/null || echo "No yarn config found"Repository: triggerdotdev/trigger.dev
Length of output: 89
🏁 Script executed:
# Look at the context around lockfile copying in buildImage.ts to understand the full picture
sed -n '860,900p' packages/cli-v3/src/deploy/buildImage.tsRepository: triggerdotdev/trigger.dev
Length of output: 1012
Install commands don't ensure reproducible builds.
The implementation should use CI/immutable install modes to fail if lockfiles are out of sync: npm ci for npm, --frozen-lockfile for yarn and pnpm. The current npm i with --no-package-lock explicitly prevents reproducible builds, and the pnpm case creates multiple Docker layers unnecessarily.
🔧 Proposed fix
function getInstallCommand(packageManager?: PackageManager | null) {
switch (packageManager?.name) {
case "yarn": {
- return "RUN yarn install";
+ return "RUN yarn install --frozen-lockfile";
}
case "pnpm": {
- return `
- RUN corepack enable
- RUN pnpm install
- `;
+ return "RUN corepack enable && pnpm install --frozen-lockfile";
}
case "npm":
default: {
- return "RUN npm i --no-audit --no-fund --no-save --no-package-lock";
+ return "RUN npm ci";
}
}
}🤖 Prompt for AI Agents
In `@packages/cli-v3/src/deploy/buildImage.ts` around lines 1171 - 1187,
getInstallCommand currently prevents reproducible installs and creates extra
Docker layers; update it so npm uses "npm ci" (not "npm i"), yarn uses a
frozen/CI mode (e.g., "yarn install --frozen-lockfile"), and pnpm runs corepack
enable and install in a single RUN with pnpm's frozen-lockfile flag (e.g.,
"corepack enable && pnpm install --frozen-lockfile") to avoid multiple layers;
modify the switch in getInstallCommand (check packageManager?.name) to return
these CI/immutable install commands and remove the
"--no-package-lock/--no-audit" pattern that disables lockfile enforcement.
Summary
Fixes #2914
Problem
\ rigger deploy\ hardcoded
pm install ...\ in the generated Dockerfile, ignoring the project's package manager (Yarn, pnpm). This caused failures for Yarn Workspaces (due to
ohoist\ being ignored) and prevented reproducible builds using lockfiles.
Fix