Exemplo n.º 1
0
  def test_pull_bom(self):
    input_dir = self.test_root
    scm = BomSourceCodeManager(self.options, input_dir, bom=self.golden_bom)
    for repo_name in ALL_STANDARD_TEST_BOM_REPO_NAMES:
      repository = scm.make_repository_spec(repo_name)
      self.assertFalse(os.path.exists(repository.git_dir))
      scm.ensure_local_repository(repository)
      self.assertTrue(os.path.exists(repository.git_dir))

      git_dir = repository.git_dir
      spec = scm.git.determine_git_repository_spec(git_dir)
      self.assertEquals(repository.name, spec.name)
      self.assertEquals(repository.git_dir, spec.git_dir)
      self.assertEquals(repository.origin, spec.origin)
      self.assertIsNone(spec.upstream_or_none())

      repo_name = repository.name
      at_commit = scm.git.query_local_repository_commit_id(git_dir)
      self.assertEquals(
          self.repo_commit_map[repo_name]['ORIGIN'], repository.origin)
      self.assertEquals(
          self.repo_commit_map[repo_name][PATCH_BRANCH], at_commit)

      summary = scm.git.collect_repository_summary(git_dir)
      semver = SemanticVersion.make(BASE_VERSION_TAG)
      expect_version = semver.next(
          SemanticVersion.PATCH_INDEX).to_version()
      self.assertEquals(expect_version, summary.version)
Exemplo n.º 2
0
  def test_pull_bom(self):
    input_dir = self.test_root
    scm = BomSourceCodeManager(self.options, input_dir, bom=self.golden_bom)
    for repo_name in ALL_STANDARD_TEST_BOM_REPO_NAMES:
      repository = scm.make_repository_spec(repo_name)
      self.assertFalse(os.path.exists(repository.git_dir))
      scm.ensure_local_repository(repository)
      self.assertTrue(os.path.exists(repository.git_dir))

      git_dir = repository.git_dir
      spec = scm.git.determine_git_repository_spec(git_dir)
      self.assertEqual(repository.name, spec.name)
      self.assertEqual(repository.git_dir, spec.git_dir)
      self.assertEqual(repository.origin, spec.origin)
      self.assertIsNone(spec.upstream_or_none())

      repo_name = repository.name
      at_commit = scm.git.query_local_repository_commit_id(git_dir)
      self.assertEqual(
          self.repo_commit_map[repo_name]['ORIGIN'], repository.origin)
      self.assertEqual(
          self.repo_commit_map[repo_name][PATCH_BRANCH], at_commit)

      summary = scm.git.collect_repository_summary(git_dir)
      semver = SemanticVersion.make(BASE_VERSION_TAG)
      expect_version = semver.next(
          SemanticVersion.PATCH_INDEX).to_version()
      self.assertEqual(expect_version, summary.version)
Exemplo n.º 3
0
class PublishSpinnakerCommand(CommandProcessor):
    """"Implements the publish_spinnaker command."""

    # pylint: disable=too-few-public-methods

    def __init__(self, factory, options, **kwargs):
        super(PublishSpinnakerCommand, self).__init__(factory, options,
                                                      **kwargs)
        check_options_set(options, [
            'spinnaker_version', 'spinnaker_release_alias', 'bom_version',
            'changelog_gist_url', 'github_owner', 'min_halyard_version'
        ])

        options_copy = copy.copy(options)
        self.__scm = BomSourceCodeManager(options_copy, self.get_input_dir())
        self.__hal = HalRunner(options)
        self.__git = GitRunner(options)
        self.__hal.check_property('spinnaker.config.input.bucket',
                                  options.halyard_bom_bucket)
        if options.only_repositories:
            self.__only_repositories = options.only_repositories.split(',')
        else:
            self.__only_repositories = []

    def push_branches_and_tags(self, bom):
        """Update the release branches and tags in each of the BOM repositires."""
        major, minor, _ = self.options.spinnaker_version.split('.')
        branch = 'release-{major}.{minor}.x'.format(major=major, minor=minor)
        logging.info('Tagging each of the BOM service repos')

        # Run in two passes so we dont push anything if we hit a problem
        # in the tagging pass. Since we are spread against multiple repositiories,
        # we cannot do this atomically. The two passes gives us more protection
        # from a partial push due to errors in a repo.
        names_to_push = set([])
        for which in ['tag', 'push']:
            for name, spec in bom['services'].items():
                if name in ['monitoring-third-party', 'defaultArtifact']:
                    # Ignore this, it is redundant to monitoring-daemon
                    continue
                if name == 'monitoring-daemon':
                    name = 'spinnaker-monitoring'
                if self.__only_repositories and name not in self.__only_repositories:
                    logging.debug('Skipping %s because of --only_repositories',
                                  name)
                    continue
                if spec is None:
                    logging.warning('HAVE bom.services.%s = None', name)
                    continue

                repository = self.__scm.make_repository_spec(name)
                self.__scm.ensure_local_repository(repository)
                if which == 'tag':
                    added = self.__branch_and_tag_repository(
                        repository, branch)
                    if added:
                        names_to_push.add(name)
                else:
                    self.__push_branch_and_maybe_tag_repository(
                        repository, branch, name in names_to_push)

    def __already_have_tag(self, repository, tag):
        """Determine if we already have the tag in the repository."""
        git_dir = repository.git_dir
        existing_commit = self.__git.query_commit_at_tag(git_dir, tag)
        if not existing_commit:
            return False
        want_commit = self.__git.query_local_repository_commit_id(git_dir)
        if want_commit == existing_commit:
            logging.debug('Already have "%s" at %s', tag, want_commit)
            return True

        raise_and_log_error(
            ConfigError(
                '"{tag}" already exists in "{repo}" at commit {have}, not {want}'
                .format(tag=tag,
                        repo=git_dir,
                        have=existing_commit,
                        want=want_commit)))

    def __branch_and_tag_repository(self, repository, branch):
        """Create a branch and/or verison tag in the repository, if needed."""
        version = self.__scm.determine_repository_version(repository)
        tag = 'version-' + version
        if self.__already_have_tag(repository, tag):
            return False

        self.__git.check_run(repository.git_dir, 'tag ' + tag)
        return True

    def __push_branch_and_maybe_tag_repository(self, repository, branch,
                                               also_tag):
        """Push the branch and verison tag to the origin."""
        tag = 'version-' + self.__scm.determine_repository_version(repository)
        self.__git.push_branch_to_origin(repository.git_dir, branch)
        if also_tag:
            self.__git.push_tag_to_origin(repository.git_dir, tag)
        else:
            logging.info('%s was already tagged with "%s" -- skip',
                         repository.git_dir, tag)

    def _do_command(self):
        """Implements CommandProcessor interface."""
        options = self.options
        spinnaker_version = options.spinnaker_version
        options_copy = copy.copy(options)
        options_copy.git_branch = 'master'  # push to master in spinnaker.github.io
        publish_changelog_command = PublishChangelogFactory().make_command(
            options_copy)
        changelog_gist_url = options.changelog_gist_url

        # Make sure changelog exists already.
        # If it does not then fail.
        try:
            logging.debug('Verifying changelog ready at %s',
                          changelog_gist_url)
            urlopen(changelog_gist_url)
        except HTTPError as error:
            logging.error(exception_to_message)
            raise_and_log_error(
                ConfigError(
                    'Changelog gist "{url}" must exist before publising a release.'
                    .format(url=changelog_gist_url),
                    cause='ChangelogMissing'))

        bom = self.__hal.retrieve_bom_version(self.options.bom_version)
        bom['version'] = spinnaker_version
        bom_path = os.path.join(self.get_output_dir(),
                                spinnaker_version + '.yml')
        write_to_path(yaml.safe_dump(bom, default_flow_style=False), bom_path)
        self.__hal.publish_bom_path(bom_path)
        self.push_branches_and_tags(bom)

        self.__hal.publish_spinnaker_release(spinnaker_version,
                                             options.spinnaker_release_alias,
                                             changelog_gist_url,
                                             options.min_halyard_version)

        logging.info('Publishing changelog')
        publish_changelog_command()
Exemplo n.º 4
0
class PublishSpinnakerCommand(CommandProcessor):
    """"Implements the publish_spinnaker command."""

    # pylint: disable=too-few-public-methods

    def __init__(self, factory, options, **kwargs):
        super(PublishSpinnakerCommand, self).__init__(factory, options,
                                                      **kwargs)
        check_options_set(options, [
            'spinnaker_version', 'bom_version', 'github_owner',
            'min_halyard_version'
        ])

        options_copy = copy.copy(options)
        self.__scm = BomSourceCodeManager(options_copy, self.get_input_dir())
        self.__hal = HalRunner(options)
        self.__git = GitRunner(options)
        self.__hal.check_property('spinnaker.config.input.bucket',
                                  options.halyard_bom_bucket)

    def push_branches_and_tags(self, bom):
        """Update the release branches and tags in each of the BOM repositires."""
        major, minor, _ = self.options.spinnaker_version.split('.')
        branch = 'release-{major}.{minor}.x'.format(major=major, minor=minor)
        logging.info('Tagging each of the BOM service repos')

        # Run in two passes so we dont push anything if we hit a problem
        # in the tagging pass. Since we are spread against multiple repositiories,
        # we cannot do this atomically. The two passes gives us more protection
        # from a partial push due to errors in a repo.
        for which in ['tag', 'push']:
            for name, spec in bom['services'].items():
                if name in ['monitoring-third-party', 'defaultArtifact']:
                    # Ignore this, it is redundant to monitoring-daemon
                    continue
                if spec is None:
                    logging.warning('HAVE bom.services.%s = None', name)
                    continue
                if name == 'monitoring-daemon':
                    name = 'spinnaker-monitoring'
                repository = self.__scm.make_repository_spec(name)
                self.__scm.ensure_local_repository(repository)
                if which == 'tag':
                    self.__branch_and_tag_repository(repository, branch)
                else:
                    self.__push_branch_and_tag_repository(repository, branch)

    def __branch_and_tag_repository(self, repository, branch):
        """Create a branch and/or verison tag in the repository, if needed."""
        source_info = self.__scm.lookup_source_info(repository)
        tag = 'version-' + source_info.summary.version
        self.__git.check_run(repository.git_dir, 'tag ' + tag)

    def __push_branch_and_tag_repository(self, repository, branch):
        """Push the branch and verison tag to the origin."""
        source_info = self.__scm.lookup_source_info(repository)
        tag = 'version-' + source_info.summary.version
        self.__git.push_branch_to_origin(repository.git_dir, branch)
        self.__git.push_tag_to_origin(repository.git_dir, tag)

    def _do_command(self):
        """Implements CommandProcessor interface."""
        options = self.options
        spinnaker_version = options.spinnaker_version
        bom = self.__hal.retrieve_bom_version(self.options.bom_version)
        bom['version'] = spinnaker_version

        self.push_branches_and_tags(bom)
        bom_path = os.path.join(self.get_output_dir(),
                                spinnaker_version + '.yml')
        changelog_base_url = 'https://www.spinnaker.io/%s' % options.github_owner
        changelog_filename = '%s-changelog' % spinnaker_version.replace(
            '.', '-')
        changelog_uri = '%s/community/releases/versions/%s' % (
            changelog_base_url, changelog_filename)

        write_to_path(yaml.dump(bom, default_flow_style=False), bom_path)
        self.__hal.publish_spinnaker_release(spinnaker_version,
                                             options.spinnaker_release_alias,
                                             changelog_uri,
                                             options.min_halyard_version)