diff --git a/changelog/+infrahubctl-proposedchange.changed.md b/changelog/+infrahubctl-proposedchange.changed.md new file mode 100644 index 00000000..9b75045d --- /dev/null +++ b/changelog/+infrahubctl-proposedchange.changed.md @@ -0,0 +1 @@ +Updated branch report command to use node metadata for proposed change creator information instead of the deprecated relationship-based approach. Requires Infrahub 1.7 or above. diff --git a/infrahub_sdk/ctl/branch.py b/infrahub_sdk/ctl/branch.py index 4182f56e..d309c1d5 100644 --- a/infrahub_sdk/ctl/branch.py +++ b/infrahub_sdk/ctl/branch.py @@ -110,6 +110,10 @@ def generate_proposed_change_tables(proposed_changes: list[CoreProposedChange]) proposed_change_tables: list[Table] = [] for pc in proposed_changes: + metadata = pc.get_node_metadata() + created_by = metadata.created_by.display_label if metadata and metadata.created_by else "-" + created_at = format_timestamp(metadata.created_at) if metadata and metadata.created_at else "-" + # Create proposal table proposed_change_table = Table(show_header=False, box=None) proposed_change_table.add_column(justify="left") @@ -119,8 +123,8 @@ def generate_proposed_change_tables(proposed_changes: list[CoreProposedChange]) proposed_change_table.add_row("Name", pc.name.value) proposed_change_table.add_row("State", str(pc.state.value)) proposed_change_table.add_row("Is draft", "Yes" if pc.is_draft.value else "No") - proposed_change_table.add_row("Created by", pc.created_by.peer.name.value) # type: ignore[attr-defined] - proposed_change_table.add_row("Created at", format_timestamp(str(pc.created_by.updated_at))) # type: ignore[attr-defined] + proposed_change_table.add_row("Created by", created_by) + proposed_change_table.add_row("Created at", created_at) proposed_change_table.add_row("Approvals", str(len(pc.approved_by.peers))) proposed_change_table.add_row("Rejections", str(len(pc.rejected_by.peers))) @@ -295,9 +299,9 @@ async def report( proposed_changes = await client.filters( kind=CoreProposedChange, # type: ignore[type-abstract] source_branch__value=branch_name, - include=["created_by"], prefetch_relationships=True, property=True, + include_metadata=True, ) branch_table = generate_branch_report_table(branch=branch, diff_tree=diff_tree, git_files_changed=git_files_changed) diff --git a/infrahub_sdk/protocols_base.py b/infrahub_sdk/protocols_base.py index 8a841b5b..7f6569ae 100644 --- a/infrahub_sdk/protocols_base.py +++ b/infrahub_sdk/protocols_base.py @@ -6,6 +6,7 @@ import ipaddress from .context import RequestContext + from .node.metadata import NodeMetadata from .schema import MainSchemaTypes @@ -203,6 +204,8 @@ def is_resource_pool(self) -> bool: ... def get_raw_graphql_data(self) -> dict | None: ... + def get_node_metadata(self) -> NodeMetadata | None: ... + @runtime_checkable class CoreNode(CoreNodeBase, Protocol): diff --git a/tests/unit/ctl/test_branch_report.py b/tests/unit/ctl/test_branch_report.py index c9af76c5..201f1c92 100644 --- a/tests/unit/ctl/test_branch_report.py +++ b/tests/unit/ctl/test_branch_report.py @@ -341,19 +341,21 @@ def mock_branch_report_with_proposed_changes(httpx_mock: HTTPXMock) -> HTTPXMock ], }, "rejected_by": {"count": 0, "edges": []}, + }, + "node_metadata": { + "created_at": "2025-11-10T14:30:00Z", "created_by": { - "node": { - "id": "187895d8-723e-8f5d-3614-c517ac8e761c", - "hfid": ["johndoe"], - "display_label": "John Doe", - "__typename": "CoreAccount", - "name": {"value": "John Doe"}, - }, - "properties": { - "updated_at": "2025-11-10T14:30:00Z", - }, + "id": "187895d8-723e-8f5d-3614-c517ac8e761c", + "__typename": "CoreAccount", + "display_label": "John Doe", }, - } + "updated_at": "2025-11-10T14:30:00Z", + "updated_by": { + "id": "187895d8-723e-8f5d-3614-c517ac8e761c", + "__typename": "CoreAccount", + "display_label": "John Doe", + }, + }, }, { "node": { @@ -392,19 +394,21 @@ def mock_branch_report_with_proposed_changes(httpx_mock: HTTPXMock) -> HTTPXMock }, ], }, + }, + "node_metadata": { + "created_at": "2025-11-12T09:15:00Z", "created_by": { - "node": { - "id": "287895d8-723e-8f5d-3614-c517ac8e762c", - "hfid": ["janesmith"], - "display_label": "Jane Smith", - "__typename": "CoreAccount", - "name": {"value": "Jane Smith"}, - }, - "properties": { - "updated_at": "2025-11-10T14:30:00Z", - }, + "id": "287895d8-723e-8f5d-3614-c517ac8e762c", + "__typename": "CoreAccount", + "display_label": "Jane Smith", + }, + "updated_at": "2025-11-12T09:15:00Z", + "updated_by": { + "id": "287895d8-723e-8f5d-3614-c517ac8e762c", + "__typename": "CoreAccount", + "display_label": "Jane Smith", }, - } + }, }, ], }