Skip to content

Commit 23d910d

Browse files
committed
feat: Add GitHub releases and semantic versioning
- Set up dynamic version reading from package metadata - Add python-semantic-release to dev dependencies - Create release.yml workflow for automated GitHub releases - Configure semantic versioning with conventional commits - Update README with version-specific installation examples - Build distribution packages (wheel and sdist)
1 parent 89ee7e0 commit 23d910d

5 files changed

Lines changed: 1554 additions & 5 deletions

File tree

.github/workflows/release.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
permissions:
8+
contents: write
9+
packages: write
10+
11+
jobs:
12+
release:
13+
name: Create Release
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
20+
- name: Install uv
21+
uses: astral-sh/setup-uv@v4
22+
with:
23+
version: "latest"
24+
enable-cache: true
25+
cache-dependency-glob: "pyproject.toml"
26+
ignore-nothing-to-cache: true
27+
28+
- name: Set up Python
29+
run: uv python install 3.9
30+
31+
- name: Install dependencies
32+
run: uv sync --group dev
33+
34+
- name: Run tests
35+
run: uv run pytest tests/ -v --tb=short
36+
37+
- name: Run semantic-release
38+
env:
39+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40+
run: uv run semantic-release publish --ci
41+
42+
- name: Build distribution packages
43+
run: uv run pip install build && python -m build
44+
45+
- name: Upload artifacts to release
46+
if: github.ref == 'refs/heads/main'
47+
env:
48+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
49+
run: |
50+
# Get the latest tag
51+
LATEST_TAG=$(git describe --tags --abbrev=0 || echo "")
52+
53+
if [ -n "$LATEST_TAG" ]; then
54+
# Upload wheel and sdist to the release
55+
gh release upload "$LATEST_TAG" dist/*.whl dist/*.tar.gz --clobber
56+
fi
57+

README.md

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,38 @@ A Python address parser built for Ryan Data that uses `usaddress` to parse US ad
1010

1111
## Installation
1212

13+
Install the latest development version:
14+
1315
```bash
14-
pip install git+https://github.com/Abstract-Data/RyanData-Address-Utils.git
16+
uv add git+https://github.com/Abstract-Data/RyanData-Address-Utils.git
17+
```
18+
19+
Install a specific version (recommended for production):
20+
21+
```bash
22+
# Install a specific release version
23+
uv add git+https://github.com/Abstract-Data/RyanData-Address-Utils.git@v0.2.0
24+
25+
# Install latest from main branch
26+
uv add git+https://github.com/Abstract-Data/RyanData-Address-Utils.git@main
1527
```
1628

1729
With pandas support:
1830

1931
```bash
20-
pip install "ryandata-address-utils[pandas] @ git+https://github.com/Abstract-Data/RyanData-Address-Utils.git"
32+
uv add "git+https://github.com/Abstract-Data/RyanData-Address-Utils.git[pandas]"
33+
```
34+
35+
For specific version with pandas:
36+
37+
```bash
38+
uv add "git+https://github.com/Abstract-Data/RyanData-Address-Utils.git@v0.2.0[pandas]"
2139
```
2240

41+
### Available Releases
42+
43+
See [GitHub Releases](https://github.com/Abstract-Data/RyanData-Address-Utils/releases) for all available versions and changelog.
44+
2345
## Quick Start
2446

2547
```python
@@ -197,6 +219,28 @@ make test
197219
make lint
198220
```
199221

222+
## Versioning
223+
224+
This project follows [Semantic Versioning](https://semver.org/). Version bumps are automated based on [Conventional Commits](https://www.conventionalcommits.org/):
225+
226+
- `feat:` commits trigger a minor version bump
227+
- `fix:` commits trigger a patch version bump
228+
- `BREAKING CHANGE:` in commit footer triggers a major version bump
229+
- `chore:`, `docs:`, `refactor:` commits don't trigger version bumps
230+
231+
### Release Process
232+
233+
1. Commits following conventional commits are pushed to `main`
234+
2. GitHub Actions automatically:
235+
- Detects version bump requirements
236+
- Updates version in `pyproject.toml`
237+
- Creates git tag (e.g., `v0.2.1`)
238+
- Builds distribution packages (wheel + sdist)
239+
- Creates GitHub release with changelog
240+
- Uploads artifacts
241+
242+
See [GitHub Actions Releases](https://github.com/Abstract-Data/RyanData-Address-Utils/actions/workflows/release.yml) to view release automation.
243+
200244
## License
201245

202246
MIT

pyproject.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ dev = [
4747
"mypy>=1.13.0",
4848
"pytest>=8.0.0",
4949
"hypothesis>=6.0.0",
50+
"python-semantic-release>=9.0.0",
5051
]
5152

5253
[build-system]
@@ -83,3 +84,8 @@ warn_return_any = true
8384
warn_unused_ignores = true
8485
disallow_untyped_defs = true
8586
ignore_missing_imports = true
87+
88+
[tool.semantic_release]
89+
version_source = "tag"
90+
tag_format = "v{version}"
91+
build_command = "pip install build && python -m build"

src/ryandata_address_utils/__init__.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,23 @@
4040

4141
from __future__ import annotations
4242

43+
import sys
4344
from typing import Optional
4445

46+
# Dynamic version from package metadata
47+
if sys.version_info >= (3, 8):
48+
from importlib.metadata import version, PackageNotFoundError
49+
else:
50+
from importlib_metadata import version, PackageNotFoundError
51+
52+
try:
53+
__version__ = version("ryandata-address-utils")
54+
except PackageNotFoundError:
55+
# Package is not installed in editable mode or not installed at all
56+
__version__ = "0.2.0"
57+
58+
__package_name__ = "ryandata-address-utils"
59+
4560
# Imports grouped by type and sorted
4661
from ryandata_address_utils.data import (
4762
BaseDataSource,
@@ -82,9 +97,6 @@
8297
ZipCodeValidator,
8398
)
8499

85-
__version__ = "0.2.0"
86-
__package_name__ = "ryandata-address-utils"
87-
88100
__all__ = [
89101
# Version
90102
"__version__",

0 commit comments

Comments
 (0)