Skip to content

docs: uv integration lock file ver upgrade #1281

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

Merged
merged 4 commits into from
Jun 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 24 additions & 19 deletions docs/configuration/configuration-guides/uv_integration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,21 @@ resolve this issue depending on your preference:

[tool.semantic_release]
build_command = """
uv lock --offline
git add uv.lock
uv build
uv lock --upgrade-package "$PACKAGE_NAME"
git add uv.lock
uv build
"""

The ``--offline`` flag is used to ensure that the lock file is updated without
updating any dependency versions. The intent of this call is **ONLY** to update
The intent of the lock upgrade-package call is **ONLY** to update
the version of your project within the lock file after PSR has updated the version
in your project's definition file (e.g., ``pyproject.toml``). When you are running
PSR, you have already tested the project as is and you don't want to actually
update the dependencies if a new one just became available.

For ease of use, PSR provides the ``$PACKAGE_NAME`` environment variable that
contains the name of your package from the project's definition file
(``pyproject.toml:project.name``).

If you are using the :ref:`PSR GitHub Action <gh_actions-psr>`, you will need to add an
installation command for ``uv`` to the :ref:`build_command <config-build_command>`
because the action runs in a Docker environment does not include ``uv`` by default.
Expand All @@ -71,21 +74,23 @@ resolve this issue depending on your preference:

[tool.semantic_release]
build_command = """
python -m pip install -e .[build]
uv lock --offline
git add uv.lock
uv build
python -m pip install -e '.[build]'
uv lock --upgrade-package "$PACKAGE_NAME"
git add uv.lock
uv build
"""

#. **Stamp the code first & then separately run release**: If you prefer to not modify the
build command, then you will need to run the ``uv lock --offline`` command prior to actually
creating the release. Essentially, you will run PSR twice: (1) once to update the version
in the project's definition file, and (2) a second time to generate the release.

The intent of the ``uv lock --offline`` command is **ONLY** to update the version of your
project within the lock file after PSR has updated the version in your project's definition
file (e.g., ``pyproject.toml``). When you are running PSR, you have already tested the project
as is and you don't want to actually update the dependencies if a new one just became available.
build command, then you will need to run the ``uv lock --upgrade-package <your-package-name>``
command prior to actually creating the release. Essentially, you will run PSR twice:
(1) once to update the version in the project's definition file, and (2) a second time
to generate the release.

The intent of the ``uv lock --upgrade-package <your-package-name>`` command is **ONLY**
to update the version of your project within the lock file after PSR has updated the
version in your project's definition file (e.g., ``pyproject.toml``). When you are
running PSR, you have already tested the project as is and you don't want to actually
update the dependencies if a new one just became available.

.. code-block:: bash

Expand All @@ -94,7 +99,7 @@ resolve this issue depending on your preference:
semantic-release -v version --skip-build --no-commit --no-tag --no-changelog

# 2. run UV lock as pyproject.toml is updated with the next version
uv lock --offline
uv lock --upgrade-package <your-package-name>

# 3. stage the lock file to ensure it is included in the PSR commit
git add uv.lock
Expand Down Expand Up @@ -129,7 +134,7 @@ look like this:

[tool.semantic_release]
build_command = """
uv lock --offline
uv lock --upgrade-package "$PACKAGE_NAME"
uv build
"""

Expand Down
1 change: 1 addition & 0 deletions docs/configuration/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ GITLAB_CI Pass-through ``true`` if exists in process env, unset
HOME Pass-through ``HOME`` of parent process
NEW_VERSION Semantically determined next version (ex. ``1.2.3``)
PATH Pass-through ``PATH`` of parent process
PACKAGE_NAME Project name as defined in ``pyproject.toml:project.name``
PSR_DOCKER_GITHUB_ACTION Pass-through ``true`` if exists in process env, unset otherwise
VIRTUAL_ENV Pass-through ``VIRTUAL_ENV`` if exists in process env, unset otherwise
======================== ======================================================================
Expand Down
1 change: 1 addition & 0 deletions src/semantic_release/cli/commands/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,7 @@ def version( # noqa: C901
**runtime.build_command_env,
# PSR injected environment variables
"NEW_VERSION": str(new_version),
"PACKAGE_NAME": runtime.project_metadata.get("name", ""),
},
noop=opts.noop,
)
Expand Down
7 changes: 7 additions & 0 deletions tests/e2e/cmd_version/test_version_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def test_version_runs_build_command(
check=True,
env={
"NEW_VERSION": next_release_version, # injected into environment
"PACKAGE_NAME": "", # PSR injected environment variable
"CI": patched_os_environment["CI"],
"BITBUCKET_CI": "true", # Converted
"GITHUB_ACTIONS": patched_os_environment["GITHUB_ACTIONS"],
Expand Down Expand Up @@ -168,6 +169,8 @@ def test_version_runs_build_command_windows(
)

# Setup
package_name = "my-package"
update_pyproject_toml("project.name", package_name)
built_wheel_file = get_wheel_file(next_release_version)
pyproject_config = FlatDict(
tomlkit.loads(example_pyproject_toml.read_text(encoding="utf-8")),
Expand Down Expand Up @@ -205,6 +208,7 @@ def test_version_runs_build_command_windows(
env={
**clean_os_environment,
"NEW_VERSION": next_release_version, # injected into environment
"PACKAGE_NAME": package_name, # PSR injected environment variable
"CI": patched_os_environment["CI"],
"BITBUCKET_CI": "true", # Converted
"GITHUB_ACTIONS": patched_os_environment["GITHUB_ACTIONS"],
Expand Down Expand Up @@ -276,6 +280,8 @@ def test_version_runs_build_command_w_user_env(
"=ignored-invalid-named-var", # TODO: validation error instead, but currently just ignore
],
)
package_name = "my-package"
update_pyproject_toml("project.name", package_name)

# Mock out subprocess.run
with mock.patch(
Expand Down Expand Up @@ -309,6 +315,7 @@ def test_version_runs_build_command_w_user_env(
env={
**clean_os_environment,
"NEW_VERSION": next_release_version, # injected into environment
"PACKAGE_NAME": package_name, # PSR injected environment variable
"CI": patched_os_environment["CI"],
"BITBUCKET_CI": "true", # Converted
"GITHUB_ACTIONS": patched_os_environment["GITHUB_ACTIONS"],
Expand Down
Loading