Best Practices
Version Control
Store Everything in Git
- Solution XML (extracted)
- FlowOn packages (.flop)
- Data specification files
- Mapping files (per environment)
- Extracted business data
- Pipeline definitions
Branch Strategy
main (production)
├── develop (integration)
│ ├── feature/new-workflow
│ ├── feature/api-update
│ └── bugfix/validation-error
└── hotfix/critical-fix
Environment Management
Maintain Separate Mappings
mappings/
├── development/
│ ├── configuration.map.xml
│ ├── entity.map.xml
│ └── serviceconnection.map.xml
├── uat/
│ ├── configuration.map.xml
│ ├── entity.map.xml
│ └── serviceconnection.map.xml
└── production/
├── configuration.map.xml
├── entity.map.xml
└── serviceconnection.map.xml
Use Environment Variables for Secrets
# Never commit credentials
export FLOWON_CONNECTION_STRING="AuthType=ClientSecret;..."
Deployment Safety
Pre-Deployment Checklist
- ✅ Disable plugins before data migration
- ✅ Backup target environment
- ✅ Verify mapping files are correct
- ✅ Test in UAT first
- ✅ Have rollback plan ready
Plugin Management During Deployment
# 1. Disable plugins
flowon disable-plugins --project "MyProject" --all
# 2. Import solution and data
flowon import --solution "..." --data "..." --apply-mappings
# 3. Re-enable plugins
flowon enable-plugins --project "MyProject" --all
Data Management
Separate Reference Data from Transactional
- Reference data: Countries, statuses, templates → Version controlled
- Transactional data: Customers, orders → NOT version controlled
Use Data Specs for Consistency
- Define which entities to extract
- Specify import behaviors
- Document dependencies
Troubleshooting
Common Issues
| Issue | Cause | Solution |
|---|---|---|
| Import fails with GUID mismatch | Records have different IDs | Use entity mapping files |
| Plugin errors after deployment | Plugin still disabled | Run enable-plugins command |
| Localization not showing | LCID mismatch | Verify localized resource map |
| Service connection fails | Wrong credentials | Update service connection map |
Verbose Logging
flowon import --verbose --solution "..." 2>&1 | tee deployment.log
Quick Reference
Common Workflows
Initial Setup:
# 1. Install tools
dotnet tool install --global FlowOn.Xrm.Tools
# 2. Generate mapping files from source
flowon generate-mappings --project "MyProject" --output "./mappings/dev" --all
# 3. Copy and modify for target environments
cp -r ./mappings/dev ./mappings/uat
cp -r ./mappings/dev ./mappings/production
# Edit target values in each environment's files
Daily Export:
flowon export \
--solution "MyProject" \
--project "MyProject" \
--output "./artifacts" \
--managed --unmanaged \
--include-data \
--data-spec "./specs/data-spec.xml"
Deploy to Environment:
flowon import \
--solution "./artifacts/solutions/MyProject_managed.zip" \
--package "./artifacts/flowon/MyProject.flop" \
--data "./artifacts/data" \
--mappings "./mappings/production" \
--apply-mappings \
--publish-customizations
Version Bump:
flowon increment-solution-version --solution "MyProject" --minor
Project Structure Recommendation
my-project/
├── .github/
│ └── workflows/
│ └── deploy.yml # GitHub Actions pipeline
├── azure-pipelines.yml # Azure DevOps pipeline
├── specs/
│ └── data-spec.xml # Data extraction specification
├── mappings/
│ ├── development/
│ │ ├── configuration.map.xml
│ │ ├── entity.map.xml
│ │ ├── localizedresource.map.xml
│ │ └── serviceconnection.map.xml
│ ├── uat/
│ │ └── ...
│ └── production/
│ └── ...
├── artifacts/ # Generated (gitignored)
│ ├── solutions/
│ ├── flowon/
│ └── data/
└── README.md
Security Recommendations
Connection String Security
- Never commit credentials to version control
- Use environment variables or secret management
- Create separate service accounts per environment
- Use least privilege principle for service accounts
Service Account Permissions
| Environment | Required Roles |
|---|---|
| Development | System Administrator (for full export) |
| UAT | System Customizer, FlowOn API Customizer |
| Production | System Customizer, FlowOn API Customizer |
Audit Trail
- All deployments logged with timestamps
- Git history provides change tracking
- Pipeline logs capture deployment details