Skip to content

Add unobtrusive newer-version notice to check and environment commands#1262

Merged
spoorcc merged 5 commits into
mainfrom
claude/dfetch-version-check-8bkjb0
Jun 14, 2026
Merged

Add unobtrusive newer-version notice to check and environment commands#1262
spoorcc merged 5 commits into
mainfrom
claude/dfetch-version-check-8bkjb0

Conversation

@spoorcc

@spoorcc spoorcc commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Poll the GitHub releases API (api.github.com/repos/dfetch-org/dfetch/releases/latest)
and display a dim hint when a newer dfetch release is available.

  • dfetch/util/github_version_check.py: pure utility — fetches latest release
    tag and returns it if newer than the running version, silently swallowing
    any network/parse failure
  • dfetch/commands/check.py: calls it when CI env var is not set
  • dfetch/commands/environment.py: calls it unconditionally (diagnostic command)
  • api.github.com:443 is already in the harden-runner allowlist in test.yml

https://claude.ai/code/session_011XLxZxgRCWhSc5PfHGam5P

Summary by CodeRabbit

New Features

  • When running dfetch check, a dim notice now appears under the header if a newer GitHub release is available (skipped in CI).
  • dfetch environment now shows the installed dfetch version and, when applicable, adds a “newer version available” notice with a releases link.

Tests

  • Expanded automated test coverage for GitHub version-check behavior, including valid comparisons, error/malformed responses, and new BDD scenarios for dfetch environment.

@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 786897a2-9970-49bc-8c3b-85d875f503d1

📥 Commits

Reviewing files that changed from the base of the PR and between dd5c6ec and e633e22.

📒 Files selected for processing (5)
  • dfetch/util/github_version_check.py
  • features/environment.feature
  • features/environment.py
  • features/steps/generic_steps.py
  • tests/test_github_version_check.py

Walkthrough

This PR adds a GitHub version-checking utility that detects newer dfetch releases and integrates update notifications into the check and environment commands. The feature gracefully handles network errors, malformed responses, validates GitHub API responses, and respects CI environments by skipping checks when the CI environment variable is set. Unit and BDD acceptance tests comprehensively validate the functionality.

Changes

GitHub Release Update Notification

Layer / File(s) Summary
GitHub version check utility and unit tests
dfetch/util/github_version_check.py, tests/test_github_version_check.py
New newer_version_available() function fetches and compares dfetch releases against the running version via the GitHub API using semantic versioning. Comprehensive tests validate version comparison logic, error handling for network failures and malformed JSON, and validation of response schema including missing, empty, and non-string tag_name fields.
Version notification logging method
dfetch/log.py
Add print_newer_version_notice(version: str) method to DLogger that formats and logs a dim notification indicating a newer dfetch release with a link to the releases page.
Command integrations
dfetch/commands/check.py, dfetch/commands/environment.py
Integrate version checking into both commands. Each imports the version-check utility and logs an informational notification when an update is detected, skipped in CI environments. The environment command also displays the current dfetch version.
BDD acceptance tests
features/environment.feature, features/environment.py, features/steps/generic_steps.py
Define and implement BDD scenarios validating dfetch environment output includes current version and update notifications. Includes scenario setup/teardown hooks for mocking GitHub availability, output normalization for version strings, and a step that controls mocked version availability.
Release notes
CHANGELOG.rst
Document the new feature: dfetch check and dfetch environment display a dim update notice when a newer release is available, disabled in CI environments.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested labels

development

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% 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 accurately summarizes the main change: adding a newer-version notice feature to the check and environment commands, which is the primary objective of this PR.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/dfetch-version-check-8bkjb0

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.

Comment thread dfetch/util/github_version_check.py Fixed
Comment thread tests/test_github_version_check.py Fixed
Comment thread tests/test_github_version_check.py Fixed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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 `@CHANGELOG.rst`:
- Line 4: The changelog entry only documents the new update notice for the
"dfetch check" command but omits the "dfetch environment" command; update the
CHANGELOG.rst entry to mention both commands and clarify their differing
behavior — state that "dfetch check" shows a dim notice below the header and is
skipped in CI environments, while the "dfetch environment" command (implemented
in dfetch.commands.environment) shows the notice unconditionally — keep the
wording concise and consistent with the existing bullet style.

In `@dfetch/commands/check.py`:
- Around line 102-108: The log interpolates raw GitHub tag text from
newer_version_available() into a Rich-formatted message (variable newer) which
could be interpreted as Rich markup; fix by escaping the value before
interpolation (use rich.markup.escape or equivalent) and log escape(newer) in
the logger.info call where newer is used so the message uses a safe, literal
version string.

In `@dfetch/commands/environment.py`:
- Around line 39-45: The Rich-formatted log interpolates the GitHub-derived
variable newer directly (see newer_version_available() and the logger.info
call), so escape the string before formatting to avoid accidental Rich markup
injection: import rich.markup.escape (or equivalent) and use escape(newer) in
the f-string passed to logger.info (e.g., f"[dim]  dfetch {escape(newer)}
available — https://github.com/dfetch-org/dfetch/releases[/dim]"); no other code
paths need changing.

In `@tests/test_github_version_check.py`:
- Around line 23-71: Add three unit tests to tests/test_github_version_check.py
to cover the edge cases where the GitHub JSON response has (1) no "tag_name"
key, (2) an empty "tag_name" value (""), and (3) a non-string "tag_name" (e.g.
integer or null). For each new test (e.g. names like
test_newer_version_missing_tag_name_returns_none,
test_newer_version_empty_tag_name_returns_none,
test_newer_version_non_string_tag_name_returns_none) patch
dfetch.util.github_version_check.urllib.request.urlopen, return a mock response
whose read() yields the appropriate JSON bytes ({"some_other_key": "x"},
{"tag_name": ""}, {"tag_name": 123} or {"tag_name": null}), and assert that
newer_version_available() returns None; reuse the existing pattern of
context-manager mock setup used in other tests.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3d945f83-d38c-40e5-8619-325c85fe572c

📥 Commits

Reviewing files that changed from the base of the PR and between 07409bb and 593b4ad.

📒 Files selected for processing (5)
  • CHANGELOG.rst
  • dfetch/commands/check.py
  • dfetch/commands/environment.py
  • dfetch/util/github_version_check.py
  • tests/test_github_version_check.py

Comment thread CHANGELOG.rst Outdated
Comment thread dfetch/commands/check.py Outdated
Comment thread dfetch/commands/environment.py Outdated
Comment thread tests/test_github_version_check.py Outdated
Comment thread dfetch/util/github_version_check.py Fixed
claude and others added 3 commits June 14, 2026 09:52
Poll the GitHub releases API (api.github.com/repos/dfetch-org/dfetch/releases/latest)
and display a dim hint when a newer dfetch release is available.

- dfetch/util/github_version_check.py: pure utility — fetches latest release
  tag and returns it if newer than the running version, silently swallowing
  any network/parse failure
- dfetch/commands/check.py: calls it when CI env var is not set
- dfetch/commands/environment.py: calls it unconditionally (diagnostic command)
- api.github.com:443 is already in the harden-runner allowlist in test.yml

https://claude.ai/code/session_011XLxZxgRCWhSc5PfHGam5P
…line

Removes `BytesIO` and `pytest` from test_github_version_check.py (both
unused, flagged by ruff F401). Black also reformats the _RELEASES_URL
constant to a single line since it fits within the 88-char limit.

https://claude.ai/code/session_011XLxZxgRCWhSc5PfHGam5P
@spoorcc spoorcc force-pushed the claude/dfetch-version-check-8bkjb0 branch from b21c5f0 to dd5c6ec Compare June 14, 2026 11:24

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

♻️ Duplicate comments (2)
CHANGELOG.rst (1)

4-4: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Clarify the release-note wording.

This still reads like a generic “check for new version” note; it doesn’t reflect the actual user-visible split between dfetch check (skips CI) and dfetch environment (always shows the notice). Updating the bullet to match that behavior would make the changelog more accurate.

🤖 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 `@CHANGELOG.rst` at line 4, The changelog entry for issue `#1262` in
CHANGELOG.rst line 4 is too generic and doesn't accurately reflect the different
behavior between the two commands. Reword the bullet point to clarify that
dfetch check skips the version notice during CI environments, while dfetch
environment consistently displays the notice regardless of the CI context. This
will make the release note more precise and informative about the actual
user-visible behavior differences.
dfetch/util/github_version_check.py (1)

41-42: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add explanatory comment for intentional exception swallowing.

The empty except clause lacks a comment explaining that failures are intentionally ignored for best-effort update checks. This violates the "avoid suppressions without fixing root cause" guideline (though the bare pass is intentional here, documentation is still required).

📝 Proposed fix
     except (urllib.error.URLError, json.JSONDecodeError, ValueError):
+        # Best-effort check: silently ignore network/parse failures so CLI remains functional
         pass
     return None
🤖 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 `@dfetch/util/github_version_check.py` around lines 41 - 42, The except clause
in the version check function that catches URLError, JSONDecodeError, and
ValueError lacks a comment explaining the intentional exception suppression. Add
a comment above or within the except block (before the pass statement) that
clearly documents that these exceptions are intentionally being ignored because
the version check is a best-effort operation and failures should not impact the
main application functionality.
🤖 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.

Duplicate comments:
In `@CHANGELOG.rst`:
- Line 4: The changelog entry for issue `#1262` in CHANGELOG.rst line 4 is too
generic and doesn't accurately reflect the different behavior between the two
commands. Reword the bullet point to clarify that dfetch check skips the version
notice during CI environments, while dfetch environment consistently displays
the notice regardless of the CI context. This will make the release note more
precise and informative about the actual user-visible behavior differences.

In `@dfetch/util/github_version_check.py`:
- Around line 41-42: The except clause in the version check function that
catches URLError, JSONDecodeError, and ValueError lacks a comment explaining the
intentional exception suppression. Add a comment above or within the except
block (before the pass statement) that clearly documents that these exceptions
are intentionally being ignored because the version check is a best-effort
operation and failures should not impact the main application functionality.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f32ac126-abcd-4b2e-868e-e88e43ffa96d

📥 Commits

Reviewing files that changed from the base of the PR and between 593b4ad and dd5c6ec.

📒 Files selected for processing (9)
  • CHANGELOG.rst
  • dfetch/commands/check.py
  • dfetch/commands/environment.py
  • dfetch/log.py
  • dfetch/util/github_version_check.py
  • features/environment.feature
  • features/environment.py
  • features/steps/generic_steps.py
  • tests/test_github_version_check.py

@spoorcc spoorcc linked an issue Jun 14, 2026 that may be closed by this pull request
@spoorcc spoorcc force-pushed the claude/dfetch-version-check-8bkjb0 branch from dd5c6ec to 4636dde Compare June 14, 2026 12:05
@spoorcc

spoorcc commented Jun 14, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@spoorcc spoorcc merged commit 4800144 into main Jun 14, 2026
36 checks passed
@spoorcc spoorcc deleted the claude/dfetch-version-check-8bkjb0 branch June 14, 2026 13:09
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.

Check for new version of dfetch

2 participants