Categories
ALM Azure Common Data Service DevOps Dynamics 365 Power Platform PowerShell Visual Studio

Power Platform DevOps : Part 5 – Deconstructing the Framework : Solutions Project

Part 5 of a series of Articles co-authored by Dylan Haskins and Eugene Van Staden covering our thoughts, strategies and tools for Application Lifecycle Management (ALM) and DevOps for the Power Platform and PowerApps Portals.

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 :

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.

SolutionExport.ps1

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")

_SetupTools.ps1

This enables the loading of the correct / latest versions of a number of PowerShell tools that we make use of.

_Config.ps1

This script loads the values from config.json into global variables for re-use in the scripts.

config.json

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")

_ConfigMigration.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.

_GenerateTypes.ps1

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

_UpdateVersion.ps1

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)

_ExportSolution.ps1

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.

_PortalConfigMigration.ps1

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.

Flow2LogAnalytics.ps1

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

SolutionPack.ps1

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.

SolutionDeploy.ps1

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 this current series, watch our for some great Future Posts.

One reply on “Power Platform DevOps : Part 5 – Deconstructing the Framework : Solutions Project”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.