Closes #845 Add support for PaginatedReport item type (#1037)

## Description

Adds `PaginatedReport` as a supported Fabric item type, enabling CI/CD
deployment of Power BI Paginated Reports.

- **`constants.py`**: Added `PAGINATED_REPORT = "PaginatedReport"` to
`ItemType` enum; inserted at position 13 in `SERIAL_ITEM_PUBLISH_ORDER`
(after `REPORT`); added to `NO_ASSIGNED_CAPACITY_REQUIRED`
- **`_paginatedreport.py`** *(new)*: Simple `PaginatedReportPublisher`
extending `ItemPublisher` — uses default definition deployment, no
custom file processing required
- **`_base_publisher.py`**: Registered `PaginatedReportPublisher` in the
factory method
- **`test_publish.py`**: Added `test_publish_paginated_report_item`
- **`item_types.md`**: Added `## Paginated Report` section

> **Note:** Sample workspace files and HTTP trace regeneration require a
real Fabric workspace export and are left as a follow-up.

## Linked Issue (REQUIRED)

<!-- 
REQUIRED: This PR must be linked to an issue via the PR title format.
PR Title MUST follow this exact format: "Fixes #123 - Short Description"

Use the appropriate action word:
- Fixes #123 (for bug fixes)
- Closes #456 (for features)  
- Resolves #789 (for other changes)

Example: "Fixes #520 - Add Python version requirements to documentation"
-->

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Shira Sassoon <shirasassoon@microsoft.com>
Co-authored-by: shirasassoon <66449905+shirasassoon@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2026-06-24 17:18:17 +03:00
1 parent a025d10756
commit 4c1042343c
11 files changed
+648 -17

No files matched your search

@@ -0,0 +1,8 @@
kind: new-items
body: Add support for Paginated Report item
time: 2026-06-22T15:57:11.5259012+03:00
custom:
Author: shirasassoon
AuthorLink: https://github.com/shirasassoon
Issue: "845"
IssueLink: https://github.com/microsoft/fabric-cicd/issues/845
+1
View File
@@ -44,6 +44,7 @@ item_type_in_scope = [
"Environment",
"SemanticModel",
"Report",
"PaginatedReport",
"Eventhouse",
"KQLDatabase",
"KQLQueryset",
+37
View File
@@ -1255,3 +1255,40 @@ key_value_replace:
}
}
```
### Paginated Reports
#### `find_replace` Parameterization Case
**Case:** A Paginated Report (`.rdl` file) is connected to a Semantic Model via the `ConnectString` element in the `DataSources` section. The connection string contains an `Initial Catalog` value in the format `sobe_wowvirtualserver-<semantic-model-id>`, where the GUID is the Semantic Model's item ID. When deploying to a target environment (PPE/PROD/etc), this GUID must be updated to point to the corresponding Semantic Model in the target workspace.
**Solution:** Use `find_replace` in the `parameter.yml` file to replace the Semantic Model ID embedded in the connection string with the dynamically resolved ID of the Semantic Model in the target environment.
<span class="md-h4-nonanchor">parameter.yml file</span>
```yaml
find_replace:
# Semantic Model ID in Paginated Report connection string
- find_value: "4febdc09-e283-4a4f-9658-38bab81bab2d"
replace_value:
PPE: "$items.SemanticModel.ABC.$id" # PPE Semantic Model ID (dynamic)
PROD: "$items.SemanticModel.ABC.$id" # PROD Semantic Model ID (dynamic)
item_type: "PaginatedReport"
file_path: "/ABC Paginated.PaginatedReport/ABC Paginated.rdl"
```
<span class="md-h4-nonanchor">ABC Paginated.rdl file</span>
```xml
<DataSources>
<DataSource Name="ABC">
<ConnectionProperties>
<DataProvider>PBIDATASET</DataProvider>
<ConnectString>Data Source=pbiazure://api.powerbi.com/;Identity Provider="https://login.microsoftonline.com/common, https://analysis.windows.net/powerbi/api, f0b72488-7082-488a-a7e8-eada97bd842d";Initial Catalog=sobe_wowvirtualserver-4febdc09-e283-4a4f-9658-38bab81bab2d;Integrated Security=ClaimsToken</ConnectString>
</ConnectionProperties>
<rd:SecurityType>None</rd:SecurityType>
</DataSource>
</DataSources>
```
**Note:** The `Initial Catalog` value follows the format `sobe_wowvirtualserver-<semantic-model-id>`. Only the GUID portion needs to be parameterized.
+6
View File
@@ -146,6 +146,12 @@
- 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.
## Paginated Report
- **Parameterization:**
- Data sources connected to items outside of the same workspace will always point to the original item unless parameterized in the `find_replace` section of the `parameter.yml` file. For more guidance, see [Parameterization -> Paginated Reports](../how_to/parameterization.md#paginated-reports).
- **Connections** are not source controlled and must be configured manually after initial deployment.
## Real-Time Dashboard
- **Parameterization:**
@@ -0,0 +1,11 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json",
"metadata": {
"type": "PaginatedReport",
"displayName": "ABC Paginated"
},
"config": {
"version": "2.0",
"logicalId": "bbf2052a-f353-a162-473d-a2e0be0becb5"
}
}
@@ -0,0 +1,517 @@
<?xml version="1.0" encoding="utf-8"?>
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner" xmlns:wa="http://schemas.microsoft.com/sqlserver/reporting/webauthoring" xmlns:df="http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition/defaultfontfamily" xmlns:am="http://schemas.microsoft.com/sqlserver/reporting/authoringmetadata" MustUnderstand="df">
<rd:ReportUnitType>Inch</rd:ReportUnitType>
<df:DefaultFontFamily>Segoe UI</df:DefaultFontFamily>
<wa:ThemeName>default</wa:ThemeName>
<wa:WebAuthoringVersion>1.0</wa:WebAuthoringVersion>
<wa:DefaultView>Paginated</wa:DefaultView>
<am:AuthoringMetadata>
<am:CreatedBy>
<am:Name>WebAuthoring</am:Name>
<am:Version>2026.6.5.2147</am:Version>
</am:CreatedBy>
<am:UpdatedBy>
<am:Name>WebAuthoring</am:Name>
<am:Version>2026.6.5.2147</am:Version>
</am:UpdatedBy>
<am:LastModifiedTimestamp>2026-06-22T13:16:57.911Z</am:LastModifiedTimestamp>
</am:AuthoringMetadata>
<wa:FilterSelections>
<wa:FilterSelection>
<wa:DataSourceName>ABC</wa:DataSourceName>
<wa:DatasetName>DataSet1</wa:DatasetName>
<wa:EntityName>Table</wa:EntityName>
<wa:PropertyName>Column1</wa:PropertyName>
<wa:FilterType>Basic</wa:FilterType>
<wa:FilterOperator>NotIn</wa:FilterOperator>
</wa:FilterSelection>
<wa:FilterSelection>
<wa:DataSourceName>ABC</wa:DataSourceName>
<wa:DatasetName>DataSet1</wa:DatasetName>
<wa:EntityName>Table_2</wa:EntityName>
<wa:PropertyName>Column1</wa:PropertyName>
<wa:FilterType>Basic</wa:FilterType>
<wa:FilterOperator>NotIn</wa:FilterOperator>
</wa:FilterSelection>
</wa:FilterSelections>
<AutoRefresh>0</AutoRefresh>
<DataSources>
<DataSource Name="ABC">
<ConnectionProperties>
<DataProvider>PBIDATASET</DataProvider>
<ConnectString>Data Source=pbiazure://api.powerbi.com/;Identity Provider="https://login.microsoftonline.com/common, https://analysis.windows.net/powerbi/api, f0b72488-7082-488a-a7e8-eada97bd842d";Initial Catalog=sobe_wowvirtualserver-4febdc09-e283-4a4f-9658-38bab81bab2d;Integrated Security=ClaimsToken</ConnectString>
</ConnectionProperties>
<rd:SecurityType>None</rd:SecurityType>
</DataSource>
</DataSources>
<DataSets>
<DataSet Name="DataSet1">
<Query>
<DataSourceName>ABC</DataSourceName>
<CommandText>DEFINE VAR __DS0Core =
SUMMARIZECOLUMNS(
ROLLUPADDISSUBTOTAL('Table'[Column1], "IsGrandTotalRowTotal"),
"SumColumn1", CALCULATE(SUM('Table_2'[Column1]))
)
EVALUATE
__DS0Core
ORDER BY
[IsGrandTotalRowTotal] DESC, 'Table'[Column1]</CommandText>
<wa:PreviewCommandText>DEFINE
VAR __DS0Core =
SUMMARIZECOLUMNS(
ROLLUPADDISSUBTOTAL('Table'[Column1], "IsGrandTotalRowTotal"),
"SumColumn1", CALCULATE(SUM('Table_2'[Column1]))
)
VAR __DS0BodyLimited =
TOPN(500, __DS0Core, [IsGrandTotalRowTotal], 0, 'Table'[Column1], 1)
EVALUATE
__DS0BodyLimited
ORDER BY
[IsGrandTotalRowTotal] DESC, 'Table'[Column1]</wa:PreviewCommandText>
</Query>
<Fields>
<Field Name="Table_Column1">
<DataField>Table[Column1]</DataField>
<AggregateIndicatorField xmlns="http://schemas.microsoft.com/sqlserver/reporting/2011/01/reportdefinition">x_5b_IsGrandTotalRowTotal_5d_</AggregateIndicatorField>
</Field>
<Field Name="Table_5f_2_Column1">
<DataField>[SumColumn1]</DataField>
</Field>
<Field Name="x_5b_IsGrandTotalRowTotal_5d_">
<DataField>[IsGrandTotalRowTotal]</DataField>
</Field>
</Fields>
<InterpretSubtotalsAsDetails>False</InterpretSubtotalsAsDetails>
</DataSet>
</DataSets>
<ReportSections>
<ReportSection>
<Body>
<ReportItems>
<Tablix Name="Tablix1">
<TablixBody>
<TablixColumns>
<TablixColumn>
<Width>47.625mm</Width>
</TablixColumn>
<TablixColumn>
<Width>47.625mm</Width>
</TablixColumn>
</TablixColumns>
<TablixRows>
<TablixRow>
<Height>0.25in</Height>
<TablixCells>
<TablixCell>
<CellContents>
<Textbox Name="Textbox80cf0acd33c54c008a482f6a34b0b157">
<CanGrow>true</CanGrow>
<UserSort>
<SortExpression>=Fields!Table_Column1.Value</SortExpression>
</UserSort>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Column1</Value>
<Style>
<FontFamily>Segoe UI Semibold</FontFamily>
<FontSize>11pt</FontSize>
<Color>=Variables!Style_FontColorHeaders.Value</Color>
</Style>
</TextRun>
</TextRuns>
</Paragraph>
</Paragraphs>
<Style>
<Border>
<Style>None</Style>
</Border>
<TopBorder>
<Style>None</Style>
</TopBorder>
<BottomBorder>
<Color>=Variables!Style_OutlineColor.Value</Color>
<Style>=If(Variables!Style_HeaderEnableBorderBottom.Value = "true", "Solid", "None")</Style>
<Width>=If(Variables!Style_HeaderBorderBottomWeight.Value = "", Variables!Style_GridHorizontalWeight.Value, Variables!Style_HeaderBorderBottomWeight.Value)</Width>
</BottomBorder>
<LeftBorder>
<Color>=Variables!Style_BackColorHeaders.Value</Color>
<Style>=If(Variables!Style_GridVerticalEnabledTable.Value = "true", "Solid", "None")</Style>
<Width>=Variables!Style_GridVerticalWeight.Value</Width>
</LeftBorder>
<BackgroundColor>=Variables!Style_BackColorHeaders.Value</BackgroundColor>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>4pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Textbox896f03ac5bdf44c9b4e87e42769ade9e">
<CanGrow>true</CanGrow>
<UserSort>
<SortExpression>=Fields!Table_5f_2_Column1.Value</SortExpression>
</UserSort>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Column1</Value>
<Style>
<FontFamily>Segoe UI Semibold</FontFamily>
<FontSize>11pt</FontSize>
<Format>0</Format>
<Color>=Variables!Style_FontColorHeaders.Value</Color>
</Style>
</TextRun>
</TextRuns>
</Paragraph>
</Paragraphs>
<Style>
<Border>
<Style>None</Style>
</Border>
<TopBorder>
<Style>None</Style>
</TopBorder>
<BottomBorder>
<Color>=Variables!Style_OutlineColor.Value</Color>
<Style>=If(Variables!Style_HeaderEnableBorderBottom.Value = "true", "Solid", "None")</Style>
<Width>=If(Variables!Style_HeaderBorderBottomWeight.Value = "", Variables!Style_GridHorizontalWeight.Value, Variables!Style_HeaderBorderBottomWeight.Value)</Width>
</BottomBorder>
<LeftBorder>
<Color>=Variables!Style_GridColor.Value</Color>
<Style>=If(Variables!Style_GridVerticalEnabledTable.Value = "true", "Solid", "None")</Style>
<Width>=Variables!Style_GridVerticalWeight.Value</Width>
</LeftBorder>
<BackgroundColor>=Variables!Style_BackColorHeaders.Value</BackgroundColor>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>4pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
</TablixCells>
</TablixRow>
<TablixRow>
<Height>0.25in</Height>
<TablixCells>
<TablixCell>
<CellContents>
<Textbox Name="Textboxf1a3a67870354537a98b127ae3f45293">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!Table_Column1.Value</Value>
<Style>
<Color>=If(RowNumber(Nothing) Mod 2 &lt;&gt; 0, Variables!Style_FontColorValues1.Value, Variables!Style_FontColorValues2.Value)</Color>
</Style>
</TextRun>
</TextRuns>
</Paragraph>
</Paragraphs>
<DataElementName>Table_Column1</DataElementName>
<Style>
<Border>
<Style>None</Style>
</Border>
<TopBorder>
<Style>None</Style>
</TopBorder>
<BottomBorder>
<Color>=Variables!Style_GridColor.Value</Color>
<Style>=If(Variables!Style_GridHorizontalEnabledTable.Value = "true", "Solid", "None")</Style>
<Width>=Variables!Style_GridHorizontalWeight.Value</Width>
</BottomBorder>
<LeftBorder>
<Color>=If(RowNumber(Nothing) Mod 2 &lt;&gt; 0, Variables!Style_BackColorValues1.Value, Variables!Style_BackColorValues2.Value)</Color>
<Style>=If(Variables!Style_GridVerticalEnabledTable.Value = "true", "Solid", "None")</Style>
<Width>=Variables!Style_GridVerticalWeight.Value</Width>
</LeftBorder>
<BackgroundColor>=If(RowNumber(Nothing) Mod 2 &lt;&gt; 0, Variables!Style_BackColorValues1.Value, Variables!Style_BackColorValues2.Value)</BackgroundColor>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>5pt</PaddingRight>
<PaddingTop>=Variables!Style_RowPadding.Value</PaddingTop>
<PaddingBottom>=Variables!Style_RowPadding.Value</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Textboxf61917a237d24141a7b6261eda575490">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Fields!Table_5f_2_Column1.Value</Value>
<Style>
<Format>0</Format>
<Color>=If(RowNumber(Nothing) Mod 2 &lt;&gt; 0, Variables!Style_FontColorValues1.Value, Variables!Style_FontColorValues2.Value)</Color>
</Style>
</TextRun>
</TextRuns>
</Paragraph>
</Paragraphs>
<DataElementName>Table_2_Column1</DataElementName>
<Style>
<Border>
<Style>None</Style>
</Border>
<TopBorder>
<Style>None</Style>
</TopBorder>
<BottomBorder>
<Color>=Variables!Style_GridColor.Value</Color>
<Style>=If(Variables!Style_GridHorizontalEnabledTable.Value = "true", "Solid", "None")</Style>
<Width>=Variables!Style_GridHorizontalWeight.Value</Width>
</BottomBorder>
<LeftBorder>
<Color>=Variables!Style_GridColor.Value</Color>
<Style>=If(Variables!Style_GridVerticalEnabledTable.Value = "true", "Solid", "None")</Style>
<Width>=Variables!Style_GridVerticalWeight.Value</Width>
</LeftBorder>
<BackgroundColor>=If(RowNumber(Nothing) Mod 2 &lt;&gt; 0, Variables!Style_BackColorValues1.Value, Variables!Style_BackColorValues2.Value)</BackgroundColor>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>5pt</PaddingRight>
<PaddingTop>=Variables!Style_RowPadding.Value</PaddingTop>
<PaddingBottom>=Variables!Style_RowPadding.Value</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
</TablixCells>
</TablixRow>
<TablixRow>
<Height>0.25in</Height>
<TablixCells>
<TablixCell>
<CellContents>
<Textbox Name="Textbox763baa62af0247e5928ca11a2adc4cac">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>Total</Value>
<Style>
<FontFamily>Segoe UI Semibold</FontFamily>
<FontSize>11pt</FontSize>
<Color>=Variables!Style_FontColorHeaders.Value</Color>
</Style>
</TextRun>
</TextRuns>
</Paragraph>
</Paragraphs>
<DataElementName>Total</DataElementName>
<Style>
<Border>
<Style>None</Style>
</Border>
<TopBorder>
<Color>=Variables!Style_OutlineColor.Value</Color>
<Style>=If(Variables!Style_HeaderEnableBorderBottom.Value = "true", "Solid", "None")</Style>
<Width>=If(Variables!Style_HeaderBorderBottomWeight.Value = "", Variables!Style_GridHorizontalWeight.Value, Variables!Style_HeaderBorderBottomWeight.Value)</Width>
</TopBorder>
<BottomBorder>
<Style>None</Style>
</BottomBorder>
<LeftBorder>
<Color>=Variables!Style_GridColor.Value</Color>
<Style>=If(Variables!Style_GridVerticalEnabledTable.Value = "true", "Solid", "None")</Style>
<Width>=Variables!Style_GridVerticalWeight.Value</Width>
</LeftBorder>
<BackgroundColor>=Variables!Style_BackColorHeaders.Value</BackgroundColor>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>4pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Textbox55cc1a5ee8174dd9a0d0a51888cbff1a">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value>=Aggregate(Fields!Table_5f_2_Column1.Value)</Value>
<Style>
<FontFamily>Segoe UI Semibold</FontFamily>
<FontSize>11pt</FontSize>
<Format>0</Format>
<Color>=Variables!Style_FontColorHeaders.Value</Color>
</Style>
</TextRun>
</TextRuns>
</Paragraph>
</Paragraphs>
<DataElementName>Total</DataElementName>
<Style>
<Border>
<Style>None</Style>
</Border>
<TopBorder>
<Color>=Variables!Style_OutlineColor.Value</Color>
<Style>=If(Variables!Style_HeaderEnableBorderBottom.Value = "true", "Solid", "None")</Style>
<Width>=If(Variables!Style_HeaderBorderBottomWeight.Value = "", Variables!Style_GridHorizontalWeight.Value, Variables!Style_HeaderBorderBottomWeight.Value)</Width>
</TopBorder>
<BottomBorder>
<Style>None</Style>
</BottomBorder>
<LeftBorder>
<Color>=Variables!Style_GridColor.Value</Color>
<Style>=If(Variables!Style_GridVerticalEnabledTable.Value = "true", "Solid", "None")</Style>
<Width>=Variables!Style_GridVerticalWeight.Value</Width>
</LeftBorder>
<BackgroundColor>=Variables!Style_BackColorHeaders.Value</BackgroundColor>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>4pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
</TablixCells>
</TablixRow>
</TablixRows>
<wa:FieldSelections>
<wa:FieldSelection>
<wa:EntityName>Table</wa:EntityName>
<wa:PropertyName>Column1</wa:PropertyName>
<wa:Aggregate>None</wa:Aggregate>
</wa:FieldSelection>
<wa:FieldSelection>
<wa:EntityName>Table_2</wa:EntityName>
<wa:PropertyName>Column1</wa:PropertyName>
<wa:Aggregate>Sum</wa:Aggregate>
</wa:FieldSelection>
</wa:FieldSelections>
<wa:ShowGrandTotals>true</wa:ShowGrandTotals>
</TablixBody>
<TablixColumnHierarchy>
<TablixMembers>
<TablixMember />
<TablixMember />
</TablixMembers>
</TablixColumnHierarchy>
<TablixRowHierarchy>
<TablixMembers>
<TablixMember>
<KeepWithGroup>After</KeepWithGroup>
<RepeatOnNewPage>true</RepeatOnNewPage>
</TablixMember>
<TablixMember>
<Group Name="Details" />
</TablixMember>
<TablixMember>
<KeepWithGroup>Before</KeepWithGroup>
<RepeatOnNewPage>true</RepeatOnNewPage>
</TablixMember>
</TablixMembers>
</TablixRowHierarchy>
<DataSetName>DataSet1</DataSetName>
<wa:StyleName>default</wa:StyleName>
<Top>0mm</Top>
</Tablix>
</ReportItems>
<Height>2.25in</Height>
</Body>
<Width>190.5mm</Width>
<Page>
<LeftMargin>0.5in</LeftMargin>
<RightMargin>0.5in</RightMargin>
<TopMargin>0.5in</TopMargin>
<BottomMargin>0.5in</BottomMargin>
</Page>
</ReportSection>
</ReportSections>
<ReportParametersLayout>
<GridLayoutDefinition>
<NumberOfColumns>4</NumberOfColumns>
<NumberOfRows>2</NumberOfRows>
</GridLayoutDefinition>
</ReportParametersLayout>
<Language>=User!Language</Language>
<Variables>
<Variable Name="Theme_BackGroundColor">
<Value>#FFFFFF</Value>
</Variable>
<Variable Name="Theme_ForeGroundColor">
<Value>#252423</Value>
</Variable>
<Variable Name="Theme_TableAccentColor">
<Value>#118DFF</Value>
</Variable>
<Variable Name="Style_OutlineColor">
<Value>#118DFF</Value>
</Variable>
<Variable Name="Style_GridColor">
<Value>#E5E5E5</Value>
</Variable>
<Variable Name="Style_GridVerticalEnabledTable">
<Value>false</Value>
</Variable>
<Variable Name="Style_GridVerticalWeight">
<Value>0pt</Value>
</Variable>
<Variable Name="Style_GridHorizontalEnabledTable">
<Value>true</Value>
</Variable>
<Variable Name="Style_GridHorizontalWeight">
<Value>0.5pt</Value>
</Variable>
<Variable Name="Style_HeaderEnableBorderBottom">
<Value>true</Value>
</Variable>
<Variable Name="Style_HeaderBorderBottomWeight">
<Value>1.0pt</Value>
</Variable>
<Variable Name="Style_BackColorHeaders">
<Value>#FFFFFF</Value>
</Variable>
<Variable Name="Style_FontColorHeaders">
<Value>#252423</Value>
</Variable>
<Variable Name="Style_BackColorValues1">
<Value>#FFFFFF</Value>
</Variable>
<Variable Name="Style_BackColorValues2">
<Value>#EEEDED</Value>
</Variable>
<Variable Name="Style_FontColorValues2">
<Value>#252423</Value>
</Variable>
<Variable Name="Style_FontColorValues1">
<Value>#252423</Value>
</Variable>
<Variable Name="Style_RowPadding">
<Value>3pt</Value>
</Variable>
</Variables>
</Report>
+7
View File
@@ -66,6 +66,13 @@ find_replace:
PROD: "$items.SemanticModel.ABC.$id"
# Optional fields:
file_path: "/ByConnection.Report/definition.pbir"
# Paginated Report - semantic model id in connection string using dynamic replacement
- find_value: "4febdc09-e283-4a4f-9658-38bab81bab2d"
replace_value:
PPE: "$items.SemanticModel.ABC.$id"
PROD: "$items.SemanticModel.ABC.$id"
item_type: "PaginatedReport"
file_path: "/ABC Paginated.PaginatedReport/ABC Paginated.rdl"
key_value_replace:
- find_key: $.variables[?(@.name=="SQL_Server")].value
@@ -160,6 +160,7 @@ 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._paginatedreport import PaginatedReportPublisher
from fabric_cicd._items._report import ReportPublisher
from fabric_cicd._items._semanticmodel import SemanticModelPublisher
from fabric_cicd._items._sparkjobdefinition import SparkJobDefinitionPublisher
@@ -181,6 +182,7 @@ class ItemPublisher(Publisher):
ItemType.NOTEBOOK: NotebookPublisher,
ItemType.SEMANTIC_MODEL: SemanticModelPublisher,
ItemType.REPORT: ReportPublisher,
ItemType.PAGINATED_REPORT: PaginatedReportPublisher,
ItemType.COPY_JOB: CopyJobPublisher,
ItemType.DATA_BUILD_TOOL_JOB: DataBuildToolJobPublisher,
ItemType.KQL_DATABASE: KQLDatabasePublisher,
@@ -0,0 +1,13 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
"""Functions to process and deploy PaginatedReport item."""
from fabric_cicd._items._base_publisher import ItemPublisher
from fabric_cicd.constants import ItemType
class PaginatedReportPublisher(ItemPublisher):
"""Publisher for PaginatedReport items."""
item_type = ItemType.PAGINATED_REPORT.value
+19 -17
View File
@@ -65,6 +65,7 @@ class ItemType(str, Enum):
MOUNTED_DATA_FACTORY = "MountedDataFactory"
NOTEBOOK = "Notebook"
ONTOLOGY = "Ontology"
PAGINATED_REPORT = "PaginatedReport"
REFLEX = "Reflex"
REPORT = "Report"
SEMANTIC_MODEL = "SemanticModel"
@@ -90,22 +91,23 @@ SERIAL_ITEM_PUBLISH_ORDER: dict[int, ItemType] = {
10: ItemType.NOTEBOOK,
11: ItemType.SEMANTIC_MODEL,
12: ItemType.REPORT,
13: ItemType.COPY_JOB,
14: ItemType.DATA_BUILD_TOOL_JOB,
15: ItemType.KQL_DATABASE,
16: ItemType.KQL_QUERYSET,
17: ItemType.REFLEX,
18: ItemType.EVENTSTREAM,
19: ItemType.KQL_DASHBOARD,
20: ItemType.DATAFLOW,
21: ItemType.DATA_PIPELINE,
22: ItemType.GRAPHQL_API,
23: ItemType.APACHE_AIRFLOW_JOB,
24: ItemType.MOUNTED_DATA_FACTORY,
25: ItemType.DATA_AGENT,
26: ItemType.ML_EXPERIMENT,
27: ItemType.ONTOLOGY,
28: ItemType.MAP,
13: ItemType.PAGINATED_REPORT,
14: ItemType.COPY_JOB,
15: ItemType.DATA_BUILD_TOOL_JOB,
16: ItemType.KQL_DATABASE,
17: ItemType.KQL_QUERYSET,
18: ItemType.REFLEX,
19: ItemType.EVENTSTREAM,
20: ItemType.KQL_DASHBOARD,
21: ItemType.DATAFLOW,
22: ItemType.DATA_PIPELINE,
23: ItemType.GRAPHQL_API,
24: ItemType.APACHE_AIRFLOW_JOB,
25: ItemType.MOUNTED_DATA_FACTORY,
26: ItemType.DATA_AGENT,
27: ItemType.ML_EXPERIMENT,
28: ItemType.ONTOLOGY,
29: ItemType.MAP,
}
@@ -206,7 +208,7 @@ SHELL_ONLY_PUBLISH = [
BULK_ITEM_COUNT_LIMIT = 1000
# Items that do not require assigned capacity
NO_ASSIGNED_CAPACITY_REQUIRED = [ItemType.SEMANTIC_MODEL.value, ItemType.REPORT.value]
NO_ASSIGNED_CAPACITY_REQUIRED = [ItemType.SEMANTIC_MODEL.value, ItemType.REPORT.value, ItemType.PAGINATED_REPORT.value]
# Exclude Path Regex Patterns for filtering files during publish
EXCLUDE_PATH_REGEX_MAPPING = {
+27
View File
@@ -218,6 +218,33 @@ def test_publish_data_build_tool_job_item(mock_endpoint, temp_workspace_dir):
mock_dbt_job_instance.publish_all.assert_called_once()
def test_publish_paginated_report_item(mock_endpoint, temp_workspace_dir):
"""Test that publish_all_items publishes PaginatedReport items when present in repository."""
create_test_item(temp_workspace_dir, None, "TestPaginatedReport", "PaginatedReport", "test-paginated-report-id")
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("fabric_cicd._items._paginatedreport.PaginatedReportPublisher") as mock_paginated_report_cls,
):
mock_paginated_report_instance = mock_paginated_report_cls.return_value
workspace = FabricWorkspace(
workspace_id="12345678-1234-5678-abcd-1234567890ab",
repository_directory=str(temp_workspace_dir),
token_credential=DummyTokenCredential(),
)
publish.publish_all_items(workspace)
assert "PaginatedReport" in workspace.repository_items
mock_paginated_report_cls.assert_called_once_with(workspace)
mock_paginated_report_instance.publish_all.assert_called_once()
def test_default_none_item_type_in_scope_includes_all_types(mock_endpoint, temp_workspace_dir):
"""Test that when item_type_in_scope is None (default), all available item types are included."""
with (