Skip to content

Commit 80affc5

Browse files
Parameterized the 'ActivatePlugins' during 'Solution Import'. Replace… (#339)
* Parameterized the 'ActivatePlugins' during 'Solution Import'. Replaced legacy 'PublishWorkflows' with 'ActivatePlugins' parameter. * Added 'StageAndUpgrade' to the import tasks. * Updating PR Loop Test * Logic to disable flows before solution import. --------- Co-authored-by: Mike! <mike@mikefactorial.onmicrosoft.com>
1 parent 8e73f37 commit 80affc5

File tree

3 files changed

+116
-19
lines changed

3 files changed

+116
-19
lines changed

Pipelines/Templates/deploy-Solution.yml

+53-18
Original file line numberDiff line numberDiff line change
@@ -124,17 +124,30 @@ steps:
124124
condition: and(succeeded(), eq(variables['IsUnmanaged'], 'true'))
125125

126126
# If called from import-unmanaged-to-dev-environment.yml, this task will run to deploy an unmanaged solution
127+
- task: microsoft-IsvExpTools.PowerPlatform-BuildTools.import-solution.PowerPlatformImportSolution@2
128+
displayName: 'Import Unmanaged Solution and no activate-plugins'
129+
inputs:
130+
authenticationType: PowerPlatformSPN
131+
PowerPlatformSPN: '${{parameters.serviceConnectionName}}'
132+
SolutionInputFile: '$(UnmanagedSolutionPath)'
133+
ActivatePlugins: false
134+
UseDeploymentSettingsFile: $(UseDeploymentSettings)
135+
DeploymentSettingsFile: $(DeploymentSettingsPath)
136+
MaxAsyncWaitTime: 120
137+
condition: and(succeeded(),eq(variables['ActivateFlowsOnTheSolutionImport'],'false'), ne(variables['SkipSolutionImport'],'true'), eq(variables['IsUnmanaged'], 'true'))
138+
139+
# If called from import-unmanaged-to-dev-environment.yml, this task will run to deploy an unmanaged solution
127140
- task: microsoft-IsvExpTools.PowerPlatform-BuildTools.import-solution.PowerPlatformImportSolution@2
128141
displayName: 'Import Unmanaged Solution'
129142
inputs:
130143
authenticationType: PowerPlatformSPN
131144
PowerPlatformSPN: '${{parameters.serviceConnectionName}}'
132145
SolutionInputFile: '$(UnmanagedSolutionPath)'
133-
PublishWorkflows: true
146+
ActivatePlugins: true
134147
UseDeploymentSettingsFile: $(UseDeploymentSettings)
135148
DeploymentSettingsFile: $(DeploymentSettingsPath)
136149
MaxAsyncWaitTime: 120
137-
condition: and(succeeded(), ne(variables['SkipSolutionImport'],'true'), eq(variables['IsUnmanaged'], 'true'))
150+
condition: and(succeeded(), ne(variables['ActivateFlowsOnTheSolutionImport'],'false'), ne(variables['SkipSolutionImport'],'true'), eq(variables['IsUnmanaged'], 'true'))
138151

139152
- pwsh: |
140153
. "$env:POWERSHELLPATH/build-deploy-solution-functions.ps1"
@@ -147,47 +160,69 @@ steps:
147160
displayName: 'Get managed solution zip path'
148161
condition: and(succeeded(),ne(variables['SkipSolutionImport'],'true'), ne(variables['IsUnmanaged'], 'true'))
149162

163+
- template: disable-flows.yml
164+
parameters:
165+
solutionName: '${{parameters.solutionName}}'
166+
167+
# If the TriggerSolutionUpgrade variable is false, then import the solution as an Update
168+
- task: microsoft-IsvExpTools.PowerPlatform-BuildTools.import-solution.PowerPlatformImportSolution@2
169+
displayName: 'Import Managed Solution as Update and no activate-plugins'
170+
inputs:
171+
authenticationType: PowerPlatformSPN
172+
PowerPlatformSPN: '${{parameters.serviceConnectionName}}'
173+
SolutionInputFile: $(ManagedSolutionPath)
174+
ActivatePlugins: false
175+
OverwriteUnmanagedCustomizations: ${{parameters.overwriteUnmanagedCustomizations}}
176+
UseDeploymentSettingsFile: $(UseDeploymentSettings)
177+
DeploymentSettingsFile: $(DeploymentSettingsPath)
178+
MaxAsyncWaitTime: 120
179+
condition: and(succeeded(),eq(variables['ActivateFlowsOnTheSolutionImport'],'false'),ne(variables['SkipSolutionImport'],'true'), ne(variables['IsUnmanaged'], 'true'), or(eq(variables['TriggerSolutionUpgrade'], 'false'), eq(variables['SolutionExists'], 'false')))
180+
150181
# If the TriggerSolutionUpgrade variable is false, then import the solution as an Update
151182
- task: microsoft-IsvExpTools.PowerPlatform-BuildTools.import-solution.PowerPlatformImportSolution@2
152183
displayName: 'Import Managed Solution as Update'
153184
inputs:
154185
authenticationType: PowerPlatformSPN
155186
PowerPlatformSPN: '${{parameters.serviceConnectionName}}'
156187
SolutionInputFile: $(ManagedSolutionPath)
157-
PublishWorkflows: true
188+
ActivatePlugins: true
158189
OverwriteUnmanagedCustomizations: ${{parameters.overwriteUnmanagedCustomizations}}
159190
UseDeploymentSettingsFile: $(UseDeploymentSettings)
160191
DeploymentSettingsFile: $(DeploymentSettingsPath)
161192
MaxAsyncWaitTime: 120
162-
condition: and(succeeded(),ne(variables['SkipSolutionImport'],'true'), ne(variables['IsUnmanaged'], 'true'), or(eq(variables['TriggerSolutionUpgrade'], 'false'), eq(variables['SolutionExists'], 'false')))
193+
condition: and(succeeded(), ne(variables['ActivateFlowsOnTheSolutionImport'],'false'), ne(variables['SkipSolutionImport'],'true'), ne(variables['IsUnmanaged'], 'true'), or(eq(variables['TriggerSolutionUpgrade'], 'false'), eq(variables['SolutionExists'], 'false')))
163194

164-
# If the TriggerSolutionUpgrade variable is true, then import the solution as an Upgrade, staging it as a holding solution, so we can apply a solution Upgrade.
195+
# If the TriggerSolutionUpgrade variable is true, then import the solution as an Upgrade, along with 'StageAndUpgrade' upgrade happens immediately after the import.
165196
# Doing this will ensure that items removed from the solution in development are also removed from the solution in the target environment after the Upgrade is applied.
166197
- task: microsoft-IsvExpTools.PowerPlatform-BuildTools.import-solution.PowerPlatformImportSolution@2
167-
displayName: 'Import Managed Solution as Upgrade'
198+
displayName: 'Import Managed Solution as Upgrade and no activate-plugins'
168199
inputs:
169200
authenticationType: PowerPlatformSPN
170201
PowerPlatformSPN: '${{parameters.serviceConnectionName}}'
171202
SolutionInputFile: $(ManagedSolutionPath)
172-
HoldingSolution: true
173203
OverwriteUnmanagedCustomizations: ${{parameters.overwriteUnmanagedCustomizations}}
174204
UseDeploymentSettingsFile: $(UseDeploymentSettings)
175205
DeploymentSettingsFile: $(DeploymentSettingsPath)
206+
ActivatePlugins: false
176207
MaxAsyncWaitTime: 120
177-
condition: and(succeeded(),ne(variables['SkipSolutionImport'],'true'), ne(variables['IsUnmanaged'], 'true'), eq(variables['TriggerSolutionUpgrade'], 'true'), eq(variables['SolutionExists'], 'true'))
208+
StageAndUpgrade: true
209+
condition: and(succeeded(), eq(variables['ActivateFlowsOnTheSolutionImport'],'false'), ne(variables['SkipSolutionImport'],'true'), ne(variables['IsUnmanaged'], 'true'), eq(variables['TriggerSolutionUpgrade'], 'true'), eq(variables['SolutionExists'], 'true'))
178210

179-
# NOTE: Sometimes you need to perform intermediary steps between staging the upgrade and applying it.
180-
# An example would be moving data from one entity to another before deleting the entity.
181-
# You would add steps to your pipeline here to accomplish this.
182-
183-
# If the TriggerSolutionUpgrade variable is true,then apply the solution Upgrade.
184-
- task: microsoft-IsvExpTools.PowerPlatform-BuildTools.apply-solution-upgrade.PowerPlatformApplySolutionUpgrade@2
211+
# If the TriggerSolutionUpgrade variable is true, then import the solution as an Upgrade, along with 'StageAndUpgrade' upgrade happens immediately after the import.
212+
# Doing this will ensure that items removed from the solution in development are also removed from the solution in the target environment after the Upgrade is applied.
213+
- task: microsoft-IsvExpTools.PowerPlatform-BuildTools.import-solution.PowerPlatformImportSolution@2
214+
displayName: 'Import Managed Solution as Upgrade'
185215
inputs:
186-
authenticationType: 'PowerPlatformSPN'
216+
authenticationType: PowerPlatformSPN
187217
PowerPlatformSPN: '${{parameters.serviceConnectionName}}'
188-
SolutionName: ${{parameters.solutionName}}
189-
AsyncOperation: true
190-
condition: and(succeeded(),ne(variables['SkipSolutionImport'],'true'), eq(variables['TriggerSolutionUpgrade'], 'true'), eq(variables['SolutionExists'], 'true'))
218+
SolutionInputFile: $(ManagedSolutionPath)
219+
OverwriteUnmanagedCustomizations: ${{parameters.overwriteUnmanagedCustomizations}}
220+
UseDeploymentSettingsFile: $(UseDeploymentSettings)
221+
DeploymentSettingsFile: $(DeploymentSettingsPath)
222+
ActivatePlugins: true
223+
MaxAsyncWaitTime: 120
224+
StageAndUpgrade: true
225+
condition: and(succeeded(),ne(variables['ActivateFlowsOnTheSolutionImport'],'false'),ne(variables['SkipSolutionImport'],'true'), ne(variables['IsUnmanaged'], 'true'), eq(variables['TriggerSolutionUpgrade'], 'true'), eq(variables['SolutionExists'], 'true'))
191226

192227
- task: microsoft-IsvExpTools.PowerPlatform-BuildTools.publish-customizations.PowerPlatformPublishCustomizations@2
193228
displayName: 'Power Platform Publish Customizations '

Pipelines/Templates/disable-flows.yml

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
parameters:
2+
- name: solutionName
3+
type: string
4+
#- name: activateFlowsOnTheSolutionImport
5+
# type: string
6+
#- name: skipSolutionImport
7+
# type: string
8+
#- name: isUnmanaged
9+
# type: string
10+
#- name: solutionExists
11+
# type: string
12+
13+
steps:
14+
- powershell: |
15+
. "$env:POWERSHELLPATH/activate-flows.ps1"
16+
17+
$microsoftPowerAppsAdministrationPowerShellModule = '$(CoETools_Microsoft_PowerApps_Administration_PowerShell)'
18+
Import-Module $microsoftPowerAppsAdministrationPowerShellModule -Force -RequiredVersion $(PowerAppsAdminModuleVersion) -ArgumentList @{ NonInteractive = $true }
19+
Add-PowerAppsAccount -TenantID $(connectionVariables.BuildTools.TenantId) -ApplicationId $(connectionVariables.BuildTools.ApplicationId) -ClientSecret $(connectionVariables.BuildTools.ClientSecret)
20+
$microsoftXrmDataPowerShellModule = '$(CoETools_Microsoft_Xrm_Data_PowerShell)'
21+
Import-Module $microsoftXrmDataPowerShellModule -Force -RequiredVersion $(XrmDataPowerShellVersion) -ArgumentList @{ NonInteractive = $true }
22+
$conn = Get-CrmConnection -ConnectionString "$(connectionVariables.BuildTools.DataverseConnectionString)"
23+
24+
Deactivate-FlowsFromSolution $conn "${{parameters.solutionName}}"
25+
displayName: 'Disable flows'
26+
condition: and(succeeded(),eq(variables['ActivateFlowsOnTheSolutionImport'],'false'),ne(variables['SkipSolutionImport'],'true'),ne(variables['IsUnmanaged'], 'true'),eq(variables['SolutionExists'], 'true'))

PowerShell/activate-flows.ps1

+37-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function Invoke-ActivateFlows {
5050

5151
Write-Flows "Printing total active flows" $flowsToActivate
5252

53-
Write-Host "Activating flows..."
53+
Write-Host "Activating/Deactivating flows..."
5454
#Activate any flows added to the collection based on sort order
5555
$flowsToActivate = $flowsToActivate | Sort-Object -Property sortOrder
5656
$flowsActivatedDeactivatedThisPass = $false
@@ -435,4 +435,40 @@ function Get-User-By-Email-or-DomainName{
435435
}
436436

437437
return $matchedUser
438+
}
439+
440+
<#
441+
This function reads the settings from customDeploymentSettings.json file and updates the connection references.
442+
#>
443+
function Deactivate-FlowsFromSolution {
444+
param (
445+
[Parameter(Mandatory)] [Microsoft.Xrm.Tooling.Connector.CrmServiceClient]$conn,
446+
[Parameter(Mandatory)] [String] [AllowEmptyString()]$solutionName
447+
)
448+
# Fetch the 'solution' using 'solutionComponentUniqueName' tag
449+
$solutions = Get-CrmRecords -conn ([Microsoft.Xrm.Tooling.Connector.CrmServiceClient]$conn) -EntityLogicalName solution -FilterAttribute "uniquename" -FilterOperator "eq" -FilterValue "$solutionName" -Fields solutionid
450+
if ($solutions.Count -gt 0) {
451+
$solutionId = $solutions.CrmRecords[0].solutionid
452+
# Get the solution components
453+
$result = Get-CrmRecords -conn $conn -EntityLogicalName solutioncomponent -FilterAttribute "solutionid" -FilterOperator "eq" -FilterValue $solutionId -Fields objectid, componenttype
454+
$solutionComponents = $result.CrmRecords
455+
456+
foreach ($solutionComponent in $solutionComponents) {
457+
if ($solutionComponent.componenttype -eq "Workflow") {
458+
$workflow = Get-CrmRecord -conn $conn -EntityLogicalName workflow -Id $solutionComponent.objectid -Fields clientdata, category, statecode, statuscode, name
459+
Write-Host "Workflow - $workflow"
460+
if($workflow -ne $null){
461+
# If workflow not already deactivated go ahead and deactivate
462+
if($workflow.statecode -ne 0 -and $workflow.StatusCode -ne 1 ){
463+
Write-Host "Deactivating Flow: " $workflow.name
464+
Set-CrmRecordState -conn $conn -EntityLogicalName workflow -Id $solutionComponent.objectid -StateCode 0 -StatusCode 1
465+
}else{
466+
Write-Host "Flow already deactivated at the target: " $solutionComponent.name
467+
}
468+
}else{
469+
Write-Host "workflow is null"
470+
}
471+
}
472+
}
473+
}
438474
}

0 commit comments

Comments
 (0)