Repository navigation
[bug-hunter] fetch-workflow-logs --since misfilters timezone-offset ISO8601 values #2158
Copy link
Copy link
Closed as not planned
Closed as not planned
Copy link
Description
Impact
Users running scripts/fetch-workflow-logs.py with a valid ISO 8601 --since value that includes a timezone offset can receive incorrect workflow runs (older runs included as if they were newer). This can skew failure triage and log analysis.
Reproduction Steps
- Create and run this new minimal script:
import importlib.util
from pathlib import Path
script_path = Path('scripts/fetch-workflow-logs.py')
spec = importlib.util.spec_from_file_location('fetch_workflow_logs', script_path)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
def fake_github_api(path, token, accept='application/vnd.github+json'):
if path.endswith('page=1'):
return b'{"workflow_runs":[{"id":1,"created_at":"2025-01-01T04:30:00Z","conclusion":"failure"}]}'
return b'{"workflow_runs":[]}'
mod.github_api = fake_github_api
runs = mod.list_workflow_runs(
repo='elastic/ai-github-actions',
workflow='ci.yml',
token='x',
since='2025-01-01T00:00:00-05:00',
until=None,
conclusion='failure',
last=20,
)
# Expected no runs: 04:30Z is before 05:00Z
assert runs == [], f'Expected [], got {[r["id"] for r in runs]} with created_at={[r.get("created_at") for r in runs]}'- Run:
python /tmp/gh-aw/agent/repro_fetch_since_tz_failing.pyExpected vs Actual
Expected: No runs are returned, because 2025-01-01T04:30:00Z is earlier than 2025-01-01T00:00:00-05:00 (2025-01-01T05:00:00Z).
Actual: The run is included, and the script fails with:
Traceback (most recent call last):
File "/tmp/gh-aw/agent/repro_fetch_since_tz_failing.py", line 26, in <module>
assert runs == [], f'Expected [], got {[r["id"] for r in runs]} with created_at={[r.get("created_at") for r in runs]}'
AssertionError: Expected [], got [1] with created_at=['2025-01-01T04:30:00Z']
Failing Test
import importlib.util
from pathlib import Path
script_path = Path('scripts/fetch-workflow-logs.py')
spec = importlib.util.spec_from_file_location('fetch_workflow_logs', script_path)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
def fake_github_api(path, token, accept='application/vnd.github+json'):
if path.endswith('page=1'):
return b'{"workflow_runs":[{"id":1,"created_at":"2025-01-01T04:30:00Z","conclusion":"failure"}]}'
return b'{"workflow_runs":[]}'
mod.github_api = fake_github_api
runs = mod.list_workflow_runs(
repo='elastic/ai-github-actions',
workflow='ci.yml',
token='x',
since='2025-01-01T00:00:00-05:00',
until=None,
conclusion='failure',
last=20,
)
assert runs == [], f'Expected [], got {[r["id"] for r in runs]} with created_at={[r.get("created_at") for r in runs]}'Evidence
scripts/fetch-workflow-logs.py:71-75compares timestamps as raw strings:_is_before_since_boundaryreturnsrun.get("created_at", "") < since
scripts/fetch-workflow-logs.py:89-92uses that boundary check to stop pagination.- With timezone offsets, lexical string comparison is not equivalent to chronological comparison.
What is this? | From workflow: Trigger Bug Hunter
Give us feedback! React with 🚀 if perfect, 👍 if helpful, 👎 if not.
- expires on Sep 30, 2026, 11:26 AM UTC
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
github-actions commentedon Sep 30, 2026
This issue was automatically closed because it expired on 2026-09-30T11:26:45.535Z.