Skip to content

feat(formats): auto-update lockfiles after version bump#617

Merged
BryanFRD merged 1 commit into
mainfrom
feat/auto-update-lockfiles
Jun 26, 2026
Merged

feat(formats): auto-update lockfiles after version bump#617
BryanFRD merged 1 commit into
mainfrom
feat/auto-update-lockfiles

Conversation

@BryanFRD

Copy link
Copy Markdown
Contributor

Closes #498.

What

Opt-in auto-refresh of the sibling lockfile after ferrflow release bumps a manifest, so downstream cargo build --locked / npm ci don't break on a stale lock. Default OFF — a repo that doesn't set updateLockfiles sees zero behaviour change.

Dispatch table

New module src/formats/lockfiles.rs models manifest → lockfile → updater as an enum + struct table (not stringly-typed):

Manifest Lockfile Command
Cargo.toml Cargo.lock cargo update -p <pkg> --offline
package.json package-lock.json npm install --package-lock-only
package.json pnpm-lock.yaml pnpm install --lockfile-only
package.json yarn.lock yarn install --mode=update-lockfile
pyproject.toml poetry.lock poetry lock --no-update
pyproject.toml uv.lock uv lock --offline
Gemfile Gemfile.lock bundle lock
mix.exs mix.lock mix deps.get

The lockfile is detected by walking up from the manifest's directory to the repo root (lexically contained — reuses join_within_repo), so a monorepo's single shared root Cargo.lock / pnpm-workspace lock is found from a nested member manifest. For Cargo the per-package cargo update -p <pkg> runs incrementally against the shared lock — no N redundant full updates; a shared lockfile is also deduped within a package so it's refreshed once.

Config (opt-in)

  • Workspace: updateLockfiles: bool (default false), snake_case field with alias = "updateLockfiles", matching the existing serde convention.
  • Per-package opt-out: package.updateLockfiles: Option<bool>Some(false) skips a single package even when the workspace default is on; None inherits. Resolver PackageConfig::effective_update_lockfiles mirrors effective_floating_tags / effective_skip_ci.

Integration point

src/monorepo/run/mod.rs::run_release_logic — after the versioned_files write_version loop succeeds and before the changelog/commit step, gated on effective_update_lockfiles. The refreshed lockfile's repo-relative path is pushed onto both files_to_commit and files_per_package so it lands in the same release commit. The dependency-cascade write path (run/cascade.rs) gets the same treatment via the shared refresh_lockfiles helper.

Robustness

  • Package manager not on PATH → tracing::warn! and skip (release continues).
  • Offline update can't resolve / non-zero exit → tracing::warn! with the first stderr line, never fatal.
  • All commands use offline / lockfile-only modes — no network.
  • New diagnostics use tracing::warn! / info! (the tracing foundation already on main), kept in the write-version/commit area to avoid colliding with the concurrent eprintln!tracing migration.

Tests

  • Real Cargo-workspace fixture: bumping one member runs cargo update -p <pkg> --offline and only that member's entry changes in Cargo.lock; the refreshed lock lands in the release commit.
  • updateLockfiles unset → Cargo.lock byte-identical, not staged (no package-manager invocation in effect).
  • Missing-package-manager path asserts the NotOnPath skip (gated on whether the tool is present, so it's a real assertion in both environments).
  • Config resolver unit tests (default off / inherit / per-package opt-out / camelCase alias parsing).
  • Module unit tests for manifest detection, sibling absent, walk-up to repo root, and no-escape past root.

Tested live against cargo (available in CI/dev). The npm/pnpm/yarn/poetry/uv/bundle/mix paths share the same dispatch + spawn code path and are covered by the unit tests and the gated "not on PATH" assertion; the full per-manager integration is not run here as those toolchains aren't guaranteed in the test env.

Cross-repo follow-ups (cannot land here)

  • schema/ferrflow.json is updated in this PR (source of truth). The byte-identical copy at FerrFlow-Cloud/packages/site/public/schema/ferrflow.json must be synced in a follow-up PR on that repo.
  • Docs: add updateLockfiles (workspace + per-package opt-out) to FerrFlow-Cloud/packages/site/.../config-file.md.
  • Per repo convention, a tracking issue on FerrLabs/FerrFlow-Cloud for the docs + schema-copy + playground work.

@BryanFRD BryanFRD enabled auto-merge (squash) June 26, 2026 14:39
@BryanFRD BryanFRD merged commit 8df3062 into main Jun 26, 2026
39 checks passed
@BryanFRD BryanFRD deleted the feat/auto-update-lockfiles branch June 26, 2026 14:42

@github-actions github-actions 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.

Benchmark

Details
Benchmark suite Current: 917f860 Previous: 0b5fe57 Ratio
config_loading/single 12195 ns/iter (± 122) 10516 ns/iter (± 92) 1.16
config_loading/mono_10 17279 ns/iter (± 150) 15635 ns/iter (± 739) 1.11
config_loading/mono_50 39591 ns/iter (± 366) 40629 ns/iter (± 432) 0.97
config_loading/mono_100 67106 ns/iter (± 2449)

This comment was automatically generated by workflow using github-action-benchmark.

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.

feat(formats): auto-update lockfiles after version bump

1 participant