Power Platform EXPORT to DevOps - Simple Pipeline
This document provides a proven, reusable pattern for implementing Power Platform DevOps pipelines. Use this template to standardize your solution export and version control processes across your organization.
Pattern Summary
Pattern Name: Power Platform Solution Export Pipeline
Category: DevOps & CI/CD
Platform: Azure DevOps + Power Platform
Difficulty: Beginner to Intermediate
Time to Implement: 1-2 hours
What This Pattern Solves
- Manual solution exports prone to human error
- Lack of version control for Power Platform solutions
- Inconsistent deployment processes across environments
- No audit trail for solution changes
- Difficulty collaborating on Power Platform development
Pattern Outcomes
After implementing this pattern, you will have:
✅ Automated solution exports from your development environment
✅ Version-controlled source code for all solution components
✅ Consistent deployment artifacts (managed & unmanaged solutions)
✅ Environment-specific settings files for configuration management
✅ Audit trail of all solution changes through Git history
Pattern Overview
This pattern demonstrates how to implement a simple yet effective DevOps pipeline for Power Platform solutions using Azure DevOps. The pipeline automates the export of solutions from your development environment, manages version control, and prepares your solutions for deployment across multiple environments.
What This Pipeline Does
Prerequisites
Before implementing this pipeline, ensure you have:
- Azure DevOps Organization with appropriate permissions
- Power Platform Environment (Development/Source)
- Service Principal configured for Power Platform authentication
- Git Repository for solution source control
- Power Platform Build Tools extension installed in Azure DevOps
Pipeline Configuration
Variables
The pipeline uses two key variables that you need to customize:
| Variable | Description | Example Value |
|---|---|---|
varPowerPlatformSPN | Service connection name for Power Platform authentication | Dataverse - Backup |
varSolutionName | Name of the solution to export | ProjectExpenseLogger |
Pipeline Steps Explained
Complete Pipeline YAML
name: EXPORT $(TeamProject)_$(BuildDefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)
variables:
- name: varPowerPlatformSPN
# value: YOUR-OWN-VALUE-HERE
value: Dataverse - Backup
- name: varSolutionName
# value: YOUR-OWN-VALUE-HERE
value: ProjectExpenseLogger
trigger: none
pool:
vmImage: 'windows-latest'
steps:
- checkout: self
persistCredentials: true
clean: true
- task: PowerPlatformToolInstaller@2
inputs:
DefaultVersion: true
AddToolsToPath: true
- task: PowerPlatformSetSolutionVersion@2
inputs:
authenticationType: 'PowerPlatformSPN'
PowerPlatformSPN: '$(varPowerPlatformSPN)'
SolutionName: '$(varSolutionName)'
SolutionVersionNumber: '1.0.0.$(Build.BuildID)'
- task: PowerPlatformExportSolution@2
inputs:
authenticationType: 'PowerPlatformSPN'
PowerPlatformSPN: '$(varPowerPlatformSPN)'
SolutionName: '$(varSolutionName)'
SolutionOutputFile: '$(Build.SourcesDirectory)\solutions\$(varSolutionName)_1.0.0.$(Build.BuildID)_managed.zip'
Managed: true
AsyncOperation: true
MaxAsyncWaitTime: '60'
- task: PowerPlatformExportSolution@2
inputs:
authenticationType: 'PowerPlatformSPN'
PowerPlatformSPN: '$(varPowerPlatformSPN)'
SolutionName: '$(varSolutionName)'
SolutionOutputFile: '$(Build.SourcesDirectory)\solutions\$(varSolutionName)_1.0.0.$(Build.BuildID).zip'
Managed: false
AsyncOperation: true
MaxAsyncWaitTime: '60'
- task: PowerPlatformUnpackSolution@2
inputs:
SolutionInputFile: '$(Build.SourcesDirectory)\solutions\$(varSolutionName)_1.0.0.$(Build.BuildID).zip'
SolutionTargetFolder: '$(Build.SourcesDirectory)\solutions\src\$(varSolutionName)'
SolutionType: 'Both'
- task: PowerShell@2
inputs:
targetType: 'inline'
script: 'pac solution create-settings --solution-zip $(Build.SourcesDirectory)\solutions\$(varSolutionName)_1.0.0.$(Build.BuildID).zip --settings-file $(Build.SourcesDirectory)\solutions\$(varSolutionName)-settings.json'
- task: CmdLine@2
inputs:
script: |
echo commit all changes
git config user.email "$(Build.RequestedForEmail)"
git config user.name "$(Build.RequestedFor)"
git checkout -b main
git add --all
git commit -m "Latest solution changes."
echo push code to new repo
git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push origin main
Step-by-Step Breakdown
1. Repository Setup
- checkout: self
persistCredentials: true
clean: true
- Purpose: Ensures we have access to the repository with credentials to push changes back
- persistCredentials: Enables the pipeline to push changes to Git
- clean: Starts with a clean working directory
2. Tool Installation
- task: PowerPlatformToolInstaller@2
inputs:
DefaultVersion: true
AddToolsToPath: true
- Purpose: Installs the Power Platform CLI tools needed for solution management
- DefaultVersion: Uses the latest stable version
- AddToolsToPath: Makes tools available throughout the pipeline
3. Version Management
- task: PowerPlatformSetSolutionVersion@2
inputs:
authenticationType: 'PowerPlatformSPN'
PowerPlatformSPN: '$(varPowerPlatformSPN)'
SolutionName: '$(varSolutionName)'
SolutionVersionNumber: '1.0.0.$(Build.BuildID)'
- Purpose: Sets a unique version number for the solution using the build ID
- Pattern:
1.0.0.{BuildNumber}ensures each export has a unique version - Benefits: Enables proper version tracking and rollback capabilities
4. Solution Export (Managed)
- task: PowerPlatformExportSolution@2
inputs:
authenticationType: 'PowerPlatformSPN'
PowerPlatformSPN: '$(varPowerPlatformSPN)'
SolutionName: '$(varSolutionName)'
SolutionOutputFile: '$(Build.SourcesDirectory)\solutions\$(varSolutionName)_1.0.0.$(Build.BuildID)_managed.zip'
Managed: true
AsyncOperation: true
MaxAsyncWaitTime: '60'
- Purpose: Exports the managed version of the solution for production deployments
- Managed Solutions: Cannot be modified after import, ideal for production
- AsyncOperation: Handles large solutions that take time to export
- File Naming: Includes version number for easy identification
5. Solution Export (Unmanaged)
- task: PowerPlatformExportSolution@2
inputs:
authenticationType: 'PowerPlatformSPN'
PowerPlatformSPN: '$(varPowerPlatformSPN)'
SolutionName: '$(varSolutionName)'
SolutionOutputFile: '$(Build.SourcesDirectory)\solutions\$(varSolutionName)_1.0.0.$(Build.BuildID).zip'
Managed: false
AsyncOperation: true
MaxAsyncWaitTime: '60'
- Purpose: Exports the unmanaged version for development/testing environments
- Unmanaged Solutions: Can be modified after import, useful for development
- Use Case: Development and UAT environment deployments
6. Solution Unpacking
- task: PowerPlatformUnpackSolution@2
inputs:
SolutionInputFile: '$(Build.SourcesDirectory)\solutions\$(varSolutionName)_1.0.0.$(Build.BuildID).zip'
SolutionTargetFolder: '$(Build.SourcesDirectory)\solutions\src\$(varSolutionName)'
SolutionType: 'Both'
- Purpose: Unpacks the solution into individual files for version control
- Benefits:
- Enables file-by-file tracking of changes
- Supports merge conflict resolution
- Provides visibility into solution components
- Enables collaborative development
7. Settings File Generation
- task: PowerShell@2
inputs:
targetType: 'inline'
script: 'pac solution create-settings --solution-zip $(Build.SourcesDirectory)\solutions\$(varSolutionName)_1.0.0.$(Build.BuildID).zip --settings-file $(Build.SourcesDirectory)\solutions\$(varSolutionName)-settings.json'
- Purpose: Creates a settings file that can be used to configure environment-specific settings
- Use Case: Different connection strings, URLs, or configurations per environment
- Format: JSON file containing deployment settings
8. Git Operations
- task: CmdLine@2
inputs:
script: |
echo commit all changes
git config user.email "$(Build.RequestedForEmail)"
git config user.name "$(Build.RequestedFor)"
git checkout -b main
git add --all
git commit -m "Latest solution changes."
echo push code to new repo
git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push origin main
- Purpose: Commits all exported and unpacked files to the repository
- Process:
- Configures Git with the build requester’s identity
- Switches to main branch
- Stages all changes
- Creates a commit with descriptive message
- Pushes changes back to the repository
Architecture Overview
Benefits of This Approach
Version Control
- Complete History: Track every change to your Power Platform solution
- Branching: Support multiple developers working on different features
- Rollback: Easy to revert to previous versions when needed
- Compliance: Audit trail for regulatory requirements
Automated Exports
- Consistency: Same export process every time
- Scheduled: Can be triggered manually or on schedule
- Reliable: Reduces human error in export process
- Efficient: Saves developer time
Multi-Environment Support
- Managed Solutions: For production deployments
- Unmanaged Solutions: For development/testing
- Settings Files: Environment-specific configurations
- Artifacts: Versioned deployment packages
File Structure After Export
/solutions/
├── ProjectExpenseLogger_1.0.0.123_managed.zip # Managed solution
├── ProjectExpenseLogger_1.0.0.123.zip # Unmanaged solution
├── ProjectExpenseLogger-settings.json # Deployment settings
└── src/
└── ProjectExpenseLogger/ # Unpacked source
├── CanvasApps/
├── Entities/
├── OptionSets/
├── Roles/
├── Workflows/
└── Other/
Next Steps
Once you have this export pipeline working, consider adding:
- Import Pipeline: Automate deployment to test environments
- Solution Checker: Validate solution quality automatically
- Environment Variables: Better configuration management
- Approval Gates: Control production deployments
- Notifications: Alert teams of successful exports/deployments
Common Issues and Solutions
Authentication Problems
- Verify Service Principal has correct permissions
- Check Power Platform Service Connection configuration
- Ensure SPN has System Administrator role in target environment
Solution Export Failures
- Check solution dependencies are included
- Verify solution exists in the source environment
- Increase MaxAsyncWaitTime for large solutions
Git Push Issues
- Ensure pipeline has Contribute permissions to repository
- Check branch policies don’t block automated commits
- Verify System.AccessToken is available to the pipeline
Customization Options
Variable Modifications
variables:
- name: varEnvironmentUrl
value: https://yourorg.crm.dynamics.com
- name: varBranchName
value: $(Build.SourceBranchName)
- name: varVersionMajor
value: 1
- name: varVersionMinor
value: 0
Advanced Version Numbering
SolutionVersionNumber: '$(varVersionMajor).$(varVersionMinor).$(Build.BuildID).$(Rev:r)'
Multiple Solutions Export
Duplicate the export tasks for each solution you want to include in your pipeline.
This pattern provides a solid foundation for Power Platform DevOps practices and can be extended based on your specific organizational needs.
Pattern Implementation Checklist
Use this checklist to ensure successful implementation:
Before You Start
- Azure DevOps organization with admin access
- Power Platform development environment
- Service Principal created and configured
- Git repository prepared for solution storage
- Power Platform Build Tools extension installed
Implementation Steps
- Create new Azure DevOps pipeline
- Configure variables (varPowerPlatformSPN, varSolutionName)
- Set up service connection to Power Platform
- Copy and customize the YAML pipeline code
- Test pipeline execution with a sample solution
- Verify Git commits and solution artifacts
- Document pipeline for team use
After Implementation
- Train team on pipeline usage
- Establish solution naming conventions
- Set up monitoring and notifications
- Plan for import/deployment pipelines
- Regular pipeline maintenance and updates
Related Patterns
Consider implementing these complementary patterns:
- Power Platform Import Pipeline - Deploy solutions to target environments
- Solution Checker Integration - Automated quality validation
- Environment Variable Management - Configuration across environments
- Approval Gates Pattern - Control production deployments
- Multi-Solution Pipeline - Handle multiple solutions in one pipeline
This pattern is part of a comprehensive Power Platform DevOps pattern library. For more patterns and best practices, visit our pattern collection.
