Our Process at Branded3 currently works like this....
we have 4 environments; continuous delivery, internal UAT, external UAT and production.
code is checked into github which includes the Sitecore root and our code (I know this is against best practice but it works well for software assurance, maybe a nuget feed would be good but I havent looked into it yet)
we then use team city to build the solution and run any gulp tasks for SAAS/js minification and finally run octopack to package up all the files into what is basically a nuget package.
we then use octopus deploy to automatically push the code out to continuous delivery. When we get to a milestone build, where we are considering pushing out to production we will use octopus deploy to push the package to internal UAT for in house testing, then to external UAT for client testing. if all is good then it goes to production.
we are using unicorn for item serialisation and these files get published into the package, when we deploy we manually run the sync command (this will soon be automated)
when the build gets pushed to each environment we run a post deploy powershell script which copies over any environment specific configs from a folder included in the package and repoints the IIS directory to the new location
we also have one project which uses the Sitecore Azure module and for that we use octopus deploy the same way but the production environment pushes only to the admin server then we log in once the release is complete and use the controls in Sitecore to deploy to the CD environment although soon i will be replacing this with our own powershell deployment so that it can all be done in one step by octopus deploy
The biggest gotcha I have found is with the way Sitecore does upgrades, it is totally at odds with the modern deployment mechanism so if you want to upgrade to a new version of sitecore you have to run the upgrade process on each environment individually and then push the updated build, otherwise you don't get item changes. The only other solution is to serialize the entire core and master database but that isn't a good idea.