Skip to content

Releases: lmstudio-ai/venvstacks

0.8.0

20 Nov 20:14
c2e47ed

Choose a tag to compare

➡️  PyPI page: venvstacks 0.8.0.

Changed

  • As part of switching to cross-platform layer locks, the generated lock files are now checked to ensure relevant wheel entries are present for all target platforms nominally supported by the layer (resolved in 326).

0.8.0b2 - 2025-11-15

14 Nov 17:14
8aa8886

Choose a tag to compare

0.8.0b2 - 2025-11-15 Pre-release
Pre-release

➡️  PyPI page: venvstacks 0.8.0b2.

Added

  • Added linux_target <linux-target> to support per-layer configuration of Linux wheel selection based on the target libc variant and version (added in #338)
  • Running on CPython 3.14 is now tested in CI. Note that due to changes in the zlib standard library module implementation, Windows layer archives built using CPython 3.14 to run the build will typically be smaller than those produced by previous versions (added in #247).

Fixed

  • The Python implementation name is now set correctly when evaluating environment markers (resolved in #331).
  • Resolved a number of issues related to incorrect layer dependency filtering for different combinations of environment markers, layer target platforms, and package provenance details (initial problem reported in #333, additional issues found when updating the test suite to ensure the example stacks are producing the expected layer lock and package summary details).

0.8.0b1 - 2025-11-08

07 Nov 17:45
f205a67

Choose a tag to compare

0.8.0b1 - 2025-11-08 Pre-release
Pre-release

➡️  PyPI page: venvstacks 0.8.0b1.

Added

  • A venvstacks.uv.toml file located alongside the stack definition file is now incorporated into the configuration passed to uv when locking environments (added in #144). This configuration may alternatively be supplied via the [tool.uv] table in the stack definition file.
  • Each layer definition may now contain a priority_indexes section that is used to adjust the uv index configuration when locking that layer (added in #144).
  • Each layer definition may now contain a package_indexes section that is used to adjust the uv sources configuration when locking that layer, or any layer that depends on it (added in #270).
  • Each layer definition may now contain a index_overrides section that allows apparent inconsistencies in layer package index configurations to be marked as expected and acceptable (added in #269).
  • Added macosx_target to support per-layer configuration of MACOSX_DEPLOYMENT_TARGET (added in #292)
  • Setting MACOSX_DEPLOYMENT_TARGET in the calling environment now affects the way layers that do not specify macosx_target are built on macOS. If this environment variable is not specified at all, the default macOS version target is the default portable target set by uv rather than the version of the system running venvstacks (resolved in #292)
  • The target GNU libc version for Linux layer builds is now the default portable target set by uv rather than the libc version of the system running venvstacks (resolved in #292)
  • If UV_EXCLUDE_NEWER is set in the environment, or exclude-newer is set in the uv tool configuration, the given time is used as the recorded lock time for all updated layer locks (proposed in #10).
  • Layer environments now provide a targets_platform() query method that indicates whether that layer will be built and published for the current (or specified) platform (added in #265).

Changed

  • Layer dependency locking is now cross-platform, using the pylock.toml format rather than a flat list of dependencies (proposed in #254). While not part of the published release, an example script is available in the venvstacks source repository to remove or rename previously generated platform specific files (this is particularly necessary to preserve version numbering if using implicit layer versioning)
  • Locking operations are no longer filtered by platform. This means the BuildEnvironment.all_environments iterator now reports all defined layers with at least one target platform configured, not just those for the current platform. Iterate over BuildEnvironment.environments_to_build without any layer filtering configured to obtain a list of layers specific to the current platform (resolved in #265).
  • Layer target platforms are now inferred from the layers they depend on. An exception is raised if a layer specifies targets that are not also targets for the lower layers it depends on (changed in #244).
  • Hidden files and folders (those with names starting with .) created at the top level of layer build environments are no longer included in the corresponding deployed environments (whether exported locally or published as a deployable layer archive).
  • The handling of shadowed packages across framework layers has changed, so unconditionally shadowed packages are no longer treated as constraints by higher layers. Environment marker conditions are also listed for shared packages from lower layers in layer summaries (resolved in #292).
  • To improve type hints reported in IDEs and errors reported by static type checking, enums now use their singular form as their canonical name, with the plural form available as an alias (changed in #308).
  • All build environment manipulation is now handled with uv (part of resolving #144). Previously, requirements compilation was handled with uv, while actually adding and removing packages was handled with pip. Due to related differences in package installation metadata (e.g. INSTALLER containing uv rather than pip), layer archive hash values will change.

Fixed

  • Layer dependency declarations are now eagerly parsed and stored as structured requirements. Invalid requirements are now reported as specification errors rather than as cryptic locking command failures (resolved in #101).
  • Using pbs-installer 2025.8.27 or later ensures that the smaller CPython base runtime installations that omit debug symbols are consistently preferred (reported in #242). No explicit lower bound is set on the dependency declaration to allow venvstacks to be updated without causing conflicts with existing pbs-installer pins to older versions.
  • Omitting all arguments now reports a non-zero exit code (reported in #246).

0.7.0 - 2025-07-05

04 Jul 15:58
6ebf700

Choose a tag to compare

➡️  PyPI page: venvstacks 0.7.0.

Added

  • show subcommand to display layer definitions (added in #159).
  • --show option on subcommands (other than show) to display the selected layers and operations before executing the command (added in #159).
  • --show-only option on subcommands (other than show) to display the selected layers and operations without executing the command (added in #159).
  • --json option on subcommands to display the selected layers and operations as JSON rather than as a human-readable tree. For commands other than show, implies --show-only if --show is not passed explicitly (added in #159).

Changed

  • Recursive source tree processing now excludes files excluded from version control when building from a git repository, and excludes __pycache__ folders otherwise. This exclusion affects both module hash calculations and the inclusion of files in built environments (resolves #203).
  • RECORD files for installed packages are now largely retained in published artifacts and locally exported environments, with only the entries corresponding to omitted files removed (resolved in #28). This allows packages that inspect the metadata for installed packages at runtime to work correctly when deployed with venvstacks.
  • Default CLI console output has been substantially reduced, with new -q/--quiet and -v/--verbose options added to adjust the message volume (changed in #5).
  • Library level messages are now emitted via the logging module rather than being written directly to stdout. The CLI configures the logging subsystem appropriately based on the given verbosity options (changed in #5).

Fixed

  • When using the --include filtering option for layer builds, existing "build if needed" environments are now correctly updated if they have not previously been successfully built with the current layer specification and environment lock details (reported in #222).
  • Implicit versioning of runtime layers no longer breaks deployed layered environments using that layer (reported in #188).
  • Implicit versioning of framework layers no longer breaks loading dynamic libraries from those layers on non-Windows systems (reported in #189)
  • Layer locks are now marked as valid if the lock is successfully regenerated without changes after being marked as invalid due to a lower layer having an invalid lock (resolved in #227)

0.6.0 - 2025-06-07

06 Jun 16:59
1395d30

Choose a tag to compare

➡️  PyPI page: venvstacks 0.6.0.

Added

  • A new optional field, support_modules, has been added to application layer specifications. This field allows application layers to embed copies of common unpackaged support libraries without needing to duplicate that code in the source tree (proposed in #202).
  • The lock subcommand now accepts an --if-needed option that skips locking layers that already have a valid layer lock (added in #200).

Changed

  • Added a --lock-if-needed option to the build subcommand that ensures layers are only locked if they don't already have valid transitive environment locks. --lock is now a deprecated alias for this option rather than being equivalent to running the lock subcommand (proposed in #196).
  • Changes to lock inputs that only affect the implicit layer versioning are now tracked separately from changes to the additional inputs that affect the result of the transitive dependency lock generation step. These changes are now ignored for layers that do not use implicit layer versioning (proposed in #201).
  • Prefer the creation of hardlinks over full copies when locally exporting environments. Depending on the filesystem, this can make local exports significantly faster when the installed packages contain large files (proposed in #205).

Fixed

  • Launch module existence checks are now skipped for layers that will not be built for the target build platform (reported in #204).

0.5.1 — 2025-05-26

26 May 13:48
77d8d77

Choose a tag to compare

➡️  PyPI page: venvstacks 0.5.1.

Changed

  • Build failures for invalid layer locks now provide more details on the discrepancies that result in the lock being considered invalid (changed in #181).

Fixed

  • launch_module is now correctly set in the internal venvstacks_layer.json configuration file shipped as part of application layers (resolved in #174).
  • Layer locks are no longer incorrectly marked as invalid solely because the lock input cache files for the declared requirements are missing (reported in #175).
  • Layer lock metadata generated by versions prior to 0.5.0 is now accepted as valid as long as the locked requirements file hasn't changed (resolved in #187).
  • Resetting runtime and framework layer locks no longer prevents locking layers that depend on the affected layers (resolved in #187).
  • Repeated local builds for environments using the dynamic library loading wrapper scripts no longer corrupt the base Python environment link (reported in #184).

0.5.0 - 2025-05-12

12 May 02:53
590087e

Choose a tag to compare

➡️  PyPI page: venvstacks 0.5.0.

Changed

  • Layer locks are now invalidated for launch module changes. This also means that implicit versioning will update the layer version (resolves #89).
  • The exception raised when reporting dynamic library symlink conflicts in a layer now reports all ambiguous library targets in the layer instead of only reporting the first ambiguity encountered (resolved in #158).

Fixed

  • Previously defined layer locks are now correctly invalidated in the following cases (resolves #149):
    • the layer's declared input requirements have changed
    • the major Python version of the layer's base runtime has changed
    • the layer depends on a layer that does not currently have a valid layer lock
    • the relative paths from the layer to the layers it depends have changed (including additions and removals of layer dependencies)
    • implicit layer versioning is enabled or disabled for the layer
  • Attempting to lock a layered environment now fails if any layer it depends on does not have a currently valid layer lock (resolves #161).
  • CLI arguments on Windows are no longer unexpectedly resolved as filesystem glob patterns (resolved in #160).
  • Dynamic library symlinks are now correctly removed if the dynamic library is no longer included in the built layer (resolved in #163).
  • As it affects launch module execution, application layer launch module hashes now incorporate the file name in addition to the file contents (resolved in #164).
  • Application layer launch packages are now consistently archived using the layer's lock timestamp, even when that is more recent than the file's local modification time (resolved in #148).

0.4.1 - 2025-04-25

24 Apr 14:55
82369cd

Choose a tag to compare

➡️  PyPI page: venvstacks 0.4.1.

Added

  • Locking layers now emits package summary files for each layer, which should make it easier to see what has changed when locks are updated (suggested in #108).

Changed

  • The exception raised when reporting dynamic library symlink conflicts in a layer now suggests using the dynlib_exclude setting to resolve the conflict (changed in #141).

Fixed

  • The --reset-lock option now propagates to derived layers as intended (reported in #137).

0.4.0 - 2025-04-11

10 Apr 19:21
ce9ecd3

Choose a tag to compare

➡️  PyPI page: venvstacks 0.4.0.

Added

  • Framework layers may now specify frameworks to depend on one or more framework layers instead of depending directly on a runtime layer. Framework dependencies must form a directed acyclic graph (DAG), and framework layers must be defined after any framework layers they depend on (proposed in #18, implemented in #119).
  • Application layers may now specify runtime to depend directly on a a runtime layer with no intervening framework layers (added as part of resolving #18).
  • All layers may now specify dynlib_exclude to indicate dynamic libraries which should not be symbolically linked into the share/venv/dynlib/ environment subfolder on Linux and macOS (added as part of resolving #38).

Changed

  • To enable loading of shared objects from other environment layers, framework and application environments on Linux and macOS now run Python via a suitably capable shell environment (bash on Linux, zsh on macOS) that can be expected to be consistently installed (changed in #38).

Fixed

  • Extension modules on Linux and macOS that rely on shared objects published by their dependencies (for example, PyTorch depending on CUDA libraries) now work correctly even if those dependencies are installed in a lower environment layer. See dynamic-linking for additional details (resolved in #38).

0.3.0 - 2025-03-28

28 Mar 03:19
1f79ea9

Choose a tag to compare

Added

  • The build and lock subcommands accept a new --reset-lock
    CLI option. This multi-use option requests that any previously
    created layer lock file be removed before locking the selected
    layers (thus ignoring any previous version pins or artifact
    hashes). This option uses the same wildcard pattern matching as
    the --include option. Only layers that are locked by the given
    command will have their previous lock files removed, as excluded
    layers will be excluded from both locking and having their lock
    files reset (added in #22).
  • "win_arm64" and "linux_aarch64" are now accepted as target platforms.
    ARM64/Aarch64 refer to the same CPU architecture, but Python reports it differently
    depending on the OS, and this is reflected in their respective platform tags
    (added in #107).

Changed

  • A Python API instability FutureWarning is now emitted at runtime (added while resolving #22).
  • The previous :func:!BuildEnvironment.get_unmatched_patterns method has been replaced
    by the new :func:BuildEnvironment.filter_layers method, which returns both the
    matching layer names and the unmatched patterns (changed in #22).
  • :func:BuildEnvironment.select_layers now accepts an iterable of environment names
    rather than an iterable of filter patterns to be matched (changed in #22).

Fixed

  • --only-binary ":all:" is now passed when locking the layers in addition
    to being passed when creating the layer environments. This avoids emitting
    requirements that can't be installed (resolved in #102).
  • Remove directories from /bin when building layers (resolved in #103)