Welcome to Part 5 of a series of Articles co-authored by Dylan Haskins and Eugene Van Staden covering our thoughts, strategies and tools for ALM and DevOps for the Power Platform and PowerApps Portals.
In Part 4 : Day-to-Day ALM for Developers we covered the process that a Developer could use on a daily basis to take part in the DevOps and ALM strategy.
The series consists of the following parts :
- Part 1 : ALM Fundamentals and Maturity
- Part 2 : Our ALM Framework and Provisioning Tool
- Part 3 : Day-to-Day ALM for Consultants
- Part 4 : Day-to-Day ALM for Developers
- Part 5 : Deconstructing the Framework : Solutions Project
- Part 6 : Deconstructing the Framework : ADO Pipeline
- Part 7 : Deconstructing the Framework : Portal Companion Apps
- Part 8 : Deconstructing the Framework : Plugins and WebResources
- Part 9 : Deconstructing the Framework : Automated Testing of Code and UI
- Part 10 : Deconstructing the Framework : Patch Management for Solutions and Deployment
- Part 11 : Real world implementation – ALM for Power Apps Portals
In this article we will start taking a deeper dive into the components that make up the Framework we have provided. We will start off by looking at the Solutions Project in the Framework, what it is made up of what and what each of those things do.
You can think of the Solutions project and the central hub of our Framework. It contains all the tools and scripts that enable our ALM and DevOps processes.
As mentioned in Part 4, the first thing to note is that the Solutions project has a Pre-Build event that triggers for all Builds done using the SolutionPackager configuration. This event runs the SolutionExport PowerShell script which versions, exports, unpacks and source controls our CDS Solutions files.
Lets start by taking a look at the Scripts folder.
In most of the scripts, you will see a block calling 2 other files _SetupTools.ps1 and _Config.ps1
######################## SETUP . (Join-Path $PSScriptRoot "_SetupTools.ps1") . (Join-Path $PSScriptRoot "_Config.ps1")
This enables the loading of the correct / latest versions of a number of PowerShell tools that we make use of.
- Microsoft.Xrm.Data.Powershell – a module providing common functions to create, delete, query, and update data, also includes many helpful functions for common tasks such as publishing, and manipulating System & CRM User Settings
- BurntToast – a module for creating and displaying Toast Notifications on Microsoft Windows 10
- Microsoft.Xrm.Devops.Data.Powershell – a module that provides an easy way to generate filtered data compatible with the Configuration Data Migration Tool.
- Microsoft.CrmSdk.CoreTools – CDS / Dynamics 365 Developer Tools
- Microsoft.Xrm.Tooling.PackageDeployment.Powershell – a module for deploying packages to a Common Data Service environment or Dynamics 365 environment
- Microsoft.PowerApps.Checker.Powershell – a module for invoking the PowerApps Solution checker service
This script loads the values from config.json into global variables for re-use in the scripts.
This currently contains some project specific values that were injected into the file during the provision process from Part 2. Currently these values are ServerUrl (your CDS / Dynamics 365 Dev environment URL), SolutionName (the name of your unmanaged development solution in CDS / Dynamics 365) and Geography (the geography you specified for your CDS / Dynamics 365 Tenant). Feel free to update these values if any of them change, to ensure that your DevOps processes continue to run smoothly.
SolutionExport.ps1 also invokes the following scripts :
############## Generate Config Migration data . (Join-Path $PSScriptRoot "_ConfigMigration.ps1") ############## Generate Types . (Join-Path $PSScriptRoot "_GenerateTypes.ps1") ############## UPDATE VERSION . (Join-Path $PSScriptRoot "_UpdateVersion.ps1") ############## EXPORT Solution . (Join-Path $PSScriptRoot "_ExportSolution.ps1")
This was covered in a bit of detail in Part 3 this uses the Microsoft.Xrm.Devops.Data.Powershell and FetchXML to export configuration data in a format compatible with the Configuration Data Migration tool and the Package Deployer, allowing us to move data from one environment to the next.
This scripts utilises the XrmContext and XrmDefinitelyTyped tools to generate strongly typed classes and TypeScript definition files for all of our CDS / Dynamics 365 Entities. This is also covered in Part 4. They both have a dependency on their respective config files XrmContext.exe.config in the XrmContext folder and XrmDefinitelyTyped.exe.config in the XrmDefinitelyTyped folder.
<?xml version="1.0" encoding="utf-8"?> <configuration> <appSettings> <add key="solutions" value="AddName"/> <add key="entities" value="systemuser,team,businessunit"/> <add key="namespace" value="Entities"/> <add key="servicecontextname" value="XrmContext"/> <add key="sdkversion" value="9"/> <add key="onefile" value="false"/> </appSettings> </configuration>
The main things you would want to tweak in these files are the list of solutions and entities that you would like them to generate for. These 2 settings are cumulative, so you only need to specify entities if they are not already included in a solution
This script connects to your CDS/Dynamics 365 Development instance and updates the Solution Version number. This ensures that a deployment knows that you have a newer solution and makes sure it gets installed on the target environment. We have adopted the following solution versioning pattern (feel free to tweak it in this file to match your preferences)
Major.Minor.Build.Revision where :
Major = Target Production Release (so Release 1, Release 2 etc.)
Minor = Year+DayofYear (yyddd for when the Unpack was run)
Build = PatchNumber (0 (zero) if it is you main solution, and 1 (one) or higher for a Patch solution)
Revision = BuildTime (time at which the Unpack was run)
This script is responsible for connecting to your CDS/Dynamics 365 Development instance and exporting an unmanaged and a managed version of the Solution. It then uses the SolutionPackager.exe tool to unpack the Solution files and prepare them for source control.
Similar to _ConfigMigration.ps1 this uses the Microsoft.Xrm.Devops.Data.Powershell and FetchXML to export configuration data in a format compatible with the Configuration Data Migration tool and the Package Deployer, it has a predefined set of FetchXML queries that export the default PowerApps Portal configuration data.
This script contains sample code for using the new PowerShell support for Power Apps (for Admins and Makers) and the Azure Monitor HTTP Data Collector API to export Flow Run logs and store them in an Azure Log Analytics workspace for reporting, monitoring and alerting. More detail on this is available in Monitoring and Alerting for Power Automate Flows
This script runs as part of the Continuous Integration Build as defined in the build.yaml of the toolset.
It packs up your solution file using SolutionPackager.exe and maps in your compiled code (Plugins, Workflows and Webresources) using the definition in the Solutions\map.xml file.
<Mapping> <FileToFile map="PluginAssemblies\**\Plugins.dll" to="..\..\Plugins\bin\**\Plugins.dll" /> <FileToFile map="PluginAssemblies\**\Workflows.dll" to="..\..\Workflows\bin\**\Workflows.dll" /> <FileToPath map="WebResources\*.*" to="..\..\WebResources\dist\**" /> <FileToPath map="WebResources\**\*.*" to="..\..\WebResources\dist\**" /> </Mapping>
It then uploads your Solution file to Microsoft Power Apps Solution Checker API to check it for known issues and best practices. Any critical errors here will fail your CI build. High, Medium and Low errors will surface as build warnings but allow the build to continue.
This script runs as part of the Continuous Integration build and deploys your Solution and configuration data to your target (Deployment Staging etc.) environments
It makes use of Microsoft.Xrm.Tooling.PackageDeployment.Powershell – a module for deploying packages to a Common Data Service environment or Dynamics 365 environment
Outside of the Scripts folder the next most important folder we are interested in is the spkl folder
We make use of Scott Durow’s spkl task runner to facilitate the deployment of Plugins, Workflows and WebResources into your development environment.
Here we use the following batch files
deploy-plugins.bat deploys our plugin code and registers the steps in our development environment and against our development solution (that we defined in Part 2 : Provisioning).
deploy-webresources.bat deploys our WebResources in our development environment and against our development solution.
deploy-workflows.bat deploys our workflow code in our development environment and against our development solution.
All the configuration was pre-populated during Part 2 : Provisioning but can be adjusted as needed by editing Solutions\spkl.json
The last remaining folder is ReferenceData, this folder stores our Source controlled XML data export. This is the output generated by _ConfigurationMigration.ps1 (as mentioned earlier in this post). It contains the Configuration Data we wish to migrate from our Development Environment to all downstream environments.
That concludes Part 5, in Part 6 : Deconstructing the Framework : ADO Pipeline we will take a deeper look into the Build.yaml file included in the Toolset and look at the inner workings of the Azure DevOps pipeline that was created.