コード例 #1
0
    def test_config_file_is_updated(self, mock_get_logger, mock_run,
                                    patch_clone_dir, patch_site_build_dir):
        conf_path = patch_clone_dir / JEKYLL_CONFIG_YML
        create_file(conf_path, 'hi: test')

        kwargs = dict(branch='branch',
                      owner='owner',
                      repository='repo',
                      site_prefix='site/prefix',
                      config=json.dumps(dict(boop='beep')),
                      base_url='/site/prefix')

        build_jekyll(**kwargs)

        with conf_path.open() as f:
            config = yaml.safe_load(f)
            assert config['hi'] == 'test'
            assert config['baseurl'] == kwargs['base_url']
            assert config['branch'] == kwargs['branch']
コード例 #2
0
    def test_with_gemfile(self, mock_get_logger, mock_run, patch_clone_dir,
                          patch_site_build_dir):
        command = 'bundle exec jekyll'

        create_file(patch_clone_dir / GEMFILE, 'foo')
        create_file(patch_clone_dir / JEKYLL_CONFIG_YML, 'hi: test')

        kwargs = dict(branch='branch',
                      owner='owner',
                      repository='repo',
                      site_prefix='site/prefix',
                      base_url='/site/prefix',
                      config=json.dumps(dict(boop='beep')))

        result = build_jekyll(**kwargs)

        assert result == mock_run.return_value

        mock_get_logger.assert_has_calls(
            [call('build-jekyll'), call('build-jekyll')])

        mock_logger = mock_get_logger.return_value

        env = build_env(kwargs['branch'], kwargs['owner'],
                        kwargs['repository'], kwargs['site_prefix'],
                        kwargs['base_url'])
        env['JEKYLL_ENV'] = 'production'

        mock_run.assert_has_calls([
            call(
                mock_logger,
                f'echo Building using Jekyll version: $({command} -v)',
                cwd=patch_clone_dir,
                env={},
                check=True,
                ruby=True,
            ),
            call(
                mock_logger,
                f'{command} build --destination {patch_site_build_dir}',
                cwd=patch_clone_dir,
                env=env,
                node=True,
                ruby=True,
            )
        ])
コード例 #3
0
def build(aws_access_key_id,
          aws_default_region,
          aws_secret_access_key,
          federalist_builder_callback,
          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()

    # Make the working directory if it doesn't exist
    WORKING_DIR_PATH.mkdir(exist_ok=True)

    logger = 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.'
            )

            ##
            # 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_federalist_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, cache_control,
                    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, federalist_builder_callback)

            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, federalist_builder_callback,
                         str(err))
        sys.exit(1)

    except TimeoutException:
        logger.warning(f'Build({build_info}) has timed out')
        post_build_timeout(status_callback, federalist_builder_callback)

    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, federalist_builder_callback,
                         err_message)