Skip to content
This repository was archived by the owner on Jun 30, 2025. It is now read-only.

Commit c16fa14

Browse files
fix: ensure release version is based on UTC timezone (#125)
1 parent 46b8feb commit c16fa14

2 files changed

Lines changed: 134 additions & 17 deletions

File tree

action/main.py

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# standard imports
2-
from datetime import datetime
2+
import datetime
33
import io
44
import json
55
import os
@@ -28,6 +28,48 @@
2828
GITHUB_HEADERS = {'Authorization': f'token {GITHUB_API_TOKEN}'}
2929

3030

31+
class TimestampUTC:
32+
"""
33+
Timestamp class to handle the timestamp conversion.
34+
35+
Attributes
36+
----------
37+
timestamp : datetime.datetime
38+
The timestamp in datetime format.
39+
year : int
40+
The year of the timestamp.
41+
month : str
42+
The month of the timestamp, zero-padded.
43+
day : str
44+
The day of the timestamp, zero-padded.
45+
hour : str
46+
The hour of the timestamp, zero-padded.
47+
minute : str
48+
The minute of the timestamp, zero-padded.
49+
second : str
50+
The second of the timestamp, zero-padded.
51+
"""
52+
def __init__(self, iso_timestamp: str):
53+
# use datetime.datetime and convert created at to yyyy.m.d-hhmmss
54+
# GitHub can provide timestamps in different formats, ensure we handle them all using `fromisoformat`
55+
# timestamp: "2023-01-25T10:43:35Z"
56+
# timestamp "2024-07-14T13:17:25-04:00"
57+
self.timestamp = datetime.datetime.fromisoformat(iso_timestamp).astimezone(datetime.timezone.utc)
58+
self.year = self.timestamp.year
59+
self.month = str(self.timestamp.month).zfill(2)
60+
self.day = str(self.timestamp.day).zfill(2)
61+
self.hour = str(self.timestamp.hour).zfill(2)
62+
self.minute = str(self.timestamp.minute).zfill(2)
63+
self.second = str(self.timestamp.second).zfill(2)
64+
65+
def __repr__(self):
66+
class_name = type(self).__name__
67+
return f"{class_name}(y{self.year}.m{self.month}.d{self.day}.h{self.hour}.m{self.minute}.s{self.second})"
68+
69+
def __str__(self):
70+
return f"{self.year=}, {self.month=}, {self.day=}, {self.hour=}, {self.minute=}, {self.second=}"
71+
72+
3173
def append_github_step_summary(message: str):
3274
"""
3375
Append a message to the GitHub Status Summary.
@@ -212,27 +254,17 @@ def get_push_event_details() -> dict:
212254
# get the commit
213255
commit_timestamp = github_event["commits"][0]['timestamp']
214256

215-
# use regex and convert created at to yyyy.m.d-hhmmss
216-
# GitHub can provide timestamps in different formats, ensure we handle them all using `fromisoformat`
217-
# timestamp: "2023-01-25T10:43:35Z"
218-
# timestamp "2024-07-14T13:17:25-04:00"
219-
timestamp = datetime.fromisoformat(commit_timestamp)
220-
year = timestamp.year
221-
month = str(timestamp.month).zfill(2)
222-
day = str(timestamp.day).zfill(2)
223-
hour = str(timestamp.hour).zfill(2)
224-
minute = str(timestamp.minute).zfill(2)
225-
second = str(timestamp.second).zfill(2)
257+
ts = TimestampUTC(iso_timestamp=commit_timestamp)
226258

227259
if os.getenv('INPUT_DOTNET', 'false').lower() == 'true':
228260
# dotnet versioning
229-
build = f"{hour}{minute}"
230-
revision = second
231-
release_version = f"{year}.{int(month)}{day}.{int(build)}.{int(revision)}"
261+
build = f"{ts.hour}{ts.minute}"
262+
revision = ts.second
263+
release_version = f"{ts.year}.{int(ts.month)}{ts.day}.{int(build)}.{int(revision)}"
232264
else:
233265
# default versioning
234-
build = f"{hour}{minute}{second}"
235-
release_version = f"{year}.{int(month)}{day}.{int(build)}"
266+
build = f"{ts.hour}{ts.minute}{ts.second}"
267+
release_version = f"{ts.year}.{int(ts.month)}{ts.day}.{int(build)}"
236268

237269
push_event_details['release_version'] = release_version
238270
return push_event_details

tests/unit/test_main.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# standard imports
22
import os
3+
from typing import Dict, Tuple, Union
34

45
# lib imports
56
import pytest
@@ -8,6 +9,90 @@
89
from action import main
910

1011

12+
@pytest.mark.parametrize('iso_timestamp', [
13+
('1970-01-01T00:00:00Z', dict(
14+
year=1970,
15+
month='01',
16+
day='01',
17+
hour='00',
18+
minute='00',
19+
second='00',
20+
)),
21+
('2023-11-27T23:58:28Z', dict(
22+
year=2023,
23+
month='11',
24+
day='27',
25+
hour='23',
26+
minute='58',
27+
second='28',
28+
)),
29+
('2023-01-25T10:43:35Z', dict(
30+
year=2023,
31+
month='01',
32+
day='25',
33+
hour='10',
34+
minute='43',
35+
second='35',
36+
)),
37+
('2024-07-14T17:17:25Z', dict(
38+
year=2024,
39+
month='07',
40+
day='14',
41+
hour='17',
42+
minute='17',
43+
second='25',
44+
)),
45+
('2024-07-14T13:17:25-04:00', dict(
46+
year=2024,
47+
month='07',
48+
day='14',
49+
hour='17', # include timezone offset
50+
minute='17',
51+
second='25',
52+
)),
53+
('2024-07-14T13:17:25+04:00', dict(
54+
year=2024,
55+
month='07',
56+
day='14',
57+
hour='09', # include timezone offset
58+
minute='17',
59+
second='25',
60+
)),
61+
('2024-07-22T22:17:25-04:00', dict(
62+
year=2024,
63+
month='07',
64+
day='23',
65+
hour='02', # include timezone offset
66+
minute='17',
67+
second='25',
68+
)),
69+
])
70+
def test_timestamp_class(iso_timestamp: Tuple[str, Dict[str, Union[int, str]]]):
71+
timestamp = main.TimestampUTC(iso_timestamp=iso_timestamp[0])
72+
73+
assert timestamp.year == iso_timestamp[1]['year']
74+
assert timestamp.month == iso_timestamp[1]['month']
75+
assert timestamp.day == iso_timestamp[1]['day']
76+
assert timestamp.hour == iso_timestamp[1]['hour']
77+
assert timestamp.minute == iso_timestamp[1]['minute']
78+
assert timestamp.second == iso_timestamp[1]['second']
79+
80+
assert repr(timestamp) == ("TimestampUTC("
81+
f"y{iso_timestamp[1]['year']}."
82+
f"m{iso_timestamp[1]['month']}."
83+
f"d{iso_timestamp[1]['day']}."
84+
f"h{iso_timestamp[1]['hour']}."
85+
f"m{iso_timestamp[1]['minute']}."
86+
f"s{iso_timestamp[1]['second']})")
87+
88+
assert str(timestamp) == (f"self.year={iso_timestamp[1]['year']}, "
89+
f"self.month='{iso_timestamp[1]['month']}', "
90+
f"self.day='{iso_timestamp[1]['day']}', "
91+
f"self.hour='{iso_timestamp[1]['hour']}', "
92+
f"self.minute='{iso_timestamp[1]['minute']}', "
93+
f"self.second='{iso_timestamp[1]['second']}'")
94+
95+
1196
@pytest.mark.parametrize('message', [
1297
'foo',
1398
'bar',

0 commit comments

Comments
 (0)