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')
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() })
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')
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')
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'
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')
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')
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')
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')