Skip to content

feat(install): add --restore flag to rebuild the lockfile from component graphs#10325

Open
zkochan wants to merge 4 commits intoteambit:masterfrom
zkochan:install-restore-flag
Open

feat(install): add --restore flag to rebuild the lockfile from component graphs#10325
zkochan wants to merge 4 commits intoteambit:masterfrom
zkochan:install-restore-flag

Conversation

@zkochan
Copy link
Copy Markdown
Member

@zkochan zkochan commented Apr 22, 2026

Summary

bit install does not normally use the per-component dependency graphs stored on each Version object. If a user deletes pnpm-lock.yaml and runs bit install, pnpm re-resolves every dep from manifest specifiers and drifts to whatever the registry now considers latest — losing the tag-time version pins the graph feature is supposed to guarantee.

--restore opts into the same code path bit import uses: fetch the dep graph for every component in the bitmap, merge them, and hand the merged graph to the package manager, which seeds pnpm-lock.yaml from it. If no workspace component has a stored graph, we fall back to a regular install with a warning.

--restore is an explicit user opt-in, so it bypasses the DEPS_GRAPH feature toggle. The flag's purpose is to gate the providers that fetch and attach graphs (tag-time generation; import-time auto-restore). Once a graph is explicitly supplied to the package manager, there's no reason to also gate the consumer.

Changes

scopes/workspace/install/install.cmd.tsx

New --restore flag, threaded through to WorkspaceInstallOptions.restoreFromDependenciesGraph.

scopes/workspace/install/install.main.runtime.ts

  • WorkspaceInstallOptions gets restoreFromDependenciesGraph.
  • New resolveDependenciesGraph helper centralizes the choice between an explicit options.dependenciesGraph, the restore path (workspace.scope.getDependenciesGraphByComponentIds(workspace.listIds(), { ignoreFeatureToggle: true })), and no graph. Extracted as a method because inlining pushed _installModules over the complexity limit.

scopes/scope/scope/scope.main.runtime.ts and components/legacy/scope/scope.ts

getDependenciesGraphByComponentIds takes an optional { ignoreFeatureToggle } flag that skips the DEPS_GRAPH short-circuit. Used only from the --restore path today.

scopes/dependencies/pnpm/pnpm.package-manager.ts

Removed the isFeatureEnabled(DEPS_GRAPH) check from the graph-to-lockfile branch. If installOptions.dependenciesGraph is set, the caller already decided to seed from it.

e2e/harmony/deps-graph.e2e.ts

Two e2e scenarios:

  1. --restore with the feature flag on: delete lockfile + node_modules after an import, bump the registry, run bit install --restore, and assert both components stay locked to their graph versions.
  2. --restore with the feature flag off: tag with the flag on so the graphs are stored, then reset features before import + --restore, and assert the lockfile is still restored from the stored graph.

Test plan

  • npm run lint clean.
  • Both new e2e scenarios pass locally against bd (dev-linked bit).
  • CI green.

…ent graphs

bit install does not normally use the per-component dependency graphs stored on
each Version object. If a user deletes pnpm-lock.yaml and runs bit install, pnpm
re-resolves every dep from the manifest specifiers and drifts to whatever the
registry now considers latest — losing the tag-time version pins that the graph
feature is supposed to guarantee.

--restore opts into the same code path bit import uses: fetch the dep graph for
every component in the bitmap, merge them, and hand the merged graph to the
package manager, which then seeds pnpm-lock.yaml from it. If no workspace
component has a stored graph, we fall back to a regular install with a warning.

Adds e2e coverage that deletes the lockfile + node_modules, bumps the registry
so fresh resolve would drift, runs bit install --restore, and asserts the
components stay locked to their graph versions.
@zkochan zkochan force-pushed the install-restore-flag branch from 05f062c to 0a03288 Compare April 23, 2026 12:44
@zkochan zkochan marked this pull request as ready for review April 23, 2026 16:24
Copilot AI review requested due to automatic review settings April 23, 2026 16:24
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new bit install --restore mode intended to rebuild pnpm-lock.yaml from the dependency graphs stored on component Versions, preventing lockfile drift when the lockfile is deleted and dependencies would otherwise be re-resolved from manifest ranges.

Changes:

  • Added --restore CLI flag and threaded it into workspace install options (restoreFromDependenciesGraph).
  • Implemented resolveDependenciesGraph() to pick between an explicitly provided graph, a restored merged graph from workspace components, or no graph (with a warning).
  • Added an e2e scenario verifying bit install --restore keeps versions pinned to the stored graphs after the registry “latest” dist-tag is bumped.

Reviewed changes

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

File Description
scopes/workspace/install/install.cmd.tsx Exposes --restore and passes it into WorkspaceInstallOptions.restoreFromDependenciesGraph.
scopes/workspace/install/install.main.runtime.ts Adds restore option + graph-resolution helper and wires the resolved graph into package-manager install options.
e2e/harmony/deps-graph.e2e.ts Adds e2e coverage validating lockfile reconstruction from stored dependency graphs via bit install --restore.

Comment thread scopes/workspace/install/install.main.runtime.ts Outdated
Comment thread scopes/workspace/install/install.main.runtime.ts
zkochan added 2 commits April 23, 2026 18:50
…oggle

The flag's purpose is to gate the *providers* that fetch and attach dep graphs:
tag-time generation on version-maker, and import-time fetching in the component
writer. Once a graph is explicitly supplied to the package manager, there's no
reason to also gate the *consumer*. --restore is an explicit user opt-in, so we
shouldn't silently ignore it because the workspace didn't flip BIT_FEATURES.

- Scope.getDependenciesGraphByComponentIds (both the main-runtime wrapper and
  the legacy implementation) take an { ignoreFeatureToggle } option that skips
  the isFeatureEnabled(DEPS_GRAPH) short-circuit.
- resolveDependenciesGraph passes it when options.restoreFromDependenciesGraph
  is true.
- PnpmPackageManager.install drops the isFeatureEnabled(DEPS_GRAPH) check from
  its graph-to-lockfile branch. The caller already decided to seed from a graph
  by supplying it; the flag no longer needs to second-guess that.

Adds an e2e case that tags with the flag on, then resets features before import
and --restore, and asserts the lockfile is still restored from the stored graph
despite the consumer running with the flag off.
Copilot review caught that PnpmPackageManager.install only seeds the lockfile
from a supplied graph when rootComponents (or rootComponentsForCapsules) is
true. Without that, --restore would silently no-op and re-resolve from manifest
specifiers. Surface the incompatibility up front: log a yellow warning from
resolveDependenciesGraph and return undefined, so the command behaves as if
--restore wasn't passed instead of pretending it worked.

hasRootComponents is computed in _installModules; threaded in as context so the
resolver doesn't have to re-read it.
Copilot AI review requested due to automatic review settings April 23, 2026 16:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

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.

2 participants