From 1f597b519a9363f4cd813a947a5968cea44719ed Mon Sep 17 00:00:00 2001 From: "Yury V. Zaytsev" Date: Thu, 13 Feb 2025 14:17:01 +0100 Subject: [PATCH 1/2] CI: disable `fail-fast` on matrix job failure --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f6f907..8f53a39 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 5 strategy: + fail-fast: false matrix: python-version: - "3.10" From 1365921029fe39d63de2d1add2f7acfa9a7d39ad Mon Sep 17 00:00:00 2001 From: "Yury V. Zaytsev" Date: Thu, 13 Feb 2025 14:14:13 +0100 Subject: [PATCH 2/2] Require timezone-aware datetimes for all model fields --- src/github_issues_import/models.py | 15 +++++++-------- tests/test_models.py | 5 ++++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/github_issues_import/models.py b/src/github_issues_import/models.py index ff6ffbb..a301e37 100644 --- a/src/github_issues_import/models.py +++ b/src/github_issues_import/models.py @@ -1,8 +1,7 @@ -from datetime import datetime from typing import Literal +from pydantic import AwareDatetime, ConfigDict, HttpUrl from pydantic import BaseModel as PydanticBaseModel -from pydantic import ConfigDict, HttpUrl DEFAULT_CONFIG = ConfigDict( populate_by_name=True, @@ -19,9 +18,9 @@ class BaseModel(PydanticBaseModel): class Issue(BaseModel): title: str body: str - created_at: datetime | None = None - updated_at: datetime | None = None - closed_at: datetime | None = None + created_at: AwareDatetime | None = None + updated_at: AwareDatetime | None = None + closed_at: AwareDatetime | None = None assignee: str | None = None milestone: int | None = None closed: bool | None = None @@ -30,7 +29,7 @@ class Issue(BaseModel): class Comment(BaseModel): body: str - created_at: datetime | None = None + created_at: AwareDatetime | None = None class IssueImportRequest(BaseModel): @@ -55,8 +54,8 @@ class IssueImportStatusResponse(BaseModel): issue_url: HttpUrl | None = None # if "imported" - created_at: datetime | None = None - updated_at: datetime | None = None + created_at: AwareDatetime | None = None + updated_at: AwareDatetime | None = None # if "failed" errors: list[IssueImportError] | None = None diff --git a/tests/test_models.py b/tests/test_models.py index c3b1f3b..65833af 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,4 +1,5 @@ import json +from datetime import timedelta from pathlib import Path import pytest @@ -15,7 +16,9 @@ def test_issue_import_request(fixture: Path): @pytest.mark.parametrize("fixture", get_fixtures("response-single-*.json")) def test_issue_import_status_response(fixture: Path): - IssueImportStatusResponse.model_validate_json(get_fixture(fixture)) + response = IssueImportStatusResponse.model_validate_json(get_fixture(fixture)) + if response.created_at is not None: + assert response.created_at.tzinfo.utcoffset(response.created_at) == timedelta(hours=-7) def test_issue_import_status_multiple():