Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
Version 0.58.3
-------------

- Fix parsing datetime in Apple API response that contains nanoseconds. [PR #465](https://github.com/codemagic-ci-cd/cli-tools/pull/465).

Version 0.58.2
-------------

Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,15 @@ Note that for the tests to run successfully, you'd have to define the following
```
And either of the two:
```shell
export TEST_GCLOUD_SERVICE_ACCOUNT_CREDENTIALS_PATH=... # Path to gcloud service account creedentials with `JSON` key type
export TEST_GCLOUD_SERVICE_ACCOUNT_CREDENTIALS_CONTENT=... # Content of gcloud service account creedentials with `JSON` key type
export TEST_GCLOUD_SERVICE_ACCOUNT_CREDENTIALS_PATH=... # Path to gcloud service account credentials with `JSON` key type
export TEST_GCLOUD_SERVICE_ACCOUNT_CREDENTIALS_CONTENT=... # Content of gcloud service account credentials with `JSON` key type
```

- For Firebase:
Either of the two:
```shell
export TEST_FIREBASE_SERVICE_ACCOUNT_CREDENTIALS_PATH=... # Path to gcloud service account creedentials with `JSON` key type
export TEST_FIREBASE_SERVICE_ACCOUNT_CREDENTIALS_CONTENT=... # Content of gcloud service account creedentials with `JSON` key type
export TEST_FIREBASE_SERVICE_ACCOUNT_CREDENTIALS_PATH=... # Path to gcloud service account credentials with `JSON` key type
export TEST_FIREBASE_SERVICE_ACCOUNT_CREDENTIALS_CONTENT=... # Content of gcloud service account credentials with `JSON` key type
```

### Pre-commit hooks
Expand Down
44 changes: 35 additions & 9 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ packaging = ">=22.0"
psutil = ">= 5.8.0"
pyjwt = "^2.4.0"
requests = ">= 2.25"
python-dateutil = ">= 2.9.0"

[tool.poetry.group.dev.dependencies]
black = "*"
Expand All @@ -56,6 +57,7 @@ pytest-cov = "*"
ruff = "*"
types-requests = "*"
types-psutil = "*"
types-python-dateutil= "*"
androguard = ">=4.0.0"

[build-system]
Expand Down
2 changes: 1 addition & 1 deletion src/codemagic/__version__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__title__ = "codemagic-cli-tools"
__description__ = "CLI tools used in Codemagic builds"
__version__ = "0.58.2.dev"
__version__ = "0.58.3.dev"
__url__ = "https://github.com/codemagic-ci-cd/cli-tools"
__licence__ = "GNU General Public License v3.0"
15 changes: 5 additions & 10 deletions src/codemagic/apple/resources/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
from typing import Union
from typing import overload

from dateutil.parser import parse
from dateutil.tz import tzutc

from codemagic.models import DictSerializable
from codemagic.models import JsonSerializable
from codemagic.models import JsonSerializableMeta
Expand Down Expand Up @@ -260,15 +263,7 @@ def from_iso_8601(cls, iso_8601_timestamp: str) -> datetime: ...

@classmethod
def from_iso_8601(cls, iso_8601_timestamp: Optional[str]):
if iso_8601_timestamp is None:
return None
try:
return datetime.strptime(iso_8601_timestamp, "%Y-%m-%dT%H:%M:%S.%f%z")
except ValueError:
# while most of API responses contain timestamp as '2020-08-04T11:44:12.000+0000'
# /builds endpoint returns timestamps with timedelta and without milliseconds
# as '2021-01-28T06:01:32-08:00'
return datetime.strptime(iso_8601_timestamp, "%Y-%m-%dT%H:%M:%S%z")
return parse(iso_8601_timestamp) if iso_8601_timestamp else None

@classmethod
@overload
Expand All @@ -282,7 +277,7 @@ def to_iso_8601(cls, dt: datetime, with_fractional_seconds: bool = True) -> str:
def to_iso_8601(cls, dt: Optional[datetime], with_fractional_seconds: bool = True):
if dt is None:
return None
if dt.tzinfo == timezone.utc and with_fractional_seconds:
if dt.tzinfo in (timezone.utc, tzutc()) and with_fractional_seconds:
# while most of API responses contain timestamps as '2020-08-04T11:44:12.000+0000'
# resolved to datetime.datetime(2020, 8, 4, 11, 44, 12, tzinfo=datetime.timezone.utc),
# /builds endpoint returns timestamps as isoformat() '2021-01-28T06:01:32-08:00'
Expand Down
6 changes: 6 additions & 0 deletions tests/apple/resources/test_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from datetime import timezone

import pytest
from dateutil.tz import tzoffset
from dateutil.tz import tzutc

from codemagic.apple.resources import Profile
from codemagic.apple.resources import Resource
Expand All @@ -17,6 +19,8 @@
(None, None),
(datetime(2020, 8, 4, 11, 44, 12, tzinfo=timezone.utc), "2020-08-04T11:44:12.000+0000"),
(datetime(1970, 1, 1, 0, 0, 0, tzinfo=timezone.utc), "1970-01-01T00:00:00.000+0000"),
(datetime(2025, 5, 28, 10, 0, 0, tzinfo=tzutc()), "2025-05-28T10:00:00.000+0000"),
(datetime(2025, 5, 23, 9, 50, 3, 168550, tzinfo=tzoffset(None, -25200)), "2025-05-23T09:50:03.168550-07:00"),
],
)
def test_to_iso_8601(iso_8601_timestamp, expected_datetime):
Expand All @@ -33,6 +37,8 @@ def test_to_iso_8601(iso_8601_timestamp, expected_datetime):
datetime(2021, 1, 28, 6, 1, 32, tzinfo=timezone(timedelta(days=-1, seconds=57600))),
),
("1970-01-01T00:00:00.000+0000", datetime(1970, 1, 1, 0, 0, 0, tzinfo=timezone.utc)),
("2021-01-28T06:01:32+08:00", datetime(2021, 1, 28, 6, 1, 32, tzinfo=tzoffset(None, 28800))),
("2025-05-23T09:50:03.168550349-07:00", datetime(2025, 5, 23, 9, 50, 3, 168550, tzinfo=tzoffset(None, -25200))),
],
)
def test_from_iso_8601(given_datetime, expected_iso_8601_timestamp):
Expand Down