Skip to content

Closes #931 - Support dynamic variable resolution in find_replace.find_value#1007

Draft
Copilot wants to merge 3 commits into
mainfrom
copilot/add-dynamic-variable-resolution-support
Draft

Closes #931 - Support dynamic variable resolution in find_replace.find_value#1007
Copilot wants to merge 3 commits into
mainfrom
copilot/add-dynamic-variable-resolution-support

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 31, 2026

Description

This updates find_replace.find_value to support dynamic variable resolution with the same $workspace.* syntax used by replace_value, while enforcing semantic constraints for unsupported cases.

  • Runtime resolution in extract_find_value

    • Added optional workspace_obj input and dynamic resolution path before regex/literal evaluation.
    • find_value now resolves $workspace.$id, $workspace.$name, $workspace.$name_encoded, $workspace.<name>, and $workspace.<name>.$id when workspace context is available.
  • Guardrails for item-attribute variables in find_value

    • $items.<type>.<name>.$<attribute> now fails fast with InputError (same-workspace target attributes are invalid as search inputs).
    • $workspace.<name>.$items.<type>.<name>.$<attribute> is allowed and resolved, with a warning that the referenced cross-workspace item must exist at deploy time.
  • Call-site wiring

    • Passed workspace_obj=self from FabricWorkspace._replace_parameters so deployment-time replacements resolve dynamic find_value inputs.
  • Validation/docs alignment

    • Added a validation note that find_value may be $-prefixed for dynamic resolution.
    • Updated parameterization docs to describe supported find_value dynamic variables, cross-workspace caution, and explicit $items.* exclusion.
    • Added a concrete example in the parameter file snippet showing dynamic find_value usage ($workspace.Dev Workspace.$id) in find_replace.
  • Changelog compliance

    • Added an unreleased changelog entry for the documentation update.
find_info = extract_find_value(parameter_dict, raw_file, filter_match, workspace_obj=self)

Linked Issue (REQUIRED)

Linked via PR title format.

Original prompt

Summary

Add support for dynamic variable resolution in the find_value field of the find_replace parameter, following the same $workspace.* and $items.* variable syntax already supported by replace_value.

Background

Currently, dynamic replacement (e.g. $workspace.<name>.$id, $items.<type>.<name>.$<attribute>) only works in replace_value. This feature extends it to find_value so users can write parameters like:

find_replace:
  - find_value: "$workspace.dev.$id"
    replace_value:
      PROD: "$workspace.prod.$id"

Variable Classification for find_value

After careful analysis, the following rules apply:

✅ Allow silently (no warning)

These always resolve before deployment runs, and their values could legitimately be present in repository files:

  • $workspace.$id, $workspace.$name, $workspace.$name_encoded
  • $workspace.<name>.$id / $workspace.<name>

⚠️ Allow with a warning

Cross-workspace item attributes could legitimately appear in files (e.g. a pipeline referencing another workspace's Lakehouse ID), but the item must already exist at deployment time:

  • $workspace.<name>.$items.<type>.<name>.$<attribute>

Warning message to use:

"Dynamic variable '{find_value}' in find_value references a cross-workspace item attribute. Ensure the referenced item exists in workspace '{workspace_name}' at deployment time, or the replacement will fail."

Where workspace_name is extracted from the variable string (the part between $workspace. and .$items.).

❌ Block with InputError

Same-workspace item attributes ($items.*) are semantically impossible as a find_value — the target item's ID is what you're writing into the file; it can never be what you're searching for:

  • $items.<type>.<name>.$<attribute>

Error message to use:

"Dynamic variable '{find_value}' is not supported in find_value. Same-workspace item attributes ($items.*) resolve to the target environment's item ID, which cannot be present in the source file."

Required Code Changes

1. src/fabric_cicd/_parameter/_utils.pyextract_find_value

Modify the function signature to accept an optional workspace_obj parameter, and add dynamic resolution logic before the regex/literal handling:

def extract_find_value(
    param_dict: dict,
    file_content: str,
    filter_match: bool,
    workspace_obj: Optional["FabricWorkspace"] = None,
) -> dict:

After getting find_value from param_dict and before the is_regex check, add:

# Resolve dynamic variable in find_value if present
if find_value and find_value.startswith("$") and workspace_obj is not None:
    if find_value.startswith("$items."):
        msg = (
            f"Dynamic variable '{find_value}' is not supported in find_value. "
            "Same-workspace item attributes ($items.*) resolve to the target environment's item ID, "
            "which cannot be present in the source file."
        )
        raise InputError(msg, logger)

    if find_value.startswith("$workspace."):
        # Warn if this is a cross-workspace item attribute reference
        var_string = find_value.removeprefix("$workspace.")
        if ".$items." in var_string:
            workspace_name = var_string.split(".$items.", 1)[0].strip()
            logger.warning(
                f"Dynamic variable '{find_value}' in find_value references a cross-workspace item attribute. "
                f"Ensure the referenced item exists in workspace '{workspace_name}' at deployment time, "
                "or the replacement will fail."
            )

    find_value = extract_replace_value(workspace_obj, find_value)

2. src/fabric_cicd/fabric_workspace.py_replace_parameters

Pass self as workspace_obj to extract_find_value:

find_info = extract_find_value(parameter_dict, raw_file, filter_match, workspace_obj=self)

3. src/fabric_cicd/_parameter/_parameter.py_validate_required_values

The find_value validation currently checks that find_value is a string (which $-prefixed variables satisfy), so no structural change is needed. However, add a note/comment that find_value may start with $ for dynamic variable resolution.

4. Tests — tests/test_parameter_utils.py

Add test cases for extract_find_value with workspace_obj:

  • $workspace.$id as find_value → resolves to workspace ID → searched in file content
  • $workspace.<name>.$id as find_value → resolves correctly
  • $workspace.<name>.$items.<type>.<name>.$id as find_value → resolves with a warning logged
  • $items.<type>.<name>.$id as find_value → raises InputError

5. Documentation — docs/how_to/parameterization.md

Under the Dynamic Replacement section, add a note that find_value also supports dynamic variables, with the same supported variable list. Clearly document:

  • $workspace.* variables are fully supported
  • Cross-workspace $workspace.<name>.$items.* variables are su...

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Add support for dynamic variable resolution in find_value Closes #931 - Support dynamic variable resolution in find_replace.find_value May 31, 2026
Copilot AI requested a review from shirasassoon May 31, 2026 12:11
@shirasassoon
Copy link
Copy Markdown
Contributor

shirasassoon commented May 31, 2026

@copilot The documentation is missing an example, maybe add it to the sample parameter file

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 31, 2026

@copilot The documentation is missing an example, maybe add it to the sample parameter file

Implemented in commit 1d52274 by adding a dynamic find_value example to the parameter.yml example block in docs/how_to/parameterization.md.

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