Archive for the ‘git’ tag
Continuous releasing with git
Agile software development can be seen as heavily influenced by the open-source world. In 1996 Eric S. Raymond described two different models of open-source-software (OSS) development in his essay The Cathedral and the Bazaar. Back then OSS has been crafted like a cathedral, i.e. an exclusive group of developers was releasing source code when a stable version has been reached. But developers like Linus Torvalds have started to follow a new philosophy: “release early and often, delegate everything you can, be open to the point of promiscuity”. Eric S. Raymond called this the bazaar model.
With agile software development the world of proprietary software presents its learnings from the “great babbling bazaar”. The development process has become more flexible and release cycles have shortened drastically. Processes like Scrum allow product managers the rapid planning of new features, e.g. to react on customer demands or market changes. Software frameworks like Ruby on Rails help developers to create new features easily. Even the quality assurance (QA) has become more agile: Tests have been automated and continuous integration systems replace the old-fashioned checklists.
But open source as well as agile software development were not possible without powerful code management systems like Subversion or git which allow the separation of code versions. This makes it possible that developers can work on new features while the QA folks are testing the code version to be released. In the following is described how we manage our code.
We are using Scrum, Ruby on Rails, and git with submodules. Our Scrum process contains sprints, stories, tasks, and bugs. One sprint is a cycle of two weeks and one of our stories describes a new use case for a feature or the change of one use case. Each story consists of a number of tasks which are development jobs that can be finished during one work day or, of course, in less time by one pair of developers. Well, and a bug is a bug.
Although we have two-weeks sprints, we are constantly able to deploy our code. Hence bugfixes or new features can go online whenever the QA gives their OK. The way we keep our code deployable is to branch it for every new story or set of stories. Creating a new branch in git goes like this.
git checkout master
git branch <branch name>
git push origin <branch name>
git checkout <branch name>
If the work on a story includes a submodule, a new branch needs to be created in this submodule, too. In the corresponding branch of the main application this story branch of the submodule needs to be checked out afterwards. Here is how to add a submodule branch to the main application.
cd <main application path>
git checkout <branch name>
git submodule add -b <branch name> <repository> <path>
git push origin <branch name>
This not only looks like pretty much overhead for small changes, it is. So there is another way of separating submodule versions. When changes in a submodule do not conflict with the work of other developers on this submodule, it is possible to do them in the master branch without going online on the next deployment. Therefore the submodule revision is only updated in the story branch of the main application, but not in the master branch. To do so, run the following commands.
cd <main application path>
git checkout <branch name>
git add <submodule path>
git commit -m"Updated submodule <submodule>"
git push origin <branch name>
After finishing a story, the master branch is merged into the story branch in order to resolve conflicts which may occure before testing. This again has to be done in the submodules, too.
git checkout <branch name>
git fetch origin
git merge master
git push origin <branch name>
When all conflicts have been resolved the story can be deployed on a staging system which is a clone of the production system, so that the quality assurance guys can have a look at it.
git checkout <branch name>
git pull <branch name>
Afterwards, when the story has passed the quality assurance tests, it can be merged into the master branch and goes online with the next deployment of our code, which can be for example once a day.
git checkout master
git merge <branchname>
git push origin master
Whenever new code has been merged into the master branch, our CI system starts to run relevant unit, functional, and integration tests. All of these tests need to pass before the deployment can be continued. If one of the tests failed the deployment stops until the failure has been fixed. This way we can prevent regressions from going online.
Edit: Made introduction more comprehensible.
Popularity: 4% [?]
Setting your custom deploy strategy in capistrano
Capistrano 2 supports custom deploy strategies. You basically just have to implement the “deploy!” and “check!” methods in your class and you’re good to go.
But how do you tell Capistrano to use your strategy?
I looked into the code and found no way of setting your strategy. So I changed capistrano, that it’s possible to set the strategy. When I asked Jamis Buck to pull the change, he suggested that I just set the strategy directly. This approach wouldn’t need any changes to to code base.
Well then we went ahead and did just that. So here’s the code for setting your custom deploy strategy (Don’t forget to require the file with your code)
set :strategy, Capistrano::Deploy::Strategy::DifferentAppRootRemoteCache.new(self)
It works like a charm.
Popularity: 2% [?]
WordPress Deployment with Capistrano 2 and git
I know: PHP deployment is really easy. You just copy the files to the server and you’re good to go. Why bother with something like Capistrano for WordPress deployment? Well, we’re using Rails and we’re spoiled children, and because we can. That’s why. Ok, to be honest: I don’t like the copy/checkout the files and upload them deployment.
There already is a good tutorial for WordPress deployment with capistrano but it’s for Capistrano 1 and SVN. I’ll show you the neccessary modifications to use cap 2 and git. It’s easy, really.
Ok, then let’s go:
Local directory structure:
base_dir
- .git (Git Repository)
- Capfile
- config
- deploy.rb
- public
- *.php (etc...)
Server side Capistrano structure:
app-dir
- current => link to releases/2008....
- shared
- wp-config.php
- uploads (wp-uploads-folder)
- releases
- 2008.....
- public/ (wordpress goes here)
So you have to configure your Apache (or lighty or whatever) to use app-dir/current/public as Docroot.
My deploy.rb file looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
set :application, "mywordpress-blog" set :deploy_to, "/var/www/apps/#{application}" set :deploy_via, :copy set :copy_strategy, :checkout set :user, 'deploy' set :use_sudo, false set :keep_releases, 3 set :scm, :git set :repository, "/Users/hvolkmer/Projects/mywordpress-blog/" set :branch, "master" role :app, "blog.example.com" role :web, "blog.example.com" role :db, "blog.example.com", :primary => true desc "This is here to overide the original :restart" deploy.task :restart, :roles => :app do # do nothing but overide the default end desc 'Link to upload folder, cache and config' task :after_symlink do run "cp #{deploy_to}/#{shared_dir}/wp-config.php #{deploy_to}/#{current_dir}/public/wp-config.php" run "ln -nfs #{deploy_to}/#{shared_dir}/uploads/ #{deploy_to}/#{current_dir}/public/wp-content/uploads" end |
Notice that I symlink the uploads folder but copy the wp-config.php file. That’s ugly but neccessary, because php resolves the basepath of the target file and not the symlink when it tries to include other files. (So it would end up trying to include files from the shared directory). I’m told that in the latest PHP that bevaiour is fixed.
Using the deploy_via “copy” model doesn’t require to install git on the target system.
I was thinking about using vlad the deployer for that task because it is supposed to be simpler and leaner and all that. But as it is currently lacking the copy-deployment model and required git on the server side, I just stayed with capistrano which turned out to be the simpler solution for for us in this case.
So always remember: Pick the right tool (for you and) for the job and be happy with it.
Popularity: 20% [?]
