Exemple #1
0
def deploy(branch=None):
    ''' Deploy to remote source. '''
    stage = shell.get_stage()
    deployer_user = shell.get_user()
    branch = branch or resolve_deployment_branch(stage)
    commit = git.last_commit(remote=False, short=True)
    notif.send(notification_types.DEPLOYMENT_STARTED, {
        'user': deployer_user,
        'branch': branch,
        'commit': commit,
        'stage': stage
    })

    with cd(get_repo_path()):
        runner.run_script_safely(known_scripts.PRE_DEPLOY)

        # Get the latest code from the repository
        sync(branch)
        install_dependencies()

        # Building the app
        build(stage)
        reload_service()
        runner.run_script_safely(known_scripts.POST_DEPLOY)

    notif.send(notification_types.DEPLOYMENT_FINISHED, {
        'user': deployer_user,
        'branch': branch,
        'commit': commit,
        'stage': stage
    })

    remote_info('Deployment Completed')
Exemple #2
0
def run_script(script, remote=True):
    ''' Run a script. '''
    custom_scripts = _get_config()['scripts']

    # If the script is not defined raise error.
    if not is_script_defined(script):
        raise RuntimeError('Missing script "{}"'.format(script))

    needs_notification = should_notify(script)

    if needs_notification:
        notif.send(RUNNING_SCRIPT_STARTED, {
            'script': script,
            'user': shell.get_user(),
            'stage': shell.get_stage()
        })

        # Get the command defined in the script.
    script_cmd = custom_scripts[script]

    info_text = 'Running {}\n{}'.format(
        cyan(script), cyan('> ' + script_cmd)
    )
    host_info(info_text, remote=remote)

    # Run a custom script defined in the config.
    with hide('running'):
        run(script_cmd, remote)

    if needs_notification:
        notif.send(RUNNING_SCRIPT_FINISHED, {
            'script': script,
            'user': shell.get_user(),
            'stage': shell.get_stage()
        })
Exemple #3
0
def deploy(branch=None):
    ''' Deploy to remote source. '''
    stage = shell.get_stage()
    deployer_user = shell.get_user()
    branch = branch or get_stage_config(stage)['branch']
    commit = git.last_commit(short=True)
    notif.send(notification_types.DEPLOYMENT_STARTED, {
        'user': deployer_user,
        'branch': branch,
        'commit': commit,
        'stage': stage
    })

    # Get the latest code from the repository
    sync(branch)
    install_dependencies()

    # Building the app
    build(stage)
    reload_service()

    notif.send(notification_types.DEPLOYMENT_FINISHED, {
        'user': deployer_user,
        'branch': branch,
        'commit': commit,
        'stage': stage
    })

    remote_info('Deployment Completed')
Exemple #4
0
def test_notif_sends_slack_notification(slack_send_m, slack_is_enabled_m,
                                        gsc_m, get_m):
    ''' Test notif.send sends slack notification if slack is enabled. '''
    commit = 't12345'
    commit_url = 'https://github.com/kabirbaidhya/boss/tree/t12345'
    get_m.return_value = {
        'project_name': 'test-project',
        'project_description': 'Just a test project',
        'repository_url': 'https://github.com/kabirbaidhya/boss',
    }
    gsc_m.return_value = {
        'public_url': 'https://example.com',
        'host': 'example.com'
    }
    slack_is_enabled_m.return_value = True
    branch_url = 'https://github.com/kabirbaidhya/boss/tree/my-branch'

    # Trigger deployment started notification
    notif.send(
        DEPLOYMENT_STARTED, {
            'user': '******',
            'commit': commit,
            'branch': 'my-branch',
            'stage': 'test-server'
        })

    # Trigger deployment finished notification with branch=HEAD
    notif.send(
        DEPLOYMENT_FINISHED, {
            'user': '******',
            'commit': commit,
            'branch': 'HEAD',
            'stage': 'test-server'
        })

    (call1, call2) = slack_send_m.call_args_list

    assert call1[0][0] == DEPLOYMENT_STARTED
    assert call1[1]['branch'] == 'my-branch'
    assert call1[1]['commit'] == commit
    assert call1[1]['commit_url'] == commit_url
    assert call1[1]['branch_url'] == branch_url
    assert call1[1]['host'] == 'example.com'
    assert call1[1]['project_name'] == 'test-project'
    assert call1[1]['public_url'] == 'https://example.com'
    assert call1[1]['repository_url'] == 'https://github.com/kabirbaidhya/boss'
    assert call1[1]['server_name'] == 'test-server'
    assert call1[1]['user'] == 'ssh-user'

    assert call2[0][0] == DEPLOYMENT_FINISHED
    assert call2[1]['branch'] is None
    assert call2[1]['commit'] == commit
    assert call2[1]['commit_url'] == commit_url
    assert call2[1]['host'] == 'example.com'
    assert call2[1]['project_name'] == 'test-project'
    assert call2[1]['public_url'] == 'https://example.com'
    assert call2[1]['repository_url'] == 'https://github.com/kabirbaidhya/boss'
    assert call2[1]['server_name'] == 'test-server'
    assert call2[1]['user'] == 'ssh-user'
def deploy(branch=None):
    ''' Deploy to remote source. '''
    stage = shell.get_stage()
    branch = branch or resolve_deployment_branch(stage)
    params = dict(user=shell.get_user(), stage=stage, branch=branch)
    notif.send(notification_types.DEPLOYMENT_STARTED, params)
    run_deploy_script(stage, branch)
    notif.send(notification_types.DEPLOYMENT_FINISHED, params)
    remote_info('Deployment Completed')
Exemple #6
0
def test_notif_without_repository_url(hipchat_send_m, hipchat_is_enabled_m,
                                      gsc_m, get_m):
    ''' Test notif.send sends hipchat notification without repository_url. '''
    get_m.return_value = {
        'project_name': 'test-project',
        'project_description': 'Just a test project'
    }
    gsc_m.return_value = {
        'public_url': 'https://example.com',
        'host': 'example.com'
    }
    hipchat_is_enabled_m.return_value = True

    # Trigger deployment finished notification
    notif.send(
        DEPLOYMENT_FINISHED, {
            'user': '******',
            'branch': 'my-branch',
            'commit': '1234567',
            'stage': 'test-server'
        })

    # Trigger Deployment Started notification with no branch
    notif.send(DEPLOYMENT_STARTED, {
        'user': '******',
        'stage': 'test-server'
    })

    (call1, call2) = hipchat_send_m.call_args_list

    assert call1[0][0] == DEPLOYMENT_FINISHED
    assert call1[1]['branch'] == 'my-branch'
    assert call1[1]['commit'] == '1234567'
    assert call1[1]['branch_url'] == None
    assert call1[1]['commit_url'] == None
    assert call1[1]['host'] == 'example.com'
    assert call1[1]['project_name'] == 'test-project'
    assert call1[1]['public_url'] == 'https://example.com'
    assert call1[1]['repository_url'] == None
    assert call1[1]['server_name'] == 'test-server'
    assert call1[1]['user'] == 'ssh-user'

    assert call2[0][0] == DEPLOYMENT_STARTED
    assert call2[1]['branch'] is None
    assert call1[1]['branch_url'] is None
    assert call1[1]['commit_url'] is None
    assert call2[1]['repository_url'] is None
    assert call2[1]['host'] == 'example.com'
    assert call2[1]['project_name'] == 'test-project'
    assert call2[1]['public_url'] == 'https://example.com'
    assert call2[1]['server_name'] == 'test-server'
    assert call2[1]['user'] == 'ssh-user'
Exemple #7
0
def deploy(branch=None):
    ''' Deploy to remote source. '''
    stage = shell.get_stage()
    branch = branch or fallback_branch(stage)
    notif.send(notif.DEPLOYMENT_STARTED, {
        'user': shell.get_user(),
        'branch': branch,
        'stage': stage
    })

    # Get the latest code from the repository
    sync(branch)
    install_dependencies()

    # Building the app
    build(stage)
    reload_service()

    notif.send(notif.DEPLOYMENT_FINISHED, {'branch': branch, 'stage': stage})

    remote_info('Deployment Completed')
Exemple #8
0
def deploy():
    ''' Zero-Downtime deployment for the backend. '''
    config = get_config()
    stage = shell.get_stage()
    is_first_deployment = not buildman.is_remote_setup()

    branch = git.current_branch(remote=False)
    commit = git.last_commit(remote=False, short=True)
    info('Deploying <{branch}:{commit}> to the {stage} server'.format(
        branch=branch, commit=commit, stage=stage))

    tmp_path = fs.get_temp_filename()
    build_dir = buildman.resolve_local_build_dir()
    included_files = config['deployment']['include_files']

    deployer_user = shell.get_user()

    notif.send(notification_types.DEPLOYMENT_STARTED, {
        'user': deployer_user,
        'commit': commit,
        'branch': branch,
        'stage': stage
    })

    (release_dir, current_path) = buildman.setup_remote()

    timestamp = datetime.utcnow()
    build_id = timestamp.strftime('%Y%m%d%H%M%S')
    build_name = buildman.get_build_name(build_id)
    build_compressed = build_name + '.tar.gz'
    release_path = release_dir + '/' + build_name
    dist_path = build_name + '/dist'

    buildman.build(stage, config)

    info('Compressing the build')
    fs.tar_archive(build_compressed, build_dir, remote=False)

    info('Uploading the build {} to {}'.format(build_compressed, tmp_path))
    fs.upload(build_compressed, tmp_path)

    # Remove the compressed build from the local directory.
    fs.rm(build_compressed, remote=False)

    # Once, the build is uploaded to the remote,
    # set things up in the remote server.
    with cd(release_dir):
        remote_info('Extracting the build {}'.format(build_compressed))
        # Create a new directory for the build in the remote.
        fs.mkdir(dist_path, nested=True)

        # Extract the build.
        fs.tar_extract(tmp_path, dist_path)

        # Remove the uploaded archived from the temp path.
        fs.rm_rf(tmp_path)

        # Upload the files to be included eg: package.json file
        # to the remote build location.
        upload_included_files(included_files, release_path)

        remote_info('Pointing the current symlink to the latest build')
        fs.update_symlink(release_path, current_path)

    # Change directory to the release path.
    with cd(current_path):
        install_remote_dependencies()

    # Start or restart the application service.
    start_or_reload_service(is_first_deployment)

    # Save build history
    buildman.record_history({
        'id': build_id,
        'path': release_path,
        'branch': branch,
        'commit': commit,
        'stage': stage,
        'createdBy': deployer_user,
        'timestamp': timestamp.strftime(buildman.TS_FORMAT)
    })

    # Send deployment finished notification.
    notif.send(notification_types.DEPLOYMENT_FINISHED, {
        'user': deployer_user,
        'branch': branch,
        'commit': commit,
        'stage': stage
    })

    remote_info('Deployment Completed')
Exemple #9
0
def deploy():
    ''' Zero-Downtime deployment for the web. '''
    config = get_config()
    stage = shell.get_stage()
    user = get_stage_config(stage)['user']

    # Get the current branch and commit (locally).
    branch = git.current_branch(remote=False)
    commit = git.last_commit(remote=False, short=True)
    info('Deploying <{branch}:{commit}> to the {stage} server'.format(
        branch=branch, commit=commit, stage=stage))

    tmp_path = fs.get_temp_filename()
    build_dir = buildman.resolve_local_build_dir()

    deploy_dir = buildman.get_deploy_dir()
    deployer_user = shell.get_user()

    notif.send(notification_types.DEPLOYMENT_STARTED, {
        'user': deployer_user,
        'branch': branch,
        'commit': commit,
        'stage': stage
    })

    (release_dir, current_path) = buildman.setup_remote()

    timestamp = datetime.utcnow()
    build_id = timestamp.strftime('%Y%m%d%H%M%S')
    build_name = buildman.get_build_name(build_id)
    build_compressed = build_name + '.tar.gz'
    release_path = release_dir + '/' + build_name

    buildman.build(stage, config)

    info('Compressing the build')
    fs.tar_archive(build_compressed, build_dir, remote=False)

    info('Uploading the build {} to {}'.format(build_compressed, tmp_path))
    fs.upload(build_compressed, tmp_path)

    # Remove the compressed build from the local directory.
    fs.rm(build_compressed, remote=False)

    # Once, the build is uploaded to the remote,
    # set things up in the remote server.
    with cd(release_dir):
        remote_info('Extracting the build {}'.format(build_compressed))
        # Create a new directory for the build in the remote.
        fs.mkdir(build_name)

        # Extract the build.
        fs.tar_extract(tmp_path, build_name)

        # Remove the uploaded archived from the temp path.
        fs.rm_rf(tmp_path)

        remote_info('Changing ownership of {} to user {}'.format(
            deploy_dir, user))
        fs.chown(release_path, user, user)

        remote_info('Pointing the current symlink to the latest build')
        fs.update_symlink(release_path, current_path)

    # Save build history
    buildman.record_history({
        'id': build_id,
        'path': release_path,
        'branch': branch,
        'commit': commit,
        'stage': stage,
        'createdBy': deployer_user,
        'timestamp': timestamp.strftime(buildman.TS_FORMAT)
    })

    # Send deployment finished notification.
    notif.send(notification_types.DEPLOYMENT_FINISHED, {
        'user': deployer_user,
        'branch': branch,
        'commit': commit,
        'stage': stage
    })

    remote_info('Deployment Completed')
Exemple #10
0
def deploy():
    ''' Zero-Downtime deployment for the backend. '''
    config = get_config()
    stage = shell.get_stage()
    is_remote_setup = buildman.is_remote_setup()
    is_first_deployment = not is_remote_setup

    if is_remote_setup and buildman.is_remote_up_to_date():
        echo('Remote build is already up to date.')
        return

    branch = git.current_branch(remote=False)
    commit = git.last_commit(remote=False, short=True)
    info('Deploying <{branch}:{commit}> to the {stage} server'.format(
        branch=branch,
        commit=commit,
        stage=stage
    ))

    build_dir = os.path.abspath(buildman.resolve_local_build_dir())
    included_files = config['deployment']['include_files']
    deployer_user = shell.get_user()
    notif_params = dict(
        user=deployer_user,
        commit=commit,
        branch=branch,
        stage=stage
    )
    notif.send(notification_types.DEPLOYMENT_STARTED, notif_params)
    runner.run_script_safely(known_scripts.PRE_DEPLOY)

    (release_dir, current_path) = buildman.setup_remote()

    timestamp = datetime.utcnow()
    build_id = timestamp.strftime('%Y%m%d%H%M%S')
    build_name = buildman.get_build_name(build_id)
    release_path = os.path.join(release_dir + '/' + build_name)
    dist_path = os.path.join(release_dir, build_name + '/dist')

    buildman.build(stage, config)

    uploader = BulkUploader()
    uploader.add(build_dir, dist_path)

    # Upload the files to be included eg: package.json file
    # to the remote build location.
    for filename in included_files:
        path = os.path.abspath(filename)
        # Add for upload if the file exist.
        if exists_local(path):
            uploader.add(path, release_path)

    uploader.upload()
    remote_info('Updating the current symlink')
    fs.update_symlink(release_path, current_path)

    # Once, the build is uploaded to the remote,
    # set things up in the remote server.
    # Change directory to the release path.
    install_remote_dependencies(
        commit=commit,
        current_path=current_path,
        smart_install=get_stage_config(stage)['deployment']['smart_install']
    )

    # Start or restart the application service.
    start_or_reload_service(is_first_deployment)

    # Save build history
    buildman.record_history({
        'id': build_id,
        'path': release_path,
        'branch': branch,
        'commit': commit,
        'stage': stage,
        'createdBy': deployer_user,
        'timestamp': timestamp.strftime(buildman.TS_FORMAT)
    })

    runner.run_script_safely(known_scripts.POST_DEPLOY)

    # Send deployment finished notification.
    notif.send(notification_types.DEPLOYMENT_FINISHED, notif_params)

    info('Deployment Completed')