Amazon.co.uk Widgets

Log in

X

This article is Publishing Power Apps to clients production environments securely using GitHub with Power Platform (part 3) (2) . You'll need to have completed part 1, part 2  and part 3 before continuing. This article deals with the GitHub workflow required to deploy a Power Platform app into a production environment via GitHub thus providing a recognisable governance and software assurance methodology for your Power Platform apps.

Create a managed solution and publish it in a GitHub repo

  • Navigate to "Actions" and select "New workflow" 
  • Click "Actions" and choose "Simple workflow"
  • Delete the content and paste the content of release-solution-to-prod-with-inputs from the Microsoft Power Platform GitHub Actions Lab repository.
  • Rename the file from "blank.yml" to "release-solution-to-prod-with-inputs.yml".
  • Edit the solution_name default from ALMLab to whatever your solution is named!
  • Now commit the changes and your workflow is created
Commit the release solution to production workflow
Commit the release solution to production workflow

Release workflow

This workflow runs automatically when you create a release in GitHub.

  • Navigate to "Actions" and select "New workflow" 
  • Click "Actions" and choose "Simple workflow"
  • Delete the content and paste the content of release-action-call from the Microsoft Power Platform GitHub Actions Lab repository.
  • Rename the file from "blank.yml" to "release.yml".
  • Update <BUILD_ENVIRONMENT_URL> with the URL for the build environment you are going to use to generate the managed solution e.g. "c0ffeebuild.crm.dynamics.com".
  • Update <PRODUCTION_ENVIRONMENT_URL> with the URL for the build environment you are going to use to generate the managed solution e.g. "c0ffeeprod.crm.dynamics.com".
  • Update <BUILD_CLIENT_ID> with the ID you saved from Azure Active Directory.
  • Update <PRODUCTION_CLIENT_ID> with the ID you saved from Azure Active Directory.
  • Update <APPID> and <TENANT ID> with the values you saved away somewhere safe back in part one of this series of articles 
  • Add the secrets variables to reflect your environments. I added  buildSecret and  prodSecret and set required to true.
  • Edit the code to ensure that buildSecret is used for the build environment (your trial environment) and prodSecret is used for the production environment (your default environment).
  • Now commit the changes and your workflow is created

My release.yml

name: Release action
# Call the reusable workflow release-solution-with-inputs.yml
# Release your solution to prod when you create a new release.

on:
  release:
      types: [created]        
permissions:
  contents: write
jobs:
  Release-solution-utopia:
    uses: ./.github/workflows/release-solution-to-prod-with-inputs.yml
    with:
      # The solution name.
      solution_name: utopia
      
      # Tenant and environment variables.
      TENANT_ID: 4fb7a570-09cb-4565-9518-0005ef2f0ef8  
      BUILD_ENVIRONMENT_URL: 'https://orge29f1013.crm11.dynamics.com'
      BUILD_CLIENT_ID: 397a288b-a275-454f-bc53-1885d29e2fb9
      PRODUCTION_ENVIRONMENT_URL: 'https://org9481e946.crm11.dynamics.com'
      PRODUCTION_CLIENT_ID: f0b791a0-cb9f-4b89-b9b0-8a858b7b7c7b
      
    # Azure Active Directory App registration for each environment lets you specify client secrets which identify and authorise GitHub Actions
    secrets:
      buildSecret: ${{ secrets.POWER_ANGUSF_TRIAL }}
      prodSecret: ${{ secrets.POWER_MULTIZONE_DEFAULT }}

Release to Production workflow details

  • Navigate to "Actions" and select "New workflow" 
  • Click "Actions" and choose "Simple workflow"
  • Delete the content and paste the content of  release-solution-to-prod-with-inputs.yml  from the Microsoft Power Platform GitHub Actions Lab repository.
  • Rename the file from "blank.yml" to "release-solution-to-prod-with-inputs.yml".
  • Update "solution_name" default to the name of your Power App solution
  • Update <BUILD_ENVIRONMENT_URL> with the URL for the build environment you are going to use to generate the managed solution e.g. "c0ffeebuild.crm.dynamics.com".
  • Update <PRODUCTION_ENVIRONMENT_URL> with the URL for the build environment you are going to use to generate the managed solution e.g. "c0ffeeprod.crm.dynamics.com".
  • Update <BUILD_CLIENT_ID> with the ID you saved from Azure Active Directory.
  • Update <PRODUCTION_CLIENT_ID> with the ID you saved from Azure Active Directory.
  • Add the secrets variables to reflect your environments. I added  buildSecret and  prodSecret and set required to true.
  • Edit the code to ensure that buildSecret is used for the build environment (your trial environment) and prodSecret is used for the production environment (your default environment).
  • Now commit the changes and your workflow is created

My release-solution-to-prod-with-inputs.yml


name: release-solution-to-prod-reusable
# Reusable workflow
# convert solution to managed (using a build PowerPlatform environment for the conversion)
# upload the solution to the GitHub artifacts and deploy to the PROD environment
on:
  workflow_call:
    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: utopia       
      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
      BUILD_ENVIRONMENT_URL:
        description: 'Build environment url.'
        type: string
        required: true      
      PRODUCTION_ENVIRONMENT_URL: 
        description: 'Production environment url.'
        type: string
        required: true
      BUILD_CLIENT_ID: 
        description: 'The client id'
        type: string
        required: true
      PRODUCTION_CLIENT_ID: 
        description: 'The client id'
        type: string
        required: true
      TENANT_ID: 
        description: 'The tenant id'
        type: string
        required: true
    secrets:
      buildSecret:
        description: 'The secret value for authentication to build env via SPN'
        required: true
      prodSecret:
        description: 'The secret value for authentication to prod env via SPN'
        required: true

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 }}.zip
        solution-type: Unmanaged

    - name: Import solution as unmanaged to build env
      uses: microsoft/powerplatform-actions/import-solution@v0
      with:
        environment-url: ${{inputs.BUILD_ENVIRONMENT_URL}}
        app-id: ${{inputs.BUILD_CLIENT_ID}}
        client-secret: ${{ secrets.buildSecret }}
        tenant-id: ${{inputs.TENANT_ID}}
        solution-file: ${{ inputs.solution_outbound_folder}}/${{ inputs.solution_name }}.zip
        force-overwrite: true
        publish-changes: true

    - name: Export solution as managed
      uses: microsoft/powerplatform-actions/export-solution@v0
      with:
        environment-url: ${{inputs.BUILD_ENVIRONMENT_URL}}
        app-id: ${{inputs.BUILD_CLIENT_ID}}
        client-secret: ${{ secrets.buildSecret }} 
        tenant-id: ${{inputs.TENANT_ID}}
        solution-name: ${{ inputs.solution_name }}
        managed: true
        solution-output-file: ${{ inputs.solution_shipping_folder}}/${{ inputs.solution_name }}_managed.zip

    - name: Upload the ready to ship solution to GH artifact store
      uses: actions/upload-artifact@v2
      with:
        name: managedSolutions
        path: ${{ inputs.solution_shipping_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.PRODUCTION_CLIENT_ID}}
        client-secret: ${{ secrets.prodSecret }}
        tenant-id: ${{inputs.TENANT_ID}}
        solution-file: ${{ inputs.solution_release_folder}}/${{ inputs.solution_name }}_managed.zip
        force-overwrite: true
        publish-changes: true

Results

If you made it this far, and didn't make any mistakes, then you should be able to run the workflow successfully. It takes your tagged release, builds it in your trial environment, and then deploys it in your production environment. This means that you built this Power Platform app with the benefit of application lifecycle management and a clear separation from development, testing, and production software. thats got to be worth the setup. I hope Microsoft make it easier. Its still too many moving parts and too difficult to manage and I suspect it will be beyond citizen developers until it is too late.

Successful release workflow, taking a Power Platform app release from GitHub, building it and deploying it via GitHub Actions
Successful release workflow, taking a Power Platform app release from GitHub, building it and deploying it via GitHub Actions