Skip to content

Conversation

@wvandeun
Copy link
Contributor

@wvandeun wvandeun commented Nov 17, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • New get_diff_tree method retrieves detailed change tracking with time-range filtering
    • New branch report command provides cleanup status analysis and proposed changes overview
  • Chores

    • Migrated build tooling from Poetry to UV
    • Updated build system to Hatch
    • Expanded Python support to versions 3.10-3.13
    • Added comprehensive developer documentation

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Nov 17, 2025

Deploying infrahub-sdk-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: 65d588a
Status: ✅  Deploy successful!
Preview URL: https://0493f58b.infrahub-sdk-python.pages.dev
Branch Preview URL: https://wvd-20251114-infp388-branch.infrahub-sdk-python.pages.dev

View logs

@wvandeun wvandeun self-assigned this Nov 17, 2025
@coderabbitai
Copy link

coderabbitai bot commented Nov 17, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This pull request transitions the project's package management and build tooling from Poetry to UV across all CI/CD workflows, development documentation, and build configuration. The pyproject.toml is migrated to PEP 621 format with Hatch as the build backend. Functionality-wise, a new public get_diff_tree() method is added to both async and sync client classes for retrieving detailed diff tree data. The CLI branch command gains a new report() command for branch cleanup status reporting. Supporting infrastructure includes expanded GraphQL variable type mappings for DateTime, new documentation files (AGENTS.md across multiple directories), and updates to development workflows to use UV-based commands.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 85.37% which is sufficient. The required threshold is 80.00%.
Title check ✅ Passed The title clearly identifies the main feature addition: a new CLI command 'infrahubctl branch report', which aligns with the substantial changes in the pull request including new branch reporting functionality, diff tree support, and related infrastructure updates.

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.

@wvandeun
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 17, 2025

✅ Actions performed

Review triggered.

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.

Copy link

@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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.github/workflows/ci.yml (2)

123-160: Override working directory for uv commands in docs job

The docs job sets defaults.run.working-directory: ./docs, but pyproject.toml and uv.lock exist only at the repo root. Running uv sync and uv run from ./docs will fail because uv cannot find the project configuration.

Override the working directory for these steps to execute from the repo root:

      - name: Install dependencies
        working-directory: .
        run: uv sync --all-groups --all-extras

      - name: "Build docs website"
        working-directory: .
        run: "uv run invoke docs"

213-266: Add explicit python-version input to astral-sh/setup-uv@v4 step

The astral-sh/setup-uv action respects the Python version set by actions/setup-python, so the current workflow will function. However, to ensure uv creates environments for each matrix Python version, the python-version input (or UV_PYTHON environment variable) should be explicitly set.

Update the setup-uv step:

- name: Install UV
  uses: astral-sh/setup-uv@v4
  with:
    version: "${{ needs.prepare-environment.outputs.UV_VERSION }}"
    python-version: ${{ matrix.python-version }}

This makes the Python version selection explicit and ensures robust behavior across the full matrix.

🧹 Nitpick comments (6)
.gitignore (1)

11-12: Consider removing the redundant .venv pattern.

Both .venv/ and .venv patterns are present; however, .venv/ alone is sufficient to ignore the virtual environment directory. The .venv pattern is technically redundant since git only tracks files within directories, not the directory itself.

Consider applying this diff to remove the redundancy:

-.venv/
-.venv
+.venv/

Alternatively, if you prefer maximum clarity about intent, keeping both is harmless and acceptable.

AGENTS.md (1)

106-106: Optional: Consider hyphenating "on demand".

Static analysis suggests "on-demand" when used as a compound adjective. This is a stylistic choice and can be deferred.

infrahub_sdk/diff.py (1)

41-52: Diff tree metadata type and Query builder align with client usage

DiffTreeData accurately captures the metadata and node list shape used by the new get_diff_tree client methods, and get_diff_tree_query() builds a Query that:

  • Filters DiffTree by branch, name, from_time, to_time.
  • Selects the expected metadata fields (num_*, {from,to}_time, base_branch, diff_branch, name) plus the full node structure that diff_tree_node_to_node_diff consumes.
  • Declares variables with appropriate Python types (str, str | None, datetime | None), matching the new DateTime variable support.

Only minor nit is that the GraphQL operation name "GetDiffTree" is now used by both the older string-based query and this new Query object, which is allowed but can be slightly confusing when debugging; not a blocker.

Also applies to: 146-206

tests/unit/ctl/test_branch_report.py (1)

12-38: Good coverage for timestamp formatting, Git diff helper, and branch report CLI

These tests thoroughly exercise:

  • format_timestamp across valid ISO, timezone-aware, invalid, and None inputs.
  • check_git_files_changed for files present, absent, empty responses, and HTTP errors.
  • The branch report CLI for both no proposed changes and complex proposed-change cases including is_draft, approvals/rejections, and creator info.

One small consideration: assertions like "Is draft No" rely on exact Rich table spacing and may become fragile if column widths change; if that starts causing churn, you might relax them to focus on content rather than alignment.

Also applies to: 40-126, 128-426

infrahub_sdk/ctl/branch.py (2)

26-33: Broaden format_timestamp typing to match actual usage

format_timestamp currently annotates timestamp: str -> str, but it gracefully handles None (and tests rely on None returning None). To better reflect reality and keep type-checkers happy, consider:

def format_timestamp(timestamp: str | None) -> str | None:
    ...

The implementation itself looks correct for the formats you’re handling.


189-294: Branch report flow is solid; a couple of small cleanups

The report command nicely ties together:

  • Branch metadata (creation time, status, sync_with_git, schema changes).
  • Optional diff creation from branched_from to now (update_diff flag).
  • Retrieval of the diff tree and Git changes, plus a summary table of diff counts.
  • Proposed changes listing with creator, draft status, approvals, and rejections.

Two small suggestions:

  1. Git files changed handling

    You initialize git_files_changed = None and then immediately overwrite it with the result of check_git_files_changed, so the "N/A" branch is never taken. If the intent was to show "N/A" for branches not synced with Git, you could make that explicit:

    git_files_changed = None
    if branch.sync_with_git:
        git_files_changed = await check_git_files_changed(client, branch=branch_name)
  2. Timestamp parsing robustness

    Parsing branch.branched_from via datetime.fromisoformat(branch.branched_from.replace("Z", "+00:00")) is fine for current formats, but if that field ever becomes a native datetime, you’ll hit an AttributeError. A small isinstance guard would make this safer, though not strictly required right now.

Overall, the command behavior is clear and matches the new tests.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc79402 and fd46ca8.

⛔ Files ignored due to path filters (2)
  • poetry.lock is excluded by !**/*.lock
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (26)
  • .github/workflows/ci.yml (6 hunks)
  • .github/workflows/define-versions.yml (1 hunks)
  • .github/workflows/publish-pypi.yml (1 hunks)
  • .github/workflows/release.yml (2 hunks)
  • .gitignore (1 hunks)
  • .vale/styles/spelling-exceptions.txt (3 hunks)
  • AGENTS.md (1 hunks)
  • CLAUDE.md (4 hunks)
  • README.md (1 hunks)
  • docs/AGENTS.md (1 hunks)
  • docs/docs/python-sdk/guides/client.mdx (1 hunks)
  • infrahub_sdk/client.py (3 hunks)
  • infrahub_sdk/ctl/AGENTS.md (1 hunks)
  • infrahub_sdk/ctl/branch.py (3 hunks)
  • infrahub_sdk/ctl/cli.py (1 hunks)
  • infrahub_sdk/diff.py (3 hunks)
  • infrahub_sdk/graphql/constants.py (1 hunks)
  • infrahub_sdk/graphql/renderers.py (2 hunks)
  • infrahub_sdk/node/attribute.py (1 hunks)
  • infrahub_sdk/node/related_node.py (2 hunks)
  • infrahub_sdk/pytest_plugin/AGENTS.md (1 hunks)
  • pyproject.toml (3 hunks)
  • tasks.py (1 hunks)
  • tests/AGENTS.md (1 hunks)
  • tests/unit/ctl/test_branch_report.py (1 hunks)
  • tests/unit/sdk/test_diff_summary.py (2 hunks)
🧰 Additional context used
🪛 LanguageTool
AGENTS.md

[uncategorized] ~106-~106: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...Nodes load attributes and relationships on demand - Batch Operations: Support for bul...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (29)
.vale/styles/spelling-exceptions.txt (1)

23-23: LGTM!

The spelling exception additions are appropriate and correctly ordered alphabetically. All four terms are legitimate:

  • callouts: Common documentation term
  • Diataxis: Documentation methodology framework
  • frontmatter: Standard documentation/markdown term
  • Typer: CLI framework used in this codebase

Also applies to: 27-27, 47-47, 120-120

docs/docs/python-sdk/guides/client.mdx (1)

20-20: LGTM!

The installation documentation correctly reflects the migration from Poetry to UV, providing users with the updated command while maintaining the pip installation option.

infrahub_sdk/ctl/cli.py (1)

7-8: LGTM!

The error message has been appropriately updated to reflect the UV-based workflow while maintaining the pip installation option for standard users.

README.md (1)

59-73: LGTM!

The new UV development setup section is well-documented and provides clear examples for different use cases. The commands are correct and will help developers understand how to set up their development environment with UV.

tasks.py (1)

42-44: LGTM!

The documentation generation commands have been correctly updated to use UV instead of Poetry, maintaining consistency with the broader tooling migration.

Also applies to: 52-52

infrahub_sdk/node/attribute.py (1)

108-108: LGTM!

Adding updated_at to the query data structure is appropriate and aligns with the existing updated_at attribute defined at line 53. This ensures the field is consistently available in generated queries.

infrahub_sdk/graphql/renderers.py (1)

4-4: Verification complete: VARIABLE_TYPE_MAPPING supports datetime.

The import of datetime in infrahub_sdk/graphql/renderers.py (line 4) is properly supported by the VARIABLE_TYPE_MAPPING in infrahub_sdk/graphql/constants.py, which includes both (datetime, "DateTime!") and (datetime | None, "DateTime") mappings. The changes are correct and well-aligned.

AGENTS.md (1)

1-245: Comprehensive guidance for AI coding assistants.

This documentation provides excellent coverage of the repository structure, development setup, architecture, conventions, and domain-specific guidance. The structure is clear and will be valuable for AI coding assistants working with the codebase.

infrahub_sdk/pytest_plugin/AGENTS.md (1)

1-324: Excellent pytest plugin development documentation.

This comprehensive guide covers the pytest plugin architecture, YAML test file format, test item classes, configuration, and common patterns. The structure is clear with practical examples that will be valuable for developers working on the custom pytest plugin.

tests/AGENTS.md (1)

1-366: Comprehensive testing guidance.

This documentation provides excellent coverage of the testing framework, directory organization, running tests, pytest configuration, fixtures, and common patterns. The examples are clear and will help developers write consistent, high-quality tests.

CLAUDE.md (3)

3-5: Appropriate deprecation notice.

The deprecation notice correctly directs users to the new AGENTS.md standard while maintaining backward compatibility.


15-54: UV migration commands look correct.

All development commands have been properly migrated from Poetry to UV syntax, including dependency installation, formatting, linting, testing, and documentation generation.


181-181: Python version range documented.

Line 181 documents CI/CD testing on Python 3.10-3.13. This should align with the Python version support documented in AGENTS.md line 19 (currently states 3.9-3.13). Please ensure consistency across all documentation.

docs/AGENTS.md (1)

1-357: Excellent documentation development guidance.

This comprehensive guide covers the Docusaurus-based documentation system, Diataxis framework, directory structure, development workflow, writing guidelines, MDX components, and code quality practices. The structure and examples will be valuable for developers contributing to documentation.

infrahub_sdk/ctl/AGENTS.md (1)

1-314: Comprehensive CLI development guidance.

This documentation provides excellent coverage of the infrahubctl CLI architecture, command structure, AsyncTyper patterns, code conventions, error handling, testing, and common patterns. The practical examples and file organization details will be valuable for developers working on CLI commands.

.github/workflows/release.yml (3)

33-39: Proper UV setup and dependency installation.

The workflow correctly migrates from Poetry to UV, using astral-sh/setup-uv@v4 and uv sync --all-groups --all-extras for dependency installation.


44-48: Correct version extraction using UV and tomllib.

The version extraction properly uses uv run python with tomllib to read from pyproject.toml, and correctly determines prerelease/devrelease status using the packaging.version.Version class. This is the appropriate approach for PEP 621-compliant projects.


58-64: Improved error messaging for tag verification.

The tag version check now provides clear "Expected vs Got" output when there's a mismatch, improving debugging experience.

.github/workflows/publish-pypi.yml (1)

44-64: UV setup and dependency caching look consistent

Using astral-sh/setup-uv@v4, caching .venv keyed on uv.lock, and running uv sync --all-groups --all-extras is a good migration away from Poetry here. No issues spotted with these steps.

pyproject.toml (2)

1-104: PEP 621 + hatchling migration looks coherent

The move to [project] metadata, optional-dependencies for ctl/all, dependency-groups for tests/lint/types/dev, and hatchling as the build backend all look consistent with the new uv-based workflow. The script and pytest plugin entry points are wired correctly to existing modules.


347-352: Build backend configuration matches package layout

Specifying requires = ["hatchling"], build-backend = "hatchling.build", and limiting wheel packages to ["infrahub_sdk"] aligns with the rest of this repo’s structure and the CI workflows using uv build.

.github/workflows/ci.yml (2)

161-187: Generated-docs validation job’s uv usage is consistent

For validate-generated-documentation, setting up Python 3.12, installing uv, running uv sync --all-groups --all-extras, and then uv run invoke docs-validate from the repo root matches the new pyproject/uv setup and should be fine.


270-302: Integration tests updated correctly to use uv

Switching the integration job to:

  • install uv,
  • uv sync --all-groups --all-extras,
  • uv run pytest --cov infrahub_sdk tests/integration/,
  • uv run codecov --flags integration-tests,

fits the new dependency management model and reuses the same tooling as unit tests.

infrahub_sdk/node/related_node.py (1)

67-80: Consistent updated_at support for related nodes

Reading updated_at from either the top-level data or properties and always including "updated_at": None in _generate_query_data gives related nodes a stable updated_at attribute (needed by consumers like the branch report). The change does alter the GraphQL selection to always include an updated_at field in properties, but that’s a reasonable trade-off for consistency.

Also applies to: 165-176

tests/unit/sdk/test_diff_summary.py (1)

1-8: Comprehensive tests for diff tree query and client behavior

The additions:

  • Validate the rendered structure of get_diff_tree_query() (operation name, variables, core fields).
  • Exercise get_diff_tree on both async and sync clients with full metadata, no diff, and filtered (name + time range) scenarios.
  • Confirm time-range validation by asserting from_time > to_time raises ValueError.

This gives solid coverage around the new diff tree functionality and should catch regressions in both query construction and client-side handling.

Also applies to: 166-405

infrahub_sdk/ctl/branch.py (1)

35-59: check_git_files_changed logic is sound

Building the diff/files URL from client.address, using client._get with the client’s default timeout, and decoding JSON via decode_json is consistent with the rest of the SDK. The iteration over data[branch].values() to find any repo with a non-empty files list correctly returns True when changes exist and False otherwise.

No functional issues here.

infrahub_sdk/client.py (3)

38-38: LGTM! Import statement adds necessary dependencies.

The import adds the required types and functions for the new get_diff_tree method. Also includes get_diff_summary_query which was previously used but not explicitly imported.


2582-2638: Verify query type consistency (sync version).

The sync implementation has the same potential inconsistency as the async version. Line 2608 calls query.render(), while the similar get_diff_summary method (line 2563) passes the query directly. Please ensure both get_diff_tree_query() and get_diff_summary_query() are being used consistently according to their return types.


1286-1342: No issues found—the query builder pattern is correct as implemented.

The apparent inconsistency between calling .render() on get_diff_tree_query() (line 1312) and passing get_diff_summary_query() directly (line 1256) is intentional and correct. Verification confirms:

  • get_diff_tree_query() returns a Query object with a .render() method that produces a GraphQL string
  • get_diff_summary_query() returns a raw GraphQL string directly
  • execute_graphql() expects a query: str parameter in both cases
  • Each usage correctly handles its respective query builder's return type

The two query builders are designed differently—one uses a programmatic Query object pattern, the other returns a raw string—and the implementation correctly applies each pattern.

Likely an incorrect or invalid review comment.

Comment on lines 7 to 8
UV_VERSION:
value: "0.9.8"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Verify the UV version is current and appropriate.

The workflow output has been correctly renamed from POETRY_VERSION to UV_VERSION with version "0.9.8". Please confirm that this version is appropriate and that all consuming workflows have been updated to reference UV_VERSION instead of POETRY_VERSION.


🌐 Web query:

What is the latest stable version of UV (uv package manager)?

💡 Result:

The latest stable release is uv 0.9.9 — released November 12, 2025. [1]

Sources:
[1] astral-sh/uv — Releases (GitHub).


🏁 Script executed:

#!/bin/bash
# Search for UV_VERSION and POETRY_VERSION references in workflows
echo "=== Searching for UV_VERSION references in workflows ==="
rg -n "UV_VERSION" .github/workflows/ --type yaml

echo ""
echo "=== Searching for POETRY_VERSION references in workflows ==="
rg -n "POETRY_VERSION" .github/workflows/ --type yaml

echo ""
echo "=== Searching for outputs from define-versions workflow ==="
rg -n "define-versions" .github/workflows/ --type yaml -A 3 -B 3

Length of output: 2246


Update UV_VERSION to current stable release (0.9.9).

The latest stable version of UV is 0.9.9, released November 12, 2025. The current version "0.9.8" in the workflow is outdated. All consuming workflows (release.yml, publish-pypi.yml, ci.yml) correctly reference UV_VERSION, and the POETRY_VERSION reference is commented out, so the migration is complete. Update line 8 in .github/workflows/define-versions.yml to set the version to "0.9.9".

🤖 Prompt for AI Agents
In .github/workflows/define-versions.yml around lines 7 to 8, the UV_VERSION
value is set to the outdated "0.9.8"; update that line to set UV_VERSION to the
current stable release "0.9.9" so dependent workflows pick up the correct
version.

@wvandeun wvandeun force-pushed the wvd-20251114-infp388-branch-cleanup-mechanism branch from fd46ca8 to fcbb594 Compare November 17, 2025 18:29
@github-actions github-actions bot added the type/documentation Improvements or additions to documentation label Nov 17, 2025
@wvandeun wvandeun force-pushed the wvd-20251114-infp388-branch-cleanup-mechanism branch from fcbb594 to 86bc4b9 Compare November 17, 2025 18:31
@wvandeun wvandeun changed the title Add infrahubctl bracnh report command Add infrahubctl branch report command Nov 17, 2025
@github-actions github-actions bot removed the type/documentation Improvements or additions to documentation label Nov 17, 2025
@wvandeun
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 17, 2025

✅ Actions performed

Review triggered.

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.

@github-actions github-actions bot added the type/documentation Improvements or additions to documentation label Nov 17, 2025
Replace runtime | operator with Union from typing to support Python 3.9-3.13:
- graphql/constants.py: VARIABLE_TYPE_MAPPING tuples
- diff.py: GraphQL query variables dict

The | operator for types only works at runtime in Python 3.10+.
(Union[bool, None], "Boolean"),
(datetime, "DateTime!"),
(datetime | None, "DateTime"),
(Union[datetime, None], "DateTime"),
Copy link
Contributor

Choose a reason for hiding this comment

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

Hey Wim, I commented on the comment that CodeRabbit added. The better approach here would be to target the infrahub-develop branch where Python 3.9 is removed. So we don't want the old style Union here as it would cause linting issues in the other branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type/documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants