"GraphKit Deployer"
import sys
+from functools import wraps
+
# Deal with the fact that we aren't *really* a Python project,
# so we haven't declared python dependencies.
### Fabric Config
# TODO: env.rcfile = 'fabfile/fabricrc.conf'
-env.project_name = 'kraken-ui'
-env.colors = True
-env.use_ssh_config = True
-
-
-### Project Config
-env.dev_server = 'localhost:8081'
-env.minify_cmd = 'uglifyjs'
+# We `update()` here so --set on the commandline will override.
+for k, v in dict(
+ project_name = 'kraken-ui',
+ colors = True,
+ use_ssh_config = True,
+
+ dev_server = 'localhost:8081',
+ minify_cmd = 'uglifyjs',
+
+ dist = 'dist',
+ local_tmp = 'tmp',
+ browserify_js = 'vendor/browserify.js',
+ supervisor_job = 'reportcard',
+).iteritems():
+ env.setdefault(k, v)
+
+for k in ('dist', 'local_tmp',):
+ env[k] = p(env[k])
-env.dist = p('dist')
-env.local_tmp = p('tmp')
env.work_dir = env.local_tmp/env.dist
-
-env.browserify_js = 'vendor/browserify.js'
env.work_browserify_js = env.work_dir/env.browserify_js
env.vendor_search_dirs = map(p, ['static', 'var', env.work_dir])
env.vendor_bundle = env.work_dir/'vendor/vendor-bundle.min.js'
env.app_bundle_min = p(env.app_bundle.replace('.js', '.min.js'))
-
### Setup Staging Environments
# Envs aren't declared with @task in the stages module so that we can
# decorate them here and have them show up at the top level.
import stages
-@task
-def prod():
- "Set deploy environment to production."
- stages.prod()
-
-@task
-def stage():
- "Set deploy environment to stage."
- stages.stage()
+for name in stages.NAMES:
+ globals()[name] = task(getattr(stages, name))
import deploy
@task(default=True)
-@stages.ensure_stage
+@stages.prompt_for_stage
def full_deploy():
""" Bundles and deploys the project. [Default]
"""
# -*- coding: utf-8 -*-
"Setup Staging Environments"
+import sys
from functools import wraps
-from fabric.api import env, abort
+from fabric.api import env, abort, prompt, execute
from fabric.colors import white, blue, cyan, green, yellow, red, magenta
-__all__ = ('prod', 'stage', 'ensure_stage',)
+__all__ = ['NAMES', 'validate_stage', 'prompt_for_stage', 'ensure_stage', 'stage',]
# (otto) There should be a way to do this using stages.
# See: http://tav.espians.com/fabric-python-with-cleaner-api-and-parallel-deployment-support.html
# env.stages = ['prod', 'staging']
+NAMES = []
+
+def validate_stage(name):
+ "Tests whether given name is a valid staging environment."
+ name = name.strip()
+ if name not in NAMES:
+ raise Exception("%r is not a valid staging environment!" % name)
+ return name
+
+
+def prompt_for_stage(fn):
+ "Decorator which prompts for a stage-name if not set."
+
+ @wraps(fn)
+ def wrapper(*args, **kwargs):
+ if 'deploy_env' not in env:
+ name = prompt(white('Please select a staging target %s:' % NAMES, bold=True), validate=validate_stage)
+ execute(name)
+ # Must call `execute` on the supplied task, otherwise the host-lists won't be updated.
+ execute(fn, *args, **kwargs)
+
+ return wrapper
+
+
+def ensure_stage(fn):
+ "Decorator that ensures a stage is set."
+
+ @wraps(fn)
+ def wrapper(*args, **kwargs):
+ if 'deploy_env' not in env:
+ abort(red('You must specify a staging environment (prod, stage) prior to deploy!', bold=True))
+ return fn(*args, **kwargs)
+
+ return wrapper
+
+def stage(fn):
+ """ Decorator indicating this function sets a stage environment:
+
+ @stage
+ def mystage():
+ env.deploy_env = 'mystage'
+ ...
+
+ """
+ NAMES.append(fn.__name__)
+ __all__.append(fn.__name__)
+ return fn
+
+
+###
# NOTE WELL: These do not have @task as they'd show up as "stages.prod",
# and we want them at the top level. See __init__.py for the wrappers.
# Unfortunately, we can't put them in __init__.py without preventing deploy.py
# from importing them.
+###
+@stage
def prod():
""" Set deploy environment to production.
"""
env.owner = 'www-data'
env.group = 'www'
-def stage():
- """ Set deploy environment to stage.
+@stage
+def test():
+ """ Set deploy environment to test.
+ """
+ env.deploy_env = 'test'
+ env.hosts = ['kripke.pmtpa.wmflabs']
+ env.gateway = 'bastion.wmflabs.org'
+ env.target_dir = '/srv/test-reportcard.wmflabs.org/kraken-ui'
+ env.owner = 'www-data'
+ env.group = 'www'
+ env.supervisor_job = 'test-reportcard'
+
+@stage
+def dev():
+ """ Set deploy environment to dev.
+ """
+ env.deploy_env = 'dev'
+ env.hosts = ['kripke.pmtpa.wmflabs']
+ env.gateway = 'bastion.wmflabs.org'
+ env.target_dir = '/srv/dev-reportcard.wmflabs.org/kraken-ui'
+ env.owner = 'www-data'
+ env.group = 'www'
+ env.supervisor_job = 'dev-reportcard'
+
+@stage
+def lessly():
+ """ Set deploy environment to lessly.
"""
- env.deploy_env = 'stage'
+ env.deploy_env = 'lessly'
env.hosts = ['less.ly']
env.target_dir = '/home/wmf/projects/kraken-ui'
env.owner = 'wmf'
env.group = 'www'
-
-def ensure_stage(fn):
- "Decorator that ensures a stage is set."
-
- @wraps(fn)
- def wrapper(*args, **kwargs):
- if 'deploy_env' not in env:
- abort(red('You must specify a staging environment (prod, stage) prior to deploy!', bold=True))
- return fn(*args, **kwargs)
-
- return wrapper
+ del env['gateway']