Skip to content

Add support for eol-checker for Apps & Stacks images#228

Merged
phracek merged 2 commits into
sclorg:masterfrom
phracek:eol_checker
May 26, 2026
Merged

Add support for eol-checker for Apps & Stacks images#228
phracek merged 2 commits into
sclorg:masterfrom
phracek:eol_checker

Conversation

@phracek
Copy link
Copy Markdown
Member

@phracek phracek commented May 25, 2026

The pull request contains several analysis.

  • Analysis lifecycle-defs
  • Analysis Jira issues if the deprecation was already filed
  • Summary report for maintainers.
  • Some variables needs to be defined before running the checker, like LIFECYCLE_DEFS_URL, JIRA_USERNAME, JIRA_PASSWORD

Summary by CodeRabbit

Release Notes

  • New Features

    • Added end-of-life checker tool to identify deprecated containers and operating systems
    • Integrated Jira ticket tracking for lifecycle deprecation management
    • Implemented colored console logging for improved readability
    • Configured monitoring system for specified containers and operating systems
  • Tests

    • Added comprehensive test coverage for checker, Jira integration, utilities, and configuration loading

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

Warning

Review limit reached

@phracek, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 53 minutes and 24 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ea4d548f-b912-4a40-8495-de19acb14073

📥 Commits

Reviewing files that changed from the base of the PR and between f828fc4 and 5538137.

📒 Files selected for processing (13)
  • eol-checker/eol_checker/__init__.py
  • eol-checker/eol_checker/checker.py
  • eol-checker/eol_checker/constants.py
  • eol-checker/eol_checker/custom_logger.py
  • eol-checker/eol_checker/jira.py
  • eol-checker/eol_checker/utils.py
  • eol-checker/eol_checker/yaml_loader.py
  • eol-checker/tests/__init__.py
  • eol-checker/tests/test_checker.py
  • eol-checker/tests/test_jira.py
  • eol-checker/tests/test_utils.py
  • eol-checker/tests/test_yaml_loader.py
  • eol-checker/tox.ini
📝 Walkthrough

Walkthrough

A new end-of-life container checker tool that downloads lifecycle YAML definitions, evaluates version end-dates against today's date, categorizes containers as EOL or approaching-EOL, optionally integrates with JIRA for deprecation ticket tracking, and generates consolidated text summaries with ticket URLs for reporting.

Changes

EOL Checker Tool Implementation

Layer / File(s) Summary
Configuration and foundation utilities
eol-checker/eol_checker/constants.py, eol-checker/eol_checker/utils.py, eol-checker/tests/test_utils.py
Module-level configuration constants define JIRA URL, supported OS/container names, and status filters. Utility functions compute EOL status (1=current month, 2=next month, 0=other), extract lifecycle arrays from dicts, and construct JIRA browse URLs. Test coverage validates all date edge cases and URL construction.
Custom logging setup
eol-checker/eol_checker/custom_logger.py
Colored formatter selects log colors by level and setup_logger() wires console output via ColoredFormatter and file output to eol_checker.log with independent handler levels.
External data integrations
eol-checker/eol_checker/yaml_loader.py, eol-checker/eol_checker/jira.py, eol-checker/tests/test_yaml_loader.py, eol-checker/tests/test_jira.py
YamlLoader constructs GitLab raw URLs from LIFECYCLE_DEFS_URL and downloads/parses lifecycle YAML with timeout, error logging, and consistent None return on failure. JiraFetcher reads credentials from environment, lazily instantiates a Jira client, fetches issuelinks from a configured deprecation ticket, filters by allowed status, accumulates cloned issue metadata, and provides container-to-ticket lookup. Comprehensive test suites validate URL construction, HTTP/YAML error handling, client caching, detail extraction, and status filtering.
Core checker and report generation
eol-checker/eol_checker/checker.py (methods: __init__, check_enddate, analyze_lifecycle_yaml, summary_for_eol_images, summary_for_approaching_eol_images, summary_report, analyze_containers, run)
ContainerEolChecker stores today's date and per-OS image maps (EOL vs approaching-EOL). check_enddate() parses enddate and uses is_eol_version() to populate the appropriate map. analyze_lifecycle_yaml() iterates lifecycle entries and applies check_enddate(). Summary methods format OS-scoped text reports with stream names and JIRA ticket URLs (selecting existing or default tickets via jira_fetcher). analyze_containers() iterates all configured OS/container pairs, downloads YAML, and analyzes lifecycles. run() triggers optional Jira detail retrieval, executes analysis, logs the summary, and returns exit code 0.
Checker tests and integration validation
eol-checker/tests/test_checker.py
Fixtures set up checker with fixed today date and preconfigured per-OS image dictionaries. Tests cover initialization, enddate categorization (EOL/approaching-EOL/ignored), YAML analysis, summary text generation with Jira-filled/unfilled paths, concatenation into consolidated report, YAML download failures, and the full run() orchestration with Jira fetching.
Test environment configuration
eol-checker/tox.ini
Tox testenv runs pytest with coverage reporting, specifying all dependencies (pytest, pytest-cov, flexmock, PyYAML, requests, xmltodict, atlassian-python-api, colorama).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A rabbit built a checker so keen,
To find what EOLs have been seen,
With JIRA tickets linked just right,
And YAML lifecycles parsed overnight,
Container status shines so bright!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.88% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding eol-checker support for Apps & Stacks images, which aligns with the PR's core objective and the substantial implementation of the ContainerEolChecker class and supporting infrastructure.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 25, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 50.69%. Comparing base (51e6765) to head (5538137).
⚠️ Report is 3 commits behind head on master.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           master     #228       +/-   ##
===========================================
+ Coverage   35.50%   50.69%   +15.18%     
===========================================
  Files           7        7               
  Lines        1011     1006        -5     
===========================================
+ Hits          359      510      +151     
+ Misses        652      496      -156     
Flag Coverage Δ
daily-tests-unit 44.26% <ø> (+18.02%) ⬆️
ocp-stream-generator-unit 84.47% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@phracek
Copy link
Copy Markdown
Member Author

phracek commented May 25, 2026

How to executed?
Just clone the repo, switch to this PR and call commands like:

$ ./eol-checker/eol-checker {--debug}
ttps://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL9/python38.yaml?ref_type=heads
ERROR - eol_checker.checker - Failed to download lifecycle YAML file from 'https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL9/python38.yaml?ref_type=heads'
ERROR - eol_checker.yaml_loader - RequestException: Failed to download lifecycle YAML file from https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL9/python39.yaml?ref_type=heads: 404 Client Error: Not Found for url: https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL9/python39.yaml?ref_type=heads
ERROR - eol_checker.checker - Failed to download lifecycle YAML file from 'https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL9/python39.yaml?ref_type=heads'
ERROR - eol_checker.yaml_loader - RequestException: Failed to download lifecycle YAML file from https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL9/python311.yaml?ref_type=heads: 404 Client Error: Not Found for url: https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL9/python311.yaml?ref_type=heads
ERROR - eol_checker.checker - Failed to download lifecycle YAML file from 'https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL9/python311.yaml?ref_type=heads'
ERROR - eol_checker.yaml_loader - RequestException: Failed to download lifecycle YAML file from https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL9/python312.yaml?ref_type=heads: 404 Client Error: Not Found for url: https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL9/python312.yaml?ref_type=heads
ERROR - eol_checker.checker - Failed to download lifecycle YAML file from 'https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL9/python312.yaml?ref_type=heads'
Analyzing OS RHEL9 completed
Analyzing OS RHEL10
ERROR - eol_checker.yaml_loader - RequestException: Failed to download lifecycle YAML file from https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/mysql.yaml?ref_type=heads: 404 Client Error: Not Found for url: https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/mysql.yaml?ref_type=heads
ERROR - eol_checker.checker - Failed to download lifecycle YAML file from 'https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/mysql.yaml?ref_type=heads'
ERROR - eol_checker.yaml_loader - RequestException: Failed to download lifecycle YAML file from https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/redis.yaml?ref_type=heads: 404 Client Error: Not Found for url: https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/redis.yaml?ref_type=heads
ERROR - eol_checker.checker - Failed to download lifecycle YAML file from 'https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/redis.yaml?ref_type=heads'
ERROR - eol_checker.yaml_loader - RequestException: Failed to download lifecycle YAML file from https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python36.yaml?ref_type=heads: 404 Client Error: Not Found for url: https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python36.yaml?ref_type=heads
ERROR - eol_checker.checker - Failed to download lifecycle YAML file from 'https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python36.yaml?ref_type=heads'
ERROR - eol_checker.yaml_loader - RequestException: Failed to download lifecycle YAML file from https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python38.yaml?ref_type=heads: 404 Client Error: Not Found for url: https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python38.yaml?ref_type=heads
ERROR - eol_checker.checker - Failed to download lifecycle YAML file from 'https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python38.yaml?ref_type=heads'
ERROR - eol_checker.yaml_loader - RequestException: Failed to download lifecycle YAML file from https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python39.yaml?ref_type=heads: 404 Client Error: Not Found for url: https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python39.yaml?ref_type=heads
ERROR - eol_checker.checker - Failed to download lifecycle YAML file from 'https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python39.yaml?ref_type=heads'
ERROR - eol_checker.yaml_loader - RequestException: Failed to download lifecycle YAML file from https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python311.yaml?ref_type=heads: 404 Client Error: Not Found for url: https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python311.yaml?ref_type=heads
ERROR - eol_checker.checker - Failed to download lifecycle YAML file from 'https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python311.yaml?ref_type=heads'
ERROR - eol_checker.yaml_loader - RequestException: Failed to download lifecycle YAML file from https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python312.yaml?ref_type=heads: 404 Client Error: Not Found for url: https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python312.yaml?ref_type=heads
ERROR - eol_checker.checker - Failed to download lifecycle YAML file from 'https://gitlab.cee.redhat.com/rcm/lifecycle-defs/-/raw/main/RHEL10/python312.yaml?ref_type=heads'
Analyzing OS RHEL10 completed
Processing container: 'mariadb' with values: '{'name': 'MariaDB 10.5'}'
ERROR - eol_checker.jira - JIRA_USERNAME and/or JIRA_PASSWORD are not set
ERROR - eol_checker.checker - Connection to Jira failed
Processing container: 'postgresql' with values: '{'name': 'PostgreSQL 13'}'
ERROR - eol_checker.jira - JIRA_USERNAME and/or JIRA_PASSWORD are not set
ERROR - eol_checker.checker - Connection to Jira failed

Summary report that reached EOL dates:
MariaDB 10.5 for RHEL8 reached EOL. Jira ticket is not filled. Use Jira issue template: https://redhat.atlassian.net/browse/RHELMISC-20810
PostgreSQL 13 for RHEL8 reached EOL. Jira ticket is not filled. Use Jira issue template: https://redhat.atlassian.net/browse/RHELMISC-20810

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 17

🧹 Nitpick comments (1)
eol-checker/tests/test_utils.py (1)

25-29: ⚡ Quick win

Add a December→January boundary test for approaching-EOL.

Current tests miss the month/year rollover case, which is a key edge case for is_eol_version.

Suggested test
 def test_is_eol_version_different_year_returns_zero():
     today = date(2025, 5, 15)
     enddate = date(2026, 5, 1)
     assert is_eol_version(enddate, today) == 0
+
+
+def test_is_eol_version_december_to_january_returns_two():
+    today = date(2025, 12, 15)
+    enddate = date(2026, 1, 1)
+    assert is_eol_version(enddate, today) == 2
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@eol-checker/tests/test_utils.py` around lines 25 - 29, Add a test covering
the December→January month/year rollover for the approaching-EOL logic: create a
test in eol-checker/tests/test_utils.py that calls is_eol_version with today in
early January and an enddate in late December of the previous year (or vice
versa depending on the semantics) to verify the function returns the expected
approaching-EOL value (e.g., 1 for approaching, 0 for not). Reference the
is_eol_version function to implement the assertion and mirror the style of
existing tests like test_is_eol_version_different_year_returns_zero so the new
case exercises the month/year boundary correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@eol-checker/eol_checker/checker.py`:
- Around line 218-221: The current condition is inverted: it logs "Connection to
Jira failed" when self.jira_fetcher.jira is not None and then calls
get_jira_deprecation_details() and check_if_jira_is_filled(); change the logic
so that logger.error("Connection to Jira failed") runs only when
self.jira_fetcher.jira is None, and ensure get_jira_deprecation_details() and
check_if_jira_is_filled() are invoked only when self.jira_fetcher.jira is not
None, using the same symbols (self.jira_fetcher.jira, logger.error,
get_jira_deprecation_details, check_if_jira_is_filled) to locate the code.
- Around line 83-94: The current logic for eol_images and approaching_eol_images
overwrites a single record per (os_name, container_to_analyze) so multiple
streams are lost; change the assignments in checker.py to append stream entries
instead (e.g., ensure self.eol_images[self.os_name][self.container_to_analyze]
and self.approaching_eol_images[...] hold lists and use .append({"name":
application_stream_name, ...})) and update summary_for_eol_images and
summary_for_approaching_eol_images to iterate the per-container lists of stream
dicts rather than expecting a single dict so all lifecycle entries are preserved
and summarized.
- Around line 64-69: The code assumes lifecycle contains
"application_stream_name" and that lifecycle["enddate"] is a valid "%Y%m%d"
string; replace the direct accesses with safe checks and guarded parsing: use
lifecycle.get("application_stream_name") and if it's missing log/skip, then wrap
datetime.strptime(lifecycle["enddate"], "%Y%m%d") in a try/except ValueError
(and also check for presence of "enddate" with lifecycle.get or "in" as
currently done) to catch malformed dates, log the bad entry (including the
lifecycle payload or key) and return/skip instead of letting KeyError/ValueError
propagate; update code paths that use application_stream_name and enddate
accordingly so they only run when parsing succeeded.
- Line 39: Remove the global TLS warning suppression and re-enable certificate
verification: delete the
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) call in
checker.py, update download_yaml() in yaml_loader.py to stop forcing
verify=False (use the default verify=True or accept a configurable CA bundle
parameter and pass it to requests.get), and adjust
eol-checker/tests/test_yaml_loader.py to mock/expect verified HTTPS calls (or
supply a test CA bundle/configuration) rather than relying on suppressed
warnings and insecure requests.

In `@eol-checker/eol_checker/constants.py`:
- Around line 26-45: CONTAINER_NAMES contains a duplicate entry "varnish" which
can cause duplicate processing; remove the redundant "varnish" string from the
CONTAINER_NAMES list (keep only one occurrence) so the list has unique container
names and downstream logic using CONTAINER_NAMES (the constant) no longer
processes varnish twice.

In `@eol-checker/eol_checker/jira.py`:
- Around line 49-52: Guard against a missing Jira client before calling
self.jira.issue by checking self.jira is not None (and optionally that
self.jira_deprecation_ticket is set) before invoking issue(); if self.jira is
None, skip the call and set self.jira_details to a safe default (e.g., empty
list or None) so downstream logic won't hit AttributeError. Update the block
referencing self.jira, self.jira_deprecation_ticket and self.jira_details to
perform this conditional check and handle the absence of a client gracefully.
- Around line 93-101: The method check_if_jira_is_filled() currently appends to
the instance list jira_deprecated_opened_issues on every call, causing
duplicates; before you start repopulating that list at the top of
check_if_jira_is_filled(), clear or reinitialize jira_deprecated_opened_issues
(e.g., set to [] or call .clear()) so each invocation starts with an empty
collection, then proceed with the existing append logic and subsequent
logger.info that reports the list.

In `@eol-checker/eol_checker/utils.py`:
- Around line 57-59: The current branch that checks isinstance(data, dict) and
returns data["lifecycles"] can return None or non-list types; update it to
validate the payload by retrieving lifecycles = data.get("lifecycles") and only
return it if isinstance(lifecycles, list) (otherwise return []); this prevents
downstream iteration errors when lifecycles is None, a string, or a dict while
keeping the existing behavior for proper lists.
- Around line 41-44: The current month-check uses today.month + 1 which breaks
on December; change the logic to compute next_month = (today.month % 12) + 1 and
next_year = today.year + (1 if today.month == 12 else 0) and then check if
enddate.year == next_year and enddate.month == next_month (the block with
enddate and today variables in eol_checker/utils.py). This preserves the
existing return values (1 for same month, 2 for next month) while correctly
handling year rollover.

In `@eol-checker/eol_checker/yaml_loader.py`:
- Line 58: The code disables TLS verification by calling requests.get(url,
timeout=30, verify=False); remove verify=False so requests.get uses the system
certificate store (e.g., requests.get(url, timeout=30)), and if you need to
support custom CA bundles expose an optional parameter (e.g., verify or
ca_bundle) on the loader function that calls requests.get and pass that through
to requests.get instead of hard-coding False; update the function that
constructs the request (the caller that assigns to response) to accept and
forward the verify option and ensure no code path sets verify=False.

In `@eol-checker/tests/test_checker.py`:
- Around line 247-253: The test test_run_fetches_jira_and_analyzes_containers
doesn't set checker.jira_fetcher.jira, so the code path that calls
get_jira_deprecation_details and check_if_jira_is_filled is never taken; update
the test to set checker.jira_fetcher.jira to a non-None value (e.g., a simple
mock object or True) before calling checker.run() so the mocked methods on
checker.jira_fetcher (get_jira_deprecation_details, check_if_jira_is_filled) are
exercised.
- Around line 126-136: The test test_summary_for_eol_images_without_jira_ticket
is not exercising the branch that calls is_jira_filled_for_container because
checker.jira_fetcher.jira is not set; update the test to set
checker.jira_fetcher.jira to a non-None/truthy value before stubbing
is_jira_filled_for_container so the code in summary_for_eol_images will call
jira_fetcher.is_jira_filled_for_container (refer to checker.jira_fetcher.jira
and the summary_for_eol_images function) and then assert the expected report
contents.
- Around line 112-123: The test
test_summary_for_eol_images_with_existing_jira_ticket doesn't set
checker.jira_fetcher.jira, so summary_for_eol_images returns early and never
calls is_jira_filled_for_container; update the test to set
checker.jira_fetcher.jira to a non-None value (e.g., a dummy object) before
calling summary_for_eol_images("RHEL9") so the code path that invokes
checker.jira_fetcher.is_jira_filled_for_container(stream_name="nodejs-18") is
exercised and the assertions about the existing Jira ticket and URL can be
validated.
- Around line 170-188: The test
test_summary_report_includes_eol_and_approaching_sections fails to exercise the
EOL path because checker.jira_fetcher.jira is left as None; set
checker.jira_fetcher.jira to a non-None value (e.g., a simple object or a
flexmock) before calling summary_report so summary_for_eol_images will call
is_jira_filled_for_container; ensure the setup is added alongside the existing
flexmock expectations for is_jira_filled_for_container so the mocked calls on
checker.jira_fetcher.is_jira_filled_for_container (stream_name="nodejs-18") are
actually invoked.
- Line 18: The tests call ContainerEolChecker(today=...), but
ContainerEolChecker.__init__ currently doesn't accept that kwarg; update
ContainerEolChecker.__init__ to accept a today parameter (e.g., def
__init__(self, today: date | None = None, **kwargs): self.today = today or
date.today()) and/or accept **kwargs so tests can pass additional fixtures, then
use self.today inside methods that compute EOL; ensure the constructor signature
and attribute name match references in eol_checker/checker.py and tests.

In `@eol-checker/tests/test_jira.py`:
- Around line 9-12: The test fixture "fetcher" creates a JiraFetcher but doesn't
seed credentials so JiraFetcher.jira returns None in CI; update the pytest
fixture "fetcher" to set JIRA_USERNAME and JIRA_PASSWORD (e.g., via os.environ
or pytest monkeypatch) before instantiating JiraFetcher and ensure you clean
up/restore them after the test; reference the JiraFetcher class and its jira
property to make the client-creation deterministic across environments.

In `@eol-checker/tests/test_yaml_loader.py`:
- Around line 6-13: The test imports a nonexistent DEFAULT_YAML_URL and assumes
a base URL while YamlLoader.get_yaml_url actually uses LIFECYCLE_DEFS_URL (or
the LIFECYCLE_DEFS_URL env); update the test to use the correct symbol or
explicitly set/mock the env value used by YamlLoader.get_yaml_url: replace
DEFAULT_YAML_URL with LIFECYCLE_DEFS_URL imported from eol_checker.constants (or
set os.environ["LIFECYCLE_DEFS_URL"] to the expected base before calling
YamlLoader.get_yaml_url) so the asserted URL matches the loader's behavior.

---

Nitpick comments:
In `@eol-checker/tests/test_utils.py`:
- Around line 25-29: Add a test covering the December→January month/year
rollover for the approaching-EOL logic: create a test in
eol-checker/tests/test_utils.py that calls is_eol_version with today in early
January and an enddate in late December of the previous year (or vice versa
depending on the semantics) to verify the function returns the expected
approaching-EOL value (e.g., 1 for approaching, 0 for not). Reference the
is_eol_version function to implement the assertion and mirror the style of
existing tests like test_is_eol_version_different_year_returns_zero so the new
case exercises the month/year boundary correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f2a692dd-d174-499f-a1b0-4323c68e6aa7

📥 Commits

Reviewing files that changed from the base of the PR and between 5b893e4 and f828fc4.

📒 Files selected for processing (13)
  • eol-checker/eol_checker/__init__.py
  • eol-checker/eol_checker/checker.py
  • eol-checker/eol_checker/constants.py
  • eol-checker/eol_checker/custom_logger.py
  • eol-checker/eol_checker/jira.py
  • eol-checker/eol_checker/utils.py
  • eol-checker/eol_checker/yaml_loader.py
  • eol-checker/tests/__init__.py
  • eol-checker/tests/test_checker.py
  • eol-checker/tests/test_jira.py
  • eol-checker/tests/test_utils.py
  • eol-checker/tests/test_yaml_loader.py
  • eol-checker/tox.ini

Comment thread eol-checker/eol_checker/checker.py
Comment thread eol-checker/eol_checker/checker.py Outdated
Comment thread eol-checker/eol_checker/checker.py
Comment thread eol-checker/eol_checker/checker.py Outdated
Comment thread eol-checker/eol_checker/constants.py
Comment thread eol-checker/tests/test_checker.py
Comment thread eol-checker/tests/test_checker.py
Comment thread eol-checker/tests/test_checker.py
Comment on lines +9 to +12
@pytest.fixture
def fetcher():
return JiraFetcher()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Seed Jira credentials in tests to make client-creation tests deterministic.

The fixture does not set JIRA_USERNAME/JIRA_PASSWORD, but JiraFetcher.jira returns None without them, so tests that assert client creation are environment-dependent.

Suggested fix
 `@pytest.fixture`
-def fetcher():
+def fetcher(monkeypatch):
+    monkeypatch.setenv("JIRA_USERNAME", "user")
+    monkeypatch.setenv("JIRA_PASSWORD", "pass")
     return JiraFetcher()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@eol-checker/tests/test_jira.py` around lines 9 - 12, The test fixture
"fetcher" creates a JiraFetcher but doesn't seed credentials so JiraFetcher.jira
returns None in CI; update the pytest fixture "fetcher" to set JIRA_USERNAME and
JIRA_PASSWORD (e.g., via os.environ or pytest monkeypatch) before instantiating
JiraFetcher and ensure you clean up/restore them after the test; reference the
JiraFetcher class and its jira property to make the client-creation
deterministic across environments.

Comment thread eol-checker/tests/test_yaml_loader.py Outdated
phracek added 2 commits May 26, 2026 09:32
The pull request contains several analysis.
* Analysis lifecycle-defs
* Analysis Jira issues if the deprecation was already filed
* Summary report for maintainers.
* Some variables needs to be defined before running the checker, like
  LIFECYCLE_DEFS_URL, JIRA_USERNAME, JIRA_PASSWORD
mentioned in lifecycle otherwise continue

Signed-off-by: Petr "Stone" Hracek <phracek@redhat.com>
@phracek phracek merged commit ee7cd89 into sclorg:master May 26, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant