예제 #1
0
 def test_project_overrides(self):
     deliv = deliverable.Deliverable(
         team='team',
         series='newton',
         name='name',
         data={
             'releases': [{
                 'version':
                 '1.5.0',
                 'projects': [
                     {
                         'repo': 'openstack/release-test',
                         'hash': 'a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5',
                         'tarball-base': 'foo'
                     },
                 ]
             }],
             'repository-settings': {
                 'openstack/release-test': {
                     'tarball-base': 'bar',
                 },
             },
         },
     )
     project = deliv.releases[-1].projects[0]
     self.assertEqual('foo', project.tarball_base)
예제 #2
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        'deliverable',
        help='the name of the deliverable, such as "nova" or "oslo.config"',
    )
    parser.add_argument(
        '--series',
        default=defaults.RELEASE,
        help='the release series, such as "newton" or "ocata"',
    )
    parser.add_argument(
        '--deliverables-dir',
        default=openstack_releases.deliverable_dir,
        help='location of deliverable files',
    )
    args = parser.parse_args()

    # Deal with the inconsistency of the name for the independent
    # directory.
    series = args.series
    if series == 'independent':
        series = '_independent'

    all_deliv = deliverable.Deliverables(
        root_dir=args.deliverables_dir,
        collapse_history=False,
    )
    for entry in all_deliv.get_deliverable_history(args.deliverable):
        deliv = deliverable.Deliverable(*entry)
        print(deliv.team)
        break
예제 #3
0
 def test_one_expected_job(self):
     deliv = deliverable.Deliverable(
         team='team',
         series='series',
         name='name',
         data={
             'repository-settings': {
                 'openstack/releases': {},
             },
         },
     )
     self.ctx._zuul_projects = {
         'openstack/releases': {
             'templates': [
                 'publish-to-pypi',
             ],
         },
     }
     project_config.require_release_jobs_for_repo(
         deliv,
         deliv.repos[0],
         'python-pypi',
         self.ctx,
     )
     self.ctx.show_summary()
     self.assertEqual(0, len(self.ctx.warnings))
     self.assertEqual(0, len(self.ctx.errors))
예제 #4
0
 def test_default_to_series(self):
     d = deliverable.Deliverable(
         team='team',
         series='ocata',
         name='name',
         data={},
     )
     self.assertEqual('extended maintenance', d.stable_status)
예제 #5
0
 def test_override_series(self):
     d = deliverable.Deliverable(
         team='team',
         series='newton',
         name='name',
         data={
             'stable-status': 'extended maintenance',
         },
     )
     self.assertEqual('extended maintenance', d.stable_status)
예제 #6
0
def repositories_list(deliverables_dir, series):
    """Yields (team, repo) tuples for cycle-with-milestones deliverables"""
    deliverables = deliverable.Deliverables(deliverables_dir)
    for team, series, dname, dinfo in deliverables.get_deliverables(None, series):
        d = deliverable.Deliverable(team, series, dname, dinfo)
        if d.model != 'cycle-with-milestones':
            continue
        if not d.repos:
            print('WARNING: no releases for {} in {}'.format(dname, series))
        for repo in sorted(d.repos):
            yield (d.team, repo)
예제 #7
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--deliverables-dir',
        default=openstack_releases.deliverable_dir,
        help='location of deliverable files',
    )
    parser.add_argument(
        '--series',
        default=defaults.RELEASE,
        help='the release series, such as "newton" or "ocata"',
    )
    args = parser.parse_args()

    all_deliv = deliverable.Deliverables(
        root_dir=args.deliverables_dir,
        collapse_history=False,
    )

    interesting_deliverables = [
        d for d in (
            deliverable.Deliverable(t, s, dn, da)
            for t, s, dn, da in all_deliv.get_deliverables(None, args.series))
        if d.model == MILESTONE
    ]

    team_data = governance.get_team_data()
    teams = {n.lower(): governance.Team(n, i) for n, i in team_data.items()}

    # Dump the dashboard data
    writer = csv.writer(sys.stdout)
    writer.writerow(
        ('Team', 'Deliverable Type', 'Deliverable Name', 'Pre-RC1', 'RC1',
         'Branched at', 'Latest RC', 'Release Notes', 'Comments', 'PTL Nick',
         'PTL Email', 'Liaison Nick', 'IRC Channel'))

    for deliv in sorted(interesting_deliverables,
                        key=lambda x: (x.team, x.name)):
        team = teams[deliv.team.lower()]
        writer.writerow((
            deliv.team.lower(),
            deliv.type,
            deliv.name,
            deliv.latest_release,
            '',  # RC1
            deliv.get_branch_location('stable/' + args.series),  # branched at
            '',  # latest RC
            deliv.release_notes,
            '',  # Comments
            team.data['ptl']['irc'],
            team.data['ptl']['email'],
            team.liaison[1] or '',
            team.data.get('irc-channel')))
예제 #8
0
 def test_is_eol_tag_true(self):
     deliverable_data = textwrap.dedent('''
     releases:
       - version: newton-eol
         projects:
           - repo: openstack/release-test
             hash: a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5
     ''')
     deliv = deliverable.Deliverable(
         team='team',
         series='newton',
         name='name',
         data=yamlutils.loads(deliverable_data),
     )
     self.assertTrue(deliv.releases[-1].is_eol)
예제 #9
0
 def test_eol_series_for_version_tag(self):
     deliverable_data = textwrap.dedent('''
     releases:
       - version: 0.3.0
         projects:
           - repo: openstack/release-test
             hash: a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5
     ''')
     deliv = deliverable.Deliverable(
         team='team',
         series='newton',
         name='name',
         data=yamlutils.loads(deliverable_data),
     )
     self.assertEqual(
         '',
         deliv.releases[-1].eol_series,
     )
예제 #10
0
 def test_not_set(self):
     deliv = deliverable.Deliverable(
         team='team',
         series='newton',
         name='name',
         data={
             'releases': [{
                 'version':
                 '1.5.0',
                 'projects': [
                     {
                         'repo': 'openstack/release-test',
                         'hash': 'a26e6a2e8a5e321b2e3517dbb01a7b9a56a8bfd5'
                     },
                 ]
             }],
         },
     )
     project = deliv.releases[-1].projects[0]
     self.assertIsNone(project.tarball_base)
예제 #11
0
 def test_no_zuul_projects(self):
     deliv = deliverable.Deliverable(
         team='team',
         series='series',
         name='name',
         data={
             'repository-settings': {
                 'openstack/releases': {},
             },
         },
     )
     self.ctx._zuul_projects = {'validate-projects-by-name': {}}
     project_config.require_release_jobs_for_repo(
         deliv,
         deliv.repos[0],
         'std',
         self.ctx,
     )
     self.assertEqual(0, len(self.ctx.warnings))
     self.assertEqual(1, len(self.ctx.errors))
예제 #12
0
def main():
    parser = argparse.ArgumentParser()
    output_mode = parser.add_mutually_exclusive_group()
    output_mode.add_argument(
        '-v',
        '--verbose',
        action='store_true',
        default=False,
        help='show more than the deliverable name',
    )
    output_mode.add_argument(
        '-r',
        '--repos',
        action='store_true',
        default=False,
        help='show the repository names not deliverable names',
    )
    parser.add_argument(
        '--team',
        help='the name of the project team, such as "Nova" or "Oslo"',
    )
    parser.add_argument(
        '--deliverable',
        help='the name of the deliverable, such as "nova" or "oslo.config"',
    )
    parser.add_argument(
        '--series',
        default=defaults.RELEASE,
        help='the release series, such as "newton" or "ocata"',
    )
    parser.add_argument(
        '--csvfile',
        help='Save results (same as when --verbose) to CSV file',
    )
    model = parser.add_mutually_exclusive_group()
    model.add_argument(
        '--model',
        help=('the release model, such as "cycle-with-milestones"'
              ' or "independent"'),
    )
    model.add_argument(
        '--cycle-based',
        action='store_true',
        default=False,
        help='include all cycle-based code repositories',
    )
    parser.add_argument(
        '--type',
        help='deliverable type, such as "library" or "service"',
    )
    parser.add_argument(
        '--tag',
        default=[],
        action='append',
        help='look for one more more tags on the deliverable or team',
    )
    parser.add_argument(
        '--deliverables-dir',
        default=openstack_releases.deliverable_dir,
        help='location of deliverable files',
    )
    parser.add_argument(
        '--no-stable-branch',
        default=False,
        action='store_true',
        help='limit the list to deliverables without a stable branch',
    )
    grp = parser.add_mutually_exclusive_group()
    grp.add_argument(
        '--unreleased',
        default=False,
        action='store_true',
        help='limit the list to deliverables not released in the cycle',
    )
    grp.add_argument(
        '--missing-milestone',
        help=('deliverables that do not have the specified milestone as '
              'the most current release; for example 2 would look for .0b2 '
              'in the version number (implies --model cycle-with-milestones)'),
    )
    grp.add_argument(
        '--missing-rc',
        action='store_true',
        help=('deliverables that do not have a release candidate, yet '
              '(implies --model cycle-with-milestones)'),
    )
    grp.add_argument(
        '--missing-final',
        action='store_true',
        help='deliverables that have pre-releases but no final releases, yet',
    )
    args = parser.parse_args()

    # Deal with the inconsistency of the name for the independent
    # directory.
    series = args.series
    if series == 'independent':
        series = '_independent'

    if args.missing_milestone:
        model = 'cycle-with-milestones'
        version_ending = '.0b{}'.format(args.missing_milestone)
    elif args.missing_rc:
        model = 'cycle-with-milestones'
        version_ending = None
    elif args.missing_final:
        model = args.model
        version_ending = None
    else:
        model = args.model
        version_ending = None

    verbose_template = '{name:30} {team:20}'
    if not args.unreleased:
        verbose_template += ' {latest_release:15}'
    if not args.type:
        verbose_template += ' {type:15}'
    if not args.model:
        verbose_template += ' {model:15}'

    csvfile = None
    if args.csvfile:
        csvfile = open(args.csvfile, 'w')
        fieldnames = [
            'name', 'latest_release', 'repo', 'hash', 'team', 'type', 'model'
        ]
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()

    all_deliv = deliverable.Deliverables(
        root_dir=args.deliverables_dir,
        collapse_history=False,
    )
    for entry in all_deliv.get_deliverables(args.team, series):
        deliv = deliverable.Deliverable(*entry)

        if args.deliverable and deliv.name != args.deliverable:
            continue

        if model and deliv.model != model:
            continue
        if args.cycle_based and not deliv.is_cycle_based:
            continue
        if args.type and deliv.type != args.type:
            continue
        if args.no_stable_branch:
            if deliv.get_branch_location('stable/' + series) is not None:
                continue
        if args.unreleased and deliv.versions:
            continue
        if version_ending and deliv.latest_release and deliv.latest_release.endswith(
                version_ending):
            continue
        if args.missing_rc and deliv.latest_release and 'rc' in deliv.latest_release:
            continue
        if args.tag:
            tags = deliv.tags
            for t in args.tag:
                if t not in tags:
                    continue
        if args.missing_final and deliv.latest_release:
            if not ('rc' in deliv.latest_release or 'a' in deliv.latest_release
                    or 'b' in deliv.latest_release):
                continue

        if csvfile:
            rel = (deliv.releases or [{}])[-1]
            for prj in rel.get('projects', [{}]):
                writer.writerow({
                    'name': deliv.name,
                    'latest_release': rel.get('version', None),
                    'repo': prj.get('repo', None),
                    'hash': prj.get('hash', None),
                    'team': deliv.team,
                    'type': deliv.type,
                    'model': deliv.model,
                })
        elif args.verbose:
            print(
                verbose_template.format(
                    name=deliv.name,
                    latest_release=deliv.latest_release,
                    team=deliv.team,
                    type=deliv.type,
                    model=deliv.model,
                ))
        elif args.repos:
            for r in sorted(deliv.repos):
                print(r)
        else:
            print(deliv.name)

    if csvfile:
        csvfile.close()
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-v',
        '--verbose',
        action='store_true',
        default=False,
        help='show more than the deliverable name',
    )
    parser.add_argument(
        '--team',
        help='the name of the project team, such as "Nova" or "Oslo"',
    )
    parser.add_argument(
        '--deliverable',
        help='the name of the deliverable, such as "nova" or "oslo.config"',
    )
    parser.add_argument(
        '--series',
        default=defaults.RELEASE,
        help='the release series, such as "newton" or "ocata"',
    )
    model = parser.add_mutually_exclusive_group()
    model.add_argument(
        '--model',
        help=('the release model, such as "cycle-with-milestones"'
              ' or "independent"'),
    )
    model.add_argument(
        '--cycle-based',
        action='store_true',
        default=False,
        help='include all cycle-based code repositories',
    )
    parser.add_argument(
        '--type',
        help='deliverable type, such as "library" or "service"',
    )
    parser.add_argument(
        '--deliverables-dir',
        default=openstack_releases.deliverable_dir,
        help='location of deliverable files',
    )
    parser.add_argument(
        '--branch',
        default=None,
        help='branch name, defaults to stable/$series',
    )
    parser.add_argument(
        '--no-cleanup',
        dest='cleanup',
        default=True,
        action='store_false',
        help='do not remove temporary files',
    )
    args = parser.parse_args()

    if args.verbose:

        def verbose(msg):
            print(msg)
    else:

        def verbose(msg):
            pass

    # Deal with the inconsistency of the name for the independent
    # directory.
    series = args.series
    if series == 'independent':
        series = '_independent'

    branch = args.branch
    if not branch:
        branch = 'stable/{}'.format(series)

    workdir = tempfile.mkdtemp(prefix='releases-')
    verbose('creating temporary files in {}'.format(workdir))

    def cleanup_workdir():
        if args.cleanup:
            try:
                verbose('cleaning up temporary files in {}'.format(workdir))
                shutil.rmtree(workdir)
            except:
                pass
        else:
            print('not cleaning up {}'.format(workdir))

    atexit.register(cleanup_workdir)

    # Count any errors for our exit code.
    errors = 0

    all_deliv = deliverable.Deliverables(
        root_dir=args.deliverables_dir,
        collapse_history=False,
    )
    for entry in all_deliv.get_deliverables(args.team, series):
        deliv = deliverable.Deliverable(*entry)
        branch_loc = deliv.get_branch_location(branch)
        if branch_loc is None:
            verbose('No stable branch for {}'.format(deliv.name))
            continue
        all_versions = deliv.versions
        if all_versions[-1] == branch_loc:
            verbose('Most recent release for {} ({}) is at {}'.format(
                deliv.name, branch_loc, branch))
            continue
        idx = all_versions.index(branch_loc)
        late_releases = all_versions[idx + 1:]
        print('{} releases {} come after {}'.format(deliv.name, late_releases,
                                                    branch))
        for repo in sorted(deliv.repos):
            verbose('cloning {}'.format(repo))
            gitutils.clone_repo(
                workdir,
                repo,
            )
            for version in late_releases:
                containing_br = gitutils.branches_containing(
                    workdir,
                    repo,
                    version,
                )
                for cb in containing_br:
                    if branch in cb:  # allow for remote prefix
                        verbose('{} version {} is on branch {}'.format(
                            repo, version, branch))
                        break
                else:
                    print('{} version {} is not on branch {} ({})'.format(
                        repo, version, branch, containing_br))
                    errors += 1

    return (1 if errors else 0)
예제 #14
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--deliverables-dir',
        default=openstack_releases.deliverable_dir,
        help='location of deliverable files',
    )
    parser.add_argument(
        '--no-cleanup',
        dest='cleanup',
        default=True,
        action='store_false',
        help='do not remove temporary files',
    )
    parser.add_argument(
        'repository_cache',
        help='location of existing copies of repositories',
    )
    parser.add_argument(
        'series',
        help='the release series, such as "newton" or "ocata"',
    )
    args = parser.parse_args()

    workdir = tempfile.mkdtemp(prefix='releases-')

    def cleanup_workdir():
        if args.cleanup:
            try:
                shutil.rmtree(workdir)
            except:
                pass

    atexit.register(cleanup_workdir)

    branch_name = 'origin/stable/' + args.series

    all_deliv = deliverable.Deliverables(
        root_dir=args.deliverables_dir,
        collapse_history=False,
    )
    for entry in all_deliv.get_deliverables(None, args.series):
        deliv = deliverable.Deliverable(*entry)
        if deliv.get_branch_location(branch_name) is not None:
            # the branch is already defined for this project
            sys.stderr.write('{} already has a branch {}\n'.format(
                deliv.name, branch_name))
            continue
        # We're only importing stable branches, and those are
        # specified by the version number. We therefore only need one
        # repository, and it shouldn't matter which one. That said, we
        # might not actually find the branch in the first repo so loop
        # until we do.
        for r in deliv.repos:
            reporoot = os.path.join(args.repository_cache, r)
            version = _get_branch_base(reporoot, branch_name)
            if version:
                print(deliv.name, args.series, version)
                break
        else:
            sys.stderr.write('could not find {} in any repos for {}\n'.format(
                branch_name, deliv.name))