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
100 changes: 100 additions & 0 deletions .github/workflows/prepare-release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: Prepare Release
on:
workflow_dispatch:
inputs:
bump:
description: "Version bump type"
required: true
type: choice
options:
- auto
- major
- minor
- patch
default: auto

permissions:
contents: read

env:
FORCE_COLOR: 1

jobs:
prepare-release:
runs-on: ubuntu-24.04
environment: release-auth
permissions:
contents: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
token: ${{ secrets.RELEASE_PAT }}
persist-credentials: true

- name: Install the latest version of uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
enable-cache: true
cache-dependency-glob: "pyproject.toml"
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Configure git
run: |
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"

- name: Calculate next version
id: version
env:
BUMP: ${{ inputs.bump }}
run: |
current=$(git describe --tags --abbrev=0 2>/dev/null || echo "0.0.0")
echo "Current version: $current"

IFS='.' read -r major minor patch <<< "$current"

bump_type="$BUMP"
if [ "$bump_type" = "auto" ]; then
feature_count=$(find docs/changelog -name "*.feature.rst" 2>/dev/null | wc -l)
breaking_count=$(find docs/changelog -name "*.breaking.rst" 2>/dev/null | wc -l)
if [ "$breaking_count" -gt 0 ]; then
bump_type="major"
echo "Auto-detected: major bump (found $breaking_count breaking changelog(s))"
elif [ "$feature_count" -gt 0 ]; then
bump_type="minor"
echo "Auto-detected: minor bump (found $feature_count feature changelog(s))"
else
bump_type="patch"
echo "Auto-detected: patch bump (no feature changelogs)"
fi
fi

case "$bump_type" in
major)
next="$((major + 1)).0.0"
;;
minor)
next="$major.$((minor + 1)).0"
;;
patch)
next="$major.$minor.$((patch + 1))"
;;
esac

echo "Next version: $next"
echo "version=$next" >> $GITHUB_OUTPUT

- name: Install tox
run: uv tool install --python-preference only-managed --python 3.14 tox@latest --with tox-uv

- name: Run release process
run: tox run -e release -- ${STEPS_VERSION_OUTPUTS_VERSION}
env:
GH_TOKEN: ${{ secrets.RELEASE_PAT }}
STEPS_VERSION_OUTPUTS_VERSION: ${{ steps.version.outputs.version }}

- name: Display completion message
run: echo "Release ${STEPS_VERSION_OUTPUTS_VERSION} prepared and pushed successfully!"
env:
STEPS_VERSION_OUTPUTS_VERSION: ${{ steps.version.outputs.version }}
113 changes: 113 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#################
Release History
#################

.. towncrier-draft-entries::

.. towncrier release notes start

********************
v1.3.0 (2026-05-05)
********************

Features - 1.3.0
================

- Add :func:`~python_discovery.iter_interpreters` for enumerating every discovered interpreter, with PATH and
UV-install support for non-CPython implementations listed in :data:`~python_discovery.KNOWN_IMPLEMENTATIONS`
(:pull:`71`)

********************
v1.2.2 (2026-04-06)
********************

Features - 1.2.2
================

- Export ``normalize_isa`` and deprecate ``KNOWN_ARCHITECTURES`` (:pull:`62`)

********************
v1.2.1 (2026-03-26)
********************

Features - 1.2.1
================

- Expose ``KNOWN_ARCHITECTURES`` as public API (:pull:`56`)

Contributor-facing changes - 1.2.1
==================================

- Add zizmor security auditing for workflows (:pull:`55`)

********************
v1.2.0 (2026-03-18)
********************

Features - 1.2.0
================

- Increase interpreter query timeout to 15s, with an override (:pull:`53`)

********************
v1.1.3 (2026-03-10)
********************

Bug fixes - 1.1.3
=================

- Add ``loongarch64`` to known ISAs (:pull:`50`)

********************
v1.1.2 (2026-03-09)
********************

Bug fixes - 1.1.2
=================

- Match prerelease versions against ``major.minor`` specs (:pull:`48`)
- Drain pipes after killing a timed-out interpreter probe (:pull:`49`)

Improved documentation - 1.1.2
==============================

- Add package description and usage to the README (:pull:`46`)

********************
v1.1.1 (2026-03-06)
********************

Bug fixes - 1.1.1
=================

- Add a timeout to interpreter probing (:pull:`42`)
- Add ``i686`` to known ISAs (:pull:`43`)

Contributor-facing changes - 1.1.1
==================================

- Add a security policy and workflow permissions hardening (:pull:`33`)

********************
v1.1.0 (2026-02-26)
********************

Features - 1.1.0
================

- Add a ``predicate`` parameter to :func:`~python_discovery.get_interpreter` (:pull:`31`)

Improved documentation - 1.1.0
==============================

- Fix the ReadTheDocs build (:pull:`29`)
- Add ``:param:`` descriptions to all public APIs (:pull:`32`)

********************
v1.0.0 (2026-02-25)
********************

Features - 1.0.0
================

- Initial release as a standalone package, extracted from ``virtualenv`` (:pull:`28`)
3 changes: 0 additions & 3 deletions docs/changelog/65.feature.rst

This file was deleted.

38 changes: 38 additions & 0 deletions docs/changelog/template.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{% set top_underline = "*" %}
{% set underline = "=" %}
{% if versiondata.name %}
{{ top_underline * ((versiondata.version + versiondata.date)|length + 5)}}
v{{ versiondata.version }} ({{ versiondata.date }})
{{ top_underline * ((versiondata.version + versiondata.date)|length + 5)}}
{% else %}
{{ top_underline * ((versiondata.version + versiondata.date)|length + 4)}}
{{ versiondata.version }} ({{ versiondata.date }})
{{ top_underline * ((versiondata.version + versiondata.date)|length + 4)}}
{% endif %}

{% for section, _ in sections.items() %}
{% if sections[section] %}
{% for category, val in definitions.items() if category in sections[section]%}
{{ definitions[category]['name'] }} - {{ versiondata.version }}
{{ underline * ((definitions[category]['name'] + versiondata.version)|length + 3)}}
{% if definitions[category]['showcontent'] %}
{% for text, values in sections[section][category].items() %}
- {{ text }} ({{ values|join(', ') }})
{% endfor %}

{% else %}
- {{ sections[section][category]['']|join(', ') }}

{% endif %}
{% if sections[section][category]|length == 0 %}
No significant changes.

{% else %}
{% endif %}
{% endfor %}
{% else %}
No significant changes.


{% endif %}
{% endfor %}
8 changes: 7 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

from datetime import datetime, timezone
from pathlib import Path

from python_discovery import __version__

Expand All @@ -19,8 +20,13 @@
"sphinx.ext.intersphinx",
"sphinx_autodoc_typehints",
"sphinxcontrib.mermaid",
"sphinxcontrib.towncrier.ext",
]

towncrier_draft_autoversion_mode = "draft"
towncrier_draft_include_empty = True
towncrier_draft_working_directory = Path(__file__).parent.parent

extlinks = {
"issue": ("https://github.com/tox-dev/python-discovery/issues/%s", "#%s"),
"pull": ("https://github.com/tox-dev/python-discovery/pull/%s", "PR #%s"),
Expand All @@ -33,7 +39,7 @@

templates_path = []
source_suffix = ".rst"
exclude_patterns = ["_build", "changelog/*.rst"]
exclude_patterns = ["_build", "changelog/*"]

main_doc = "index"
pygments_style = "default"
Expand Down
6 changes: 6 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,9 @@ repeated lookups are fast.
:hidden:

explanation

.. toctree::
:caption: Project
:hidden:

changelog
34 changes: 34 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ optional-dependencies.docs = [
"sphinx>=9.1",
"sphinx-autodoc-typehints>=3.6.3",
"sphinxcontrib-mermaid>=2",
"sphinxcontrib-towncrier>=0.4",
"towncrier>=25.8",
]
optional-dependencies.testing = [
"covdefaults>=2.3",
Expand All @@ -64,6 +66,14 @@ urls.Homepage = "https://github.com/tox-dev/python-discovery"
urls.Source = "https://github.com/tox-dev/python-discovery"
urls.Tracker = "https://github.com/tox-dev/python-discovery/issues"

[dependency-groups]
release = [
"gitpython>=3.1.46",
"packaging>=26",
"pre-commit>=4.5.1",
"towncrier>=25.8",
]

[tool.hatch]
version.source = "vcs"

Expand Down Expand Up @@ -98,6 +108,12 @@ lint.per-file-ignores."src/python_discovery/_py_info.py" = [
lint.per-file-ignores."src/python_discovery/_windows/_pep514.py" = [
"PTH", # os.path.exists is monkeypatched in tests; pathlib.Path.exists bypasses the mock
]
lint.per-file-ignores."tasks/**/*.py" = [
"D", # release helper scripts, not API
"INP001", # no __init__.py in tasks directory
"S404", # subprocess import (release tooling)
"S603", # `subprocess` call: argv built from trusted inputs (version, gh CLI)
]
lint.per-file-ignores."tests/**/*.py" = [
"D", # don't care about documentation in tests
"FBT", # don't care about booleans as positional arguments in tests
Expand Down Expand Up @@ -180,3 +196,21 @@ report.partial_branches = [
report.show_missing = true
html.show_contexts = true
html.skip_covered = false

[tool.towncrier]
name = "python-discovery"
filename = "docs/changelog.rst"
directory = "docs/changelog"
title_format = false
issue_format = ":issue:`{issue}`"
template = "docs/changelog/template.jinja2"
type = [
{ directory = "breaking", name = "Backward incompatible changes", showcontent = true },
{ directory = "deprecation", name = "Deprecations (removal in next major release)", showcontent = true },
{ directory = "feature", name = "Features", showcontent = true },
{ directory = "bugfix", name = "Bug fixes", showcontent = true },
{ directory = "doc", name = "Improved documentation", showcontent = true },
{ directory = "packaging", name = "Packaging updates and notes for downstreams", showcontent = true },
{ directory = "contrib", name = "Contributor-facing changes", showcontent = true },
{ directory = "misc", name = "Miscellaneous internal changes", showcontent = true },
]
Loading