mirror of
https://github.com/microsoft/fabric-cicd.git
synced 2026-11-04 12:02:01 +00:00
This pull request adds support for publishing and managing "Org App" and "Org App Audience" item types in the deployment pipeline. It introduces new publisher classes, updates constants and mappings, enhances documentation, and adds comprehensive tests to ensure correct handling of these new item types, including their relationships and deployment order. **Support for new item types: Org App and Org App Audience** - Added `OrgAppPublisher` and `OrgAppAudiencePublisher` classes to handle publishing logic for the new item types (`src/fabric_cicd/_items/_orgapp.py`, `src/fabric_cicd/_items/_orgappaudience.py`) [[1]](diffhunk://#diff-f530c5a6a9918ed3f60e147c9dc1622bbee4054c217183e3cd58bdbfb0cb2401R1-R20) [[2]](diffhunk://#diff-a637318ff073320392d7046a9539f7b33dbee4955718b94bd0081e6888794e0dR1-R13). - Updated the publisher factory and item type mappings to recognize and instantiate these publishers (`src/fabric_cicd/_items/_base_publisher.py`, `src/fabric_cicd/constants.py`) [[1]](diffhunk://#diff-a077ffe516cef014bef47cce16065137725effecb517d141167e72d082592c3fR165-R166) [[2]](diffhunk://#diff-a077ffe516cef014bef47cce16065137725effecb517d141167e72d082592c3fR208-R209) [[3]](diffhunk://#diff-91c2d32be351f155f090c4bd57ebe3c10e646edbc1b663e2a72b697f956a949cR71-R72) [[4]](diffhunk://#diff-91c2d32be351f155f090c4bd57ebe3c10e646edbc1b663e2a72b697f956a949cR118-R119). - Added exclusion rules for Org App children to ensure correct payload structure (`src/fabric_cicd/constants.py`). --------- Co-authored-by: Alon Yeshurun <alonyeshurun+microsoft@microsoft.com> Co-authored-by: shirasassoon <66449905+shirasassoon@users.noreply.github.com>
This commit is contained in:
14 files changed
+296
-6
No files matched your search
@@ -0,0 +1,8 @@
|
||||
kind: new-items
|
||||
body: Add support for Org App and Org App Audience items
|
||||
time: 2026-10-08T12:07:25.20395+03:00
|
||||
custom:
|
||||
Author: ayeshurun
|
||||
AuthorLink: https://github.com/ayeshurun
|
||||
Issue: "1026"
|
||||
IssueLink: https://github.com/microsoft/fabric-cicd/issues/1026
|
||||
@@ -6,7 +6,11 @@
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from azure.identity import AzureCliCredential, AzurePowerShellCredential, ClientSecretCredential
|
||||
from azure.identity import (
|
||||
AzureCliCredential,
|
||||
AzurePowerShellCredential,
|
||||
ClientSecretCredential,
|
||||
)
|
||||
|
||||
root_directory = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(root_directory / "src"))
|
||||
@@ -14,7 +18,7 @@ sys.path.insert(0, str(root_directory / "src"))
|
||||
from fabric_cicd import append_feature_flag, change_log_level, deploy_with_config
|
||||
|
||||
# Uncomment to enable debug
|
||||
# change_log_level()
|
||||
change_log_level()
|
||||
|
||||
# In this example, the config file sits within the root/sample/workspace directory
|
||||
config_file = str(root_directory / "sample" / "workspace" / "config.yml")
|
||||
|
||||
@@ -161,6 +161,17 @@
|
||||
- Referenced items that exist in a different workspace will always point to the original item unless parameterized in the `find_replace` section of the `parameter.yml` file.
|
||||
- Referenced items within the same workspace are automatically re-pointed to the new item in the target workspace.
|
||||
|
||||
## Org App
|
||||
|
||||
- **Parameterization:**
|
||||
- Embedded items within the same workspace are automatically re-pointed to the new item in the target workspace.
|
||||
|
||||
## Org App Audience
|
||||
|
||||
- **Parameterization:**
|
||||
- The parent Org App reference (`parentAppId`) and referenced content items are automatically re-pointed to the deployed items in the target workspace.
|
||||
- In Fabric, an Org App Audience is not a standalone item. However, during deployment, it is treated as such. Its source control files are located within a `.children` folder under the directory of the parent Org App.
|
||||
|
||||
## Paginated Report
|
||||
|
||||
- **Parameterization:**
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json",
|
||||
"metadata": {
|
||||
"type": "OrgAppAudience",
|
||||
"displayName": "OrgApp_ABC"
|
||||
},
|
||||
"config": {
|
||||
"version": "2.0",
|
||||
"logicalId": "84da0817-74f5-b51a-48aa-402f418745cd"
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/orgappaudience/definition/orgAppAudienceDefinition/1.0.0/schema.json",
|
||||
"settings": {
|
||||
"hasAccessToHiddenContent": false,
|
||||
"tabOrder": 0
|
||||
},
|
||||
"parentAppId": "13889f2d-6b42-8aca-4ff0-5528b5e9c284",
|
||||
"elementReferences": [
|
||||
{
|
||||
"elementId": "d41e08fa-7283-4cb2-82ce-b9d3f7f62044",
|
||||
"itemType": "Notebook",
|
||||
"itemLogicalId": "99b570c5-0c79-9dc4-4c9b-fa16c621384c"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json",
|
||||
"metadata": {
|
||||
"type": "OrgApp",
|
||||
"displayName": "OrgApp_ABC"
|
||||
},
|
||||
"config": {
|
||||
"version": "2.0",
|
||||
"logicalId": "13889f2d-6b42-8aca-4ff0-5528b5e9c284"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/fabric/item/orgapp/definition/orgAppDefinition/2.0.0/schema.json",
|
||||
"settings": {},
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "item",
|
||||
"elementId": "d41e08fa-7283-4cb2-82ce-b9d3f7f62044",
|
||||
"itemType": "Notebook",
|
||||
"itemLogicalId": "99b570c5-0c79-9dc4-4c9b-fa16c621384c",
|
||||
"displayName": "Hello World"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -55,6 +55,8 @@ unpublish: # Unpublish configuration (optional)
|
||||
|
||||
features: # Feature flags to enable (optional)
|
||||
- enable_shortcut_publish
|
||||
- enable_experimental_features
|
||||
- enable_bulk_publish
|
||||
|
||||
constants: # Global constants to override (optional)
|
||||
DEFAULT_API_ROOT_URL: "https://msitapi.fabric.microsoft.com"
|
||||
@@ -162,6 +162,8 @@ class ItemPublisher(Publisher):
|
||||
from fabric_cicd._items._mounteddatafactory import MountedDataFactoryPublisher
|
||||
from fabric_cicd._items._notebook import NotebookPublisher
|
||||
from fabric_cicd._items._ontology import OntologyPublisher
|
||||
from fabric_cicd._items._orgapp import OrgAppPublisher
|
||||
from fabric_cicd._items._orgappaudience import OrgAppAudiencePublisher
|
||||
from fabric_cicd._items._paginatedreport import PaginatedReportPublisher
|
||||
from fabric_cicd._items._report import ReportPublisher
|
||||
from fabric_cicd._items._semanticmodel import SemanticModelPublisher
|
||||
@@ -203,6 +205,8 @@ class ItemPublisher(Publisher):
|
||||
ItemType.ONTOLOGY: OntologyPublisher,
|
||||
ItemType.MAP: MapPublisher,
|
||||
ItemType.GRAPH_MODEL: GraphModelPublisher,
|
||||
ItemType.ORG_APP: OrgAppPublisher,
|
||||
ItemType.ORG_APP_AUDIENCE: OrgAppAudiencePublisher,
|
||||
}
|
||||
|
||||
publisher_class = publisher_mapping.get(item_type)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
"""Functions to process and deploy Org App item."""
|
||||
|
||||
from fabric_cicd._common._item import Item
|
||||
from fabric_cicd._items._base_publisher import ItemPublisher
|
||||
from fabric_cicd.constants import EXCLUDE_PATH_REGEX_MAPPING, ItemType
|
||||
|
||||
|
||||
class OrgAppPublisher(ItemPublisher):
|
||||
"""Publisher for Org App items."""
|
||||
|
||||
item_type = ItemType.ORG_APP.value
|
||||
|
||||
def publish_one(self, item_name: str, _item: Item) -> None:
|
||||
"""Publish the app definition without separately deployed child audiences."""
|
||||
self.fabric_workspace_obj._publish_item(
|
||||
item_name=item_name, item_type=self.item_type, exclude_path=EXCLUDE_PATH_REGEX_MAPPING.get(self.item_type)
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
"""Functions to process and deploy Org App Audience item."""
|
||||
|
||||
from fabric_cicd._items._base_publisher import ItemPublisher
|
||||
from fabric_cicd.constants import ItemType
|
||||
|
||||
|
||||
class OrgAppAudiencePublisher(ItemPublisher):
|
||||
"""Publisher for Org App Audience items."""
|
||||
|
||||
item_type = ItemType.ORG_APP_AUDIENCE.value
|
||||
@@ -68,6 +68,8 @@ class ItemType(str, Enum):
|
||||
MOUNTED_DATA_FACTORY = "MountedDataFactory"
|
||||
NOTEBOOK = "Notebook"
|
||||
ONTOLOGY = "Ontology"
|
||||
ORG_APP = "OrgApp"
|
||||
ORG_APP_AUDIENCE = "OrgAppAudience"
|
||||
PAGINATED_REPORT = "PaginatedReport"
|
||||
REFLEX = "Reflex"
|
||||
REPORT = "Report"
|
||||
@@ -113,6 +115,8 @@ SERIAL_ITEM_PUBLISH_ORDER: dict[int, ItemType] = {
|
||||
29: ItemType.ML_EXPERIMENT,
|
||||
30: ItemType.MAP,
|
||||
31: ItemType.GRAPH_MODEL,
|
||||
32: ItemType.ORG_APP,
|
||||
33: ItemType.ORG_APP_AUDIENCE,
|
||||
}
|
||||
|
||||
|
||||
@@ -226,6 +230,12 @@ SENSITIVE_RESPONSE_HEADERS = frozenset({
|
||||
})
|
||||
|
||||
# Publish
|
||||
|
||||
# Item types whose folder location is managed by a parent and cannot move independently
|
||||
NON_MOVABLE_ITEM_TYPES = [
|
||||
ItemType.ORG_APP_AUDIENCE.value,
|
||||
]
|
||||
|
||||
SHELL_ONLY_PUBLISH = [
|
||||
ItemType.LAKEHOUSE.value,
|
||||
ItemType.WAREHOUSE.value,
|
||||
@@ -245,6 +255,7 @@ EXCLUDE_PATH_REGEX_MAPPING = {
|
||||
ItemType.REPORT.value: r".*\.pbi[/\\].*",
|
||||
ItemType.SEMANTIC_MODEL.value: r".*\.pbi[/\\].*",
|
||||
ItemType.EVENTHOUSE.value: r".*\.children[/\\].*",
|
||||
ItemType.ORG_APP.value: r".*\.children[/\\].*",
|
||||
}
|
||||
|
||||
# API Format Mapping for item types that require specific API formats
|
||||
@@ -265,6 +276,7 @@ DATAFLOW_SOURCE_REGEX = (
|
||||
)
|
||||
INVALID_FOLDER_CHAR_REGEX = r'[~"#.%&*:<>?/\\{|}]'
|
||||
KQL_DATABASE_FOLDER_PATH_REGEX = r"(?i)^(.*)/[^/]+\.Eventhouse/\.children(?:/.*)?$"
|
||||
ORG_APP_AUDIENCE_FOLDER_PATH_REGEX = r"(?i)^(.*)/[^/]+\.OrgApp/\.children(?:/.*)?$"
|
||||
DYNAMIC_VARIABLES_REGEX = r"^\$(workspace|items)\."
|
||||
|
||||
# Well known file names
|
||||
|
||||
@@ -15,8 +15,17 @@ import dpath
|
||||
from azure.core.credentials import TokenCredential
|
||||
|
||||
from fabric_cicd import constants
|
||||
from fabric_cicd._common._check_utils import check_regex, check_valid_json_content, check_valid_yaml_content
|
||||
from fabric_cicd._common._exceptions import FailedPublishedItemStatusError, InputError, ParameterFileError, ParsingError
|
||||
from fabric_cicd._common._check_utils import (
|
||||
check_regex,
|
||||
check_valid_json_content,
|
||||
check_valid_yaml_content,
|
||||
)
|
||||
from fabric_cicd._common._exceptions import (
|
||||
FailedPublishedItemStatusError,
|
||||
InputError,
|
||||
ParameterFileError,
|
||||
ParsingError,
|
||||
)
|
||||
from fabric_cicd._common._fabric_endpoint import FabricEndpoint, handle_retry
|
||||
from fabric_cicd._common._item import Item
|
||||
from fabric_cicd._common._logging import log_header
|
||||
@@ -467,6 +476,10 @@ class FabricWorkspace:
|
||||
pattern = re.compile(constants.KQL_DATABASE_FOLDER_PATH_REGEX)
|
||||
match = pattern.match(relative_path)
|
||||
relative_parent_path = match.group(1) if match else None
|
||||
elif item_type == ItemType.ORG_APP_AUDIENCE.value:
|
||||
# Set the OrgAppAudience to the same workspace folder as its parent OrgApp.
|
||||
match = re.match(constants.ORG_APP_AUDIENCE_FOLDER_PATH_REGEX, relative_path)
|
||||
relative_parent_path = match.group(1) if match else None
|
||||
else:
|
||||
relative_parent_path = "/".join(relative_path.split("/")[:-1])
|
||||
|
||||
@@ -857,7 +870,12 @@ class FabricWorkspace:
|
||||
)
|
||||
api_response = metadata_update_response
|
||||
|
||||
if FeatureFlag.DISABLE_WORKSPACE_FOLDER_PUBLISH.value not in constants.FEATURE_FLAG:
|
||||
# Parent-managed items cannot move independently, even if their cached
|
||||
# folder differs after a parent move.
|
||||
if (
|
||||
FeatureFlag.DISABLE_WORKSPACE_FOLDER_PUBLISH.value not in constants.FEATURE_FLAG
|
||||
and item_type not in constants.NON_MOVABLE_ITEM_TYPES
|
||||
):
|
||||
deployed_item = self.deployed_items.get(item_type, {}).get(item_name) if is_deployed else None
|
||||
# Check if the folder has changed
|
||||
if deployed_item is not None and deployed_item.folder_id != item.folder_id:
|
||||
|
||||
+149
-1
@@ -3,6 +3,7 @@
|
||||
|
||||
"""Test publishing functionality including selective publishing based on repository content."""
|
||||
|
||||
import base64
|
||||
import json
|
||||
import logging
|
||||
import tempfile
|
||||
@@ -16,7 +17,10 @@ from fixtures.credentials import DummyTokenCredential
|
||||
import fabric_cicd.publish as publish
|
||||
from fabric_cicd import constants
|
||||
from fabric_cicd._common._exceptions import InputError
|
||||
from fabric_cicd._items._base_publisher import ItemPublisher
|
||||
from fabric_cicd._items._notebook import NotebookPublisher
|
||||
from fabric_cicd._items._orgapp import OrgAppPublisher
|
||||
from fabric_cicd._items._orgappaudience import OrgAppAudiencePublisher
|
||||
from fabric_cicd._items._paginatedreport import PaginatedReportPublisher
|
||||
from fabric_cicd.constants import API_FORMAT_MAPPING, ItemType
|
||||
from fabric_cicd.fabric_workspace import FabricWorkspace
|
||||
@@ -107,6 +111,143 @@ def create_test_item(base_path: Path, folder: Optional[str], name: str, item_typ
|
||||
# =============================================================================
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("item_type", "publisher_class"),
|
||||
[(ItemType.ORG_APP, OrgAppPublisher), (ItemType.ORG_APP_AUDIENCE, OrgAppAudiencePublisher)],
|
||||
)
|
||||
def test_org_app_publisher_uses_default_definition(item_type, publisher_class):
|
||||
"""Both publishers use the generic definition pipeline, excluding app children."""
|
||||
workspace = MagicMock()
|
||||
publisher = ItemPublisher.create(item_type, workspace)
|
||||
|
||||
assert isinstance(publisher, publisher_class)
|
||||
publisher.publish_one("TestItem", MagicMock())
|
||||
|
||||
expected_kwargs = {"item_name": "TestItem", "item_type": item_type.value}
|
||||
if item_type == ItemType.ORG_APP:
|
||||
expected_kwargs["exclude_path"] = constants.EXCLUDE_PATH_REGEX_MAPPING[item_type.value]
|
||||
else:
|
||||
assert item_type.value not in constants.EXCLUDE_PATH_REGEX_MAPPING
|
||||
workspace._publish_item.assert_called_once_with(**expected_kwargs)
|
||||
assert item_type.value not in constants.SHELL_ONLY_PUBLISH
|
||||
assert item_type.value not in constants.API_FORMAT_MAPPING
|
||||
assert not publisher.has_dependency_tracking
|
||||
|
||||
|
||||
def test_publish_org_app_with_nested_audience(mock_endpoint, temp_workspace_dir):
|
||||
"""Child definitions stay out of the app payload and resolve the deployed parent ID."""
|
||||
app_logical_id = "11111111-1111-1111-1111-111111111111"
|
||||
app_dir = create_test_item(temp_workspace_dir, None, "TestApp", "OrgApp", app_logical_id)
|
||||
audience_dir = create_test_item(
|
||||
app_dir, ".children", "TestAudience", "OrgAppAudience", "22222222-2222-2222-2222-222222222222"
|
||||
)
|
||||
(app_dir / "definition.json").write_text(json.dumps({"elements": []}), encoding="utf-8")
|
||||
(audience_dir / "definition.json").write_text(
|
||||
json.dumps({"parentAppId": app_logical_id, "elementReferences": []}), encoding="utf-8"
|
||||
)
|
||||
|
||||
with (
|
||||
patch("fabric_cicd.fabric_workspace.FabricEndpoint", return_value=mock_endpoint),
|
||||
patch.object(FabricWorkspace, "_refresh_deployed_items", new=lambda self: setattr(self, "deployed_items", {})),
|
||||
patch.object(
|
||||
FabricWorkspace, "_refresh_deployed_folders", new=lambda self: setattr(self, "deployed_folders", {})
|
||||
),
|
||||
):
|
||||
workspace = FabricWorkspace(
|
||||
workspace_id="12345678-1234-5678-abcd-1234567890ab",
|
||||
repository_directory=str(temp_workspace_dir),
|
||||
item_type_in_scope=["OrgApp", "OrgAppAudience"],
|
||||
token_credential=DummyTokenCredential(),
|
||||
)
|
||||
|
||||
publish.publish_all_items(workspace)
|
||||
|
||||
bodies = [
|
||||
call.kwargs["body"]
|
||||
for call in mock_endpoint.invoke.call_args_list
|
||||
if call.kwargs.get("method") == "POST" and call.kwargs.get("url", "").endswith("/items")
|
||||
]
|
||||
assert [body["type"] for body in bodies] == ["OrgApp", "OrgAppAudience"]
|
||||
app_parts = bodies[0]["definition"]["parts"]
|
||||
assert all(".children" not in part["path"] for part in app_parts)
|
||||
assert "definition.json" in {part["path"] for part in app_parts}
|
||||
audience_definition = next(
|
||||
part for part in bodies[1]["definition"]["parts"] if part["path"] == "definition.json"
|
||||
)
|
||||
assert json.loads(base64.b64decode(audience_definition["payload"]))["parentAppId"] == "mock-item-id"
|
||||
|
||||
|
||||
def test_publish_org_app_before_audience(mock_endpoint, temp_workspace_dir):
|
||||
"""Repository discovery and publishing place apps before audiences at the end."""
|
||||
create_test_item(temp_workspace_dir, None, "TestApp", "OrgApp", "11111111-1111-1111-1111-111111111111")
|
||||
create_test_item(temp_workspace_dir, None, "TestAudience", "OrgAppAudience", "22222222-2222-2222-2222-222222222222")
|
||||
|
||||
with (
|
||||
patch("fabric_cicd.fabric_workspace.FabricEndpoint", return_value=mock_endpoint),
|
||||
patch.object(FabricWorkspace, "_refresh_deployed_items", new=lambda self: setattr(self, "deployed_items", {})),
|
||||
patch.object(
|
||||
FabricWorkspace, "_refresh_deployed_folders", new=lambda self: setattr(self, "deployed_folders", {})
|
||||
),
|
||||
patch.object(FabricWorkspace, "_publish_item") as mock_publish,
|
||||
):
|
||||
workspace = FabricWorkspace(
|
||||
workspace_id="12345678-1234-5678-abcd-1234567890ab",
|
||||
repository_directory=str(temp_workspace_dir),
|
||||
item_type_in_scope=["OrgAppAudience", "OrgApp"],
|
||||
token_credential=DummyTokenCredential(),
|
||||
)
|
||||
|
||||
publish.publish_all_items(workspace)
|
||||
|
||||
assert set(workspace.repository_items) == {"OrgApp", "OrgAppAudience"}
|
||||
assert [call.kwargs for call in mock_publish.call_args_list] == [
|
||||
{
|
||||
"item_name": "TestApp",
|
||||
"item_type": "OrgApp",
|
||||
"exclude_path": constants.EXCLUDE_PATH_REGEX_MAPPING["OrgApp"],
|
||||
},
|
||||
{"item_name": "TestAudience", "item_type": "OrgAppAudience"},
|
||||
]
|
||||
assert list(constants.SERIAL_ITEM_PUBLISH_ORDER.values())[-2:] == [
|
||||
ItemType.ORG_APP,
|
||||
ItemType.ORG_APP_AUDIENCE,
|
||||
]
|
||||
|
||||
|
||||
def test_unpublish_org_app_audience_before_app(mock_endpoint, temp_workspace_dir):
|
||||
"""Orphan audiences are deleted before their apps without feature flags."""
|
||||
deployed_items = {
|
||||
"OrgApp": {"TestApp": MagicMock(guid="11111111-1111-1111-1111-111111111111")},
|
||||
"OrgAppAudience": {"TestAudience": MagicMock(guid="22222222-2222-2222-2222-222222222222")},
|
||||
}
|
||||
|
||||
with (
|
||||
patch("fabric_cicd.fabric_workspace.FabricEndpoint", return_value=mock_endpoint),
|
||||
patch.object(
|
||||
FabricWorkspace, "_refresh_deployed_items", new=lambda self: setattr(self, "deployed_items", deployed_items)
|
||||
),
|
||||
patch.object(
|
||||
FabricWorkspace, "_refresh_deployed_folders", new=lambda self: setattr(self, "deployed_folders", {})
|
||||
),
|
||||
patch.object(FabricWorkspace, "_unpublish_folders"),
|
||||
patch.object(FabricWorkspace, "_unpublish_item") as mock_unpublish,
|
||||
patch.object(constants, "FEATURE_FLAG", set()),
|
||||
):
|
||||
workspace = FabricWorkspace(
|
||||
workspace_id="12345678-1234-5678-abcd-1234567890ab",
|
||||
repository_directory=str(temp_workspace_dir),
|
||||
item_type_in_scope=["OrgApp", "OrgAppAudience"],
|
||||
token_credential=DummyTokenCredential(),
|
||||
)
|
||||
|
||||
publish.unpublish_all_orphan_items(workspace)
|
||||
|
||||
assert [call.kwargs for call in mock_unpublish.call_args_list] == [
|
||||
{"item_name": "TestAudience", "item_type": "OrgAppAudience"},
|
||||
{"item_name": "TestApp", "item_type": "OrgApp"},
|
||||
]
|
||||
|
||||
|
||||
def test_publish_only_existing_item_types(mock_endpoint, temp_workspace_dir):
|
||||
"""Test that publish_all_items only attempts to publish item types that exist in repository."""
|
||||
create_test_item(temp_workspace_dir, None, "TestNotebook", "Notebook", "test-notebook-id")
|
||||
@@ -488,7 +629,14 @@ def test_unpublish_feature_flag_warnings(mock_endpoint, temp_workspace_dir, capl
|
||||
workspace = FabricWorkspace(
|
||||
workspace_id="12345678-1234-5678-abcd-1234567890ab",
|
||||
repository_directory=str(temp_workspace_dir),
|
||||
item_type_in_scope=["Lakehouse", "Warehouse", "SQLDatabase", "CosmosDBDatabase", "Eventhouse", "GraphModel"],
|
||||
item_type_in_scope=[
|
||||
"Lakehouse",
|
||||
"Warehouse",
|
||||
"SQLDatabase",
|
||||
"CosmosDBDatabase",
|
||||
"Eventhouse",
|
||||
"GraphModel",
|
||||
],
|
||||
token_credential=DummyTokenCredential(),
|
||||
)
|
||||
|
||||
|
||||
Reference in new issue
Block a user