Skip to content

Commit 29f81c5

Browse files
committed
Prepare for initial release on PyPI
1 parent 77ba590 commit 29f81c5

File tree

6 files changed

+146
-1
lines changed

6 files changed

+146
-1
lines changed

.github/workflows/pypi.yml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: Publish Python distribution to PyPI and TestPyPI
2+
# Source:
3+
# https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/
4+
on:
5+
push:
6+
branches:
7+
- main
8+
tags:
9+
- 'v*'
10+
jobs:
11+
build:
12+
name: Build distribution package
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
- name: Set up Python
17+
uses: actions/setup-python@v5
18+
with:
19+
python-version: "3.x"
20+
- run: pip install build
21+
- name: Add untagged version suffix
22+
if: ${{ ! startsWith(github.ref, 'refs/tags/v') }}
23+
run: python version.py update
24+
- name: Build a binary wheel and a source tarball
25+
run: python -m build
26+
- name: Store the distribution packages
27+
uses: actions/upload-artifact@v4
28+
with:
29+
name: python-package-distributions
30+
path: dist/
31+
version-check:
32+
name: Check for version match in git tag and unmagic.__version__
33+
runs-on: ubuntu-latest
34+
if: startsWith(github.ref, 'refs/tags/v')
35+
steps:
36+
- uses: actions/checkout@v4
37+
- name: Set up Python
38+
uses: actions/setup-python@v5
39+
with:
40+
python-version: "3.x"
41+
- name: Install pytest-unmagic
42+
run: pip install -e .
43+
- name: Check version
44+
run: python version.py check "${{ github.ref }}"
45+
pypi-publish:
46+
name: Upload release to PyPI
47+
needs: [build, version-check]
48+
runs-on: ubuntu-latest
49+
if: startsWith(github.ref, 'refs/tags/v')
50+
environment:
51+
name: pypi
52+
url: https://pypi.org/p/pytest-unmagic
53+
permissions:
54+
id-token: write
55+
steps:
56+
- name: Download all the dists
57+
uses: actions/download-artifact@v4
58+
with:
59+
name: python-package-distributions
60+
path: dist/
61+
- name: Publish package distributions to PyPI
62+
uses: pypa/gh-action-pypi-publish@release/v1
63+
pypi-test-publish:
64+
name: Upload release to test PyPI
65+
needs: [build]
66+
runs-on: ubuntu-latest
67+
environment:
68+
name: testpypi
69+
url: https://test.pypi.org/p/pytest-unmagic
70+
permissions:
71+
id-token: write
72+
steps:
73+
- name: Download all the dists
74+
uses: actions/download-artifact@v4
75+
with:
76+
name: python-package-distributions
77+
path: dist/
78+
- name: Publish package distributions to PyPI
79+
uses: pypa/gh-action-pypi-publish@release/v1
80+
with:
81+
repository-url: https://test.pypi.org/legacy/

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
__pycache__
2+
/dist

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,14 @@ cd path/to/pytest-unmagic
193193
pip install -e .
194194
pytest
195195
```
196+
197+
198+
## Publishing a new verison to PyPI
199+
200+
Push a new tag to Github using the format vX.Y.Z where X.Y.Z matches the version
201+
in [`__init__.py`](src/unmagic/__init__.py).
202+
203+
A new version is published to https://test.pypi.org/p/pytest-unmagic on every
204+
push to the *main* branch.
205+
206+
Publishing is automated with [Github Actions](.github/workflows/pypi.yml).

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
name = "pytest-unmagic"
33
authors = [{name = "Daniel Miller", email = "millerdev@gmail.com"}]
44
license = {file = "LICENSE"}
5+
readme = {file = "README.md", content-type = "text/markdown"}
56
dynamic = ["version", "description"]
67
requires-python = ">= 3.9"
78
classifiers = [
@@ -10,6 +11,10 @@ classifiers = [
1011
"License :: OSI Approved :: BSD License",
1112
"Programming Language :: Python :: 3",
1213
"Programming Language :: Python :: 3.9",
14+
"Programming Language :: Python :: 3.10",
15+
"Programming Language :: Python :: 3.11",
16+
"Programming Language :: Python :: 3.12",
17+
"Programming Language :: Python :: 3.13",
1318
"Topic :: Software Development :: Libraries",
1419
"Topic :: Software Development :: Testing",
1520
]

src/unmagic/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""Reduce pytest magic
1+
"""Pytest fixtures with conventional import semantics
22
33
The primary motivation of this project is to remove the argument-name-
44
matching magic in pytest fixtures.

version.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
"""Check or update version in __init__.py"""
2+
import re
3+
import sys
4+
from datetime import datetime
5+
from pathlib import Path
6+
7+
8+
def main(argv=sys.argv):
9+
if len(argv) < 2:
10+
sys.exit(f"usage: {argv[0]} (check|update) [...]")
11+
cmd, *args = sys.argv[1:]
12+
if cmd in COMMANDS:
13+
COMMANDS[cmd](*args)
14+
else:
15+
sys.exit(f"unknown arguments: {argv[1:]}")
16+
17+
18+
def check(ref):
19+
import unmagic
20+
if not ref.startswith("refs/tags/v"):
21+
sys.exit(f"unexpected ref: {ref}")
22+
version = ref.removeprefix("refs/tags/v")
23+
if version != unmagic.__version__:
24+
sys.exit(f"version mismatch: {version} != {unmagic.__version__}")
25+
26+
27+
def update():
28+
path = Path(__file__).parent / "src/unmagic/__init__.py"
29+
vexpr = re.compile(r"""(?<=^__version__ = )['"](.+)['"]$""", flags=re.M)
30+
with open(path, "r+") as file:
31+
text = file.read()
32+
match = vexpr.search(text)
33+
if not match:
34+
sys.exit("unmagic.__version__ not found")
35+
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
36+
version = f"{match.group(1)}.dev{timestamp}"
37+
print("new version:", version)
38+
file.seek(0)
39+
file.write(vexpr.sub(repr(version), text))
40+
file.truncate()
41+
42+
43+
COMMANDS = {"check": check, "update": update}
44+
45+
46+
if __name__ == "__main__":
47+
main()

0 commit comments

Comments
 (0)