The manual export-import-deploy cycle is the biggest friction point in mature Power Platform development. Once you have done it manually a few dozen times, you start to understand why automation matters.

Azure DevOps with the Power Platform Build Tools gives you a deployment pipeline that takes a solution from development to production with version control, build validation, and approval gates β€” with nobody touching a file manually.

Prerequisites

The repository structure

my-solution/
  β”œβ”€β”€ src/
  β”‚   └── MySolution/          ← unpacked solution files
  β”‚       β”œβ”€β”€ canvasapps/
  β”‚       β”œβ”€β”€ workflows/
  β”‚       β”œβ”€β”€ tables/
  β”‚       └── solution.xml
  β”œβ”€β”€ pipelines/
  β”‚   β”œβ”€β”€ build.yml
  β”‚   β”œβ”€β”€ deploy-test.yml
  β”‚   └── deploy-prod.yml
  └── config/
      β”œβ”€β”€ dev.json             ← environment variable values
      β”œβ”€β”€ test.json
      └── prod.json

The build pipeline

The build pipeline runs on every pull request to main. It exports the solution from Dev, unpacks it, and stores the files in your repository. This is what gives you source control on Power Platform components.

trigger: none
pr:
  branches:
    include: [main]

pool:
  vmImage: windows-latest

steps:
- task: PowerPlatformToolInstaller@2
  displayName: Install Power Platform tools

- task: PowerPlatformExportSolution@2
  displayName: Export solution from Dev
  inputs:
    authenticationType: PowerPlatformSPN
    PowerPlatformSPN: Dev-ServiceConnection
    SolutionName: MySolution
    SolutionOutputFile: $(Build.ArtifactStagingDirectory)/MySolution.zip

- task: PowerPlatformUnpackSolution@2
  displayName: Unpack solution
  inputs:
    SolutionInputFile: $(Build.ArtifactStagingDirectory)/MySolution.zip
    SolutionTargetFolder: src/MySolution

- script: git add . && git commit -m "chore: solution export [skip ci]"
  displayName: Commit solution files

The deployment pipeline

The deployment pipeline packs the solution from source, builds a managed solution, and deploys it to the target environment with environment variable substitution.

- task: PowerPlatformPackSolution@2
  displayName: Pack managed solution
  inputs:
    SolutionSourceFolder: src/MySolution
    SolutionOutputFile: $(Build.ArtifactStagingDirectory)/MySolution_managed.zip
    SolutionType: Managed

- task: PowerPlatformImportSolution@2
  displayName: Deploy to Production
  inputs:
    authenticationType: PowerPlatformSPN
    PowerPlatformSPN: Prod-ServiceConnection
    SolutionInputFile: $(Build.ArtifactStagingDirectory)/MySolution_managed.zip
    ConvertToManaged: true
    OverwriteUnmanagedCustomizations: true

The first time this pipeline runs end-to-end and deploys a solution to production without you touching a zip file, it is genuinely satisfying. Set it up once, use it forever.

Approval gates

Configure an environment in Azure DevOps for your Production deployment stage and add required approvers. Nobody deploys to production without a human sign-off β€” the pipeline enforces this automatically.

The Power Platform Pipelines feature (in-product) is also worth knowing about for teams without Azure DevOps. It gives you a simpler deployment experience built into the platform itself. For teams with existing DevOps infrastructure, the Azure DevOps approach gives you more control and integration options.