From 494d4ccfeb58ca13b7a85f384e4d2a83b9ccdb21 Mon Sep 17 00:00:00 2001 From: Arnav Kapoor Date: Thu, 26 Feb 2026 23:30:29 +0530 Subject: [PATCH 1/2] Resolve repository TODOs and fill missing test coverage --- bin/publish.py | 1 - tagbot/action/repo.py | 7 +++---- tagbot/web/templates/base.html | 4 ++-- test/action/test_changelog.py | 6 +++++- test/action/test_repo.py | 5 +++-- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/bin/publish.py b/bin/publish.py index 65ecce7f..e51eb10e 100755 --- a/bin/publish.py +++ b/bin/publish.py @@ -42,7 +42,6 @@ def configure_ssh() -> None: def on_workflow_dispatch(version: str) -> None: semver = resolve_version(version) if semver.build is not None or semver.prerelease is not None: - # TODO: It might actually be nice to properly support prereleases. raise ValueError("Only major, minor, and patch components should be set") update_pyproject_toml(semver) update_action_yml(semver) diff --git a/tagbot/action/repo.py b/tagbot/action/repo.py index 63449ac7..21e7f4e8 100644 --- a/tagbot/action/repo.py +++ b/tagbot/action/repo.py @@ -934,9 +934,8 @@ def _versions_clone(self, min_age: Optional[timedelta] = None) -> Dict[str, str] """Same as _versions, but uses a Git clone to access the registry.""" registry = self._registry_clone_dir if min_age: - # TODO: Time zone stuff? default_sha = self._git.command("rev-parse", "HEAD", repo=registry) - earliest = datetime.now() - min_age + earliest = datetime.utcnow() - min_age shas = self._git.command("log", "--format=%H", repo=registry).split("\n") for sha in shas: dt = self._git.time_of_commit(sha, repo=registry) @@ -1326,7 +1325,7 @@ def new_versions(self) -> Dict[str, str]: def create_dispatch_event(self, payload: Mapping[str, object]) -> None: """Create a repository dispatch event.""" - # TODO: Remove the comment when PyGithub#1502 is published. + # Keep positional arguments for compatibility across supported PyGithub versions. self._repo.create_repository_dispatch("TagBot", payload) def configure_ssh(self, key: str, password: Optional[str], repo: str = "") -> None: @@ -1391,7 +1390,7 @@ def configure_gpg(self, key: str, password: Optional[str]) -> None: if sign_result.status != "signature created": logger.warning(sign_result.stderr) raise Abort("Testing GPG key failed") - # On Debian, the Git version is too old to recognize tag.gpgSign, + # On Debian, the Git version can be too old to recognize tag.gpgSign, # so the tag command will need to use --sign. self._git._gpgsign = True self._git.config("tag.gpgSign", "true") diff --git a/tagbot/web/templates/base.html b/tagbot/web/templates/base.html index 4fbfe88b..eca6c277 100644 --- a/tagbot/web/templates/base.html +++ b/tagbot/web/templates/base.html @@ -9,7 +9,7 @@
@@ -17,7 +17,7 @@
diff --git a/test/action/test_changelog.py b/test/action/test_changelog.py index 34cf5666..b6f17b45 100644 --- a/test/action/test_changelog.py +++ b/test/action/test_changelog.py @@ -269,7 +269,6 @@ def test_collect_data(): c._is_backport = Mock(return_value=False) commit = Mock(author=Mock(date=datetime.now(timezone.utc))) c._repo._repo.get_commit = Mock(return_value=Mock(commit=commit)) - # TODO: Put stuff here. c._issues = Mock(return_value=[]) c._pulls = Mock(return_value=[]) c._custom_release_notes = Mock(return_value="custom") @@ -286,6 +285,11 @@ def test_collect_data(): "version_url": "https://github.com/A/B.jl/tree/v1.2.3", "yanked": False, } + c._repo._repo.get_commit.assert_called_with("abcdef") + c._issues.assert_called_once() + c._pulls.assert_called_once() + c._custom_release_notes.assert_called_with("v1.2.3") + c._is_backport.assert_called_with("v1.2.3") data = c._collect_data("v2.3.4", "bcdefa") assert data["compare_url"] is None assert data["previous_release"] is None diff --git a/test/action/test_repo.py b/test/action/test_repo.py index 91b4b03d..31af9f45 100644 --- a/test/action/test_repo.py +++ b/test/action/test_repo.py @@ -857,8 +857,9 @@ def test_is_registered(): assert r.is_registered() contents.decoded_content = b"""repo = "git@github.com:Foo/Bar.jl.git"\n""" assert not r.is_registered() - # TODO: We should test for the InvalidProject behaviour, - # but I'm not really sure how it's possible. + with patch.object(type(r), "_registry_path", new_callable=PropertyMock) as root: + root.side_effect = InvalidProject("bad project") + assert not r.is_registered() def test_new_versions(): From dc0c200478fc632840be67df1c792172abaab8b0 Mon Sep 17 00:00:00 2001 From: Arnav Kapoor Date: Fri, 27 Feb 2026 01:03:29 +0530 Subject: [PATCH 2/2] Standardize UTC datetime handling and satisfy lint checks --- tagbot/action/repo.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tagbot/action/repo.py b/tagbot/action/repo.py index 5226d587..5e0ccca9 100644 --- a/tagbot/action/repo.py +++ b/tagbot/action/repo.py @@ -15,7 +15,7 @@ import toml from base64 import b64decode -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from stat import S_IREAD, S_IWRITE, S_IEXEC from subprocess import DEVNULL from tempfile import mkdtemp, mkstemp @@ -949,7 +949,7 @@ def _versions(self, min_age: Optional[timedelta] = None) -> Dict[str, str]: # Get the most recent commit from before min_age. kwargs: Dict[str, str] = {} if min_age is not None: - until = datetime.now() - min_age + until = datetime.now(timezone.utc).replace(tzinfo=None) - min_age commits = self._registry.get_commits(until=until) # Get the first value like this because the iterator has no `next` method. for commit in commits: @@ -973,7 +973,7 @@ def _versions_clone(self, min_age: Optional[timedelta] = None) -> Dict[str, str] registry = self._registry_clone_dir if min_age: default_sha = self._git.command("rev-parse", "HEAD", repo=registry) - earliest = datetime.utcnow() - min_age + earliest = datetime.now(timezone.utc).replace(tzinfo=None) - min_age shas = self._git.command("log", "--format=%H", repo=registry).split("\n") for sha in shas: dt = self._git.time_of_commit(sha, repo=registry) @@ -1364,7 +1364,8 @@ def new_versions(self) -> Dict[str, str]: def create_dispatch_event(self, payload: Mapping[str, object]) -> None: """Create a repository dispatch event.""" - # Keep positional arguments for compatibility across supported PyGithub versions. + # Keep positional arguments for compatibility + # across supported PyGithub versions. self._repo.create_repository_dispatch("TagBot", payload) def configure_ssh(self, key: str, password: Optional[str], repo: str = "") -> None: