How does your company approach code deployments? Bonus points on dealing with multiple code bases on multiple servers over multiple data centers where up-time is critical.
I use fabric (I'm a Python developer).
Found Engine Yard superb with Ruby, and you may want to look at Beanstalkapp http://beanstalkapp.com/features/deployments for deploying to multiple servers.
Our codebase is kept in git repos which we host on a private Github and we've developed a custom integration between them and Jenkins for CI/CD.
The deploy pipeline uses Gradle with our own DSL extensions and is also hosted in Github.
This repo includes a hierarchy of job config scripts (one for each service, written in Groovy) and when the deploy pipeline is pushed, it causes config changes to Jenkins to support the newly defined jobs.
Updates to our git service repos trigger Jenkins to drive Mesos/Marathon to deploy containerized (Docker) services in multiple languages (JS, Clojure, Elixir, etc.) to several AWS availability zones.
Developers can at any time deploy to our dev environment (including Proof-Of-Concept work) and can also deploy into production once the dev deploy is successful (though we encourage them to check with tech management before doing so) by clicking a link in Jenkins.
Each deployment goes through two main phases: build and launch.
The build phase occurs within its own build directory (named using the name of the service and its semver version) on the target service machine and includes source retrieval, installation of requirements, data migrations (if needed), code linting & coverage, unit-testing, integration-testing (if required), and clean-up. If any stage fails, the build is cancelled.
(Rather than use a separate build tool like grunt for our nodejs services, we use package.json scripts and npm for all build stages. For a rationale for this, see "Node.js, Ant, Grunt and other build tools")
The launch stage is composed of service start, spin-up (warming), and smoke-test, all on non-production ports, before the final deploy which occurs by relinking the current build directory to the service run directory and restarting the service. This strategy reduces down-time to a single service restart.
We keep a number of previous build directories intact so we can quickly roll-back to the last deploy as needed.
Currently, we have more than three hundred instances deployed using this methodology.