diff --git a/.bumpversion.cfg b/.bumpversion.cfg index b0b2f33..f82f2c5 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,8 +1,8 @@ [bumpversion] -current_version = 0.1.8 +current_version = 0.1.9 commit = True tag = True -message = "Bump version: {current_version} → {new_version} [skip ci]" +message = "Bump version: {current_version} → {new_version} [publish]" [bumpversion:file:setup.py] search = version="{current_version}" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index cee962a..01a0ecc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,7 +7,7 @@ on: jobs: publish: - if: github.actor != 'github-actions[bot]' + if: github.actor != 'github-actions[bot]' && contains(github.event.head_commit.message, '[publish]') runs-on: ubuntu-latest permissions: @@ -28,40 +28,11 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install setuptools wheel twine bump2version - - - name: Configure Git - run: | - git config --global user.email "grafuls@gmail.com" - git config --global user.name "Your Name" - - - name: Bump version - run: | - # Keep bumping until we find a version without an existing tag - for i in {1..10}; do - NEW_VERSION=$(bump2version --dry-run --list patch | grep new_version | sed -r 's/^.*=//') - if git rev-parse "v${NEW_VERSION}" >/dev/null 2>&1; then - echo "Tag v${NEW_VERSION} already exists, bumping past it..." - bump2version patch --no-tag --no-commit --allow-dirty - else - echo "Bumping to v${NEW_VERSION}" - bump2version patch - break - fi - done + pip install setuptools wheel twine - name: Build package run: python setup.py sdist bdist_wheel - - name: Sync changes with all branches - run: | - git checkout latest - git pull origin latest --rebase - git push origin latest - git checkout development - git merge latest - git push origin development - - name: Publish package env: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 3173008..e53f504 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -73,6 +73,16 @@ For merging, you should: 3. Add a note to ``CHANGELOG.rst`` about the changes. 4. Add yourself to ``AUTHORS.rst``. +Release Process +=============== + +To release a new version, run the following command:: + + bumpversion patch + +This will increment the version number and commit the changes. + + Tips ---- diff --git a/docs/conf.py b/docs/conf.py index 3625d9a..924206a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,7 +15,7 @@ year = "2025" author = "Gonzalo Rafuls" copyright = f"{year}, {author}" -version = release = "0.1.8" +version = release = "0.1.9" pygments_style = "trac" templates_path = ["."] diff --git a/setup.py b/setup.py index 000f906..ef1813d 100755 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ def read(*names, **kwargs): setup( name="quads-lib", - version="0.1.8", + version="0.1.9", license="LGPL-3.0-only", description="Python client library for interacting with the QUADS API", long_description="{}\n{}".format( diff --git a/src/quads_lib/__init__.py b/src/quads_lib/__init__.py index 32d45c8..0526669 100644 --- a/src/quads_lib/__init__.py +++ b/src/quads_lib/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.1.8" +__version__ = "0.1.9" from .quads import QuadsApi diff --git a/src/quads_lib/base.py b/src/quads_lib/base.py index 0f6ae35..790b973 100644 --- a/src/quads_lib/base.py +++ b/src/quads_lib/base.py @@ -32,7 +32,8 @@ def __init__( password: Password for QUADS authentication base_url: Base URL for the QUADS API verify: Controls TLS certificate verification. Can be: - - False: Disable certificate verification (default, for backward compatibility) + - False: Disable certificate verification (default, for + backward compatibility) - True: Enable verification using default CA bundle - str: Path to a custom CA bundle file """ diff --git a/src/quads_lib/quads.py b/src/quads_lib/quads.py index 591801d..931d814 100644 --- a/src/quads_lib/quads.py +++ b/src/quads_lib/quads.py @@ -1,6 +1,5 @@ from pathlib import Path from typing import Optional -from urllib import parse as url_parse from urllib.parse import urlencode from urllib.parse import urljoin @@ -15,7 +14,11 @@ class QuadsApi(QuadsBase): # Auth def register(self) -> dict: - json_response = self._make_request("POST", "register", {"email": self.username, "password": self.password}) + json_response = self._make_request( + "POST", + "register", + {"email": self.username, "password": self.password}, + ) return json_response def login(self) -> dict: @@ -46,19 +49,19 @@ def get_host_models(self) -> dict: @returns("List[Host]") def filter_hosts(self, data: dict) -> dict: - url_params = url_parse.urlencode(data) + url_params = urlencode(data) json_response = self.get(f"hosts?{url_params}") return json_response @returns("List[Cloud]") def filter_clouds(self, data: dict) -> dict: - url_params = url_parse.urlencode(data) + url_params = urlencode(data) json_response = self.get(f"clouds?{url_params}") return json_response @returns("List[Assignment]") def filter_assignments(self, data: dict) -> dict: - url_params = url_parse.urlencode(data) + url_params = urlencode(data) json_response = self.get(f"assignments?{url_params}") return json_response @@ -85,10 +88,10 @@ def remove_host(self, hostname: str) -> dict: return json_response def is_available(self, hostname: str, data: dict) -> bool: - url_params = url_parse.urlencode(data) + url_params = urlencode(data) endpoint = Path("available") / hostname json_response = self.get(f"{endpoint}?{url_params}") - return True if "true" in json_response else False + return "true" in json_response # Clouds @returns("List[Cloud]") @@ -107,7 +110,7 @@ def get_cloud(self, cloud_name: str) -> dict: return json_response def get_summary(self, data: dict) -> dict: - url_params = url_parse.urlencode(data) + url_params = urlencode(data) endpoint = Path("clouds") / "summary" url = f"{endpoint}" if data: @@ -135,7 +138,7 @@ def remove_cloud(self, cloud_name: str) -> dict: def get_schedules(self, data: Optional[dict] = None) -> dict: if data is None: data = {} - url_params = url_parse.urlencode(data) + url_params = urlencode(data) url = "schedules" if url_params: url = f"{url}?{url_params}" @@ -149,7 +152,7 @@ def get_current_schedules(self, data: Optional[dict] = None) -> dict: endpoint = Path("schedules") / "current" url = f"{endpoint}" if data: - url_params = url_parse.urlencode(data) + url_params = urlencode(data) url = f"{endpoint}?{url_params}" json_response = self.get(url) return json_response @@ -164,7 +167,7 @@ def get_schedule(self, schedule_id: int) -> dict: def get_future_schedules(self, data: Optional[dict] = None) -> dict: if data is None: data = {} - url_params = url_parse.urlencode(data) + url_params = urlencode(data) endpoint = Path("schedules") / "future" url = f"{endpoint}" if data: @@ -279,7 +282,7 @@ def create_memory(self, hostname: str, data: dict) -> dict: return json_response def remove_memory(self, memory_id: int) -> dict: - endpoint = Path("memory") / memory_id + endpoint = Path("memory") / str(memory_id) json_response = self.delete(str(endpoint)) return json_response @@ -297,7 +300,7 @@ def update_disk(self, hostname: str, data: dict) -> dict: return json_response def remove_disk(self, hostname: str, disk_id: int) -> dict: - endpoint = Path("disks") / hostname / disk_id + endpoint = Path("disks") / hostname / str(disk_id) json_response = self.delete(str(endpoint)) return json_response @@ -309,11 +312,10 @@ def create_processor(self, hostname: str, data: dict) -> dict: return json_response def remove_processor(self, processor_id: int) -> dict: - endpoint = Path("processors") / processor_id + endpoint = Path("processors") / str(processor_id) json_response = self.delete(str(endpoint)) return json_response - # Vlans @returns("List[Vlan]") def get_vlans(self) -> dict: json_response = self.get("vlans") @@ -345,7 +347,7 @@ def create_vlan(self, data: dict) -> dict: def get_moves(self, date: Optional[str] = None) -> dict: url = "moves" if date: - url_params = url_parse.urlencode({"date": date}) + url_params = urlencode({"date": date}) url = f"moves?{url_params}" json_response = self.get(url) return json_response