This is the version control/CD process I designed:
- We have a normal Git repository, hosted in Azure DevOps cloud
- Developers work in the "unmanaged" cloud-hosted Development environment
- When ready to move a set of changes forwards, the developer branches the repo, and runs a PowerShell script to export the solution from the Development environment to a local ZIP file, which is then automatically unzipped. The only other thing I do is reset the version number to 0.0.0 within the `solution.xml` file, because I'm pedantic and the code isn't necessarily a deployable build yet - it could be an intermediate piece of work.
- Developer reviews the changes, commits with a message that links to work items in Azure DevOps, and creates a pull request -- all standard stuff
- On the Azure DevOps side, once a PR is merged, we build a managed ZIP -- which is really just the same code, with a flag set and re-zipped up with a version number that matches the DevOps build number (in the Power Apps world, "managed" package deployments can't be customized on UAT/Production without explicit configuration allowing it)
- We then use all the normal Azure DevOps YAML pipeline stuff to move this between UAT, Staging and Production with user approvals etc. The Azure AD and Power Apps integration makes this very pleasant - everything is very easy to secure, and you don't need to pass secrets around.
- You can rollback to a specific commit using normal Git tooling or just redeploy a past build if there is one available.
That all being said, most people don't do the above. I should probably sell a training course, because it took quite some time to put all the pieces together. The bigger problems are planning ahead for changes without breaking stuff that is already live, because you generally only use 1 development environment for an entire team.