From 6085678bf4f5308712dedb41ae13b939c50f1dff Mon Sep 17 00:00:00 2001 From: Scott Florentino <3495150+smflorentino@users.noreply.github.com> Date: Thu, 8 Oct 2026 12:58:15 -0700 Subject: [PATCH 1/4] build: embed source git commit in built package Add a hatchling custom build hook (hatch_build.py) that generates a git-ignored _version.py at build time, following the setuptools-scm / hatch-vcs convention: __version__ and __commit_id__ (aliases version, commit_id). The file ships in both the sdist and the wheel, so an installed package can report the exact commit it was built from. The commit is HEAD of the checkout (only when the project is tracked by it); when building a wheel from an sdist the commit recorded in the sdist is kept. Co-Authored-By: Claude Opus 5.5 --- .gitignore | 5 ++ packages/uipath-core/hatch_build.py | 89 +++++++++++++++++++++++++ packages/uipath-core/pyproject.toml | 8 +++ packages/uipath-platform/hatch_build.py | 89 +++++++++++++++++++++++++ packages/uipath-platform/pyproject.toml | 8 +++ packages/uipath/hatch_build.py | 89 +++++++++++++++++++++++++ packages/uipath/pyproject.toml | 8 +++ 7 files changed, 296 insertions(+) create mode 100644 packages/uipath-core/hatch_build.py create mode 100644 packages/uipath-platform/hatch_build.py create mode 100644 packages/uipath/hatch_build.py diff --git a/.gitignore b/.gitignore index 6b24bbd06..99472b51b 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,8 @@ samples/**/entry-points.json samples/**/uv.lock testcases/**/uv.lock + +# Generated at build time by packages/*/hatch_build.py +packages/uipath-core/src/uipath/core/_version.py +packages/uipath-platform/src/uipath/platform/_version.py +packages/uipath/src/uipath/_version.py diff --git a/packages/uipath-core/hatch_build.py b/packages/uipath-core/hatch_build.py new file mode 100644 index 000000000..3436b1187 --- /dev/null +++ b/packages/uipath-core/hatch_build.py @@ -0,0 +1,89 @@ +"""Hatch build hook that stamps the source git commit into the built package. + +Writes the file named by ``version-file`` in ``[tool.hatch.build.hooks.custom]`` +using the setuptools-scm / hatch-vcs convention (``__version__`` and +``__commit_id__``), so an installed package can report the exact commit it was +built from:: + + from ._version import __commit_id__ + +The file is generated at build time and git-ignored. The commit comes from +``git rev-parse HEAD`` when building from a checkout of this repo. When there is +no checkout (e.g. building a wheel from an sdist), the commit already recorded +in the file is kept. If neither is available, ``__commit_id__`` is ``None``. +""" + +import ast +import subprocess +from pathlib import Path +from typing import Any + +from hatchling.builders.hooks.plugin.interface import BuildHookInterface + +TEMPLATE = '''\ +"""Version and source commit of this build. Generated by hatch_build.py.""" + +__all__ = ["__version__", "__commit_id__", "version", "commit_id"] + +__version__ = version = {version!r} +__commit_id__ = commit_id = {commit_id!r} +''' + + +class CommitIdBuildHook(BuildHookInterface): + """Generate the version file before each build.""" + + PLUGIN_NAME = "custom" + + def initialize(self, version: str, build_data: dict[str, Any]) -> None: + """Write the version file and ship it despite it being git-ignored.""" + relative_path = self.config["version-file"] + version_file = Path(self.root) / relative_path + commit_id = _git_commit(Path(self.root)) or _recorded_commit(version_file) + version_file.write_text( + TEMPLATE.format(version=self.metadata.version, commit_id=commit_id), + encoding="utf-8", + ) + build_data["artifacts"].append(f"/{relative_path}") + + +def _git_commit(root: Path) -> str | None: + """Return HEAD's full SHA if ``root`` is tracked in a git checkout.""" + try: + # Confirms root belongs to this repo, not to an unrelated parent checkout. + subprocess.run( + ["git", "ls-files", "--error-unmatch", "pyproject.toml"], + cwd=root, + check=True, + capture_output=True, + ) + result = subprocess.run( + ["git", "rev-parse", "HEAD"], + cwd=root, + check=True, + capture_output=True, + text=True, + ) + except (OSError, subprocess.CalledProcessError): + return None + return result.stdout.strip() or None + + +def _recorded_commit(version_file: Path) -> str | None: + """Return the commit already in ``version_file`` (e.g. one shipped in an sdist).""" + try: + tree = ast.parse(version_file.read_text(encoding="utf-8")) + except (OSError, SyntaxError): + return None + for node in tree.body: + if ( + isinstance(node, ast.Assign) + and any( + isinstance(t, ast.Name) and t.id == "__commit_id__" + for t in node.targets + ) + and isinstance(node.value, ast.Constant) + and isinstance(node.value.value, str) + ): + return node.value.value + return None diff --git a/packages/uipath-core/pyproject.toml b/packages/uipath-core/pyproject.toml index 80e2327f8..fea8f7d01 100644 --- a/packages/uipath-core/pyproject.toml +++ b/packages/uipath-core/pyproject.toml @@ -46,6 +46,9 @@ dev = [ "pre-commit>=4.1.0", ] +[tool.hatch.build.hooks.custom] +version-file = "src/uipath/core/_version.py" + [tool.hatch.build.targets.wheel] packages = ["src/uipath"] @@ -87,6 +90,11 @@ no_implicit_reexport = true disallow_untyped_defs = false +[[tool.mypy.overrides]] +# hatchling is only installed in the isolated build env (used by hatch_build.py). +module = ["hatchling.*"] +ignore_missing_imports = true + [tool.pydantic-mypy] init_forbid_extra = true init_typed = true diff --git a/packages/uipath-platform/hatch_build.py b/packages/uipath-platform/hatch_build.py new file mode 100644 index 000000000..3436b1187 --- /dev/null +++ b/packages/uipath-platform/hatch_build.py @@ -0,0 +1,89 @@ +"""Hatch build hook that stamps the source git commit into the built package. + +Writes the file named by ``version-file`` in ``[tool.hatch.build.hooks.custom]`` +using the setuptools-scm / hatch-vcs convention (``__version__`` and +``__commit_id__``), so an installed package can report the exact commit it was +built from:: + + from ._version import __commit_id__ + +The file is generated at build time and git-ignored. The commit comes from +``git rev-parse HEAD`` when building from a checkout of this repo. When there is +no checkout (e.g. building a wheel from an sdist), the commit already recorded +in the file is kept. If neither is available, ``__commit_id__`` is ``None``. +""" + +import ast +import subprocess +from pathlib import Path +from typing import Any + +from hatchling.builders.hooks.plugin.interface import BuildHookInterface + +TEMPLATE = '''\ +"""Version and source commit of this build. Generated by hatch_build.py.""" + +__all__ = ["__version__", "__commit_id__", "version", "commit_id"] + +__version__ = version = {version!r} +__commit_id__ = commit_id = {commit_id!r} +''' + + +class CommitIdBuildHook(BuildHookInterface): + """Generate the version file before each build.""" + + PLUGIN_NAME = "custom" + + def initialize(self, version: str, build_data: dict[str, Any]) -> None: + """Write the version file and ship it despite it being git-ignored.""" + relative_path = self.config["version-file"] + version_file = Path(self.root) / relative_path + commit_id = _git_commit(Path(self.root)) or _recorded_commit(version_file) + version_file.write_text( + TEMPLATE.format(version=self.metadata.version, commit_id=commit_id), + encoding="utf-8", + ) + build_data["artifacts"].append(f"/{relative_path}") + + +def _git_commit(root: Path) -> str | None: + """Return HEAD's full SHA if ``root`` is tracked in a git checkout.""" + try: + # Confirms root belongs to this repo, not to an unrelated parent checkout. + subprocess.run( + ["git", "ls-files", "--error-unmatch", "pyproject.toml"], + cwd=root, + check=True, + capture_output=True, + ) + result = subprocess.run( + ["git", "rev-parse", "HEAD"], + cwd=root, + check=True, + capture_output=True, + text=True, + ) + except (OSError, subprocess.CalledProcessError): + return None + return result.stdout.strip() or None + + +def _recorded_commit(version_file: Path) -> str | None: + """Return the commit already in ``version_file`` (e.g. one shipped in an sdist).""" + try: + tree = ast.parse(version_file.read_text(encoding="utf-8")) + except (OSError, SyntaxError): + return None + for node in tree.body: + if ( + isinstance(node, ast.Assign) + and any( + isinstance(t, ast.Name) and t.id == "__commit_id__" + for t in node.targets + ) + and isinstance(node.value, ast.Constant) + and isinstance(node.value.value, str) + ): + return node.value.value + return None diff --git a/packages/uipath-platform/pyproject.toml b/packages/uipath-platform/pyproject.toml index 091bd2284..eaedf130a 100644 --- a/packages/uipath-platform/pyproject.toml +++ b/packages/uipath-platform/pyproject.toml @@ -50,6 +50,9 @@ dev = [ "pre-commit>=4.1.0", ] +[tool.hatch.build.hooks.custom] +version-file = "src/uipath/platform/_version.py" + [tool.hatch.build.targets.wheel] packages = ["src/uipath"] @@ -91,6 +94,11 @@ no_implicit_reexport = true disallow_untyped_defs = false +[[tool.mypy.overrides]] +# hatchling is only installed in the isolated build env (used by hatch_build.py). +module = ["hatchling.*"] +ignore_missing_imports = true + [tool.pydantic-mypy] init_forbid_extra = true init_typed = true diff --git a/packages/uipath/hatch_build.py b/packages/uipath/hatch_build.py new file mode 100644 index 000000000..3436b1187 --- /dev/null +++ b/packages/uipath/hatch_build.py @@ -0,0 +1,89 @@ +"""Hatch build hook that stamps the source git commit into the built package. + +Writes the file named by ``version-file`` in ``[tool.hatch.build.hooks.custom]`` +using the setuptools-scm / hatch-vcs convention (``__version__`` and +``__commit_id__``), so an installed package can report the exact commit it was +built from:: + + from ._version import __commit_id__ + +The file is generated at build time and git-ignored. The commit comes from +``git rev-parse HEAD`` when building from a checkout of this repo. When there is +no checkout (e.g. building a wheel from an sdist), the commit already recorded +in the file is kept. If neither is available, ``__commit_id__`` is ``None``. +""" + +import ast +import subprocess +from pathlib import Path +from typing import Any + +from hatchling.builders.hooks.plugin.interface import BuildHookInterface + +TEMPLATE = '''\ +"""Version and source commit of this build. Generated by hatch_build.py.""" + +__all__ = ["__version__", "__commit_id__", "version", "commit_id"] + +__version__ = version = {version!r} +__commit_id__ = commit_id = {commit_id!r} +''' + + +class CommitIdBuildHook(BuildHookInterface): + """Generate the version file before each build.""" + + PLUGIN_NAME = "custom" + + def initialize(self, version: str, build_data: dict[str, Any]) -> None: + """Write the version file and ship it despite it being git-ignored.""" + relative_path = self.config["version-file"] + version_file = Path(self.root) / relative_path + commit_id = _git_commit(Path(self.root)) or _recorded_commit(version_file) + version_file.write_text( + TEMPLATE.format(version=self.metadata.version, commit_id=commit_id), + encoding="utf-8", + ) + build_data["artifacts"].append(f"/{relative_path}") + + +def _git_commit(root: Path) -> str | None: + """Return HEAD's full SHA if ``root`` is tracked in a git checkout.""" + try: + # Confirms root belongs to this repo, not to an unrelated parent checkout. + subprocess.run( + ["git", "ls-files", "--error-unmatch", "pyproject.toml"], + cwd=root, + check=True, + capture_output=True, + ) + result = subprocess.run( + ["git", "rev-parse", "HEAD"], + cwd=root, + check=True, + capture_output=True, + text=True, + ) + except (OSError, subprocess.CalledProcessError): + return None + return result.stdout.strip() or None + + +def _recorded_commit(version_file: Path) -> str | None: + """Return the commit already in ``version_file`` (e.g. one shipped in an sdist).""" + try: + tree = ast.parse(version_file.read_text(encoding="utf-8")) + except (OSError, SyntaxError): + return None + for node in tree.body: + if ( + isinstance(node, ast.Assign) + and any( + isinstance(t, ast.Name) and t.id == "__commit_id__" + for t in node.targets + ) + and isinstance(node.value, ast.Constant) + and isinstance(node.value.value, str) + ): + return node.value.value + return None diff --git a/packages/uipath/pyproject.toml b/packages/uipath/pyproject.toml index dc3dc5795..4de24822d 100644 --- a/packages/uipath/pyproject.toml +++ b/packages/uipath/pyproject.toml @@ -86,6 +86,9 @@ dev = [ "packaging>=24.0", ] +[tool.hatch.build.hooks.custom] +version-file = "src/uipath/_version.py" + [tool.hatch.build.targets.wheel] packages = ["src/uipath"] include = ["src/uipath/_resources"] @@ -137,6 +140,11 @@ check_untyped_defs = true no_implicit_reexport = true disallow_untyped_defs = false +[[tool.mypy.overrides]] +# hatchling is only installed in the isolated build env (used by hatch_build.py). +module = ["hatchling.*"] +ignore_missing_imports = true + [tool.pydantic-mypy] init_forbid_extra = true init_typed = true From 6e65aaa739636884f44e8956115f6d68e09993c0 Mon Sep 17 00:00:00 2001 From: Scott Florentino <3495150+smflorentino@users.noreply.github.com> Date: Thu, 8 Oct 2026 13:38:28 -0700 Subject: [PATCH 2/4] build: type-check hatch_build.py against real hatchling Add hatchling as a dev dependency instead of exempting it from mypy, and bound the build backend to the same range (hatchling>=1.32,<2) so the version mypy checks against matches the one that runs the hook. Give BuildHookInterface its BuilderConfig type argument, which mypy now requires. uv.lock regenerated with uv 0.12, which also bumps the lockfile format revision (3 -> 5); no existing package versions change. Co-Authored-By: Claude Opus 5.5 --- packages/uipath-core/hatch_build.py | 3 +- packages/uipath-core/pyproject.toml | 8 ++--- packages/uipath-core/uv.lock | 38 ++++++++++++++++++++- packages/uipath-platform/hatch_build.py | 3 +- packages/uipath-platform/pyproject.toml | 8 ++--- packages/uipath-platform/uv.lock | 39 +++++++++++++++++++++- packages/uipath/hatch_build.py | 3 +- packages/uipath/pyproject.toml | 8 ++--- packages/uipath/uv.lock | 44 +++++++++++++++++++++++-- 9 files changed, 128 insertions(+), 26 deletions(-) diff --git a/packages/uipath-core/hatch_build.py b/packages/uipath-core/hatch_build.py index 3436b1187..07699b728 100644 --- a/packages/uipath-core/hatch_build.py +++ b/packages/uipath-core/hatch_build.py @@ -18,6 +18,7 @@ from pathlib import Path from typing import Any +from hatchling.builders.config import BuilderConfig from hatchling.builders.hooks.plugin.interface import BuildHookInterface TEMPLATE = '''\ @@ -30,7 +31,7 @@ ''' -class CommitIdBuildHook(BuildHookInterface): +class CommitIdBuildHook(BuildHookInterface[BuilderConfig]): """Generate the version file before each build.""" PLUGIN_NAME = "custom" diff --git a/packages/uipath-core/pyproject.toml b/packages/uipath-core/pyproject.toml index fea8f7d01..ff62b44e7 100644 --- a/packages/uipath-core/pyproject.toml +++ b/packages/uipath-core/pyproject.toml @@ -28,7 +28,7 @@ Repository = "https://github.com/UiPath/uipath-python" Documentation = "https://uipath.github.io/uipath-python/" [build-system] -requires = ["hatchling"] +requires = ["hatchling>=1.32,<2"] build-backend = "hatchling.build" [dependency-groups] @@ -44,6 +44,7 @@ dev = [ "pytest-cov>=4.1.0", "pytest-mock>=3.11.1", "pre-commit>=4.1.0", + "hatchling>=1.32,<2", ] [tool.hatch.build.hooks.custom] @@ -90,11 +91,6 @@ no_implicit_reexport = true disallow_untyped_defs = false -[[tool.mypy.overrides]] -# hatchling is only installed in the isolated build env (used by hatch_build.py). -module = ["hatchling.*"] -ignore_missing_imports = true - [tool.pydantic-mypy] init_forbid_extra = true init_typed = true diff --git a/packages/uipath-core/uv.lock b/packages/uipath-core/uv.lock index 8cc930b64..73ece3988 100644 --- a/packages/uipath-core/uv.lock +++ b/packages/uipath-core/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.11" [options] @@ -236,6 +236,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] +[[package]] +name = "hatchling" +version = "1.32.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, + { name = "pathspec" }, + { name = "pluggy" }, + { name = "tomlkit" }, + { name = "trove-classifiers" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f6/97/b5312f01a8c6daf729a9d272dd442e0c546dbcc630495788786c4b567ed0/hatchling-1.32.4.tar.gz", hash = "sha256:c4468f73144c054d2aab4ef0f0378c43b9878bf07f8ffd6b79690e970d375f07", size = 58065, upload-time = "2026-09-20T22:48:45.398Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/80/91f51f439c05d4ec4623c22928ce16a938d6d793bf709477830823497859/hatchling-1.32.4-py3-none-any.whl", hash = "sha256:08ecf7548fb48205e7f213d70c71e67b8271b7242093dc3f1da578b42c734a2c", size = 78748, upload-time = "2026-09-20T22:48:44.19Z" }, +] + [[package]] name = "httpcore" version = "1.0.9" @@ -971,6 +987,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size = 14477, upload-time = "2026-01-11T11:22:37.446Z" }, ] +[[package]] +name = "tomlkit" +version = "0.15.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/96/e07752635b98536177fa1f37671c8f3cdde2e724c6bcf6034b2cfb571565/tomlkit-0.15.1.tar.gz", hash = "sha256:e25bbf38843005246210a12982776f27f99cb9be67160e14434d0c0d21ee1e97", size = 180129, upload-time = "2026-07-17T01:48:04.562Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/bc/8c13eb66537dce1d2bd3a57132902f38d0e7f5bb46fa9f4daed9fe9d76ee/tomlkit-0.15.1-py3-none-any.whl", hash = "sha256:177a05aece5a8ca5266fd3c448abb47b8d352f09d477d3ca8332db4d89b24304", size = 49449, upload-time = "2026-07-17T01:48:05.728Z" }, +] + [[package]] name = "trio" version = "0.32.0" @@ -988,6 +1013,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/bf/945d527ff706233636c73880b22c7c953f3faeb9d6c7e2e85bfbfd0134a0/trio-0.32.0-py3-none-any.whl", hash = "sha256:4ab65984ef8370b79a76659ec87aa3a30c5c7c83ff250b4de88c29a8ab6123c5", size = 512030, upload-time = "2025-10-31T07:18:15.885Z" }, ] +[[package]] +name = "trove-classifiers" +version = "2026.9.21.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/93/af436dfaa845cab5d96f0adbc1e4f3730532d37fa249e4eb796fb1d7fc82/trove_classifiers-2026.9.21.13.tar.gz", hash = "sha256:0a9ebc8d4e2f3e8a22848c5258033035bec17a3012ac3fea16dbaa764489eb71", size = 17085, upload-time = "2026-09-21T13:29:07.301Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/81/0da8afb52a71d0a4f2bd3152357b1a441e393b286374802b9d3addab4ab5/trove_classifiers-2026.9.21.13-py3-none-any.whl", hash = "sha256:8b1ff4f9c191b1040b71c37f1e445ab99732911e3cd91de52838453a854d7a17", size = 14232, upload-time = "2026-09-21T13:29:06.123Z" }, +] + [[package]] name = "typing-extensions" version = "4.15.0" @@ -1022,6 +1056,7 @@ dependencies = [ [package.dev-dependencies] dev = [ { name = "bandit" }, + { name = "hatchling" }, { name = "mypy" }, { name = "pre-commit" }, { name = "pytest" }, @@ -1044,6 +1079,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "bandit", specifier = ">=1.8.2" }, + { name = "hatchling", specifier = ">=1.32,<2" }, { name = "mypy", specifier = ">=1.14.1" }, { name = "pre-commit", specifier = ">=4.1.0" }, { name = "pytest", specifier = ">=7.4.0" }, diff --git a/packages/uipath-platform/hatch_build.py b/packages/uipath-platform/hatch_build.py index 3436b1187..07699b728 100644 --- a/packages/uipath-platform/hatch_build.py +++ b/packages/uipath-platform/hatch_build.py @@ -18,6 +18,7 @@ from pathlib import Path from typing import Any +from hatchling.builders.config import BuilderConfig from hatchling.builders.hooks.plugin.interface import BuildHookInterface TEMPLATE = '''\ @@ -30,7 +31,7 @@ ''' -class CommitIdBuildHook(BuildHookInterface): +class CommitIdBuildHook(BuildHookInterface[BuilderConfig]): """Generate the version file before each build.""" PLUGIN_NAME = "custom" diff --git a/packages/uipath-platform/pyproject.toml b/packages/uipath-platform/pyproject.toml index eaedf130a..d726fcbfb 100644 --- a/packages/uipath-platform/pyproject.toml +++ b/packages/uipath-platform/pyproject.toml @@ -32,7 +32,7 @@ Repository = "https://github.com/UiPath/uipath-python" Documentation = "https://uipath.github.io/uipath-python/" [build-system] -requires = ["hatchling"] +requires = ["hatchling>=1.32,<2"] build-backend = "hatchling.build" [dependency-groups] @@ -48,6 +48,7 @@ dev = [ "pytest-cov>=4.1.0", "pytest-mock>=3.11.1", "pre-commit>=4.1.0", + "hatchling>=1.32,<2", ] [tool.hatch.build.hooks.custom] @@ -94,11 +95,6 @@ no_implicit_reexport = true disallow_untyped_defs = false -[[tool.mypy.overrides]] -# hatchling is only installed in the isolated build env (used by hatch_build.py). -module = ["hatchling.*"] -ignore_missing_imports = true - [tool.pydantic-mypy] init_forbid_extra = true init_typed = true diff --git a/packages/uipath-platform/uv.lock b/packages/uipath-platform/uv.lock index 8d7cccdcc..1722c31f1 100644 --- a/packages/uipath-platform/uv.lock +++ b/packages/uipath-platform/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.11" [options] @@ -239,6 +239,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] +[[package]] +name = "hatchling" +version = "1.32.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, + { name = "pathspec" }, + { name = "pluggy" }, + { name = "tomlkit" }, + { name = "trove-classifiers" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f6/97/b5312f01a8c6daf729a9d272dd442e0c546dbcc630495788786c4b567ed0/hatchling-1.32.4.tar.gz", hash = "sha256:c4468f73144c054d2aab4ef0f0378c43b9878bf07f8ffd6b79690e970d375f07", size = 58065, upload-time = "2026-09-20T22:48:45.398Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/80/91f51f439c05d4ec4623c22928ce16a938d6d793bf709477830823497859/hatchling-1.32.4-py3-none-any.whl", hash = "sha256:08ecf7548fb48205e7f213d70c71e67b8271b7242093dc3f1da578b42c734a2c", size = 78748, upload-time = "2026-09-20T22:48:44.19Z" }, +] + [[package]] name = "httpcore" version = "1.0.9" @@ -1014,6 +1030,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size = 14477, upload-time = "2026-01-11T11:22:37.446Z" }, ] +[[package]] +name = "tomlkit" +version = "0.15.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/96/e07752635b98536177fa1f37671c8f3cdde2e724c6bcf6034b2cfb571565/tomlkit-0.15.1.tar.gz", hash = "sha256:e25bbf38843005246210a12982776f27f99cb9be67160e14434d0c0d21ee1e97", size = 180129, upload-time = "2026-07-17T01:48:04.562Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/bc/8c13eb66537dce1d2bd3a57132902f38d0e7f5bb46fa9f4daed9fe9d76ee/tomlkit-0.15.1-py3-none-any.whl", hash = "sha256:177a05aece5a8ca5266fd3c448abb47b8d352f09d477d3ca8332db4d89b24304", size = 49449, upload-time = "2026-07-17T01:48:05.728Z" }, +] + [[package]] name = "trio" version = "0.33.0" @@ -1031,6 +1056,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1c/93/dab25dc87ac48da0fe0f6419e07d0bfd98799bed4e05e7b9e0f85a1a4b4b/trio-0.33.0-py3-none-any.whl", hash = "sha256:3bd5d87f781d9b0192d592aef28691f8951d6c2e41b7e1da4c25cde6c180ae9b", size = 510294, upload-time = "2026-02-14T18:40:53.313Z" }, ] +[[package]] +name = "trove-classifiers" +version = "2026.9.21.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/93/af436dfaa845cab5d96f0adbc1e4f3730532d37fa249e4eb796fb1d7fc82/trove_classifiers-2026.9.21.13.tar.gz", hash = "sha256:0a9ebc8d4e2f3e8a22848c5258033035bec17a3012ac3fea16dbaa764489eb71", size = 17085, upload-time = "2026-09-21T13:29:07.301Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/81/0da8afb52a71d0a4f2bd3152357b1a441e393b286374802b9d3addab4ab5/trove_classifiers-2026.9.21.13-py3-none-any.whl", hash = "sha256:8b1ff4f9c191b1040b71c37f1e445ab99732911e3cd91de52838453a854d7a17", size = 14232, upload-time = "2026-09-21T13:29:06.123Z" }, +] + [[package]] name = "truststore" version = "0.10.4" @@ -1081,6 +1115,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "bandit", specifier = ">=1.8.2" }, + { name = "hatchling", specifier = ">=1.32,<2" }, { name = "mypy", specifier = ">=1.14.1" }, { name = "pre-commit", specifier = ">=4.1.0" }, { name = "pytest", specifier = ">=7.4.0" }, @@ -1110,6 +1145,7 @@ dependencies = [ [package.dev-dependencies] dev = [ { name = "bandit" }, + { name = "hatchling" }, { name = "mypy" }, { name = "pre-commit" }, { name = "pytest" }, @@ -1136,6 +1172,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "bandit", specifier = ">=1.8.2" }, + { name = "hatchling", specifier = ">=1.32,<2" }, { name = "mypy", specifier = ">=1.19.0" }, { name = "pre-commit", specifier = ">=4.1.0" }, { name = "pytest", specifier = ">=7.4.0" }, diff --git a/packages/uipath/hatch_build.py b/packages/uipath/hatch_build.py index 3436b1187..07699b728 100644 --- a/packages/uipath/hatch_build.py +++ b/packages/uipath/hatch_build.py @@ -18,6 +18,7 @@ from pathlib import Path from typing import Any +from hatchling.builders.config import BuilderConfig from hatchling.builders.hooks.plugin.interface import BuildHookInterface TEMPLATE = '''\ @@ -30,7 +31,7 @@ ''' -class CommitIdBuildHook(BuildHookInterface): +class CommitIdBuildHook(BuildHookInterface[BuilderConfig]): """Generate the version file before each build.""" PLUGIN_NAME = "custom" diff --git a/packages/uipath/pyproject.toml b/packages/uipath/pyproject.toml index 4de24822d..4a5d86306 100644 --- a/packages/uipath/pyproject.toml +++ b/packages/uipath/pyproject.toml @@ -52,7 +52,7 @@ uipath = "uipath._cli:cli" ipc = ["uipath-ipc>=2.5.1,<2.6.0"] [build-system] -requires = ["hatchling"] +requires = ["hatchling>=1.32,<2"] build-backend = "hatchling.build" [dependency-groups] @@ -84,6 +84,7 @@ dev = [ "types-PyYAML>=6.0", "pytest-timeout>=2.4.0", "packaging>=24.0", + "hatchling>=1.32,<2", ] [tool.hatch.build.hooks.custom] @@ -140,11 +141,6 @@ check_untyped_defs = true no_implicit_reexport = true disallow_untyped_defs = false -[[tool.mypy.overrides]] -# hatchling is only installed in the isolated build env (used by hatch_build.py). -module = ["hatchling.*"] -ignore_missing_imports = true - [tool.pydantic-mypy] init_forbid_extra = true init_typed = true diff --git a/packages/uipath/uv.lock b/packages/uipath/uv.lock index eb6d18ede..16b43259d 100644 --- a/packages/uipath/uv.lock +++ b/packages/uipath/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.11" [options] @@ -7,10 +7,10 @@ exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for exclude-newer-span = "P2D" [options.exclude-newer-package] +uipath-core = false uipath-ipc = false -uipath-runtime = false uipath-platform = false -uipath-core = false +uipath-runtime = false [[package]] name = "aiohappyeyeballs" @@ -797,6 +797,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] +[[package]] +name = "hatchling" +version = "1.32.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, + { name = "pathspec" }, + { name = "pluggy" }, + { name = "tomlkit" }, + { name = "trove-classifiers" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f6/97/b5312f01a8c6daf729a9d272dd442e0c546dbcc630495788786c4b567ed0/hatchling-1.32.4.tar.gz", hash = "sha256:c4468f73144c054d2aab4ef0f0378c43b9878bf07f8ffd6b79690e970d375f07", size = 58065, upload-time = "2026-09-20T22:48:45.398Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/80/91f51f439c05d4ec4623c22928ce16a938d6d793bf709477830823497859/hatchling-1.32.4-py3-none-any.whl", hash = "sha256:08ecf7548fb48205e7f213d70c71e67b8271b7242093dc3f1da578b42c734a2c", size = 78748, upload-time = "2026-09-20T22:48:44.19Z" }, +] + [[package]] name = "httpcore" version = "1.0.9" @@ -2532,6 +2548,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675, upload-time = "2025-01-15T12:07:22.074Z" }, ] +[[package]] +name = "tomlkit" +version = "0.15.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/96/e07752635b98536177fa1f37671c8f3cdde2e724c6bcf6034b2cfb571565/tomlkit-0.15.1.tar.gz", hash = "sha256:e25bbf38843005246210a12982776f27f99cb9be67160e14434d0c0d21ee1e97", size = 180129, upload-time = "2026-07-17T01:48:04.562Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/bc/8c13eb66537dce1d2bd3a57132902f38d0e7f5bb46fa9f4daed9fe9d76ee/tomlkit-0.15.1-py3-none-any.whl", hash = "sha256:177a05aece5a8ca5266fd3c448abb47b8d352f09d477d3ca8332db4d89b24304", size = 49449, upload-time = "2026-07-17T01:48:05.728Z" }, +] + [[package]] name = "trio" version = "0.32.0" @@ -2549,6 +2574,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/bf/945d527ff706233636c73880b22c7c953f3faeb9d6c7e2e85bfbfd0134a0/trio-0.32.0-py3-none-any.whl", hash = "sha256:4ab65984ef8370b79a76659ec87aa3a30c5c7c83ff250b4de88c29a8ab6123c5", size = 512030, upload-time = "2025-10-31T07:18:15.885Z" }, ] +[[package]] +name = "trove-classifiers" +version = "2026.9.21.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/93/af436dfaa845cab5d96f0adbc1e4f3730532d37fa249e4eb796fb1d7fc82/trove_classifiers-2026.9.21.13.tar.gz", hash = "sha256:0a9ebc8d4e2f3e8a22848c5258033035bec17a3012ac3fea16dbaa764489eb71", size = 17085, upload-time = "2026-09-21T13:29:07.301Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/81/0da8afb52a71d0a4f2bd3152357b1a441e393b286374802b9d3addab4ab5/trove_classifiers-2026.9.21.13-py3-none-any.whl", hash = "sha256:8b1ff4f9c191b1040b71c37f1e445ab99732911e3cd91de52838453a854d7a17", size = 14232, upload-time = "2026-09-21T13:29:06.123Z" }, +] + [[package]] name = "truststore" version = "0.10.4" @@ -2634,6 +2668,7 @@ ipc = [ dev = [ { name = "bandit" }, { name = "filelock" }, + { name = "hatchling" }, { name = "inflection" }, { name = "mkdocs" }, { name = "mkdocs-click" }, @@ -2692,6 +2727,7 @@ provides-extras = ["ipc"] dev = [ { name = "bandit", specifier = ">=1.8.2" }, { name = "filelock", specifier = ">=3.20.3" }, + { name = "hatchling", specifier = ">=1.32,<2" }, { name = "inflection", specifier = ">=0.5.1" }, { name = "mkdocs", specifier = ">=1.6.1" }, { name = "mkdocs-click", specifier = ">=0.9.0" }, @@ -2739,6 +2775,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "bandit", specifier = ">=1.8.2" }, + { name = "hatchling", specifier = ">=1.32,<2" }, { name = "mypy", specifier = ">=1.14.1" }, { name = "pre-commit", specifier = ">=4.1.0" }, { name = "pytest", specifier = ">=7.4.0" }, @@ -2788,6 +2825,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "bandit", specifier = ">=1.8.2" }, + { name = "hatchling", specifier = ">=1.32,<2" }, { name = "mypy", specifier = ">=1.19.0" }, { name = "pre-commit", specifier = ">=4.1.0" }, { name = "pytest", specifier = ">=7.4.0" }, From c81692eb15bd6f71402e4f1313f5682309bf9c34 Mon Sep 17 00:00:00 2001 From: Scott Florentino <3495150+smflorentino@users.noreply.github.com> Date: Thu, 8 Oct 2026 13:40:31 -0700 Subject: [PATCH 3/4] build: drop hatchling version bounds The hook works on any recent hatchling (checked 1.18 through 1.32), isolated builds always fetch the latest, and uv.lock already pins the dev version, so the bounds added nothing. build-system requires is back to its original form. Co-Authored-By: Claude Opus 5.5 --- packages/uipath-core/pyproject.toml | 4 ++-- packages/uipath-core/uv.lock | 2 +- packages/uipath-platform/pyproject.toml | 4 ++-- packages/uipath-platform/uv.lock | 4 ++-- packages/uipath/pyproject.toml | 4 ++-- packages/uipath/uv.lock | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/uipath-core/pyproject.toml b/packages/uipath-core/pyproject.toml index ff62b44e7..5094bd590 100644 --- a/packages/uipath-core/pyproject.toml +++ b/packages/uipath-core/pyproject.toml @@ -28,7 +28,7 @@ Repository = "https://github.com/UiPath/uipath-python" Documentation = "https://uipath.github.io/uipath-python/" [build-system] -requires = ["hatchling>=1.32,<2"] +requires = ["hatchling"] build-backend = "hatchling.build" [dependency-groups] @@ -44,7 +44,7 @@ dev = [ "pytest-cov>=4.1.0", "pytest-mock>=3.11.1", "pre-commit>=4.1.0", - "hatchling>=1.32,<2", + "hatchling", ] [tool.hatch.build.hooks.custom] diff --git a/packages/uipath-core/uv.lock b/packages/uipath-core/uv.lock index 73ece3988..0ddd5b14b 100644 --- a/packages/uipath-core/uv.lock +++ b/packages/uipath-core/uv.lock @@ -1079,7 +1079,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "bandit", specifier = ">=1.8.2" }, - { name = "hatchling", specifier = ">=1.32,<2" }, + { name = "hatchling" }, { name = "mypy", specifier = ">=1.14.1" }, { name = "pre-commit", specifier = ">=4.1.0" }, { name = "pytest", specifier = ">=7.4.0" }, diff --git a/packages/uipath-platform/pyproject.toml b/packages/uipath-platform/pyproject.toml index d726fcbfb..837d1b9a7 100644 --- a/packages/uipath-platform/pyproject.toml +++ b/packages/uipath-platform/pyproject.toml @@ -32,7 +32,7 @@ Repository = "https://github.com/UiPath/uipath-python" Documentation = "https://uipath.github.io/uipath-python/" [build-system] -requires = ["hatchling>=1.32,<2"] +requires = ["hatchling"] build-backend = "hatchling.build" [dependency-groups] @@ -48,7 +48,7 @@ dev = [ "pytest-cov>=4.1.0", "pytest-mock>=3.11.1", "pre-commit>=4.1.0", - "hatchling>=1.32,<2", + "hatchling", ] [tool.hatch.build.hooks.custom] diff --git a/packages/uipath-platform/uv.lock b/packages/uipath-platform/uv.lock index 1722c31f1..01e6e5959 100644 --- a/packages/uipath-platform/uv.lock +++ b/packages/uipath-platform/uv.lock @@ -1115,7 +1115,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "bandit", specifier = ">=1.8.2" }, - { name = "hatchling", specifier = ">=1.32,<2" }, + { name = "hatchling" }, { name = "mypy", specifier = ">=1.14.1" }, { name = "pre-commit", specifier = ">=4.1.0" }, { name = "pytest", specifier = ">=7.4.0" }, @@ -1172,7 +1172,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "bandit", specifier = ">=1.8.2" }, - { name = "hatchling", specifier = ">=1.32,<2" }, + { name = "hatchling" }, { name = "mypy", specifier = ">=1.19.0" }, { name = "pre-commit", specifier = ">=4.1.0" }, { name = "pytest", specifier = ">=7.4.0" }, diff --git a/packages/uipath/pyproject.toml b/packages/uipath/pyproject.toml index 4a5d86306..8da24ac3f 100644 --- a/packages/uipath/pyproject.toml +++ b/packages/uipath/pyproject.toml @@ -52,7 +52,7 @@ uipath = "uipath._cli:cli" ipc = ["uipath-ipc>=2.5.1,<2.6.0"] [build-system] -requires = ["hatchling>=1.32,<2"] +requires = ["hatchling"] build-backend = "hatchling.build" [dependency-groups] @@ -84,7 +84,7 @@ dev = [ "types-PyYAML>=6.0", "pytest-timeout>=2.4.0", "packaging>=24.0", - "hatchling>=1.32,<2", + "hatchling", ] [tool.hatch.build.hooks.custom] diff --git a/packages/uipath/uv.lock b/packages/uipath/uv.lock index 16b43259d..362f2b9c6 100644 --- a/packages/uipath/uv.lock +++ b/packages/uipath/uv.lock @@ -2727,7 +2727,7 @@ provides-extras = ["ipc"] dev = [ { name = "bandit", specifier = ">=1.8.2" }, { name = "filelock", specifier = ">=3.20.3" }, - { name = "hatchling", specifier = ">=1.32,<2" }, + { name = "hatchling" }, { name = "inflection", specifier = ">=0.5.1" }, { name = "mkdocs", specifier = ">=1.6.1" }, { name = "mkdocs-click", specifier = ">=0.9.0" }, @@ -2775,7 +2775,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "bandit", specifier = ">=1.8.2" }, - { name = "hatchling", specifier = ">=1.32,<2" }, + { name = "hatchling" }, { name = "mypy", specifier = ">=1.14.1" }, { name = "pre-commit", specifier = ">=4.1.0" }, { name = "pytest", specifier = ">=7.4.0" }, @@ -2825,7 +2825,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "bandit", specifier = ">=1.8.2" }, - { name = "hatchling", specifier = ">=1.32,<2" }, + { name = "hatchling" }, { name = "mypy", specifier = ">=1.19.0" }, { name = "pre-commit", specifier = ">=4.1.0" }, { name = "pytest", specifier = ">=7.4.0" }, From f51f9c3e6ee62243b1859b8f59c51f2b7c525c93 Mon Sep 17 00:00:00 2001 From: Scott Florentino <3495150+smflorentino@users.noreply.github.com> Date: Thu, 8 Oct 2026 13:41:46 -0700 Subject: [PATCH 4/4] chore: bump version so the next release carries the commit id Co-Authored-By: Claude Opus 5.5 --- packages/uipath-core/pyproject.toml | 2 +- packages/uipath-core/uv.lock | 2 +- packages/uipath-platform/pyproject.toml | 2 +- packages/uipath-platform/uv.lock | 4 ++-- packages/uipath/pyproject.toml | 2 +- packages/uipath/uv.lock | 6 +++--- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/uipath-core/pyproject.toml b/packages/uipath-core/pyproject.toml index 5094bd590..56209a35e 100644 --- a/packages/uipath-core/pyproject.toml +++ b/packages/uipath-core/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "uipath-core" -version = "0.5.33" +version = "0.5.34" description = "UiPath Core abstractions" readme = { file = "README.md", content-type = "text/markdown" } requires-python = ">=3.11" diff --git a/packages/uipath-core/uv.lock b/packages/uipath-core/uv.lock index 0ddd5b14b..11fc0ced3 100644 --- a/packages/uipath-core/uv.lock +++ b/packages/uipath-core/uv.lock @@ -1045,7 +1045,7 @@ wheels = [ [[package]] name = "uipath-core" -version = "0.5.33" +version = "0.5.34" source = { editable = "." } dependencies = [ { name = "opentelemetry-instrumentation" }, diff --git a/packages/uipath-platform/pyproject.toml b/packages/uipath-platform/pyproject.toml index 837d1b9a7..8c4bd9898 100644 --- a/packages/uipath-platform/pyproject.toml +++ b/packages/uipath-platform/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "uipath-platform" -version = "0.2.34" +version = "0.2.35" description = "HTTP client library for programmatic access to UiPath Platform" readme = { file = "README.md", content-type = "text/markdown" } requires-python = ">=3.11" diff --git a/packages/uipath-platform/uv.lock b/packages/uipath-platform/uv.lock index 01e6e5959..3f17d07fc 100644 --- a/packages/uipath-platform/uv.lock +++ b/packages/uipath-platform/uv.lock @@ -1097,7 +1097,7 @@ wheels = [ [[package]] name = "uipath-core" -version = "0.5.33" +version = "0.5.34" source = { editable = "../uipath-core" } dependencies = [ { name = "opentelemetry-instrumentation" }, @@ -1130,7 +1130,7 @@ dev = [ [[package]] name = "uipath-platform" -version = "0.2.34" +version = "0.2.35" source = { editable = "." } dependencies = [ { name = "anyio" }, diff --git a/packages/uipath/pyproject.toml b/packages/uipath/pyproject.toml index 8da24ac3f..a60a2bfe9 100644 --- a/packages/uipath/pyproject.toml +++ b/packages/uipath/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "uipath" -version = "2.14.36" +version = "2.14.37" description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools." readme = { file = "README.md", content-type = "text/markdown" } requires-python = ">=3.11" diff --git a/packages/uipath/uv.lock b/packages/uipath/uv.lock index 362f2b9c6..86f270d97 100644 --- a/packages/uipath/uv.lock +++ b/packages/uipath/uv.lock @@ -2633,7 +2633,7 @@ wheels = [ [[package]] name = "uipath" -version = "2.14.36" +version = "2.14.37" source = { editable = "." } dependencies = [ { name = "applicationinsights" }, @@ -2757,7 +2757,7 @@ dev = [ [[package]] name = "uipath-core" -version = "0.5.33" +version = "0.5.34" source = { editable = "../uipath-core" } dependencies = [ { name = "opentelemetry-instrumentation" }, @@ -2799,7 +2799,7 @@ wheels = [ [[package]] name = "uipath-platform" -version = "0.2.34" +version = "0.2.35" source = { editable = "../uipath-platform" } dependencies = [ { name = "anyio" },