Skip to content

Commit 790c4c2

Browse files
authored
New functions to facilitate Deployment pipelines in Fabric #144
New functions to facilitate Deployment pipelines in Fabric
2 parents fecd18b + d74f3e3 commit 790c4c2

29 files changed

+1504
-22
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
*.local.*
33
!**/README.md
44
.kitchen/
5+
*.code-workspace
56

67
~*.*
78
*.nupkg

CHANGELOG.md

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,44 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66
## [Unreleased]
77

88
### Added
9-
- added unit tests for `Get-FabricWorkspaceUser` function to ensure it works correctly with multiple workspaces both in the pipeline and passed to a parameter.
9+
10+
- Added unit tests for `Get-FabricWorkspaceUser` function to ensure it works correctly with multiple workspaces both in the pipeline and passed to a parameter.
1011
- Added unit tests for Aliases for `Get-FabricWorkspaceUser` function to ensure backward compatibility.
11-
- Added credits for authors to all functions and Unit tests to verify the existence of such tags #89
12+
- Added credits for authors to all functions and Unit tests to verify the existence of such tags (#89)
1213
- Added `NoWait` switch parameter to `New-FabricSQLDatabase` (#123)
14+
- Added functions related to Deployment Pipelines (#121):
15+
- `Add-FabricWorkspaceToStage`,
16+
- `Get-FabricDeploymentPipeline`,
17+
- `Get-FabricDeploymentPipelineOperation`,
18+
- `Get-FabricDeploymentPipelineRoleAssignments`,
19+
- `Get-FabricDeploymentPipelineStage`,
20+
- `Get-FabricDeploymentPipelineStageItem`,
21+
- `New-FabricDeploymentPipeline`,
22+
- `Remove-FabricDeploymentPipeline`,
23+
- `Remove-FabricWorkspaceFromStage`,
24+
- `Start-FabricDeploymentPipelineStage`
25+
- Added private function `Get-FabricContinuationToken` to facilitate pagination
1326

1427
### Changed
28+
1529
- Updated `Get-FabricWorkspaceUser` to support pipeline input for `WorkspaceId` and `WorkspaceName` parameters.
1630
- Renamed `Get-FabricWorkspaceUsers` to match the singular form
17-
- Get-FabricSqlDatabase accepts Workspace as a pipeline, handles errors correctly and can filter by name (#117).
31+
- `Get-FabricSqlDatabase` accepts Workspace as a pipeline, handles errors correctly and can filter by name (#117).
1832
- Applied splatting for several parameters in `Invoke-FabricRestMethod` and output results in debug mode
1933
- `Remove-FabricSQLDatabase` uses unified function to handle API results
2034

2135
Updated the `WorkspaceId`, `CapacitiesIds`,`CapacityId`,`CopyJobId`,`datamartId`,`DataPipelineId`,`DataWarehouseGUID`,`DomainId`,`EnvironmentId`,`EventhouseId`,`EventstreamId`,`ExternalDataShareId`,`ItemId`,`KQLDashboardId`,`KQLDatabaseId`,`KQLQuerysetId`,`LakehouseId`,`MirroredDatabaseId`,`MirroredWarehouseId`,`MLExperimentId`,`MLModelId`,`NotebookId`,`operationId`,`PaginatedReportId`,`ParentDomainId`,`parentEventhouseId`,`PrincipalId`,`ReflexId`,`ReportId`,`SemanticModelId`,`SparkCustomPoolId`,`SparkJobDefinitionId`,`SQLDatabaseId`,`SQLEndpointId`,`subscriptionID`,`UserId`,`WarehouseId`,`WorkspaceGUID`,`WorkspaceId`,`WorkspaceIds`,and `WorkspaceRoleAssignmentId` parameters to the datatype GUID [#125](https://github.com/dataplat/FabricTools/issues/125)
2236

23-
24-
2537
### Fixed
38+
2639
- Enhanced logic in unified function `Test-FabricApiResponse` to handle API results and moved it to private functions
2740
- Fixed bug in `Get-FabricLongRunningOperation` - Uri was incorectly created (#131)
2841
- Fixed bug in `Get-FabricLongRunningOperationResult` - uses correct statusCode (#131)
2942

3043
### Deprecated
44+
3145
### Removed
46+
3247
- Removed Revision History from `Get-FabricSQLDatabase`, `Get-FabricSQLDatabase`
3348

3449
### Security

FabricTools.code-workspace

Lines changed: 0 additions & 7 deletions
This file was deleted.

helper/build-and-test.ps1

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
$PSVersionTable
2+
3+
Import-module PSScriptAnalyzer
4+
5+
Find-Module Microsoft.PowerShell.PSResourceGet
6+
.\build.ps1 -ResolveDependency -Tasks noop -UsePSResourceGet
7+
8+
9+
######### BUILD #########
10+
11+
./build.ps1 -ResolveDependency -Tasks noop
12+
13+
Remove-Module -Name FabricTools -ErrorAction SilentlyContinue
14+
./build.ps1 -Tasks build
15+
ipmo .\output\module\FabricTools\0.0.1\FabricTools.psd1
16+
Get-Module Fab*
17+
18+
Invoke-ScriptAnalyzer -Path .\source\Public\**
19+
20+
21+
$tests = Invoke-Pester .\tests\ -PassThru
22+
$tests.Tests | where Result -eq 'Failed' | Measure-Object | Select-Object -ExpandProperty Count
23+
$tests.Tests | where Result -eq 'Failed' | ft -Property ExpandedName, ErrorRecord
24+
$tests.Tests | where Result -eq 'Failed' | ft -Property Name, Result, ErrorRecord -AutoSize
25+
26+
$e = $tests.Tests | where Result -eq 'Failed' | Select-Object -First 1
27+
$e.ErrorRecord

helper/build.ps1

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Remove-Module -Name FabricTools -ErrorAction SilentlyContinue
2+
./build.ps1 -Tasks build
3+
ipmo .\output\module\FabricTools\0.0.1\FabricTools.psd1
4+
Get-Module FabricTools
5+
6+
Write-Host "Connecting to Fabric Account..." -ForegroundColor Cyan
7+
Connect-FabricAccount
8+
9+
Write-Host "Build completed successfully!" -ForegroundColor Green
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<#
2+
.SYNOPSIS
3+
Internal function to handle continuation token logic for Fabric API calls.
4+
5+
.DESCRIPTION
6+
The `Get-FabricContinuationToken` function processes the API response to extract and handle continuation tokens.
7+
It returns the continuation token variable and provides debug logging.
8+
9+
.PARAMETER Response
10+
The API response object that may contain a continuation token.
11+
12+
.EXAMPLE
13+
Get-FabricContinuationToken -Response $response
14+
15+
Processes the response and returns the continuation token if present.
16+
17+
.NOTES
18+
This is an internal function used by other functions in the module.
19+
20+
Author: Kamil Nowinski
21+
#>
22+
23+
function Get-FabricContinuationToken {
24+
[CmdletBinding()]
25+
param (
26+
[Parameter(Mandatory = $true)]
27+
[object]$Response
28+
)
29+
30+
$continuationToken = $null
31+
if ($null -ne $Response) {
32+
# Update the continuation token if present
33+
if ($Response.PSObject.Properties.Match("continuationToken")) {
34+
$continuationToken = $Response.continuationToken
35+
Write-Message -Message "New continuation token: $continuationToken" -Level Debug
36+
} else {
37+
Write-Message -Message "New continuation token to null" -Level Debug
38+
}
39+
} else {
40+
Write-Message -Message "No data received from the API." -Level Warning
41+
}
42+
$continuationToken
43+
}

source/Private/Test-FabricApiResponse.ps1

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ function Test-FabricApiResponse {
5353
[switch] $NoWait = $false
5454
)
5555

56+
Write-Message -Message "[Test-FabricApiResponse]::Begin" -Level Debug
57+
5658
$responseHeader = $script:responseHeader
5759
$statusCode = $script:statusCode
5860
$result = $null
@@ -114,15 +116,14 @@ function Test-FabricApiResponse {
114116
}
115117

116118
switch ($verb) {
117-
'New' { $msg = "$TypeName '$ObjectIdOrName' created successfully!" }
118-
'Update' { $msg = "$TypeName '$ObjectIdOrName' updated successfully!" }
119-
'Remove' { $msg = "$TypeName '$ObjectIdOrName' deleted successfully!" }
120-
'Get' { $msg = "" }
121-
default { $msg = "Received $statusCode status code for $verb operation on $TypeName '$ObjectIdOrName'." }
122-
}
123-
if ($msg) {
124-
Write-Message -Message $msg -Level Info
119+
'New' { $msg = "$TypeName '$ObjectIdOrName' created successfully."; $level = 'Info' }
120+
'Update' { $msg = "$TypeName '$ObjectIdOrName' updated successfully."; $level = 'Info' }
121+
'Remove' { $msg = "$TypeName '$ObjectIdOrName' deleted successfully."; $level = 'Info' }
122+
'Get' { $msg = "Successfully retrieved $TypeName details."; $level = 'Debug' }
123+
default { $msg = "Received $statusCode status code for $verb operation on $TypeName '$ObjectIdOrName'."; $level = 'Info' }
125124
}
125+
Write-Message -Message $msg -Level $level
126+
Write-Message -Message "[Test-FabricApiResponse]::End" -Level Debug
126127

127128
$result
128129

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<#
2+
.SYNOPSIS
3+
Assigns a workspace to a deployment pipeline stage.
4+
5+
.DESCRIPTION
6+
The `Add-FabricWorkspaceToStage` function assigns the specified workspace to the specified deployment pipeline stage.
7+
This operation will fail if there's an active deployment operation.
8+
9+
.PARAMETER DeploymentPipelineId
10+
Required. The ID of the deployment pipeline.
11+
12+
.PARAMETER StageId
13+
Required. The ID of the deployment pipeline stage.
14+
15+
.PARAMETER WorkspaceId
16+
Required. The ID of the workspace to assign to the stage.
17+
18+
.EXAMPLE
19+
Add-FabricWorkspaceToStage -DeploymentPipelineId "GUID-GUID-GUID-GUID" -StageId "GUID-GUID-GUID-GUID" -WorkspaceId "GUID-GUID-GUID-GUID"
20+
21+
Assigns the specified workspace to the deployment pipeline stage.
22+
23+
.NOTES
24+
- Calls `Confirm-TokenState` to ensure token validity before making the API request.
25+
- Requires Pipeline.ReadWrite.All and Workspace.ReadWrite.All delegated scopes.
26+
- Requires admin deployment pipelines role and admin workspace role.
27+
- This operation will fail if:
28+
* There's an active deployment operation
29+
* The specified stage is already assigned to another workspace
30+
* The specified workspace is already assigned to another stage
31+
* The caller is not a workspace admin
32+
- This API is in preview.
33+
34+
Author: Kamil Nowinski
35+
#>
36+
37+
function Add-FabricWorkspaceToStage {
38+
[CmdletBinding()]
39+
param(
40+
[Parameter(Mandatory = $true)]
41+
[ValidateNotNullOrEmpty()]
42+
[Guid]$DeploymentPipelineId,
43+
44+
[Parameter(Mandatory = $true)]
45+
[ValidateNotNullOrEmpty()]
46+
[Guid]$StageId,
47+
48+
[Parameter(Mandatory = $true)]
49+
[ValidateNotNullOrEmpty()]
50+
[Guid]$WorkspaceId
51+
)
52+
53+
try {
54+
# Step 1: Ensure token validity
55+
Confirm-TokenState
56+
57+
# Step 2: Construct the API URL
58+
$apiEndpointUrl = ("deploymentPipelines/{0}/stages/{1}/assignWorkspace" -f $DeploymentPipelineId, $StageId)
59+
Write-Message -Message "API Endpoint: $apiEndpointUrl" -Level Debug
60+
61+
# Step 3: Construct the request body
62+
$requestBody = @{
63+
workspaceId = $WorkspaceId
64+
}
65+
66+
# Step 4: Make the API request and validate response
67+
$response = Invoke-FabricRestMethod -Uri $apiEndpointUrl -Method Post -Body $requestBody
68+
Test-FabricApiResponse -Response $response
69+
70+
# Step 5: Return results
71+
Write-Message -Message "Successfully assigned workspace to deployment pipeline stage." -Level Info
72+
$response
73+
} catch {
74+
# Step 6: Error handling
75+
$errorDetails = $_.Exception.Message
76+
Write-Message -Message "Failed to assign workspace to deployment pipeline stage. Error: $errorDetails" -Level Error
77+
}
78+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<#
2+
.SYNOPSIS
3+
Retrieves deployment pipeline(s) from Microsoft Fabric.
4+
5+
.DESCRIPTION
6+
The `Get-FabricDeploymentPipeline` function fetches deployment pipeline(s) from the Fabric API.
7+
It can either retrieve all pipelines or a specific pipeline by ID.
8+
It automatically handles pagination when retrieving all pipelines.
9+
10+
.PARAMETER DeploymentPipelineId
11+
Optional. The ID of a specific deployment pipeline to retrieve. If not provided, all pipelines will be retrieved.
12+
13+
.PARAMETER DeploymentPipelineName
14+
Optional. The display name of a specific deployment pipeline to retrieve. If provided, it will filter the results to match this name.
15+
16+
.EXAMPLE
17+
Get-FabricDeploymentPipeline
18+
19+
Retrieves all deployment pipelines that the user can access.
20+
21+
.EXAMPLE
22+
Get-FabricDeploymentPipeline -DeploymentPipelineId "GUID-GUID-GUID-GUID"
23+
24+
Retrieves a specific deployment pipeline with detailed information including its stages.
25+
26+
.NOTES
27+
- Calls `Confirm-TokenState` to ensure token validity before making the API request.
28+
- Returns a collection of deployment pipelines with their IDs, display names, and descriptions.
29+
- When retrieving a specific pipeline, returns extended information including stages.
30+
- Requires Pipeline.Read.All or Pipeline.ReadWrite.All delegated scopes.
31+
32+
Author: Kamil Nowinski
33+
#>
34+
35+
function Get-FabricDeploymentPipeline {
36+
[CmdletBinding()]
37+
param(
38+
[Parameter(Mandatory = $false)]
39+
[ValidateNotNullOrEmpty()]
40+
[Guid]$DeploymentPipelineId,
41+
42+
[Parameter(Mandatory = $false)]
43+
[Alias("Name", "DisplayName")]
44+
[string]$DeploymentPipelineName
45+
)
46+
47+
try {
48+
# Step 1: Ensure token validity
49+
Confirm-TokenState
50+
51+
if ($PSBoundParameters.ContainsKey("DeploymentPipelineName") -and $PSBoundParameters.ContainsKey("DeploymentPipelineId"))
52+
{
53+
Write-Warning "The parameters DeploymentPipelineName and DeploymentPipelineId cannot be used together"
54+
return
55+
}
56+
57+
# If DeploymentPipelineId is provided, get specific pipeline
58+
if ($DeploymentPipelineId) {
59+
Write-Message -Message "Retrieving specific deployment pipeline with ID: $DeploymentPipelineId" -Level Debug
60+
$apiEndpointUrl = "deploymentPipelines/$DeploymentPipelineId"
61+
62+
$response = Invoke-FabricRestMethod -Uri $apiEndpointUrl -Method Get
63+
64+
# Validate response
65+
Test-FabricApiResponse -response $response -ObjectIdOrName $DeploymentPipelineId -typeName "deployment pipeline"
66+
67+
if ($response) {
68+
Write-Message -Message "Successfully retrieved deployment pipeline." -Level Debug
69+
return $response
70+
} else {
71+
Write-Message -Message "No deployment pipeline found with the specified ID." -Level Warning
72+
return $null
73+
}
74+
}
75+
76+
# Step 2: Initialize variables for listing all pipelines
77+
$continuationToken = $null
78+
$pipelines = @()
79+
80+
if (-not ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GetName().Name -eq "System.Web" })) {
81+
Add-Type -AssemblyName System.Web
82+
}
83+
84+
# Step 3: Loop to retrieve all pipelines with continuation token
85+
Write-Message -Message "Loop started to get continuation token" -Level Debug
86+
$baseApiEndpointUrl = "deploymentPipelines"
87+
88+
do {
89+
# Step 4: Construct the API URL
90+
$apiEndpointUrl = $baseApiEndpointUrl
91+
92+
if ($null -ne $continuationToken) {
93+
# URL-encode the continuation token
94+
$encodedToken = [System.Web.HttpUtility]::UrlEncode($continuationToken)
95+
$apiEndpointUrl = "{0}?continuationToken={1}" -f $apiEndpointUrl, $encodedToken
96+
}
97+
Write-Message -Message "API Endpoint: $apiEndpointUrl" -Level Debug
98+
99+
# Step 5: Make the API request
100+
$response = Invoke-FabricRestMethod -Uri $apiEndpointUrl -Method Get
101+
102+
# Validate response
103+
Test-FabricApiResponse -response $response -typeName "deployment pipeline"
104+
105+
# Step 6: Process response and update continuation token
106+
if ($null -ne $response) {
107+
$pipelines += $response.value
108+
}
109+
$continuationToken = Get-FabricContinuationToken -Response $response
110+
111+
} while ($null -ne $continuationToken)
112+
113+
Write-Message -Message "Loop finished and all data added to the list" -Level Debug
114+
115+
if ($DeploymentPipelineName)
116+
{
117+
# Filter the list by name
118+
Write-Message -Message "Filtering deployment pipelines by name: $DeploymentPipelineName" -Level Debug
119+
$pipelines = $pipelines | Where-Object { $_.displayName -eq $DeploymentPipelineName }
120+
}
121+
122+
# Step 7: Handle results
123+
$pipelines
124+
# if ($pipelines) {
125+
# Write-Message -Message "Successfully retrieved deployment pipelines." -Level Debug
126+
# return $pipelines
127+
# } else {
128+
# Write-Message -Message "No deployment pipelines found." -Level Warning
129+
# return $null
130+
# }
131+
132+
} catch {
133+
# Step 8: Error handling
134+
$errorDetails = $_.Exception.Message
135+
Write-Message -Message "Failed to retrieve deployment pipelines. Error: $errorDetails" -Level Error
136+
}
137+
}

0 commit comments

Comments
 (0)