Repository: prkumar/uplink
Pull request #320: Prepare for 0.10.0a1 release
Author: login: prkumar
Created: 2025-03-16T05:31:04Z | Merged: 2025-03-16T16:47:28Z

- Update version to 0.10.0a1
- Convert string literals to single quotes in pyproject.toml
- Add PyPI publishing workflow to CI configuration


Diff:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3349faa1..c7c31d0d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -25,3 +25,22 @@ jobs:
 
       - name: Run tests
         run:  uv tool run --with=tox-uv tox r -e py${{ matrix.python-version }}
+
+  publish:
+    needs: test
+    runs-on: ubuntu-latest
+    if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
+    environment: release
+    
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+
+      - name: Install uv
+        uses: astral-sh/setup-uv@v5
+
+      - name: Build package
+        run: uv build
+
+      - name: Publish to PyPI
+        run: uv publish --trusted-publishing always
diff --git a/pyproject.toml b/pyproject.toml
index 472e2e13..56707392 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,62 +1,61 @@
 [project]
-name = "uplink"
-version = "1.0.0-alpha"
-description = "A Declarative HTTP Client for Python."
-readme = "README.md"
-maintainers = [{ name = "P. Raj Kumar", email = "raj.pritvi.kumar@gmail.com" }]
+name = 'uplink'
+version = '0.10.0a1'
+description = 'A Declarative HTTP Client for Python.'
+readme = 'README.md'
+maintainers = [{ name = 'P. Raj Kumar', email = 'raj.pritvi.kumar@gmail.com' }]
 authors = [
-  { name = "Kareem Moussa" },
-  { name = "Brandon Milton" },
-  { name = "Fabio Rosado" },
-  { name = "Niko Eckerskorn" },
-  { name = "Or Carmi" },
-  { name = "George Kontridze" },
-  { name = "Sean Chambers" },
-  { name = "Nils Philippsen" },
-  { name = "Alexander Duryagin" },
-  { name = "Sakorn Waungwiwatsin" },
-  { name = "Jacob Floyd" },
-  { name = "Guilherme Crocetti" },
-  { name = "Alexander Shadchin" },
-  { name = "Lieser Fernández Gallo", email = "leiserfg@gmail.com" },
+  { name = 'Kareem Moussa' },
+  { name = 'Brandon Milton' },
+  { name = 'Fabio Rosado' },
+  { name = 'Niko Eckerskorn' },
+  { name = 'Or Carmi' },
+  { name = 'George Kontridze' },
+  { name = 'Sean Chambers' },
+  { name = 'Nils Philippsen' },
+  { name = 'Alexander Duryagin' },
+  { name = 'Sakorn Waungwiwatsin' },
+  { name = 'Jacob Floyd' },
+  { name = 'Guilherme Crocetti' },
+  { name = 'Alexander Shadchin' },
+  { name = 'Lieser Fernández Gallo', email = 'leiserfg@gmail.com' },
 ]
-license = { file = "LICENSE" }
-keywords = ["http", "api", "rest", "client", "retrofit"]
-urls = { Repository = "https://github.com/prkumar/uplink" }
+license = { file = 'LICENSE' }
+keywords = ['http', 'api', 'rest', 'client', 'retrofit']
+urls = { Repository = 'https://github.com/prkumar/uplink' }
 classifiers = [
-  "Development Status :: 4 - Beta",
-  "Intended Audience :: Developers",
-  "License :: OSI Approved :: MIT License",
-  "Operating System :: OS Independent",
-  "Programming Language :: Python :: 3.10",
-  "Programming Language :: Python :: 3.11",
-  "Programming Language :: Python :: 3.12",
-  "Programming Language :: Python :: 3.13",
-  "Programming Language :: Python :: 3 :: Only",
-  "Programming Language :: Python :: Implementation :: CPython",
-  "Programming Language :: Python :: Implementation :: PyPy",
-  "Topic :: Software Development :: Libraries",
+  'Development Status :: 4 - Beta',
+  'Intended Audience :: Developers',
+  'License :: OSI Approved :: MIT License',
+  'Operating System :: OS Independent',
+  'Programming Language :: Python :: 3.10',
+  'Programming Language :: Python :: 3.11',
+  'Programming Language :: Python :: 3.12',
+  'Programming Language :: Python :: 3.13',
+  'Programming Language :: Python :: 3 :: Only',
+  'Programming Language :: Python :: Implementation :: CPython',
+  'Programming Language :: Python :: Implementation :: PyPy',
+  'Topic :: Software Development :: Libraries',
 ]
-
-requires-python = ">=3.10"
-dependencies = ["requests>=2.18.0", "six>=1.13.0", "uritemplate>=3.0.0"]
+requires-python = '>=3.10'
+dependencies = ['requests>=2.18.0', 'six>=1.13.0', 'uritemplate>=3.0.0']
 
 [dependency-groups]
 test = [
-  "pytest",
-  "pytest-mock",
-  "pytest-cov",
-  "pytest-twisted",
-  "pytest-asyncio",
+  'pytest',
+  'pytest-mock',
+  'pytest-cov',
+  'pytest-twisted',
+  'pytest-asyncio',
 ]
-marshmallow = ["marshmallow>=2.15.0"]
-pydantic = ["pydantic>=2.0.0"]
-aiohttp = ["aiohttp>=3.8.1"]
-twisted = ["twisted>=21.7.0"]
+marshmallow = ['marshmallow>=2.15.0']
+pydantic = ['pydantic>=2.0.0']
+aiohttp = ['aiohttp>=3.8.1']
+twisted = ['twisted>=21.7.0']
 
 [build-system]
-requires = ["hatchling"]
-build-backend = "hatchling.build"
+requires = ['hatchling']
+build-backend = 'hatchling.build'
 
-[tools.pytest]
+[tool.pytest]
 twisted=1
diff --git a/uplink/__about__.py b/uplink/__about__.py
index a86157d8..1ef689e9 100644
--- a/uplink/__about__.py
+++ b/uplink/__about__.py
@@ -4,4 +4,6 @@
 codebase.
 """
 
-__version__ = "0.9.7"
+import importlib.metadata
+
+__version__ = importlib.metadata.version("uplink")
diff --git a/uv.lock b/uv.lock
index 227e24d5..9df3d5fe 100644
--- a/uv.lock
+++ b/uv.lock
@@ -924,7 +924,7 @@ wheels = [
 
 [[package]]
 name = "uplink"
-version = "1.0.0a0"
+version = "0.10.0a1"
 source = { editable = "." }
 dependencies = [
     { name = "requests" },


Reviews:
user: login: leiserfg
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-16T06:54:14Z
user: login: prkumar
state: COMMENTED
author_association: OWNER
submitted_at: 2025-03-16T08:33:08Z
user: login: leiserfg
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-16T11:58:42Z

Review comments:
diff_hunk: @@ -1,62 +1,65 @@
 [project]
-name = "uplink"
-version = "1.0.0-alpha"
-description = "A Declarative HTTP Client for Python."
-readme = "README.md"
-maintainers = [{ name = "P. Raj Kumar", email = "raj.pritvi.kumar@gmail.com" }]
+name = 'uplink'
+description = 'A Declarative HTTP Client for Python.'
+readme = 'README.md'
+maintainers = [{ name = 'P. Raj Kumar', email = 'raj.pritvi.kumar@gmail.com' }]
 authors = [
-  { name = "Kareem Moussa" },
-  { name = "Brandon Milton" },
-  { name = "Fabio Rosado" },
-  { name = "Niko Eckerskorn" },
-  { name = "Or Carmi" },
-  { name = "George Kontridze" },
-  { name = "Sean Chambers" },
-  { name = "Nils Philippsen" },
-  { name = "Alexander Duryagin" },
-  { name = "Sakorn Waungwiwatsin" },
-  { name = "Jacob Floyd" },
-  { name = "Guilherme Crocetti" },
-  { name = "Alexander Shadchin" },
-  { name = "Lieser Fernández Gallo", email = "leiserfg@gmail.com" },
+  { name = 'Kareem Moussa' },
+  { name = 'Brandon Milton' },
+  { name = 'Fabio Rosado' },
+  { name = 'Niko Eckerskorn' },
+  { name = 'Or Carmi' },
+  { name = 'George Kontridze' },
+  { name = 'Sean Chambers' },
+  { name = 'Nils Philippsen' },
+  { name = 'Alexander Duryagin' },
+  { name = 'Sakorn Waungwiwatsin' },
+  { name = 'Jacob Floyd' },
+  { name = 'Guilherme Crocetti' },
+  { name = 'Alexander Shadchin' },
+  { name = 'Lieser Fernández Gallo', email = 'leiserfg@gmail.com' },
 ]
-license = { file = "LICENSE" }
-keywords = ["http", "api", "rest", "client", "retrofit"]
-urls = { Repository = "https://github.com/prkumar/uplink" }
+license = { file = 'LICENSE' }
+keywords = ['http', 'api', 'rest', 'client', 'retrofit']
+urls = { Repository = 'https://github.com/prkumar/uplink' }
 classifiers = [
-  "Development Status :: 4 - Beta",
-  "Intended Audience :: Developers",
-  "License :: OSI Approved :: MIT License",
-  "Operating System :: OS Independent",
-  "Programming Language :: Python :: 3.10",
-  "Programming Language :: Python :: 3.11",
-  "Programming Language :: Python :: 3.12",
-  "Programming Language :: Python :: 3.13",
-  "Programming Language :: Python :: 3 :: Only",
-  "Programming Language :: Python :: Implementation :: CPython",
-  "Programming Language :: Python :: Implementation :: PyPy",
-  "Topic :: Software Development :: Libraries",
+  'Development Status :: 4 - Beta',
+  'Intended Audience :: Developers',
+  'License :: OSI Approved :: MIT License',
+  'Operating System :: OS Independent',
+  'Programming Language :: Python :: 3.10',
+  'Programming Language :: Python :: 3.11',
+  'Programming Language :: Python :: 3.12',
+  'Programming Language :: Python :: 3.13',
+  'Programming Language :: Python :: 3 :: Only',
+  'Programming Language :: Python :: Implementation :: CPython',
+  'Programming Language :: Python :: Implementation :: PyPy',
+  'Topic :: Software Development :: Libraries',
 ]
 
-requires-python = ">=3.10"
-dependencies = ["requests>=2.18.0", "six>=1.13.0", "uritemplate>=3.0.0"]
+requires-python = '>=3.10'
+dependencies = ['requests>=2.18.0', 'six>=1.13.0', 'uritemplate>=3.0.0']
+dynamic = ['version']
 
 [dependency-groups]
 test = [
-  "pytest",
-  "pytest-mock",
-  "pytest-cov",
-  "pytest-twisted",
-  "pytest-asyncio",
+  'pytest',
+  'pytest-mock',
+  'pytest-cov',
+  'pytest-twisted',
+  'pytest-asyncio',
 ]
-marshmallow = ["marshmallow>=2.15.0"]
-pydantic = ["pydantic>=2.0.0"]
-aiohttp = ["aiohttp>=3.8.1"]
-twisted = ["twisted>=21.7.0"]
+marshmallow = ['marshmallow>=2.15.0']
+pydantic = ['pydantic>=2.0.0']
+aiohttp = ['aiohttp>=3.8.1']
+twisted = ['twisted>=21.7.0']
 
 [build-system]
-requires = ["hatchling"]
-build-backend = "hatchling.build"
+requires = ['hatchling']
+build-backend = 'hatchling.build'
 
-[tools.pytest]
+[tool.hatch.version]
path: pyproject.toml
user: login: leiserfg
body: Do you think we need this? isn't better to have the version here in the pyproject? If it is needed at runtime it can be gathered with 
```python
from importlib.metadata import version
version("poetry")
```
created_at: 2025-03-16T06:54:14Z
author_association: COLLABORATOR
diff_hunk: @@ -1,62 +1,65 @@
 [project]
-name = "uplink"
-version = "1.0.0-alpha"
-description = "A Declarative HTTP Client for Python."
-readme = "README.md"
-maintainers = [{ name = "P. Raj Kumar", email = "raj.pritvi.kumar@gmail.com" }]
+name = 'uplink'
+description = 'A Declarative HTTP Client for Python.'
+readme = 'README.md'
+maintainers = [{ name = 'P. Raj Kumar', email = 'raj.pritvi.kumar@gmail.com' }]
 authors = [
-  { name = "Kareem Moussa" },
-  { name = "Brandon Milton" },
-  { name = "Fabio Rosado" },
-  { name = "Niko Eckerskorn" },
-  { name = "Or Carmi" },
-  { name = "George Kontridze" },
-  { name = "Sean Chambers" },
-  { name = "Nils Philippsen" },
-  { name = "Alexander Duryagin" },
-  { name = "Sakorn Waungwiwatsin" },
-  { name = "Jacob Floyd" },
-  { name = "Guilherme Crocetti" },
-  { name = "Alexander Shadchin" },
-  { name = "Lieser Fernández Gallo", email = "leiserfg@gmail.com" },
+  { name = 'Kareem Moussa' },
+  { name = 'Brandon Milton' },
+  { name = 'Fabio Rosado' },
+  { name = 'Niko Eckerskorn' },
+  { name = 'Or Carmi' },
+  { name = 'George Kontridze' },
+  { name = 'Sean Chambers' },
+  { name = 'Nils Philippsen' },
+  { name = 'Alexander Duryagin' },
+  { name = 'Sakorn Waungwiwatsin' },
+  { name = 'Jacob Floyd' },
+  { name = 'Guilherme Crocetti' },
+  { name = 'Alexander Shadchin' },
+  { name = 'Lieser Fernández Gallo', email = 'leiserfg@gmail.com' },
 ]
-license = { file = "LICENSE" }
-keywords = ["http", "api", "rest", "client", "retrofit"]
-urls = { Repository = "https://github.com/prkumar/uplink" }
+license = { file = 'LICENSE' }
+keywords = ['http', 'api', 'rest', 'client', 'retrofit']
+urls = { Repository = 'https://github.com/prkumar/uplink' }
 classifiers = [
-  "Development Status :: 4 - Beta",
-  "Intended Audience :: Developers",
-  "License :: OSI Approved :: MIT License",
-  "Operating System :: OS Independent",
-  "Programming Language :: Python :: 3.10",
-  "Programming Language :: Python :: 3.11",
-  "Programming Language :: Python :: 3.12",
-  "Programming Language :: Python :: 3.13",
-  "Programming Language :: Python :: 3 :: Only",
-  "Programming Language :: Python :: Implementation :: CPython",
-  "Programming Language :: Python :: Implementation :: PyPy",
-  "Topic :: Software Development :: Libraries",
+  'Development Status :: 4 - Beta',
+  'Intended Audience :: Developers',
+  'License :: OSI Approved :: MIT License',
+  'Operating System :: OS Independent',
+  'Programming Language :: Python :: 3.10',
+  'Programming Language :: Python :: 3.11',
+  'Programming Language :: Python :: 3.12',
+  'Programming Language :: Python :: 3.13',
+  'Programming Language :: Python :: 3 :: Only',
+  'Programming Language :: Python :: Implementation :: CPython',
+  'Programming Language :: Python :: Implementation :: PyPy',
+  'Topic :: Software Development :: Libraries',
 ]
 
-requires-python = ">=3.10"
-dependencies = ["requests>=2.18.0", "six>=1.13.0", "uritemplate>=3.0.0"]
+requires-python = '>=3.10'
+dependencies = ['requests>=2.18.0', 'six>=1.13.0', 'uritemplate>=3.0.0']
+dynamic = ['version']
 
 [dependency-groups]
 test = [
-  "pytest",
-  "pytest-mock",
-  "pytest-cov",
-  "pytest-twisted",
-  "pytest-asyncio",
+  'pytest',
+  'pytest-mock',
+  'pytest-cov',
+  'pytest-twisted',
+  'pytest-asyncio',
 ]
-marshmallow = ["marshmallow>=2.15.0"]
-pydantic = ["pydantic>=2.0.0"]
-aiohttp = ["aiohttp>=3.8.1"]
-twisted = ["twisted>=21.7.0"]
+marshmallow = ['marshmallow>=2.15.0']
+pydantic = ['pydantic>=2.0.0']
+aiohttp = ['aiohttp>=3.8.1']
+twisted = ['twisted>=21.7.0']
 
 [build-system]
-requires = ["hatchling"]
-build-backend = "hatchling.build"
+requires = ['hatchling']
+build-backend = 'hatchling.build'
 
-[tools.pytest]
+[tool.hatch.version]
path: pyproject.toml
user: login: prkumar
body: Good point! I wasn't aware of `importlib.metadata` package. Keeping version in pyproject again, and updated `__version__` to use `importlib.metadata.version`.
created_at: 2025-03-16T08:33:08Z
author_association: OWNER

PR comments:
user: login: leiserfg
created_at: 2025-03-16T06:29:31Z
body: You can do 'uv publish' directly, no needs of involving pip and twine.
```yaml
      - name: Build
        run: uv build

      - name: Publish
        run: uv publish -t ${{ secrets.PYPI_TOKEN }}
```
author_association: COLLABORATOR
user: login: prkumar
created_at: 2025-03-16T08:06:41Z
body: > You can do 'uv publish' directly, no needs of involving pip and twine.
> 
> ```yaml
>       - name: Build
>         run: uv build
> 
>       - name: Publish
>         run: uv publish -t ${{ secrets.PYPI_TOKEN }}
> ```

Huh, good point. I would prefer to [PyPI with a Trusted Publisher](https://docs.pypi.org/trusted-publishers/) but wasn't aware that `uv publish` supported that.
author_association: OWNER
user: login: leiserfg
created_at: 2025-03-16T08:24:36Z
body: > I would prefer to [PyPI with a Trusted Publisher](https://docs.pypi.org/trusted-publishers/)

Uv supports it too, see https://docs.astral.sh/uv/guides/package/#publishing-your-package
author_association: COLLABORATOR
user: login: prkumar
created_at: 2025-03-16T08:32:00Z
body: > Uv supports it too, see https://docs.astral.sh/uv/guides/package/#publishing-your-package

Yep, I found that after you mentioned uv publish. I’ve updated the job config! TY!
author_association: OWNER