I run a Rails website for a brass band in Wisconsin in a very similar setup to what you're describing, though it currently operates out of hostingrails.com. I host my code on github, though there's no reason you couldn't host it privately. My flow has evolved over the last year and a half, so take from this only what you need in the short term.
At the center of my flow, I have set up a semi-elaborate Capistrano script to handle the deployment, including a separate staging environment that makes a whole copy of the production database for testing. This took a while (hours, not days) to build, but it has been so worth it.
My workflow keeps at least 2 branches:
current_release
: Live production code. Emergency bugfixes are made here.
master
: Finished features ready for release. These features wait here to be tested live. Emergency bugfixes are merged in from current_release
.
<feature_name>
: Features under development. I try not to have more than 3 of these outstanding at any given time. Emergency bugfixes are merged in, and master
is frequently merged in to keep the feature current.
Having this setup allows me to work on several things concurrently. Week-to-week (as this is nowhere near a full-time occupation), I do the following:
I edit in feature branches. I switch back and forth, get bored, get excited, whatever. Sometimes I merge two features that grow together.
[edit]
$ git commit
$ git push github [feature]
Finished features ready for iminent deployment are merged one-at-a-time to the master
branch.
$ git checkout master
$ git merge [feature]
[fix immediate problems or inconsistencies]
$ git commit
$ git push github master
$ git branch -d [feature]
I stage the website to a private URL (happens to be stage.madisonbrass.com). The staging environment always pulls from the master
branch.
$ cap staging deploy # master
is now live at stage.madisonbrass.com
Bam, while I'm testing, I find an emergency bug on the public website. Fortunately, I have current_release
working separately, and thus can separately fix and deploy it.
$ git checkout current_release
[fix bug]
$ git commit
$ git push github current_release
$ cap production deploy
I return to the master
branch, and start by merging the emergency fix.
$ git checkout master
$ git merge current_release
I continue testing master
. Hopefully no new issues appear, but if they do I fix them in master, I merge these changes into current_release
and do another production deployment.
$ git checkout current_release
$ git merge master
$ git push github current_release
$ cap production deploy
I tear down my staging environment, lest it somehow get indexed by a search engine.
$ git staging teardown