jerhinesmith
jerhinesmith

Reputation: 15492

Git Workflow With Capistrano

I'm trying to get my head around a good git workflow using capistrano. I've found a few good articles, but I'm either not grasping completely what they're suggesting (likely) or they're somewhat lacking.

Here's kind of what I had in mind so far, but I get caught up when to merge back into the master branch (i.e. before moving to stage? after?) and trying to hook it into capistrano for deployments:

  1. Make sure you’re up to date with all the changes made on the remote master branch by other developers
    • git checkout master
    • git pull
  2. Create a new branch that pertains to the particular bug you're trying to fix
    • git checkout -b bug-fix-branch
  3. Make your changes
    • git status
    • git add .
    • git commit -m "Friendly message about the commit"

So, this is usually where I get stuck. At this point, I have a master branch that is healthy and a new bug-fix-branch that contains my (untested -- other than unit tests) changes.

If I want to push my changes to stage (through cap staging deploy), do I have to merge my changes back into the master branch (I'd prefer not to since it seems like master should be kept free of untested code)? Do I even deploy from master (or should I be tagging a release first and then modifying my production.rb file to deploy from that tag)? git-deployment seems to address some of these workflow issues, but I can't seem to find out how on earth it actually hooks into cap staging deploy and cap production deploy.

Thoughts? I assume there's a likely canonical way to do this, but I either can't find it or I'm too new to git to recognize that I have found it.

Help!

Upvotes: 5

Views: 1741

Answers (1)

Jed Schneider
Jed Schneider

Reputation: 14671

The way that I do it is to have a 'staging' branch that is tracked on your blessed repo. You will want to use the gem 'capistrano-ext' which provides a few extra config options for stages (I think you are already using this considering your call to deploy on staging). capistrano-ext defines stages, which allows you to have a deploy file for each stage, eg 'staging' where you define the branch set :branch, "staging" unique to each stage you are deploying to. You can do your workflow above and add:

#after commiting on bug-fix branch
git checkout staging # => tracks staging on origin
git merge bug-fix-branch # => bring new code in
git push origin staging # => capsitrano acts locally, it needs the code to get from origin
cap staging deploy # => wasnt that easy?

in an ideal world, you also have a production branch, thus the git branches become agreed upon by the team as

  • master - edge code where the team shares between devs
  • staging - code to be tested by the client on a staging server (fast-forwards on master merge)
  • production - stable release (fastforwards from staging)

EDIT: the response to the comment was too long so i had to append to the answer.

You have several ways to deal with this, I can think of one right away. A fix on prod needs to be reflected in all branches asap so your devs are working on the same base. Assuming prod has a direct common ancestor to staging, and staging to master, a fix on prod should be added to a topic branch based off the HEAD of the prod branch, then merge that change with master and then into staging and finally for deploy into production. The idea is that the only diff is the commits for the bug fix, next time you fast-forward production to the head on staging, you would already have the object that represents the change from the prod bug you fixed, so there is no problem (and since there is good testing for the bug you know it works, after running the suite on each branch). Otherwise you would probably have to cherry-pick a commit from master and apply to prod and staging. Take a look at pro-git.org for more advanced workflows like that.

Upvotes: 3

Related Questions