- We can use GitHub Repositories as Source Control for Power Platform Solutions.
- To implement CI/CD process with GitHub, we can store the Power Platform solution in the source control. There are two main Paths –
- Export the unmanaged solution and place it as unpacked in the source control system. The build process imports the packed solution as unmanaged into a temporary build environment , then export the solution as managed and store it as a build artifact in your source control system.
- Export the solution as unmanaged and also export the solution as managed, and place both in the source control system.
We will follow the Path 2 in this article.
- We can Create GitHub Workflows using yaml code for
- Export the Solutions from Dev, unpack and store in a repository branch
- Generate Build Artifact and Import to Production
Steps :
Create source and target environments. Both should have Dataverse database enabled. Create an unmanaged Solution in the source environment
- Go to https://portal.azure.com
- Search for App Registration, click New Registration
- Provide the name, keep other fields with default value and click Register
- Once the App is created, go to API Permissions, click Add a Permission>Select Dynamics CRM>Add Permission >Grant Admin Consent for
- Go to Overview>Client credentials>New Secret. Copy the value into a notepad as this will be needed later and you won’t be able to get it once navigate away from this page.
- Come back to overview, and copy the Application (client) ID and Directory (tenant) ID in the same notepad. You will need these 3 values while creating GitHub workflows.
This workflow will export the Power Platform solution and keep both the managed and unmanaged version as unpacked in Github repository.
- Go to your Repository .Click on Actions and click set up a workflow yourself or click Configure in the Simple workflow box under the suggested for this repository section. This will start a new YAML file with a basic workflow to help you get started with GitHub actions. Update the name of the yaml file “Export Solution from Dev”
- Remove the content and paste below yaml code . Change the values Highlighted in yellow.
Solution Name – Provide your Solution Name (not the display name)
Environment Url – Go to make.powerapps.com> Select your Source environment >Go to Settings>Session details>copy the Instance url
Client ID and Tenant ID – Get it from the App registration created earlier
—————————————————————–
name: export-and-branch-solution
# Export solution from DEV environment
# unpack it and prepare, commit and push a git branch with the changes
on:
workflow_dispatch:
inputs:
# Change this value
solution_name:
description: ‘name of the solution to worked on from Power Platform’
required: true
default: ContosoDemo
#Do Not change these values
solution_exported_folder:
description: ‘folder name for staging the exported solution *do not change*’
required: true
default: out/exported/
solution_folder:
description: ‘staging the unpacked solution folder before check-in *do not change*’
required: true
default: out/solutions/
solution_target_folder:
description: ‘folder name to be created and checked in *do not change*’
required: true
default: solutions/
env:
#edit your values here
ENVIRONMENT_URL: ‘
CLIENT_ID: ‘
TENANT_ID: ‘
jobs:
export-from-dev:
runs-on: windows-latest
# or you can say runs-on: ubuntu-latest
env:
RUNNER_DEBUG: 1
steps:
– uses: actions/checkout@v2
with:
lfs: true
– name: export-solution action -unmanaged
uses: microsoft/powerplatform-actions/export-solution@v0
with:
environment-url: ${{env.ENVIRONMENT_URL}}
app-id: ${{env.CLIENT_ID}}
client-secret: ${{ secrets.PowerPlatformSPN }}
tenant-id: ${{env.TENANT_ID}}
solution-name: ${{ github.event.inputs.solution_name }}
solution-output-file: ${{ github.event.inputs.solution_exported_folder}}/${{ github.event.inputs.solution_name }}.zip
– name: export-solution action -managed
uses: microsoft/powerplatform-actions/export-solution@v0
with:
environment-url: ${{env.ENVIRONMENT_URL}}
app-id: ${{env.CLIENT_ID}}
client-secret: ${{ secrets.PowerPlatformSPN }}
tenant-id: ${{env.TENANT_ID}}
solution-name: ${{ github.event.inputs.solution_name }}
managed: true
solution-output-file: ${{ github.event.inputs.solution_exported_folder}}/${{ github.event.inputs.solution_name }}_managed.zip
– name: unpack-solution action
uses: microsoft/powerplatform-actions/unpack-solution@v0
with:
solution-file: ${{ github.event.inputs.solution_exported_folder}}/${{ github.event.inputs.solution_name }}.zip
solution-folder: ${{ github.event.inputs.solution_folder}}/${{ github.event.inputs.solution_name }}
solution-type: ‘Both’
overwrite-files: true
– name: branch-solution, prepare it for a PullRequest
uses: microsoft/powerplatform-actions/branch-solution@v0
with:
solution-folder: ${{ github.event.inputs.solution_folder}}/${{ github.event.inputs.solution_name }}
solution-target-folder: ${{ github.event.inputs.solution_target_folder}}/${{ github.event.inputs.solution_name }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
allow-empty-commit: true
——————————————————————————————
- You are now ready to commit your changes. Select Start commit, type Create export yml in the title field, and then add a description (optional). Next, click Commit new file.
- Navigate to Actions, Run workflow, and choose Run workflow
- After the workflow has completed, validate that a new branch has been created
- Go to Pull Requests, select the Branch and click Create Pull Request.
- On the Open a Pull request screen, add a title and description, as desired, then click Create pull request.
- The screen will update showing the newly create pull request. As the pull request is created confirmation will be provided showing that our branch has no conflict with the main branch. This confirmation means that the changes can be merged into the main branch automatically. Click Merge pull request and then click Confirm merge.
- Navigate back to the default (main) branch and validate the solution is now available there as well.
This workflow will generate build artifact for managed solution and import it to Production environment.
Create another workflow file following the same process above, paste the below yaml code . Update the highlighted values following the same steps as above
————————————————————————————-
name: release-solution-to-prod
# Reusable workflow
# upload the solution to the GitHub artifacts and deploy to the PROD environment
on:
workflow_dispatch:
inputs:
#Do Not change these values
#Values are set by the caller
#caller sample: release-action-call.ymnl
solution_name:
description: ‘The solution name.’
type: string
default:
solution_shipping_folder:
description: ‘folder name for staging the exported solution *do not change*’
type: string
default: out/ship/
solution_outbound_folder:
description: ‘staging the unpacked solution folder before check-in *do not change*’
type: string
default: out/solutions/
solution_source_folder:
description: ‘folder name to be created and checked in *do not change*’
type: string
default: solutions/
solution_release_folder:
description: ‘folder where the released binaries are going to be hosted *do not change*’
type: string
default: out/release
PRODUCTION_ENVIRONMENT_URL:
description: ‘Production environment url.’
type: string
required: true
default: ‘
CLIENT_ID:
description: ‘The client id’
type: string
required: true
default: ‘
TENANT_ID:
description: ‘The tenant id’
type: string
required: true
default: ‘
jobs:
convert-to-managed:
runs-on: windows-latest
# or you can say runs-on: ubuntu-latest
env:
RUNNER_DEBUG: 1
steps:
– uses: actions/checkout@v2
with:
lfs: true
– name: Pack solution
uses: microsoft/powerplatform-actions/pack-solution@v0
with:
solution-folder: ${{ inputs.solution_source_folder}}/${{ inputs.solution_name }}
solution-file: ${{ inputs.solution_outbound_folder}}/${{ inputs.solution_name }}_managed.zip
solution-type: Managed
– name: Upload the ready to ship solution to GH artifact store
uses: actions/upload-artifact@v2
with:
name: managedSolutions
path: ${{ inputs.solution_outbound_folder}}
release-to-staging:
needs: [ convert-to-managed ]
runs-on: windows-latest
env:
RUNNER_DEBUG: 1
steps:
– uses: actions/checkout@v2
with:
lfs: true
– name: Fetch the ready to ship solution from GH artifact store
uses: actions/download-artifact@v2
with:
name: managedSolutions
path: ${{ inputs.solution_release_folder}}
– name: Import solution to prod env
uses: microsoft/powerplatform-actions/import-solution@v0
with:
environment-url: ${{inputs.PRODUCTION_ENVIRONMENT_URL}}
app-id: ${{inputs.CLIENT_ID}}
client-secret: ${{ secrets.PowerPlatformSPN }}
tenant-id: ${{inputs.TENANT_ID}}
solution-file: ${{ inputs.solution_release_folder}}/${{ inputs.solution_name }}_managed.zip
force-overwrite: true
publish-changes: true
———————————————————————————————–
Run the workflow and validate that the solution has been deployed to Production.