New GitHub Sample Workflows for Power Platform
Tags: azure, devops, frontend, powerfuldevs
Published: 2023-03-11 00:30:15


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

## Wait there are GitHub actions for Power Platform? 
[Power Platform Build Tools ](https://github.com/microsoft/powerplatform-actions)as they are officially called, have been available for GitHub for over a year. So, yes, the answer is yes. We have Power Platform GitHub actions documentation available at this [location ](https://learn.microsoft.com/en-us/power-platform/alm/devops-github-actions). In addition to the documentation, we also have hands on lab content available [here](https://github.com/microsoft/powerplatform-actions-lab) for the users to go try out. One of the folders in the Power Platform Hands on lab is the samples folder. This is the location where our team posts sample workflows (as the name suggests) on actions that can be done with Power Platform and GitHub. 

### What are the new workflows that we have added? 
A lot of you wanted to see the kind of flexibility of the tasks offered for Power Platform in GitHub actions. The purpose of this post is to show you just that. 

### Username and Password or Service Principal? 
That is the first question a lot of folks ask. In the samples folder you will see that there are examples of both. I am biased towards service principals, and I am not ashamed to say it. Username and Password are a viable choice, but make sure that such accounts are not impacted by MFA policies. Considering that runners (if you are using cloud-based pools) are dynamically allocated, MFA will cause issues for your GitHub workflows.

### What are the new samples? 
The sample workflows are as follows: 
1) [Create environments](https://github.com/microsoft/powerplatform-actions-lab/blob/main/sample-workflows/create-envs.yml)
2) [Export, Unpack and Commit](https://github.com/microsoft/powerplatform-actions-lab/blob/main/sample-workflows/exportandunpack.yml) 
3) [Delete environments](https://github.com/microsoft/powerplatform-actions-lab/blob/main/sample-workflows/delete-environments.yml)
4) [Deploy Managed Application](https://github.com/microsoft/powerplatform-actions-lab/blob/main/sample-workflows/deploy-managed-application.yml)
5) [Deploy Unmanaged Application](https://github.com/microsoft/powerplatform-actions-lab/blob/main/sample-workflows/deploy-unmanaged-application.yml) 

These new workflows as their name states do things within the Power Platform, let us start with the first one

#### Create environment
All the workflows use workflow_dispatch calls which means they are manually activated. If you would like to know what are the other types of dispatch mechanism. I would recommend reading up on the event triggers on the [GitHub website](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows). Create environment takes a few variables as user input or when invoked remotely via Power Automate (that is a different blog) and then proceed to create a developer environment for Dev, a Sandbox environment for Test, and a Production environment for Production. This particular workflow assumes that you are going to create 3 environments, the assumption here is that Production and Testing environments maybe long lived environments but you developer environments are ephemeral, as in you will be deleting them once you are done. What you say? Deleting developer environments?  Yes, if you are persisting your solutions into source control like GitHub, then you can always reconstitute the developer environment from source code. 

`- name: Create Developer Environment
      uses: microsoft/powerplatform-actions/create-environment@v0
      with:
        app-id: ${{secrets.CLIENT_ID}}
        client-secret: ${{ secrets.PowerPlatformSPN }}
        tenant-id: ${{secrets.TENANT_ID}}
        name: ${{ github.event.inputs.env_name}}_Dev
        type: Developer
        domain: ${{ github.event.inputs.env_name}}Dev`
In this case, based on the variables used you can see we are creating the Developer environment and using service principals to do so. Now remember when creating an environment with a service principal, by default the service principal owns it. The next task is user assignment in this case I am adding another user to the environment with similar privileges as the service principal. You can absolutely change those if you like.
`- name: assign-user to developer environment
      uses:  microsoft/powerplatform-actions/assign-user@v0
      with:
        app-id: ${{secrets.CLIENT_ID}}
        client-secret: ${{ secrets.PowerPlatformSPN }}
        tenant-id: ${{secrets.TENANT_ID}}
        environment: 'https://${{ github.event.inputs.env_name}}Dev.dynamics.com'
        user:${{ github.event.inputs.user_id }}
        role: System Administrator`
But in your case, you can add any other role here. You can also add another service principal account as well using 
`application-user` parameter.

#### Export Unpack and Commit 
In this workflow we export a given solution as unmanaged, unpack it, then export the managed version of the solution, and then commit them to the GitHub repository. 

About committing managed solution into the source code repository. I am wading into philosophical waters here! Checking in a managed solution to me is like checking in a dll into source code.So, if you have the source code, why check in the dll as well, you can always reconstitute it, right! BTW, if you have no idea what I am talking about for [managed and unmanaged solutions](https://learn.microsoft.com/en-us/power-platform/alm/solution-concepts-alm), the power platform ALM page is a wonderful place to get acquainted with the concepts.  I come from a world where you only check-in the unmanaged contents, put it in a build server and then export from the build server as managed, which makes it immutable and ready for deployment into Test and/or Production. 
There is another school of thought, that states that you export both the unmanaged and managed versions of the solution and if all well with the application then just proceed to deploy the managed version into Test and/or Production. The good thing is we support both.

Now, you can unpack managed solutions to and check them in. If you are going to do that make sure the unpack in a different location. the Sample workflow only unpacks the unmanaged solution. Your process maybe different.

#### Delete environments
This is a simple one where we just delete the Development, Test, and Production environments. When deleting environment remember if there is data in the environment (as in inside dataverse) they would get lost as well. You can use the data migration tool (in a different blog) to export the data and check that into source code as well.

` - name: Delete Dev Environment
      uses: microsoft/powerplatform-actions/delete-environment@v0
      with:
        app-id: ${{secrets.CLIENT_ID}}
        client-secret: ${{ secrets.PowerPlatformSPN }}
        tenant-id: ${{secrets.TENANT_ID}}
        environment-url: ${{ inputs.dev_env }}`

#### Deploying applications
Here we have 2 workflows, in the case of the managed solution, you can see that we only deploy the solution.zip and it pretty straight forward. 
`- name: Import solution as unmanaged to build env
        uses: microsoft/powerplatform-actions/import-solution@v0
        with:
          environment-url: ${{github.event.inputs.environment_url}}
          app-id: ${{secrets.CLIENT_ID}}
          client-secret: ${{ secrets.PowerPlatformSPN }}
          tenant-id: ${{secrets.TENANT_ID}}
          solution-file: ${{ github.event.repository.name}}/${{ github.event.inputs.solution_name }}_managed.zip
          force-overwrite: true
          publish-changes: true`
All it does is that takes the managed zip file and imports it to the target environment.  

Now in the case of the unmanaged solution, there is an extra task that needs to be done. This is called packing the solution, as in reconstituting the solution.zip file. So that it is ready to import. 
` - name: Pack the solution
        uses: microsoft/powerplatform-actions/pack-solution@v0
        with:
          solution-folder: ${{ github.event.repository.name}}/${{ github.event.inputs.solution_name }}
          solution-file: ${{ github.event.repository.name}}/${{ github.event.inputs.solution_name }}.zip
          solution-type: Unmanaged`
`- name: Import solution as unmanaged to build env
        uses: microsoft/powerplatform-actions/import-solution@v0
        with:
          environment-url: ${{github.event.inputs.environment_url}}
          app-id: ${{secrets.CLIENT_ID}}
          client-secret: ${{ secrets.PowerPlatformSPN }}
          tenant-id: ${{secrets.TENANT_ID}}
          solution-file: ${{ github.event.repository.name}}/${{ github.event.inputs.solution_name }}.zip
          force-overwrite: true
          publish-changes: true`

    
Now also realize, when are you importing an unmanaged solution into a target environment, unmanaged means that it can change (as in edit the application), so if you do make changes to the application in the QA environment then make sure export the unmanaged changes to the source repository before exporting the managed solution. Now , importing unmanaged solutions into any environment other than development makes me uneasy, as the best practice is to have unmanaged solutions in your developer environment, and only managed solutions in QA and Production. Some of the patterns you can think of are 

- Dev (Exports Unmanaged) -> (Imports UnManaged) Build-> Build (Exports Managed) -> (Imports Managed) QA (Exports Managed) -> (Imports Managed) Prod
- Dev (Exports Unmanaged + Managed) -> (Imports Managed) QA (Exports Managed) -> (Imports Managed) Prod 

There are plenty of other patterns that you can explore these are just some of them

  


There plenty of other sample workflows in the repository, I am also thinking about creating a repository for the community to share their workflows as well. If this an idea you all like. Please do let me know. 

Looking forward to hearing from you all and exploring what other patterns that you have implemented.