Skip to content

Phase 1: Dynamic versioning from git tags via setuptools-scm#17

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/automate-package-release-workflow
Draft

Phase 1: Dynamic versioning from git tags via setuptools-scm#17
Copilot wants to merge 2 commits intomainfrom
copilot/automate-package-release-workflow

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 21, 2026

Description

Switches from hardcoded version = "1.1.0" to git-tag-derived versioning using setuptools-scm. Maintainers tag a release (git tag v1.2.0 && git push --tags) and the version propagates automatically through build and runtime — no manual bumps needed.

pyproject.toml:

  • Replace static version with dynamic = ["version"]
  • Add setuptools-scm>=8 to build requires
  • Configure scikit_build_core.metadata.setuptools_scm as the version provider
  • Add [tool.setuptools_scm] section

pyhwm2014/__init__.py:

  • Replace __version__ = "1.1.0" with importlib.metadata.version() lookup, falling back to "0.0.0" when not installed from a built package

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • My code follows the project style guidelines (black, ruff, mypy)
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added tests that prove my fix/feature works
  • New and existing tests pass with my changes
  • Test coverage remains > 80%
  • I have updated the documentation (docstrings, README, guides)
  • I have added an entry to CHANGELOG.md
  • I have updated type hints for modified functions

Testing

# Validate pyproject.toml structure
python -c "
import tomllib
with open('pyproject.toml', 'rb') as f:
    data = tomllib.load(f)
assert 'version' not in data['project']
assert 'version' in data['project']['dynamic']
assert 'setuptools-scm>=8' in data['build-system']['requires']
print('OK')
"

# Verify runtime fallback (uninstalled)
python -c "
from importlib.metadata import PackageNotFoundError, version
try: v = version('pyhwm2014')
except PackageNotFoundError: v = '0.0.0'
assert v == '0.0.0'
print('Fallback OK')
"

Additional Context

This is Phase 1 of the automated release plan. Subsequent phases will add towncrier changelog generation, uv build, and a GitHub Actions release workflow triggered by version tags.

Original prompt

This section details on the original issue you should resolve

<issue_title>Modern Python Package Release Plan (uv workflow)</issue_title>
<issue_description># Plan: Automated Python Package Releases

Goal

Create a fully automated release workflow where:

  • versions come from git tags
  • changelogs are generated automatically
  • CI builds and publishes the package
  • maintainers only create a tag to release

Phase 1 -- Version comes from git tags

[project]
name = "pyhwm14"
description = "Python interface for the Horizontal Wind Model 2014 (HWM14)"
readme = "README.md"
requires-python = ">=3.13"
dynamic = ["version"]

This means the version comes from git tags automatically.


Phase 2 — Changelog with Towncrier

Towncrier generates release notes automatically.

Create configuration in pyproject.toml.

[tool.towncrier]
package = "mypackage"
directory = "changelog.d"
filename = "CHANGELOG.md"

Create fragments for changes.

Example:

changelog.d/123.feature.md

Contents:

Added support for XYZ.

Types typically used:

feature
bugfix
doc
removal
misc

These fragments are merged into the changelog during release.


Phase 3 — Build Package

Build locally with:

uv build

Artifacts appear in:

dist/
  pyhwm14-x.y.z.tar.gz
  pyhwm14-x.y.z.whl

Phase 4 — Automated Publishing

Use GitHub Trusted Publishing for PyPI.

Workflow .github/workflows/release.yml:

name: Release

on:
  push:
    tags:
      - "v*"

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      id-token: write

    steps:
      - uses: actions/checkout@v4

      - name: Install uv
        run: curl -Ls https://astral.sh/uv/install.sh | sh

      - run: uv build

      - run: uv publish

Phase 5 — Release Process

Maintainers release by tagging.

git tag v0.3.0
git push --tags

Automated steps:

  1. version derived from tag
  2. package built
  3. package uploaded to PyPI
  4. release created

Result

Maintainers only need to:

  1. merge pull requests
  2. create a release tag

Everything else is automated.
</issue_description>

<agent_instructions>Let's start with resolving Phase 1, if you understand the Issue.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💬 Send tasks to Copilot coding agent from Slack and Teams to turn conversations into code. Copilot posts an update in your thread when it's finished.

- Remove static version from pyproject.toml, add dynamic = ["version"]
- Add setuptools-scm>=8 to build-system requires
- Configure scikit-build-core metadata.version.provider
- Add [tool.setuptools_scm] section
- Update __init__.py to read version via importlib.metadata

Co-authored-by: rilma <14822065+rilma@users.noreply.github.com>
Agent-Logs-Url: https://github.com/rilma/pyHWM14/sessions/fe9b4fd3-2200-4f81-ab2b-32ebce284437
Copilot AI changed the title [WIP] Create an automated Python package release workflow Phase 1: Dynamic versioning from git tags via setuptools-scm Mar 21, 2026
Copilot AI requested a review from rilma March 21, 2026 13:47
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.

Modern Python Package Release Plan (uv workflow)

2 participants