Skip to content

Instantly share code, notes, and snippets.

@konradhalas
Created April 25, 2012 18:41
Show Gist options
  • Save konradhalas/2492084 to your computer and use it in GitHub Desktop.
Save konradhalas/2492084 to your computer and use it in GitHub Desktop.
fabfile - simple django app deploy
import os
from fabric.api import run, cd, env, abort
from fabric.contrib.console import confirm
from fabric.context_managers import prefix
from fabric.tasks import Task
env.hosts = ['sample@example.com']
env.settings = ['staging', 'production']
env.dirs = {
'staging': '~/websites/dev.sample.com/',
'production': '~/websites/sample.com/'
}
env.source_dir = 'sample'
env.django_project_dir = 'src/sample'
env.venv_dir = 'sample_venv'
env.apps = {
'staging': 'staging_sample_app',
'production': 'production_sample_app'
}
env.branches = {
'staging': 'default',
'production': 'production'
}
class DeployTask(Task):
name = 'deploy'
def run(self, settings='staging'):
self.settings = settings
self.check_settings()
with self.virtualenv():
with self.cd_django_project():
self.dump_db()
old_revision = self.current_revision()
self.pull_and_update_code()
self.update_venv()
self.run_tests(old_revision)
self.update_static_files()
self.update_db()
self.restart_app()
def virtualenv(self):
VENV_ABSOLUTE_PATH = os.path.join(env.dirs[self.settings], env.venv_dir)
return prefix('source {0}/bin/activate'.format(VENV_ABSOLUTE_PATH))
def cd_django_project(self):
DJANGO_PROJECT_PATH = os.path.join(env.dirs[self.settings], env.source_dir, env.django_project_dir)
return cd(DJANGO_PROJECT_PATH)
def check_settings(self):
if self.settings not in env.settings:
abort('Invalid settings.')
if self.settings == 'production' and not confirm('Do you realy want to deploy to production?'):
abort('Aborting!')
def dump_db(self):
DUMP_FILE_PATH = os.path.join(env.dirs[self.settings], 'deploy_dump.json')
run('./manage.py dumpdata --settings=settings.{0} > {1}'.format(self.settings, DUMP_FILE_PATH))
def current_revision(self):
return run('hg parent --template "{node}"')
def pull_and_update_code(self):
run('hg pull'.format(env.branches[self.settings]))
run('hg update {0}'.format(env.branches[self.settings]))
def update_venv(self):
REQUIREMENTS_FILE_PATH = os.path.join(env.dirs[self.settings], env.source_dir, 'requirements.txt')
run('pip install -q -r {0}'.format(REQUIREMENTS_FILE_PATH))
def run_tests(self, old_revision):
result = run('./manage.py test --settings=settings.local')
if result.failed:
run('hg update -r {0}'.format(old_revision))
abort('Tests faild.')
def update_static_files(self):
run('./manage.py synccompress --settings=settings.{0}'.format(self.settings))
run('./manage.py collectstatic --noinput')
def update_db(self):
run('./manage.py syncdb --settings=settings.{0} --noinput'.format(self.settings))
run('./manage.py migrate --settings=settings.{0}'.format(self.settings))
def restart_app(self):
run('restart-app {0}'.format(env.apps[self.settings]))
deploy = DeployTask()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment