Exemplo n.º 1
0
def resume(args):
    try:
        distclean()
        repository = Repository(REPO_ROOT, args.repo)
        br_name = branch_name(args.release)
        if not repository.branch_exists(br_name):
            raise ScriptError('No local branch exists for this release.')
        gh_release = repository.find_release(args.release)
        if gh_release and not gh_release.draft:
            print(
                'WARNING!! Found non-draft (public) release for this version!')
            proceed = yesno(
                'Are you sure you wish to proceed? Modifying an already '
                'released version is dangerous! y/N ',
                default=False)
            if proceed.lower() is not True:
                raise ScriptError('Aborting release')

        release_branch = repository.checkout_branch(br_name)
        if args.cherries:
            cherries = input(
                'Indicate (space-separated) PR numbers to cherry-pick then press Enter:\n'
            )
            repository.cherry_pick_prs(release_branch, cherries.split())

        create_bump_commit(repository, release_branch, args.bintray_user,
                           args.bintray_org)
        pr_data = repository.find_release_pr(args.release)
        if not pr_data:
            pr_data = repository.create_release_pull_request(args.release)
        check_pr_mergeable(pr_data)
        if not args.skip_ci:
            monitor_pr_status(pr_data)
        downloader = BinaryDownloader(args.destination)
        files = downloader.download_all(args.release)
        if not gh_release:
            gh_release = create_release_draft(repository, args.release,
                                              pr_data, files)
        delete_assets(gh_release)
        upload_assets(gh_release, files)
        tag_as_latest = is_tag_latest(args.release)
        img_manager = ImageManager(args.release, tag_as_latest)
        img_manager.build_images(repository)
    except ScriptError as e:
        print(e)
        return 1

    print_final_instructions(args)
    return 0
Exemplo n.º 2
0
def monitor_pr_status(pr_data):
    print('Waiting for CI to complete...')
    last_commit = pr_data.get_commits().reversed[0]
    while True:
        status = last_commit.get_combined_status()
        if status.state == 'pending' or status.state == 'failure':
            summary = {
                'pending': 0,
                'success': 0,
                'failure': 0,
                'error': 0,
            }
            for detail in status.statuses:
                if detail.context == 'dco-signed':
                    # dco-signed check breaks on merge remote-tracking ; ignore it
                    continue
                if detail.state in summary:
                    summary[detail.state] += 1
            print(
                '{pending} pending, {success} successes, {failure} failures, '
                '{error} errors'.format(**summary))
            if summary['failure'] > 0 or summary['error'] > 0:
                raise ScriptError('CI failures detected!')
            elif summary['pending'] == 0 and summary['success'] > 0:
                # This check assumes at least 1 non-DCO CI check to avoid race conditions.
                # If testing on a repo without CI, use --skip-ci-check to avoid looping eternally
                return True
            time.sleep(30)
        elif status.state == 'success':
            print('{} successes: all clear!'.format(status.total_count))
            return True
Exemplo n.º 3
0
def monitor_pr_status(pr_data):
    print('Waiting for CI to complete...')
    last_commit = pr_data.get_commits().reversed[0]
    while True:
        status = last_commit.get_combined_status()
        if status.state == 'pending' or status.state == 'failure':
            summary = {
                'pending': 0,
                'success': 0,
                'failure': 0,
            }
            for detail in status.statuses:
                if detail.context == 'dco-signed':
                    # dco-signed check breaks on merge remote-tracking ; ignore it
                    continue
                summary[detail.state] += 1
            print('{pending} pending, {success} successes, {failure} failures'.
                  format(**summary))
            if status.total_count == 0:
                # Mostly for testing purposes against repos with no CI setup
                return True
            elif summary['pending'] == 0 and summary['failure'] == 0:
                return True
            elif summary['failure'] > 0:
                raise ScriptError('CI failures detected!')
            time.sleep(30)
        elif status.state == 'success':
            print('{} successes: all clear!'.format(status.total_count))
            return True
Exemplo n.º 4
0
def pypi_upload(args):
    print('Uploading to PyPi')
    try:
        twine_upload([
            'dist/docker_compose-{}*.whl'.format(args.release),
            'dist/docker-compose-{}*.tar.gz'.format(args.release)
        ])
    except HTTPError as e:
        if e.response.status_code == 400 and 'File already exists' in e.message:
            if not args.finalize_resume:
                raise ScriptError(
                    'Package already uploaded on PyPi.'
                )
            print('Skipping PyPi upload - package already uploaded')
        else:
            raise ScriptError('Unexpected HTTP error uploading package to PyPi: {}'.format(e))
Exemplo n.º 5
0
def finalize(args):
    distclean()
    try:
        check_pypirc()
        repository = Repository(REPO_ROOT, args.repo)
        img_manager = ImageManager(args.release)
        pr_data = repository.find_release_pr(args.release)
        if not pr_data:
            raise ScriptError('No PR found for {}'.format(args.release))
        if not check_pr_mergeable(pr_data):
            raise ScriptError(
                'Can not finalize release with an unmergeable PR')
        if not img_manager.check_images():
            raise ScriptError('Missing release image')
        br_name = branch_name(args.release)
        if not repository.branch_exists(br_name):
            raise ScriptError('No local branch exists for this release.')
        gh_release = repository.find_release(args.release)
        if not gh_release:
            raise ScriptError('No Github release draft for this version')

        repository.checkout_branch(br_name)

        pypandoc.convert_file(os.path.join(REPO_ROOT, 'README.md'),
                              'rst',
                              outputfile=os.path.join(REPO_ROOT, 'README.rst'))
        run_setup(os.path.join(REPO_ROOT, 'setup.py'),
                  script_args=['sdist', 'bdist_wheel'])

        merge_status = pr_data.merge()
        if not merge_status.merged and not args.finalize_resume:
            raise ScriptError('Unable to merge PR #{}: {}'.format(
                pr_data.number, merge_status.message))

        pypi_upload(args)

        img_manager.push_images()
        repository.publish_release(gh_release)
    except ScriptError as e:
        print(e)
        return 1

    return 0
Exemplo n.º 6
0
def finalize(args):
    distclean()
    try:
        check_pypirc()
        repository = Repository(REPO_ROOT, args.repo)
        tag_as_latest = _check_if_tag_latest(args.release)
        img_manager = ImageManager(args.release, tag_as_latest)
        pr_data = repository.find_release_pr(args.release)
        if not pr_data:
            raise ScriptError('No PR found for {}'.format(args.release))
        if not check_pr_mergeable(pr_data):
            raise ScriptError('Can not finalize release with an unmergeable PR')
        if not img_manager.check_images():
            raise ScriptError('Missing release image')
        br_name = branch_name(args.release)
        if not repository.branch_exists(br_name):
            raise ScriptError('No local branch exists for this release.')
        gh_release = repository.find_release(args.release)
        if not gh_release:
            raise ScriptError('No Github release draft for this version')

        repository.checkout_branch(br_name)

        os.system('python {setup_script} sdist bdist_wheel'.format(
            setup_script=os.path.join(REPO_ROOT, 'setup.py')))

        merge_status = pr_data.merge()
        if not merge_status.merged and not args.finalize_resume:
            raise ScriptError(
                'Unable to merge PR #{}: {}'.format(pr_data.number, merge_status.message)
            )

        pypi_upload(args)

        img_manager.push_images()
        repository.publish_release(gh_release)
    except ScriptError as e:
        print(e)
        return 1

    return 0