Best way to deploy from git
We work in teams of developers on different using the git workflow as below:
- Receive ticket
- git pull/checkout
- Create feature/bugfix branch
- Do changes
- Commit to branch
- Merge to test branch, git pull to test environment
- Test on same environment as live
- If test is successful, merge to proof, git pull to proof
- Client sign off
- Merge to live
- git pull on live
However I can’t decide on the best way for developers to pull their changes to live servers.
Currently, developers SSH to the live server (with individual user accounts) and perform a git pull – however they need to have read/write access to the codebase on the server.
An alternative is to create a web accessible git pull script, so when a developer wants to do a pull, the script literally executes git pull on the server and outputs to the browser.
The best alternative, in my opinion, is for a hook to be triggered when a repo is pushed to – we use gitlab so I think this implementation would be relatively trivial, the script on the web server receives a POST object containing information about the repository, so it could be scripted to only trigger a pull if the branch that receives the hook has been updated (if that makes sense). An email could also be sent to the user that did the push with an output of the git pull message, to ensure that everything went according to plan.
However I am uncomfortable that developers could accidentally push to the wrong branch and the commits become live prematurely – ideally there should be some kind of github style merge request feature.
Does anyone have any other recommendations or suggestions?
3 Solutions collect form web for “Best way to deploy from git”
At work we use capistrano + webistrano. Although it’s ruby based, and many features are ruby specific, it works perfectly for what we need.
Here is our workflow:
1-5: Same as yours
6: Go to dev webistrano -> select branch -> deploy
7: Client sign-off, etc
8: Go to live webistrano -> select branch -> deploy
It also supports deploy scripts, and a bunch of other stuff. With the deploy script, we use a
shared folder and
current folder. The deploy script creates symlinks to the shared folder, that contains libraries and other stuff that is not on the git repository.
Here is a sample deploy script for magento.
Jenkins is another option for continuous integration. It supports some extra stuff compared to capistrano (automated test execution), so it may be worth checking out.
We like to use Gerrit for code review. A Gerrit instance sits on top of the central Git repository and lets the project leader(s) review stuff. Once a commit is reviewed and accepted, Jenkins CI kicks in, does automatic code style checks, unit tests, generates API documentation automatically etc and finally deploys (if all tests passed) using Apache Ant scripts. This is a fairly complex setup, but we’ve come to love it.
These great tutorials go into detail about the setup.
Aside from the issues you’ve identified with the process, I’d also be concerned about parallel changes colliding and creating ineffective testing in your “Proof” environment.
Say Bob pulls change #1 to Proof, then Dave pulls change #2 to Proof, then client tests change #1 (against a codebase with #1 and #2), when you go to pull change #1 to Live, you’re effectively pulling untested code.
I’d recommend thinking in terms of immutable builds and build artifacts. A colleague of mine wrote a good article on this topic. The main change to your process would be:
- 1-5: (Same)
- 6: Retrieve from Test branch; capture build artifact; deploy build artifact to Test
- 7: (same)
- 8: Promote build to Proof; deploy build artifact
- 9 (same)
- 10 Promote build to Live; deploy build artifact
You should also consider using a deployment/delivery automation tool like Inedo’s BuildMaster. The free version should be more than what you need, and it will help you go from “log in and run a script” to “click a button after the appropriate approvals”.
disclaimer: I work for Inedo