def test_it_loads_pages_json_when_it_exists(self, patch_clone_dir): filename = 'pages.json' json_contents = json.dumps({ 'name': filename, }) create_file(patch_clone_dir / filename, contents=json_contents) result = repo_config.from_json_file(patch_clone_dir) assert result.config['name'] == filename assert len(os.listdir(patch_clone_dir)) == 1
def build(aws_access_key_id, aws_default_region, aws_secret_access_key, status_callback, baseurl, branch, bucket, build_id, config, generator, github_token, owner, repository, site_prefix, user_environment_variables=[]): ''' Main task to run a full site build process. All values needed for the build are loaded from environment variables. ''' # keep track of total time start_time = datetime.now() logger = None commit_sha = None cache_control = os.getenv('CACHE_CONTROL', 'max-age=60') database_url = os.environ['DATABASE_URL'] user_environment_variable_key = os.environ['USER_ENVIRONMENT_VARIABLE_KEY'] try: post_build_processing(status_callback) # throw a timeout exception after TIMEOUT_SECONDS with Timeout(TIMEOUT_SECONDS, swallow_exc=False): build_info = f'{owner}/{repository}@id:{build_id}' decrypted_uevs = decrypt_uevs(user_environment_variable_key, user_environment_variables) priv_vals = [uev['value'] for uev in decrypted_uevs] priv_vals.append(aws_access_key_id) priv_vals.append(aws_secret_access_key) if github_token: priv_vals.append(github_token) logattrs = { 'branch': branch, 'buildid': build_id, 'owner': owner, 'repository': repository, } init_logging(priv_vals, logattrs, database_url) logger = get_logger('main') def run_step(returncode, msg): if returncode != 0: raise StepException(msg) logger.info(f'Running build for {owner}/{repository}/{branch}') if generator not in GENERATORS: raise ValueError(f'Invalid generator: {generator}') ## # FETCH # run_step( fetch_repo(owner, repository, branch, github_token), 'There was a problem fetching the repository, see the above logs for details.' ) commit_sha = fetch_commit_sha(CLONE_DIR_PATH) federalist_config = repo_config.from_json_file( CLONE_DIR_PATH, dict(headers=dict([('cache-control', cache_control)]), excludePaths=[ '*/Dockerfile', '*/docker-compose.yml', '/federalist.json', '/pages.json' ], includePaths=['/.well-known/security.txt'])) if federalist_config.full_clone(): run_step( update_repo(CLONE_DIR_PATH), 'There was a problem updating the repository, see the above logs for details.' ) ## # BUILD # run_step( setup_node(), 'There was a problem setting up Node, see the above logs for details.' ) # Run the npm `federalist` task (if it is defined) run_step( run_build_script(branch, owner, repository, site_prefix, baseurl, decrypted_uevs), 'There was a problem running the federalist script, see the above logs for details.' ) # Run the appropriate build engine based on generator if generator == 'jekyll': run_step( setup_ruby(), 'There was a problem setting up Ruby, see the above logs for details.' ) run_step( setup_bundler(), 'There was a problem setting up Bundler, see the above logs for details.' ) run_step( build_jekyll(branch, owner, repository, site_prefix, baseurl, config, decrypted_uevs), 'There was a problem running Jekyll, see the above logs for details.' ) elif generator == 'hugo': # extra: --hugo-version (not yet used) run_step( download_hugo(), 'There was a problem downloading Hugo, see the above logs for details.' ) run_step( build_hugo(branch, owner, repository, site_prefix, baseurl, decrypted_uevs), 'There was a problem running Hugo, see the above logs for details.' ) elif generator == 'static': # no build arguments are needed build_static() elif (generator == 'node.js' or generator == 'script only'): logger.info('build already ran in \'npm run federalist\'') else: raise ValueError(f'Invalid generator: {generator}') ## # PUBLISH # publish(baseurl, site_prefix, bucket, federalist_config, aws_default_region, aws_access_key_id, aws_secret_access_key) delta_string = delta_to_mins_secs(datetime.now() - start_time) logger.info(f'Total build time: {delta_string}') # Finished! post_build_complete(status_callback, commit_sha) sys.exit(0) except StepException as err: ''' Thrown when a step itself fails, usually because a command exited with a non-zero return code ''' logger.error(str(err)) post_build_error(status_callback, str(err), commit_sha) sys.exit(1) except TimeoutException: logger.warning(f'Build({build_info}) has timed out') post_build_timeout(status_callback, commit_sha) except Exception as err: # pylint: disable=W0703 # Getting here means something really weird has happened # since all errors caught during tasks should be caught # in the previous block as `UnexpectedExit` exceptions. err_string = str(err) # log the original exception msg = f'Unexpected exception raised during build({build_info}): {err_string}' if logger: logger.warning(msg) else: print(msg) err_message = (f'Unexpected build({build_info}) error. Please try ' 'again and contact federalist-support if it persists.') post_build_error(status_callback, err_message, commit_sha)