Skip to content
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
87 changes: 87 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,93 @@
CHANGELOG
=========

.. _changelog-v10.5.0:

v10.5.0 (2025-11-09)
====================

✨ Features
-----------

* **cmd-version**: Add automatic repository un-shallowing to version workflow (`PR#1366`_,
`90a1ffa`_)

* **cmd-version**: Add functionality to create & update partial version tags (`PR#1115`_,
`a28f940`_)

* **cmd-version**: Adds c-macro style version definition support to ``version_variables``, closes
`#1348`_ (`PR#1349`_, `4ce1fca`_)

* **cmd-version**: Adds upstream check into workflow to prevent commit push collisions (`PR#1360`_,
`d77193e`_)

🪲 Bug Fixes
------------

* **cmd-version**: Prevent regular expression errors on ``tag_format`` (`PR#1367`_, `e7d7aa7`_)

📖 Documentation
----------------

* **commands**: Add description of automated upstream version checking upon version creation
(`PR#1360`_, `d77193e`_)

* **configuration**: Add description for ``add_partial_tags`` setting & usage examples (`PR#1115`_,
`a28f940`_)

* **configuration**: Fix ``tag_format`` definition (`PR#1367`_, `e7d7aa7`_)

* **configuration**: Update ``version_variables`` examples with a c-macro style replacement
(`PR#1349`_, `4ce1fca`_)

* **github-actions**: Adds release job outputs definition to example (`PR#1344`_, `0fb4875`_)

* **github-actions**: Removed verify upstream status step from example workflow (`PR#1360`_,
`d77193e`_)

* **github-actions**: Update example to remove need to specify repo checkout's fetch depth
(`PR#1366`_, `90a1ffa`_)

* **uv-integration**: Remove verify upstream check from uv integration example (`PR#1360`_,
`d77193e`_)

* **uv-integration**: Update example to remove need to specify repo checkout's fetch depth
(`PR#1366`_, `90a1ffa`_)

⚙️ Build System
----------------

* **deps**: Bump ``tomlkit`` dependency from ~=0.11.0 to ~=0.13.0 (`PR#1355`_, `55c94ec`_)

* **deps**: Change github-actions container image to ``python:3.14-slim-trixie`` (`PR#1346`_,
`1a23712`_)

💡 Additional Release Information
---------------------------------

* **cmd-version**: If you were previously handling the unshallowing of a repository clone in your
CI/CD pipelines, you may now remove that step from your workflow. PSR will now detect a shallow
repository and unshallow it before evaluating the commit history.

.. _#1348: https://github.com/python-semantic-release/python-semantic-release/issues/1348
.. _0fb4875: https://github.com/python-semantic-release/python-semantic-release/commit/0fb4875fa24ed283ed2d97ff6ab1879669a787ca
.. _1a23712: https://github.com/python-semantic-release/python-semantic-release/commit/1a237125badcb597ae7a92db4e01c2ff3293bce8
.. _4ce1fca: https://github.com/python-semantic-release/python-semantic-release/commit/4ce1fcac60ac73657a4aaaaa3cb7c4afc7eac2c1
.. _55c94ec: https://github.com/python-semantic-release/python-semantic-release/commit/55c94ecde1aec47b88aa172d031ab33afa7f795d
.. _90a1ffa: https://github.com/python-semantic-release/python-semantic-release/commit/90a1ffa55c5a1605c59cb26a1797f9a37fdfa784
.. _a28f940: https://github.com/python-semantic-release/python-semantic-release/commit/a28f9401c4b285aa1007b72eb051d42567f33f93
.. _d77193e: https://github.com/python-semantic-release/python-semantic-release/commit/d77193e30807968ba6a26bd356a868db62dc1098
.. _e7d7aa7: https://github.com/python-semantic-release/python-semantic-release/commit/e7d7aa74a216cd2fdd78afc1e0e8b6b8044954ec
.. _PR#1115: https://github.com/python-semantic-release/python-semantic-release/pull/1115
.. _PR#1344: https://github.com/python-semantic-release/python-semantic-release/pull/1344
.. _PR#1346: https://github.com/python-semantic-release/python-semantic-release/pull/1346
.. _PR#1349: https://github.com/python-semantic-release/python-semantic-release/pull/1349
.. _PR#1355: https://github.com/python-semantic-release/python-semantic-release/pull/1355
.. _PR#1360: https://github.com/python-semantic-release/python-semantic-release/pull/1360
.. _PR#1366: https://github.com/python-semantic-release/python-semantic-release/pull/1366
.. _PR#1367: https://github.com/python-semantic-release/python-semantic-release/pull/1367


.. _changelog-v10.4.1:

v10.4.1 (2025-09-13)
Expand Down
18 changes: 9 additions & 9 deletions docs/configuration/automatic-releases/github-actions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -893,14 +893,14 @@ to the GitHub Release Assets as well.
- name: Action | Semantic Version Release
id: release
# Adjust tag with desired version if applicable.
uses: python-semantic-release/python-semantic-release@v10.4.1
uses: python-semantic-release/python-semantic-release@v10.5.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
git_committer_name: "github-actions"
git_committer_email: "actions@users.noreply.github.com"

- name: Publish | Upload to GitHub Release Assets
uses: python-semantic-release/publish-action@v10.4.1
uses: python-semantic-release/publish-action@v10.5.0
if: steps.release.outputs.released == 'true'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
Expand Down Expand Up @@ -969,15 +969,15 @@ to the GitHub Release Assets as well.
the ``token`` input) in order to gain push access.

.. note::
As of $NEW_RELEASE_TAG, Python Semantic Release automatically detects and converts
As of v10.5.0, Python Semantic Release automatically detects and converts
shallow clones to full clones when needed. While you can still use ``fetch-depth: 0``
with ``actions/checkout@v4`` to fetch the full history upfront, it is no longer
required. If you use the default shallow clone, Python Semantic Release will
automatically fetch the full history before evaluating commits. If you are using
an older version of PSR, you will need to unshallow the repository prior to use.

.. note::
As of $NEW_RELEASE_TAG, the verify upstream step is no longer required as it has been
As of v10.5.0, the verify upstream step is no longer required as it has been
integrated into PSR directly. If you are using an older version of PSR, you will need
to review the older documentation for that step. See Issue `#1201`_ for more details.

Expand Down Expand Up @@ -1005,7 +1005,7 @@ The equivalent GitHub Action configuration would be:

- name: Action | Semantic Version Release
# Adjust tag with desired version if applicable.
uses: python-semantic-release/python-semantic-release@v10.4.1
uses: python-semantic-release/python-semantic-release@v10.5.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
force: patch
Expand Down Expand Up @@ -1064,14 +1064,14 @@ Publish Action.

- name: Release submodule 1
id: release-submod-1
uses: python-semantic-release/python-semantic-release@v10.4.1
uses: python-semantic-release/python-semantic-release@v10.5.0
with:
directory: ${{ env.SUBMODULE_1_DIR }}
github_token: ${{ secrets.GITHUB_TOKEN }}

- name: Release submodule 2
id: release-submod-2
uses: python-semantic-release/python-semantic-release@v10.4.1
uses: python-semantic-release/python-semantic-release@v10.5.0
with:
directory: ${{ env.SUBMODULE_2_DIR }}
github_token: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -1083,15 +1083,15 @@ Publish Action.
# ------------------------------------------------------------------- #

- name: Publish | Upload package 1 to GitHub Release Assets
uses: python-semantic-release/publish-action@v10.4.1
uses: python-semantic-release/publish-action@v10.5.0
if: steps.release-submod-1.outputs.released == 'true'
with:
directory: ${{ env.SUBMODULE_1_DIR }}
github_token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ steps.release-submod-1.outputs.tag }}

- name: Publish | Upload package 2 to GitHub Release Assets
uses: python-semantic-release/publish-action@v10.4.1
uses: python-semantic-release/publish-action@v10.5.0
if: steps.release-submod-2.outputs.released == 'true'
with:
directory: ${{ env.SUBMODULE_2_DIR }}
Expand Down
68 changes: 56 additions & 12 deletions docs/configuration/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,52 @@ from the :ref:`remote.name <config-remote-name>` location of your git repository

----

.. _config-add_partial_tags:

``add_partial_tags``
""""""""""""""""""""

**Type:** ``bool``

Specify if partial version tags should be handled when creating a new version. If set to
``true``, a ``major`` and a ``major.minor`` tag will be created or updated, using the format
specified in :ref:`tag_format`. If version has build metadata, a ``major.minor.patch`` tag
will also be created or updated.

Partial version tags are **disabled** for pre-release versions.

**Example**

.. code-block:: toml

[semantic_release]
tag_format = "v{version}"
add_partial_tags = true

This configuration with the next version of ``1.2.3`` will result in:

.. code-block:: bash

git log --decorate --oneline --graph --all
# * 4d4cb0a (tag: v1.2.3, tag: v1.2, tag: v1, origin/main, main) 1.2.3
# * 3a2b1c0 fix: some bug
# * 2b1c0a9 (tag: v1.2.2) 1.2.2
# ...

If build-metadata is used, the next version of ``1.2.3+20251109`` will result in:

.. code-block:: bash

git log --decorate --oneline --graph --all
# * 4d4cb0a (tag: v1.2.3+20251109, tag: v1.2.3, tag: v1.2, tag: v1, origin/main, main) 1.2.3+20251109
# * 3a2b1c0 chore: add partial tags to PSR configuration
# * 2b1c0a9 (tag: v1.2.3+20251031) 1.2.3+20251031
# ...

**Default:** ``false``

----

.. _config-tag_format:

``tag_format``
Expand All @@ -1170,17 +1216,8 @@ from the :ref:`remote.name <config-remote-name>` location of your git repository
**Type:** ``str``

Specify the format to be used for the Git tag that will be added to the repo during
a release invoked via :ref:`cmd-version`. The format string is a regular expression,
which also must include the format keys below, otherwise an exception will be thrown.
It *may* include any of the optional format keys, in which case the contents
described will be formatted into the specified location in the Git tag that is created.

For example, ``"(dev|stg|prod)-v{version}"`` is a valid ``tag_format`` matching tags such
as:

- ``dev-v1.2.3``
- ``stg-v0.1.0-rc.1``
- ``prod-v2.0.0+20230701``
a release invoked via :ref:`cmd-version`. The string is used as a template for the tag
name, and must include the ``{version}`` format key.

This format will also be used for parsing tags already present in the repository into
semantic versions; therefore if the tag format changes at some point in the
Expand All @@ -1196,6 +1233,13 @@ Format Key Mandatory Contents

Tags which do not match this format will not be considered as versions of your project.

This is critical for Monorepo projects where the tag format defines which package the
version tag belongs to. Generally, the tag format for each package of the monorepo will
include the package name as the prefix of the tag format. For example, if the package
is named ``pkg1``, the tag format would be ``pkg1-v{version}`` and in the other package
``pkg2``, the tag format would be ``pkg2-v{version}``. This allows PSR to determine
which tags to use to determine the version for each package.

**Default:** ``"v{version}"``

----
Expand Down Expand Up @@ -1354,7 +1398,7 @@ The regular expression generated from the ``version_variables`` definition will:
2. The variable name defined by ``variable`` and the version must be separated by
an operand symbol (``=``, ``:``, ``:=``, or ``@``). Whitespace is optional around
the symbol. As of v10.0.0, a double-equals (``==``) operator is also supported
as a valid operand symbol. As of $NEW_RELEASE_TAG, PSR can omit all operands as long
as a valid operand symbol. As of v10.5.0, PSR can omit all operands as long
as there is at least one whitespace character between the variable name and the version.

3. The value of the variable must match a `SemVer`_ regular expression and can be
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "python-semantic-release"
version = "10.4.1"
version = "10.5.0"
description = "Automatic Semantic Versioning for Python projects"
requires-python = "~= 3.8"
license = { text = "MIT" }
Expand Down
2 changes: 1 addition & 1 deletion src/gh_action/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
python-semantic-release == 10.4.1
python-semantic-release == 10.5.0
35 changes: 32 additions & 3 deletions src/semantic_release/cli/commands/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,13 @@ def is_forced_prerelease(
)


def last_released(repo_dir: Path, tag_format: str) -> tuple[Tag, Version] | None:
def last_released(
repo_dir: Path, tag_format: str, add_partial_tags: bool = False
) -> tuple[Tag, Version] | None:
with Repo(str(repo_dir)) as git_repo:
ts_and_vs = tags_and_versions(
git_repo.tags, VersionTranslator(tag_format=tag_format)
git_repo.tags,
VersionTranslator(tag_format=tag_format, add_partial_tags=add_partial_tags),
)

return ts_and_vs[0] if ts_and_vs else None
Expand Down Expand Up @@ -454,7 +457,11 @@ def version( # noqa: C901
if print_last_released or print_last_released_tag:
# TODO: get tag format a better way
if not (
last_release := last_released(config.repo_dir, tag_format=config.tag_format)
last_release := last_released(
config.repo_dir,
tag_format=config.tag_format,
add_partial_tags=config.add_partial_tags,
)
):
logger.warning("No release tags found.")
return
Expand All @@ -475,6 +482,7 @@ def version( # noqa: C901
major_on_zero = runtime.major_on_zero
no_verify = runtime.no_git_verify
opts = runtime.global_cli_options
add_partial_tags = config.add_partial_tags
gha_output = VersionGitHubActionsOutput(
gh_client=hvcs_client if isinstance(hvcs_client, Github) else None,
mode=(
Expand Down Expand Up @@ -777,6 +785,27 @@ def version( # noqa: C901
tag=new_version.as_tag(),
noop=opts.noop,
)
# Create or update partial tags for releases
if add_partial_tags and not prerelease:
partial_tags = [new_version.as_major_tag(), new_version.as_minor_tag()]
# If build metadata is set, also retag the version without the metadata
if build_metadata:
partial_tags.append(new_version.as_patch_tag())

for partial_tag in partial_tags:
project.git_tag(
tag_name=partial_tag,
message=f"{partial_tag} => {new_version.as_tag()}",
isotimestamp=commit_date.isoformat(),
noop=opts.noop,
force=True,
)
project.git_push_tag(
remote_url=remote_url,
tag=partial_tag,
noop=opts.noop,
force=True,
)

# Update GitHub Actions output value now that release has occurred
gha_output.released = True
Expand Down
5 changes: 4 additions & 1 deletion src/semantic_release/cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ class RawConfig(BaseModel):
remote: RemoteConfig = RemoteConfig()
no_git_verify: bool = False
tag_format: str = "v{version}"
add_partial_tags: bool = False
publish: PublishConfig = PublishConfig()
version_toml: Optional[Tuple[str, ...]] = None
version_variables: Optional[Tuple[str, ...]] = None
Expand Down Expand Up @@ -827,7 +828,9 @@ def from_raw_config( # noqa: C901

# version_translator
version_translator = VersionTranslator(
tag_format=raw.tag_format, prerelease_token=branch_config.prerelease_token
tag_format=raw.tag_format,
prerelease_token=branch_config.prerelease_token,
add_partial_tags=raw.add_partial_tags,
)

build_cmd_env = {}
Expand Down
Loading
Loading