Using DevOps to export a Power Platform solution into source control
Tags: powerplatform, devops, azuredevops, dynamics365
Published: 2021-11-21 10:27:14

UPDATED 17/4/2023


In the previous [post](https://dev.to/diskdrive/accessing-power-platform-in-devop-pipelines-using-service-principals-ndi), we setup a Service Principal that allowed DevOps to access and perform actions in an Power Platform environment.

In this article, we'll actually utilise the service principal to export a solution and then save it into a DevOps repo.

#Prerequisites

- You need a Power Platform environment with a solution you'd like to export. Your solution can be whatever you want. To make it very simple , I've just created a model driven app with one table that stores zoo animals.
- You need a DevOps project with a repo you'd like the solution to be saved into.
- You need a service principal with access to the Power Platform environment ([see here](https://dev.to/diskdrive/accessing-power-platform-in-devop-pipelines-using-service-principals-ndi))

##Setting up your repo
Just a few things that's important after you've set up your repo 

###Provide the required permissions
![Security settings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5rt1swubxwu6ld2t439d.png)
First, you need to give your Build Service Contribute permission. This is to allow the pipeline to actually make changes to the repo. You can do this at Project Settings -> Repositories

###Limit merge types on the main branch
![Go to your main branch policies](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zwegdo4sni5zy3ytr9vx.png)

![Limit merge type](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iu64qiabpz9fgvm4ohju.png)

Secondly, you should limit merge types which will prevent anyone from committing to the main branch without a PR. Admittedly this is optional, but I still would recommend doing it. I normally recommend doing it on all your repos not just this one, but it's more important here because the pipeline will be doing the committing and you don't want to accidentally commit to the main branch without going through your required PR approval process.

###Create a feature branch
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/43emrqaob849rlico83a.png)
Create your first Feature branch to start off with. This is the branch the pipeline will save the solution to. Based on your git branch strategy, it may be the only one you use or you may choose to have a new one for each commit.


#Creating the Pipeline
Now that we have all our prerequisites, we can start building our pipeline.

Go to Pipelines -> New Pipelines and follow the prompts.

![Use classic editor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/puycanxj52atck0wcunj.png)
<figcaption>Select "Use classic editor"</figcaption>

![Select your repo and branch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kfakdl4zqvclg20ptwvt.png)
 
<figcaption>Select your repo and your Feature branch </figcaption>

![empty job](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qduca8qq7hmqtjah0lou.png)
<figcaption>Start with an Empty Job</figcaption>


#Configuring your pipeline

###Allow OAuth token 
You'll need to allow this because one of the later steps will require you to run the some powershell which'll need this token.
![Allow OAuth](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4fxqkzxx18aun17uldr2.png)

###Install the Power Platform Build Tools extension
![Build Tools](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ufjue3lbdgae2dvkisun.png)
This'll only appear if your DevOps organisation has not installed it yet. If you type "Power" into the search bar and you see this option, then go ahead and get this extension from the marketplace for your DevOps organisation. You'll only need to do this for the first pipeline you build.

###Add the steps
DevOps pipelines runs a series of operations which is defined in a list of ordered steps. Each time the pipeline is triggered, a container is created on an agent in the agent pool and once it finishes running, the container is destroyed.

To add a step, you add the + sign and find the step
![Adding a step](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qimp93k00hby2401j0pv.png)
 
For this pipeline, these will be the steps

![Steps](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mxrnxjxzixdvbm4z9rmz.png)

###Fetch from repo and clean solutions folder

This is a bash script

     

```
git fetch
git config --global user.email $(Build.RequestedForEmail) 
git config --global user.name $(Build.RequestedFor)
        
git switch $(Build.SourceBranchName)

rm -rf Solutions
```

What it's doing is configuring git, switching to the feature branch. I'm also cleaning the solutions folder because my export steps are going to generate new files for me and I don't want any deleted components etc to still be in there.

###Power Platform Tool Installer
This installs the power platform tools on the container so that we can run the rest of the operations

### Set Solution Version

Go to this article (https://dev.to/diskdrive/auto-incrementing-your-power-platform-solution-version-in-your-devops-pipeline-46lo) to see why this needs to be configured.

###Export Solution unmanaged 
This step will go into Power Platform environment request the unmanaged solution be exported and then saved in an output folder. 

For our purposes, I'll specify the Service Principal in the Service Connection which will tell the pipeline where the Power Platform environment is as well as give it access.

I need to also specify the solution I want to export and an output location which I've put as "$(Build.ArtifactStagingDirectory)\$(BuildFolder)\Drop\Solution.zip" - this is a folder inside my container that I'll reference in the next step.

Make to not tick "Export as Managed Solution".

![Export Solution configuration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0vju5xzs7henq8dijav1.png)

###Export Solution managed
I want to export both the unmanaged and managed solution. The Unmanaged solution is intended to be editable later so this is for importing into new dev enviornments. The managed solution is read-only and this is for migrating into environments beyond dev (eg. test or prod).

It should be the same step as unmanaged except make sure to append _solution to the output file and tick the Export as Managed Solution checkbox.

![Export Managed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i5dux9dyozbafd6begor.png)

 
###Unpack Solution
When you export a Power Platform solution, you get a zip file. Running unpack will extract the zip into a directory with a number of mainly xml files that define the solution. 

For our purposes, I need to specify the input file which should be the same as the output file in the last step. Then I need to specify where in the repo to save to - and I've selected the Solutions folder in the repo.

Make sure to unpack both. We should have a solution.zip file and a solution_managed.zip file and ticking Both will automatically unpack both of these files.


![Unpack](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/roh4ibz6r3fz0ndbq76y.png)

 
###Commit and push to feature branch
So far, we've exported the solution, unpacked the content into the container on the agent running the pipeline. The last step is push these changes over into DevOps and to do that, we need to run a Powershell script that runs a few git commands.

```
git add -A
git commit -m "changes exported from dev"
```
Adds all the files and make a commit with description.

```
git push https://$env:SYSTEM_ACCESSTOKEN@dev.azure.com/wai0211/TestProj/_git/Zoo
```
Pushes the code to your DevOps repo. See [here](https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#systemaccesstoken) for what `env:SYSTEM_ACCESSTOKEN` does but it's an authentication token for the build service. This is why in the prereq. you needed to enable the Contribute permission and why we needed to allow scripts to access the oauth token


#Running your pipeline

Now the pipeline has been built, you should be able to run it. This will run through all the steps. 

![Run pipelines](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s3nltasurmjeyue3hnwm.png)

By default, we've set up to run the pipeline against the "Feature" branch but depending on how you work you may want to have to have another branch here so feel free to change this before running the pipeline.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wl2ntjjuz01s20u4shla.png)
 
#Creating a PR

If your pipeline is successful, you should be able to navigate to Repo, switch to the Feature branch and see the changes

![PR Request](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8m0d6uhe8jtddw50ft9v.png)
 
Click on Create new PR Request to get this merged into master.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nec64qoj8nyuue6ksfzg.png)

You should be able to see all the changes. As this is my first commit, there's 21 changes - but later on, as you run the pipeline again, you should only be able to see the differences.

Hit Create, and follow your standard PR approval process to merge this into main.

#Summary
What we've done in this post is create an automated way to get your changes in your Power Platform environment pushed into source control. 

The workflow is that you make the changes you want into the solution, run the pipeline, this'll export the solution and unpack the code into a feature branch.

Then you create a PR to merge this feature branch into your main branch once you're happy with it.

In an upcoming post, I will document how to use DevOps - once you've done the merging - to import the code in your main branch into another environment.

*Update - please see this [post] (https://dev.to/diskdrive/auto-incrementing-your-power-platform-solution-version-in-your-devops-pipeline-46lo) for how to autoincrement the version number of your solution on each export.