Skip to content

Conversation

@guptahars
Copy link


This checklist is used to make sure that common guidelines for a pull request are followed.

Related command

General Guidelines

  • Have you run azdev style <YOUR_EXT> locally? (pip install azdev required)
  • Have you run python scripts/ci/test_index.py -q locally? (pip install wheel==0.30.0 required)
  • My extension version conforms to the Extension version schema

For new extensions:

About Extension Publish

There is a pipeline to automatically build, upload and publish extension wheels.
Once your pull request is merged into main branch, a new pull request will be created to update src/index.json automatically.
You only need to update the version information in file setup.py and historical information in file HISTORY.rst in your PR but do not modify src/index.json.

Copilot AI review requested due to automatic review settings November 24, 2025 08:51
@azure-client-tools-bot-prd
Copy link

Validation for Breaking Change Starting...

Thanks for your contribution!

@azure-client-tools-bot-prd
Copy link

Hi @guptahars,
Please write the description of changes which can be perceived by customers into HISTORY.rst.
If you want to release a new extension version, please update the version in setup.py as well.

@yonzhan
Copy link
Collaborator

yonzhan commented Nov 24, 2025

Thank you for your contribution! We will review the pull request and get back to you soon.

@github-actions
Copy link

The git hooks are available for azure-cli and azure-cli-extensions repos. They could help you run required checks before creating the PR.

Please sync the latest code with latest dev branch (for azure-cli) or main branch (for azure-cli-extensions).
After that please run the following commands to enable git hooks:

pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>

@github-actions
Copy link

CodeGen Tools Feedback Collection

Thank you for using our CodeGen tool. We value your feedback, and we would like to know how we can improve our product. Please take a few minutes to fill our codegen survey

Copilot finished reviewing on behalf of guptahars November 24, 2025 08:54
@github-actions
Copy link

Hi @guptahars

Release Suggestions

Module: workload-orchestration

  • Please log updates into to src/workload-orchestration/HISTORY.rst
  • Update VERSION to 5.0.0 in src/workload-orchestration/setup.py

Notes

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces "Backfill v2 changes" for the workload-orchestration Azure CLI extension, adding new commands and updating existing ones to support configuration schema operations, template hierarchy management, and improved configuration workflows.

Key Changes:

  • Added new command groups for configuration schema management and config-template hierarchy operations
  • Introduced a ConfigurationHelper utility class to handle common operations like retrieving configuration IDs, template identifiers, and schemas
  • Refactored configuration commands (show, set, download) to use dynamic configuration paths based on hierarchy IDs instead of hardcoded target names

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
configuration/schema/__cmd_group.py New command group for managing configuration template schemas
configuration/_schema_show.py New command to display schema placeholders for configuration and solution templates
configuration/_config_helper.py New helper class providing utility methods for configuration operations (ID resolution, schema retrieval, template lookups)
configuration/_config_show.py Updated to use hierarchy IDs and dynamic configuration paths instead of static naming
configuration/_config_set.py Enhanced with YAML validation, create/update flow handling, and schema-based placeholder generation
configuration/_config_download.py Refactored to use dynamic configuration names and improved filename generation
configuration/__init__.py Added import for new schema_show module
config_template/hierarchy/__cmd_group.py New command group for config template hierarchy management
config_template/hierarchy/_show.py New command to show linked hierarchies for config templates
config_template/hierarchy/__init__.py Module initialization for hierarchy subcommands
config_template/_link.py New command to link config templates to hierarchies
config_template/_unlink.py New command to unlink config templates from hierarchies
config_template/__init__.py Added imports for new link/unlink commands and hierarchy submodule

Comment on lines +89 to +92
for linked_hierarchy in linked:
context_info["linkedHierarchies"].extend(
linked_hierarchy.get("hierarchyIds", [])
)
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

Potential performance issue: The nested loop starting at line 89 uses .extend() inside a loop which builds up the linkedHierarchies list. If there are many linked_hierarchy items, this could be inefficient. Consider using a list comprehension or flattening the structure in a single pass.

Suggested change
for linked_hierarchy in linked:
context_info["linkedHierarchies"].extend(
linked_hierarchy.get("hierarchyIds", [])
)
context_info["linkedHierarchies"] = [
hid
for linked_hierarchy in linked
for hid in linked_hierarchy.get("hierarchyIds", [])
]

Copilot uses AI. Check for mistakes.
Comment on lines +134 to +135
template_subscription = self.ctx.args.template_subscription if self.ctx.args.template_subscription else self.ctx.subscription_id
solution_flag = self.ctx.args.solution if self.ctx.args.solution else False
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

Code duplication: The logic for determining template_subscription and solution_flag (lines 134-135) is duplicated in multiple places throughout the file (lines 159-160, etc.). This pattern appears in _config_show.py, _config_set.py, and _config_download.py. Consider extracting this into a helper method to reduce duplication and improve maintainability.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +20
def __init__(self):
"""Initialize the configuration helper"""
pass

Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

Missing documentation: The __init__ method creates an unused instance. Since all methods are static, this class doesn't need an __init__ method at all, or the class should be documented to clarify that it's meant to be used as a namespace for static helper methods only.

Suggested change
def __init__(self):
"""Initialize the configuration helper"""
pass

Copilot uses AI. Check for mistakes.
# Convert hierarchy_id to string if it's an AAZ type
hierarchy_id_str = str(hierarchy_id) if hierarchy_id else ""

def try_get_config_id(lookup_id, api_version = "2025-08-01"):
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

The variable api_version parameter has a default value but is used in a function signature with a space before the equals sign. This should be api_version="2025-08-01" without spaces to follow Python conventions.

Suggested change
def try_get_config_id(lookup_id, api_version = "2025-08-01"):
def try_get_config_id(lookup_id, api_version="2025-08-01"):

Copilot uses AI. Check for mistakes.
Comment on lines +449 to +451

yaml.add_representer(type(None), represent_none)
placeholder_yaml = yaml.dump(placeholder_dict, default_flow_style=False, allow_unicode=True)
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

The YAML representer function is being added to the global YAML module configuration inside a method. This modifies global state and can cause issues if the method is called multiple times or if other code uses YAML differently. Consider using yaml.SafeDumper with a custom representer instance or resetting the representer after use.

Suggested change
yaml.add_representer(type(None), represent_none)
placeholder_yaml = yaml.dump(placeholder_dict, default_flow_style=False, allow_unicode=True)
class CustomDumper(yaml.SafeDumper):
pass
CustomDumper.add_representer(type(None), represent_none)
placeholder_yaml = yaml.dump(
placeholder_dict,
default_flow_style=False,
allow_unicode=True,
Dumper=CustomDumper
)

Copilot uses AI. Check for mistakes.
placeholder_yaml = yaml.dump(placeholder_dict, default_flow_style=False, allow_unicode=True)
return placeholder_yaml
else:
raise CLIInternalError("No editable configs.")
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

Error message duplication and inconsistency: The same "No editable configs." error message appears at line 421 and line 454. Additionally, line 232 in _config_helper.py uses "No Editable configs." with different capitalization. These should be consolidated to a single consistent message, preferably as a constant or coming from the helper function.

Copilot uses AI. Check for mistakes.
response = client.send_request(request=request, stream=False)

if response.http_response.status_code == 404:
raise CLIInternalError(f"No Editable configs. Schema doesn't exist for template: {template_version_id}")
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

Inconsistent capitalization in error message: "No Editable configs." has capital 'E' while the same message elsewhere uses lowercase. This should be consistent with other error messages, preferably "No editable configs." or better yet, a more descriptive message.

Suggested change
raise CLIInternalError(f"No Editable configs. Schema doesn't exist for template: {template_version_id}")
raise CLIInternalError(f"No editable configs. Schema doesn't exist for template: {template_version_id}")

Copilot uses AI. Check for mistakes.
Comment on lines +136 to +140
# Validate that --solution flag is only used with target hierarchy IDs
if hasattr(self.ctx.args, 'solution') and self.ctx.args.solution:
hierarchy_id = str(self.ctx.args.hierarchy_id).lower()
if "microsoft.edge/targets" not in hierarchy_id:
raise CLIInternalError("The --solution flag can only be used when the hierarchy-id is for a target (Microsoft.Edge/targets). Solutions are only configurable at a target level.")
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

Potential security issue: The validation check for the --solution flag only checks if the string "microsoft.edge/targets" is in the lowercase hierarchy_id. This check could produce false positives if the hierarchy ID contains this substring in an unexpected position (e.g., in a resource group name). Consider using a more robust ARM ID parsing approach to verify the resource type.

Copilot uses AI. Check for mistakes.
def _output(self, *args, **kwargs):
result = self.deserialize_output(self.ctx.vars.instance, client_flatten=True)
print(result["properties"]["values"])
pass
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

Unnecessary pass statement after returning a value. This line serves no purpose and should be removed.

Suggested change
pass

Copilot uses AI. Check for mistakes.
Comment on lines +100 to +114
except Exception:
pass
try:
configuration_id = try_get_config_id(service_group_id)
if configuration_id:
return configuration_id
except Exception:
pass
else:
try:
configuration_id = try_get_config_id(hierarchy_id_str)
if configuration_id:
return configuration_id
except Exception:
pass
Copy link

Copilot AI Nov 24, 2025

Choose a reason for hiding this comment

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

Exception handling anti-pattern: Catching all exceptions with bare except Exception: and silently passing (lines 100-101, 106-107, 113-114) can hide real errors and make debugging difficult. At minimum, these should log the exception or provide more specific error handling for expected failure cases.

Copilot uses AI. Check for mistakes.
@guptahars guptahars closed this Nov 24, 2025
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.

2 participants