As more organizations build business-critical applications using Dynamics 365 and Power Platform, the need for structured Application Lifecycle Management (ALM) becomes essential. Manual deployments are error-prone, time-consuming, and lack traceability. The solution? DevOps automation—specifically using GitHub Actions to manage Dynamics 365 solutions efficiently.
GitHub Actions offers a powerful, cloud-native way to automate workflows directly from your code repository. When combined with the Power Platform CLI (PAC CLI) and solution best practices, it becomes an essential tool for implementing enterprise-grade ALM.
In this guide, you’ll learn how to use GitHub Actions to manage Dynamics 365 solutions, automate solution deployment, enforce quality checks, and streamline CI/CD pipelines.
Why Use GitHub Actions for Dynamics Solutions?
GitHub Actions allows you to:
- Automate solution exports, imports, and validations.
- Trigger deployments based on events (e.g., code push, PR merge).
- Run solution checker for code quality.
- Push portal content (Power Pages) as part of CI/CD.
- Integrate with secrets, approvals, and build artifacts.
When combined with Power Platform CLI and solution packaging, GitHub Actions becomes a DevOps powerhouse for Power Platform and Dynamics 365 teams.
Prerequisites
Before setting up GitHub Actions for Dynamics 365:
- Access to a GitHub repository
- Dynamics 365 environment(s) (Dev, Test, Prod)
- A registered Azure AD App (for Service Principal authentication)
- Power Platform CLI installed locally (for testing)
- Dynamics 365 solutions in source control (unpacked using
pac solution unpack
)
1. Overview of the Workflow
A typical Dynamics 365 GitHub Actions workflow includes:
- Exporting a solution from development.
- Running Solution Checker.
- Importing into Test or UAT.
- Optional approval before production deployment.
- Uploading portal (Power Pages) content if applicable.
- Versioning, backups, and rollback capability.
2. Authenticating with Power Platform in GitHub Actions
First, create a Service Principal in Azure Active Directory and register your app. Then, store the following as secrets in your GitHub repo:
CLIENT_ID
CLIENT_SECRET
TENANT_ID
ENV_URL
(Dataverse environment URL)
To authenticate in GitHub Actions, use:
- name: Authenticate with Power Platform
run: |
pac auth create --url ${{ secrets.ENV_URL }} --clientId ${{ secrets.CLIENT_ID }} --clientSecret ${{ secrets.CLIENT_SECRET }} --tenant ${{ secrets.TENANT_ID }}
3. GitHub Actions Workflow File Structure
Create a file in your repo under .github/workflows/deploy.yml
:
name: Deploy Dynamics Solution
on:
push:
branches:
- main
jobs:
deploy:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup PAC CLI
run: |
npm install -g paconn
npm install -g @microsoft/powerplatform-cli
- name: Authenticate
run: |
pac auth create --url ${{ secrets.ENV_URL }} --clientId ${{ secrets.CLIENT_ID }} --clientSecret ${{ secrets.CLIENT_SECRET }} --tenant ${{ secrets.TENANT_ID }}
- name: Pack solution
run: |
pac solution pack --folder ./solutions/MySolution --zipfile ./MySolution.zip --packagetype Managed
- name: Import to Environment
run: |
pac solution import --path ./MySolution.zip --async --wait 30
4. Exporting and Unpacking Solutions (Optional CI Stage)
If you want to export a solution from your Dev environment and store it in the repo (e.g., as part of nightly builds or backups):
- name: Export solution
run: |
pac solution export --name "MySolution" --path ./MySolution.zip --managed
- name: Unpack solution for source control
run: |
pac solution unpack --zipfile ./MySolution.zip --folder ./solutions/MySolution --allowDelete
This helps track changes via Git and allows peer reviews.
5. Running Solution Checker
Solution Checker is critical for ensuring code quality before deployment:
- name: Run Solution Checker
run: |
pac solution checker --path ./MySolution.zip --outputDirectory ./checkresults
- name: Upload Checker Results
uses: actions/upload-artifact@v3
with:
name: checker-results
path: ./checkresults
For GitHub Advanced Security users, you can convert this output to SARIF format and publish as security alerts.
6. Portal Deployment with GitHub Actions
If you’re also using Power Pages, add steps to push content:
- name: Upload portal content
run: |
pac paportal upload --path ./portal
You can store Power Pages content in a portal
folder within your repo, synchronized using pac paportal download
.
7. Deployment to Multiple Environments
Split your workflow into multiple jobs or stages, with secrets for each environment:
jobs:
test:
runs-on: windows-latest
steps:
# authenticate with UAT and import
- name: Import to UAT
run: |
pac auth create --url ${{ secrets.UAT_ENV_URL }} --clientId ${{ secrets.CLIENT_ID }} --clientSecret ${{ secrets.CLIENT_SECRET }} --tenant ${{ secrets.TENANT_ID }}
pac solution import --path ./MySolution.zip
prod:
needs: test
runs-on: windows-latest
if: github.event_name == 'workflow_dispatch'
steps:
# same steps for production
You can use workflow_dispatch
for manual triggering of the production job, simulating approval gates.
8. Artifact Management and Versioning
Store build artifacts for traceability and rollback:
- name: Upload solution artifact
uses: actions/upload-artifact@v3
with:
name: ManagedSolution
path: ./MySolution.zip
Also consider adding semantic versioning via tags or commit messages, such as:
- name: Tag version
run: |
git tag -a v1.0.${{ github.run_number }} -m "Automated build"
git push origin --tags
9. Secrets and Security
Keep all sensitive values out of code by storing them in GitHub secrets.
Set them at:
Repository → Settings → Secrets and variables → Actions → New repository secret
Avoid hardcoding environment URLs or client credentials in your YAML file.
10. Bonus: GitHub Actions with ALM Accelerator
If you’re using ALM Accelerator for Power Platform from Microsoft’s CoE Starter Kit, you can integrate GitHub Actions into its process.
Use GitHub as your source control provider, and trigger deployments based on pull requests, tagging, or approvals.
ALM Accelerator provides pre-built pipelines, but you can enhance or override them using custom GitHub Actions workflows like those described above.
11. Best Practices for Dynamics + GitHub Actions
Best Practice | Why It Matters |
---|---|
✅ Use secrets | Never expose credentials in workflows |
✅ Store unpacked solutions | Enables Git-based source control |
✅ Run Solution Checker | Prevents poor-quality code in production |
✅ Use tags or versions | Enables traceability and rollback |
✅ Separate environments | Avoid mixing dev/test/prod workflows |
✅ Use workflow_dispatch | Manual deployment control for production |
✅ Combine with portal content | For Power Pages deployment |
✅ Monitor artifacts | Use checker reports and solution zips |
✅ Limit branch access | Enforce protected branches and reviews |
12. Real-World Scenario: Dynamics App Deployment via GitHub
Let’s say Contoso uses Dynamics 365 for Sales and has a custom extension managed through solutions. Their workflow looks like this:
- Developers make changes and commit to
feature
branches. - Pull requests trigger a GitHub Action to run Solution Checker.
- Once merged to
main
, the CI pipeline:- Packs and uploads the managed solution
- Runs quality checks
- Imports to UAT
- After UAT validation, a release manager triggers
workflow_dispatch
to push to production.
All changes are logged, versioned, and traceable—aligned with enterprise DevOps practices.