Skip to content

feat: add frozen-lockfile and ci install modes - #23

Open
sebdanielsson wants to merge 3 commits into
pnpm:mainfrom
sebdanielsson:claude/pnpm-install-options-82heax
Open

feat: add frozen-lockfile and ci install modes#23
sebdanielsson wants to merge 3 commits into
pnpm:mainfrom
sebdanielsson:claude/pnpm-install-options-82heax

Conversation

@sebdanielsson

@sebdanielsson sebdanielsson commented Aug 8, 2026

Copy link
Copy Markdown

The install input now selects which install runs: true/install (pnpm install, unchanged default), frozen-lockfile (pnpm install --frozen-lockfile), ci (pnpm ci), or false to skip.

Closes #8
Closes #10

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Added standard, frozen-lockfile, clean CI, or skipped dependency installation modes.
    • Added validation for unsupported and empty installation values.
    • Preserves configured runtime settings during installation.
  • Documentation
    • Updated guidance with supported modes, lockfile requirements, clean-install behavior, and examples.
  • Tests
    • Added coverage for installation success, lockfile changes, stale dependencies, runtime retention, and invalid inputs.

The `install` input now selects which install runs: `true`/`install`
(`pnpm install`, unchanged default), `frozen-lockfile`
(`pnpm install --frozen-lockfile`), `ci` (`pnpm ci`), or `false` to skip.

Closes pnpm#8

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FQ4xoewnc8tAGuQ8cyawRC
Copilot AI lite review requested due to automatic review settings August 8, 2026 10:04
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The action now supports true, require-lockfile, ci, and false. It validates the input, selects the corresponding pnpm command, preserves runtime handling, and adds workflow coverage for valid and invalid modes.

Changes

Install mode support

Layer / File(s) Summary
Install mode contract
src/inputs/index.ts, action.yml, README.md
The install input now supports typed modes, boolean compatibility, case-insensitive parsing, and validation for empty or unsupported values. Documentation describes lockfile behavior, CI cleanup, runtime handling, and cache scope.
Command selection and execution
src/index.ts, src/pnpm-install/index.ts
Installation runs after cache restoration. The action selects standard, require-lockfile, CI, or skipped installation and appends --no-runtime when required.
Integration coverage
.github/workflows/test.yaml
Workflow jobs verify require-lockfile behavior, CI cleanup, runtime selection, and invalid or empty inputs.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Action
  participant Cache
  participant InstallLogic
  participant pnpm
  Action->>Cache: restore dependency cache
  Cache-->>Action: cache restored
  Action->>InstallLogic: pass parsed install mode
  InstallLogic->>pnpm: run selected install command
  pnpm-->>InstallLogic: return status
  InstallLogic-->>Action: report result
Loading

Possibly related PRs

  • pnpm/setup#1: Extends the same install input and installation implementation.
  • pnpm/setup#2: Overlaps in install argument construction and runtime handling.
  • pnpm/setup#3: Revisits configurable automatic installation behavior.

Suggested reviewers: zkochan

Poem

A rabbit checks the lockfile tight,
Then cleans stale modules from sight.
Each install mode follows its way,
While runtimes hold their chosen stay.
The action hops through tests today.

🚥 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 describes the added CI and frozen-lockfile installation capabilities, which are central to the pull request.
Linked Issues check ✅ Passed The changes add automatic pnpm ci support and frozen-lockfile installation through the require-lockfile mode, satisfying issues #8 and #10.
Out of Scope Changes check ✅ Passed The implementation, documentation, and workflow tests are directly related to the requested install modes and failure behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch claude/pnpm-install-options-82heax
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds support for multiple install modes in the action so workflows can choose between a normal install, a frozen-lockfile install, a CI-style clean install, or skipping installs entirely.

Changes:

  • Extend the install input to accept true/install, frozen-lockfile, ci, or false.
  • Update install execution to run the selected pnpm command (pnpm install, pnpm install --frozen-lockfile, or pnpm ci) and improve related messaging.
  • Document the new modes and add workflow coverage for the new install behaviors and validation.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/pnpm-install/index.ts Builds the pnpm install command based on the selected install mode and executes it.
src/inputs/index.ts Parses and validates the expanded install input values (`InstallMode
src/index.ts Always calls the install step; install skipping is now handled inside pnpmInstall.
README.md Documents the new install modes with examples and caveats.
action.yml Updates the install input documentation/contract to match the new modes.
.github/workflows/test.yaml Adds CI coverage to verify frozen-lockfile, ci, and invalid/empty install behaviors.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/pnpm-install/index.ts Outdated
Comment thread src/pnpm-install/index.ts Outdated
Review feedback on pnpm#23:

- `command` was built before `--no-runtime` was appended, so a failing
  install reported `pnpm ci` while the log showed `pnpm ci --no-runtime`.
  Build it from the final args so every message matches.
- `if (status)` treated a signal-terminated install as success, since
  spawnSync reports `status: null` with no `error` in that case. Fail on
  `signal`, and use `status !== 0`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FQ4xoewnc8tAGuQ8cyawRC
Comment thread action.yml Outdated
runtime isn't shadowed by a different version declared in
`devEngines.runtime`.
- `true` (the default) or `install`: `pnpm install`
- `frozen-lockfile`: `pnpm install --frozen-lockfile` — fails instead of

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Isn't frozen-lockfile the default, so this is unnecessary?

Per the docs:

This setting is true by default in CI environments.

@sebdanielsson sebdanielsson Aug 10, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

On pnpm 12 the lockfile is created (if missing) and silently updated (if outdated). On pnpm 11 the lockfile is properly failing when the lockfile is outdated but still created if missing. Tested with pnpm 11.21.0, pnpm 12.0.0-rc.3 with CI=true and GITHUB_ACTIONS=true.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

pnpm v12 should have the same behaviour as v11 (v12 has no intentional breaking changes), so that sounds like a bug that should be reported there.

The problem for me is that having a frozen-lockfile setting here implies that the default is not frozen lockfile, which isn't the case; the default is "frozen lockfile if lockfile exists". Perhaps the setting should be require-lockfile or something to make it clearer 🤷‍♂️

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yeah, good idea. I'll change the name of the flag. I’m not a fan of how frozen-lockfile seems to differ when invoked via CI: true vs explicitly using the flag..

Raised an issue here: pnpm/pnpm#13760

…ile`

Review feedback on pnpm#23. The value now describes what it guarantees — the
install must be fully described by pnpm-lock.yaml — rather than naming the
pnpm flag it happens to pass. The flag itself is unchanged.

Docs now spell out that this is not the same as pnpm's own CI default: pnpm 11
only blocks updates to an existing lockfile, and pnpm 12 does not apply the CI
default at all as of 12.0.0-rc.3.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FQ4xoewnc8tAGuQ8cyawRC

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
.github/workflows/test.yaml (2)

667-679: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Cover the renamed install mode explicitly.

The test rejects install: frozen, but the previous public spelling was frozen-lockfile. If the rename intentionally removes the old spelling, add install: frozen-lockfile as another invalid case. The current test does not verify that contract change.

Suggested coverage
+      - id: renamed
+        continue-on-error: true
+        uses: ./
+        with:
+          version: '12.0.0-beta.4'
+          install: frozen-lockfile
+
       - id: control
...
           OUTCOME: ${{ steps.invalid.outcome }}
+          RENAMED: ${{ steps.renamed.outcome }}
           EMPTY: ${{ steps.empty.outcome }}
           CONTROL: ${{ steps.control.outcome }}
...
+          if [ "${RENAMED}" != "failure" ]; then
+            echo "Expected the old frozen-lockfile mode to be rejected"; exit 1
+          fi

Also applies to: 689-704

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test.yaml around lines 667 - 679, Add a separate invalid
workflow test alongside the existing invalid and empty cases, using install:
frozen-lockfile with the same version and continue-on-error settings, to
explicitly verify the old spelling is rejected after the rename.

524-543: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Verify that the successful require-lockfile run preserves the lockfile.

Line 548 creates the checksum after the successful action run at Lines 533-536. If that run modifies pnpm-lock.yaml, the test records the modified file as the baseline and still passes. Create the checksum before the action and verify it after the install.

Suggested assertion
       - run: pnpm install --lockfile-only
         shell: bash
+      - name: Save matching lockfile checksum
+        run: sha256sum pnpm-lock.yaml > matching-lockfile.sha256
+        shell: bash

       - uses: ./
         with:
           version: '12.0.0-beta.4'
           install: require-lockfile

       - name: 'Test: dependencies installed from the lockfile'
         run: |
           set -e
           if [ ! -d node_modules/is-odd ]; then
             echo "Expected install: require-lockfile to populate node_modules/is-odd"; exit 1
           fi
         shell: bash
+      - name: 'Test: matching lockfile was not changed'
+        run: sha256sum --check --status matching-lockfile.sha256
+        shell: bash
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test.yaml around lines 524 - 543, Update the workflow test
around the successful require-lockfile action invocation to checksum
pnpm-lock.yaml before the action runs, then verify the checksum afterward. Keep
the existing node_modules/is-odd installation assertion, but ensure any lockfile
modification by the action causes the test to fail.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/test.yaml:
- Around line 667-679: Add a separate invalid workflow test alongside the
existing invalid and empty cases, using install: frozen-lockfile with the same
version and continue-on-error settings, to explicitly verify the old spelling is
rejected after the rename.
- Around line 524-543: Update the workflow test around the successful
require-lockfile action invocation to checksum pnpm-lock.yaml before the action
runs, then verify the checksum afterward. Keep the existing node_modules/is-odd
installation assertion, but ensure any lockfile modification by the action
causes the test to fail.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 79d059c7-610f-420b-ae03-b15267647b0a

📥 Commits

Reviewing files that changed from the base of the PR and between fc2e94d and 8720124.

⛔ Files ignored due to path filters (1)
  • dist/index.js is excluded by !**/dist/**
📒 Files selected for processing (5)
  • .github/workflows/test.yaml
  • README.md
  • action.yml
  • src/inputs/index.ts
  • src/pnpm-install/index.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • action.yml
  • README.md
  • src/pnpm-install/index.ts
📜 Review details
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-05-11T16:19:49.450Z
Learnt from: zkochan
Repo: pnpm/setup PR: 1
File: src/cache-restore/run.ts:35-35
Timestamp: 2026-05-11T16:19:49.450Z
Learning: When using `actions/exec` (`getExecOutput` / `exec`), it is valid for the `commandLine` option to include both the command and its arguments in a single string (e.g., `getExecOutput('pnpm store path --silent')`). The library tokenizes `commandLine` internally (via `argStringToArray()`), so this behaves like passing an equivalent command + args array (e.g., `getExecOutput('pnpm', ['store','path','--silent'])`). In code reviews, do not flag this as incorrect—this matches documented behavior and a production-tested pattern.

Applied to files:

  • src/inputs/index.ts
🔇 Additional comments (2)
src/inputs/index.ts (1)

14-16: LGTM!

.github/workflows/test.yaml (1)

582-655: 🗄️ Data Integrity & Integration

No change needed. The install: ci test invokes pnpm ci --no-runtime, and that command is accepted by the pinned pnpm major track used here.

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.

Support installing frozen lock files Option for using pnpm ci automatically

4 participants