Esempio n. 1
0
def next_version(ctx, bump):
    """
    Returns incremented version number by looking at git tags
    """
    # Get latest git tag:
    try:
        latest_tag = latest_version(ctx)
    except ReleaseError:
        latest_tag = '0.0.0'

    increment = {
        'build': semver.bump_build,
        'patch': semver.bump_patch,
        'minor': semver.bump_minor,
        'major': semver.bump_major
    }

    if bump in ['pre-patch', 'pre-minor', 'pre-major']:
        incremented = increment[bump[4:]](latest_tag)
        try:
            #Check
            incremented = semver.bump_prerelease(
                latest_prerelease(ctx, incremented)
            )  # Try to increment the pre-release if there are existing pre-releases
        except:
            # No existing pre-release, so create one
            incremented = semver.bump_prerelease(incremented)

    else:
        incremented = increment[bump](latest_tag)

    return incremented
Esempio n. 2
0
 def test_should_bump_prerelease(self):
     self.assertEqual(bump_prerelease('3.4.5-rc.9'),
                      '3.4.5-rc.10')
     self.assertEqual(bump_prerelease('3.4.5-0009.dev'),
                      '3.4.5-0010.dev')
     self.assertEqual(bump_prerelease('3.4.5'),
                      '3.4.5-rc.1')
Esempio n. 3
0
def bump(latest):
    merge_request_id = extract_merge_request_id_from_commit()
    labels = retrieve_labels_from_merge_request(merge_request_id)
    new_version = None
    print('MR Labels', labels)
    if "bump-major" in labels:
        print('Bump major')
        new_version = semver.bump_major(latest)
    elif "bump-minor" in labels:
        print('Bump minor')
        new_version = semver.bump_minor(latest)
    elif "bump-patch" in labels:
        print('Bump patch')
        new_version = semver.bump_patch(latest)
    elif "finalize-rc" in labels:
        print('Finalize rc')
        new_version = semver.finalize_version(latest)
    elif "bump-build":
        print('Bump build')
        new_version = semver.bump_build(new_version if new_version else latest)

    if "bump-rc" in labels and not "finalize-rc" in labels:
        print('Bump rc')
        new_version = semver.bump_prerelease(
            new_version if new_version else latest)
        new_version = semver.bump_build(new_version)

    return new_version if new_version else latest
Esempio n. 4
0
def update_version() -> str:
    """
    Retrieves the current version from github, bumps the version, and updates the values in service_config.json before
    committing to the dst branch
    :return: The new version.
    """
    cur_version = get_current_version(args.stage)

    if args.stage == "prod":
        prv_version = get_current_version(stage='staging')
        new_version = semver.finalize_version(prv_version)
    elif args.stage == "staging":
        prv_version = get_current_version(stage='integration')
        assert '-integration' in prv_version
        new_version = prv_version.replace(
            '-integration', '-rc')  # don't bump the version number
    else:
        new_version = getattr(semver, f'bump_{args.release}')(str(cur_version))
        new_version = new_version if semver.parse_version_info(new_version).prerelease \
            else semver.bump_prerelease(new_version, token='integration')

    if cur_version == new_version:
        print("Nothing to promote")
        exit(0)
    else:
        print(f"Upgrading: {cur_version} -> {new_version}")
        return new_version
def version_bump_prerelease(version_config: VersionConfig,
                            version: Optional[str], global_seq: Optional[int]):
    result = Result()
    version_info = semver.parse_version_info(
        version) if version is not None else semver.parse_version_info("0.0.0")

    if version_info.prerelease:
        prerelease_version_elements = version_info.prerelease.split(".")
        if len(prerelease_version_elements
               ) > 0 and prerelease_version_elements[0].upper() == "SNAPSHOT":
            if len(prerelease_version_elements) == 1:
                result.error(
                    os.EX_DATAERR,
                    _("The pre-release increment has been skipped."),
                    _("In order to retain Maven compatibility, "
                      "the pre-release component of snapshot versions must not be versioned."
                      ))
            else:
                result.error(
                    os.EX_DATAERR,
                    _("Failed to increment the pre-release component of version {version}."
                      ).format(version=repr(version)),
                    _("Snapshot versions must not have a pre-release version.")
                )
            result.value = version
        elif len(prerelease_version_elements) == 1:
            if version_config.versioning_scheme != VersioningScheme.SEMVER_WITH_SEQ:
                result.error(
                    os.EX_DATAERR,
                    _("Failed to increment the pre-release component of version {version}."
                      ).format(version=repr(version)),
                    _("The qualifier {qualifier} must already be versioned.").
                    format(qualifier=repr(prerelease_version_elements[0])))
        result.value = semver.bump_prerelease(version)
    else:
        result.error(
            os.EX_DATAERR,
            _("Failed to increment the pre-release component of version {version}."
              ).format(version=repr(version)),
            _("Pre-release increments cannot be performed on release versions."
              ))

    if result.has_errors():
        result.value = None
    elif result.value is not None and not semver.compare(
            result.value, version) > 0:
        result.value = None

    if not result.value:
        result.error(
            os.EX_SOFTWARE,
            _("Failed to increment the pre-release of version {version} for unknown reasons."
              ).format(version=repr(version)), None)
    return result
Esempio n. 6
0
def semver_command(bump, prerelease_name, path, version_file, version_initial,
                   **options):
    """
    Bump version to specified level [init, major, minor, patch]
    Other keyword will create pre-release version

    :param options:
    :return:
    """

    ctx = click.get_current_context()

    # Check version file exists
    current_version = ctx.invoke(current,
                                 path=path,
                                 version_file=version_file,
                                 quiet=True)

    version = current_version or version_initial
    if bump == "major":
        version = semver.bump_major(version)
    elif bump == "minor":
        version = semver.bump_minor(version)
    elif bump == "patch":
        version = semver.bump_patch(version)
    elif bump == "pre":
        version = semver.bump_prerelease(version, prerelease_name)

    # Handle pre-release with other than pre bump
    if bump != "pre" and prerelease_name:
        version = semver.bump_prerelease(version, prerelease_name)

    click.confirm(f"You are going to bump version \"{version}\", proceed?",
                  default=True,
                  abort=True)

    # Write version
    with open(version_file, "w+") as h:
        h.write(version)
Esempio n. 7
0
def make_new_semver(current_semver, last_release_semver, all_triggers,
                    **overrides):
    """Defines how to increment semver based on which significant figure is triggered

    :param current_semver: the version to increment
    :param last_release_semver: the previous release version, if available
    :param all_triggers: list of major/minor/patch/prerelease
    :param overrides: explicit values for some or all of the sigfigs
    :return:
    """
    version_string = str(current_semver)

    # if the current version isn't a full release
    if not is_release(current_semver) and last_release_semver:
        # we check to see how important the changes are
        # in the triggers, compared to the changes made between the current version and previous release
        if sigfig_gt(max_sigfig(all_triggers),
                     semver_diff(current_semver, last_release_semver)):
            # here, the changes are more significant than the original RC bump, so we re-bump
            pass
        else:
            # here the changes are same or lesser than the original RC bump, so we only bump prerelease
            all_triggers = {SemVerSigFig.prerelease}

    if is_release(current_semver):
        # if the current semver is a release, we can't just do a prerelease or build increment
        # there *must* be a minimum patch increment, otherwise you could get 2.0.0 -> 2.0.0-RC.1
        all_triggers.add(SemVerSigFig.patch)

    bump_sigfig = max_sigfig(all_triggers)

    if bump_sigfig:
        # perform an increment using the most-significant trigger
        version_string = getattr(semver, "bump_" + bump_sigfig)(
            str(current_semver), **get_token_args(bump_sigfig))

        if sigfig_gt(bump_sigfig, SemVerSigFig.prerelease):
            # if we *didnt* increment sub-patch already, then we should do so
            # this provides the "devmode template" as previously
            # and ensures a simple 'bump' doesn't look like a full release
            version_string = semver.bump_prerelease(
                version_string, token=config.PRERELEASE_TOKEN)

    # perform any explicit setting of sigfigs
    version_info = semver.parse_version_info(version_string)
    for k, v in overrides.items():
        token_args = get_token_args(k)
        prefix = list(token_args.values()).pop() + "." if token_args else ""
        setattr(version_info, "_" + k, prefix + str(v))

    return version_info
Esempio n. 8
0
def update_version(ctx):
    """Update version number in Podspec and Frameworks."""
    if _git_modified_files():
        _logger.error('Branch must be clean before updating version spec. '
                      'Clean up modified files and try again.')
        return

    current_version = _get_current_version('Fritz.podspec')
    new_version = semver.bump_prerelease(current_version, token='beta')
    _update_changelog(new_version)
    _update_podspec('Fritz.podspec', current_version, new_version)
    _update_info_plists(new_version)

    os.system('git commit -am "Bump to version {}"'.format(new_version))
Esempio n. 9
0
def next_semver(major, minor, prerelease=None, versions=None):
    # type: (int, int, str, list) -> str
    major = int(major)
    minor = int(minor)

    def stuff_we_care_about(v):
        """
    we only care about stuff that:
    - has our same major+minor version
    - is a release OR has our same prerelease token
    """
        if v.major != major:
            return False
        if v.minor != minor:
            return False
        if not prerelease:
            return True
        if v.prerelease is None:
            return True
        prefix = prerelease + "."
        if v.prerelease.startswith(prefix):
            # also needs to end in an int for us to care about it
            return bool(re.match("^\d+$", v.prerelease[len(prefix):]))
        return False

    semvers = [
        VersionInfo.parse(v[1:] if v.startswith("v") else v)
        for v in versions or []
    ]
    semvers = filter(stuff_we_care_about, semvers)
    if semvers:
        latest = sorted(semvers)[-1]
        version = str(latest)
        # do we bump patch?
        if not latest.prerelease:
            version = semver.bump_patch(version)
        # is this a final version?
        if prerelease:
            version = semver.bump_prerelease(version, prerelease)
        else:
            version = semver.finalize_version(version)
    else:
        # nothing exists on the current minor version so create a new one
        version = "%s.%s.0" % (major, minor)
        if prerelease:
            version += "-%s.1" % prerelease
    return "v" + version
Esempio n. 10
0
    def bump(self, what):
        if self.bumped:
            debug('version already bumped, don\'t do it twice')
            return
        if '=' in what:
            what, what_name = what.split('=')
        else:
            what, what_name = what, None

        old = semver.format_version(*self.version)
        types = ['major', 'minor', 'patch', 'prerelease', 'build']
        if what == "last":
            # count how many non None parts there are
            parts = len([k for k in self.version if k is not None])
            new = semver_bump[parts - 1](old)
        elif what == 'finalize':
            new = semver.finalize_version(old)
        elif what in types:
            if what_name:
                if what == 'prerelease':  # to enable x.y.z-beta.1 -> x.y.z->rc.0
                    old_final = semver.finalize_version(old)
                    new = semver_bump[types.index(what)](old_final, what_name)
                elif what in ['major', 'minor',
                              'patch']:  # to go from 0.1.0 -> 0.2.0-beta1
                    new = semver_bump[types.index(what)](old)
                    new = semver.bump_prerelease(new, what_name)
                else:
                    new = semver_bump[types.index(what)](old, what_name)
            else:
                new = semver_bump[types.index(what)](old)
        else:
            error("unknown what: {}", what)
        info("version was {}, is now {}", old, new)
        self.version = [
            k for k in semver.parse_version_info(new) if k is not None
        ]
        self.bumped = True
Esempio n. 11
0
def update_version(repo, src, dst) -> str:
    """
    Retrieves the current version from github, bumps the version, and updates the values in service_config.json before
    committing to the dst branch
    :return: The new version.
    """
    cur_version = get_current_version(repo, cmd_args.stage)

    if src == "prod":
        prv_version = get_current_version(repo, _stage=dst)
        _new_version = semver.finalize_version(prv_version)
    else:
        _new_version = getattr(semver,
                               f"bump_{cmd_args.release}")(str(cur_version))
        _new_version = (_new_version
                        if semver.parse_version_info(_new_version).prerelease
                        else semver.bump_prerelease(_new_version, token="rc"))

    if cur_version == _new_version:
        print("Nothing to promote")
        exit(0)
    else:
        print(f"Upgrading: {cur_version} -> {_new_version}")
        return _new_version
Esempio n. 12
0
def make_new_semver(version_string, all_triggers, **overrides):
    """Defines how to increment semver based on which significant figure is triggered
    (most significant takes precendence)

    :param version_string: the version to increment
    :param all_triggers: major/minor/patch/prerelease
    :param overrides: explicit values for some or all of the sigfigs
    :return:
    """

    # perform an increment using the most-significant trigger
    also_prerelease = True
    for sig_fig in SemVerSigFig:  # iterate sig figs in order of significance
        if sig_fig in all_triggers:
            if sig_fig in (SemVerSigFig.prerelease, SemVerSigFig.build):
                also_prerelease = False
            version_string = getattr(semver, "bump_" + sig_fig)(
                version_string, **get_token_args(sig_fig))
            break

    if also_prerelease:
        # if we *didnt* increment sub-patch, then we should do so
        # this provides the "devmode template" as previously
        # and ensures a simple 'bump' doesn't look like a full release
        version_string = semver.bump_prerelease(version_string,
                                                token=config.PRERELEASE_TOKEN)

    # perform any explicit setting of parts
    version_info = semver.parse_version_info(version_string)
    for k, v in overrides.items():
        token_args = get_token_args(k)
        prefix = list(token_args.values()).pop() + "." if token_args else ""
        setattr(version_info, "_" + k, prefix + str(v))
    version_string = str(version_info)

    return version_string
Esempio n. 13
0
def test_should_ignore_build_on_prerelease_bump():
    assert bump_prerelease('3.4.5-rc.1+build.4') == '3.4.5-rc.2'
Esempio n. 14
0
    "The rpc_release value of %s does not comply with the release naming"
    " standard. Please correct it!" % rpc_release)
# Extract the SemVer-compliant portion of the version (no 'r' prefix)
rpc_release_semver = re.sub('^r', '', rpc_release)

# If the rpc_rc_release and rpc_release versions match,
# then we need to increment the value of rpc_release.
if rpc_rc_release == rpc_release:

    # If the current version is a prerelease version,
    # then increment the prerelease.

    if rpc_release != "master":
        rpc_release_parts = semver.parse(rpc_release_semver)
        if rpc_release_parts['prerelease'] is not None:
            rpc_release_semver_new = semver.bump_prerelease(rpc_release_semver)
        # Otherwise, this is a standard release and we
        # just need to do a patch version increment.
        else:
            rpc_release_semver_new = semver.bump_patch(rpc_release_semver)

    # Now add the 'r' prefix back on for the final version
        rpc_release = "r" + rpc_release_semver_new

if rpc_release == 'master':
    release_data['maas_release'] = 'master'
    release_data['osa_release'] = 'master'
    release_data['rpc_release'] = 'master'
else:
    # Adjust the maas release
    release_data['maas_release'] = maas_release
Esempio n. 15
0
def test_should_bump_prerelease():
    assert bump_prerelease('3.4.5-rc.9') == '3.4.5-rc.10'
    assert bump_prerelease('3.4.5-0009.dev') == '3.4.5-0010.dev'
    assert bump_prerelease('3.4.5') == '3.4.5-rc.1'
Esempio n. 16
0
 def test_should_ignore_build_on_prerelease_bump(self):
     self.assertEqual(bump_prerelease('3.4.5-rc.1+build.4'), '3.4.5-rc.2')
Esempio n. 17
0
def test_should_bump_prerelease(version, token, expected):
    token = "rc" if not token else token
    assert bump_prerelease(version, token) == expected
Esempio n. 18
0
 def bump_pre(self, token=None):
     v = semver.bump_prerelease(str(self), token=self.pre_token)
     self.parse_version(v)
     return v
Esempio n. 19
0
def test_should_ignore_build_on_prerelease_bump():
    assert bump_prerelease("3.4.5-rc.1+build.4") == "3.4.5-rc.2"
Esempio n. 20
0
def test_should_ignore_build_on_prerelease_bump():
    assert bump_prerelease('3.4.5-rc.1+build.4') == '3.4.5-rc.2'
Esempio n. 21
0
def test_should_bump_prerelease():
    assert bump_prerelease('3.4.5-rc.9') == '3.4.5-rc.10'
    assert bump_prerelease('3.4.5') == '3.4.5-rc.1'
assert release_naming_standard.match(rpc_release), (
    "The rpc_release value of %s does not comply with the release naming"
    " standard. Please correct it!" % rpc_release)

# Extract the SemVer-compliant portion of the version (no 'r' prefix)
rpc_release_semver = re.sub('^r', '', rpc_release)

# If the rpc_rc_release and rpc_release versions match,
# then we need to increment the value of rpc_release.
if rpc_rc_release == rpc_release:

    # If the current version is a prerelease version,
    # then increment the prerelease.
    rpc_release_parts = semver.parse(rpc_release_semver)
    if rpc_release_parts['prerelease'] is not None:
        rpc_release_semver_new = semver.bump_prerelease(rpc_release_semver)

    # Otherwise, this is a standard release and we
    # just need to do a minor version increment.
    else:
        rpc_release_semver_new = semver.bump_minor(rpc_release_semver)

    # Now add the 'r' prefix back on for the final version
    rpc_release = "r" + rpc_release_semver_new

# Adjust the maas release
release_data['maas_release'] = maas_release

# Adjust the OSA SHA
release_data['osa_release'] = osa_release
Esempio n. 23
0
def test_should_bump_prerelease(version, token, expected):
    token = "rc" if not token else token
    assert bump_prerelease(version, token) == expected
Esempio n. 24
0
 def test_should_ignore_build_on_prerelease_bump(self):
     self.assertEqual(bump_prerelease('3.4.5-rc.1+build.4'),
                      '3.4.5-rc.2')
Esempio n. 25
0
        exit(1)
else:
    print "Error: No file extension found in the artifact_name (%s)" % args.artifact_name
    exit(1)

# Go find what versions already exist

artifact_prefix = args.bucket_dir + "/" + file_name
bucket = s3.Bucket(args.bucket_name)
obj_iterator = bucket.objects.filter(Prefix=artifact_prefix)
item_names = sorted([x.key for x in obj_iterator])

if not len(item_names):
    # New file to begin versioning
    new_ver = semver.format_version(0, 0, 1)
    new_ver = semver.bump_prerelease(new_ver)
    print new_ver
    exit(0)

ver_index = item_names[-1].rfind("_")
highest_existing_ver = item_names[-1][ver_index:]

if item_names[-1][:ver_index] != artifact_prefix:
    print "Error: Found no versioned files based on %s" % artifact_prefix
    exit(1)

if highest_existing_ver.startswith("_"):
    highest_existing_ver = highest_existing_ver[1:]
else:
    print "Have highest_existing_ver=%s" % highest_existing_ver
    print "Error: the highest existing version number doesn't start with \"_\" (%s)" % item_names[
Esempio n. 26
0
    def _get_version(cls, release_version, bump_and_set_dev):
        if not bump_and_set_dev:
            return release_version

        bumped = semver.bump_patch(release_version)
        return semver.bump_prerelease(bumped, token='dev')
Esempio n. 27
0
    'internal': 'integrations-internal',
    'agent': 'datadog-agent',
}

VERSION_BUMP = {
    'Added': semver.bump_minor,
    'Changed': semver.bump_major,
    'Deprecated': semver.bump_minor,
    'Fixed': semver.bump_patch,
    'Removed': semver.bump_major,
    'Security': semver.bump_minor,
    'major': semver.bump_major,
    'minor': semver.bump_minor,
    'patch': semver.bump_patch,
    'fix': semver.bump_patch,
    'rc': lambda v: semver.bump_prerelease(v, 'rc'),
    'alpha': lambda v: semver.bump_prerelease(v, 'alpha'),
    'beta': lambda v: semver.bump_prerelease(v, 'beta'),
}

CHANGELOG_TYPES_ORDERED = [
    'Added', 'Fixed', 'Security', 'Changed', 'Deprecated', 'Removed'
]

AGENT_V5_ONLY = {
    'agent_metrics', 'docker_daemon', 'go-metro', 'kubernetes', 'ntp'
}

BETA_PACKAGES = {'datadog_checks_dev', 'datadog_checks_downloader'}

NOT_CHECKS = {'datadog_checks_dev'}
Esempio n. 28
0
 def test_should_bump_prerelease(self):
     self.assertEqual(bump_prerelease('3.4.5-rc.9'), '3.4.5-rc.10')
     self.assertEqual(bump_prerelease('3.4.5-0009.dev'), '3.4.5-0010.dev')
     self.assertEqual(bump_prerelease('3.4.5'), '3.4.5-rc.1')
Esempio n. 29
0
CHANGELOG_LABEL_PREFIX = 'changelog/'
CHANGELOG_TYPE_NONE = 'no-changelog'
VERSION_BUMP = OrderedDict(
    [
        ('Added', semver.bump_minor),
        ('Changed', semver.bump_major),
        ('Deprecated', semver.bump_minor),
        ('Fixed', semver.bump_patch),
        ('Removed', semver.bump_major),
        ('Security', semver.bump_minor),
        ('major', semver.bump_major),
        ('minor', semver.bump_minor),
        ('patch', semver.bump_patch),
        ('fix', semver.bump_patch),
        ('rc', lambda v: semver.bump_prerelease(v, 'rc')),
        ('alpha', lambda v: semver.bump_prerelease(v, 'alpha')),
        ('beta', lambda v: semver.bump_prerelease(v, 'beta')),
    ]
)

AGENT_V5_ONLY = {'agent_metrics', 'docker_daemon', 'go-metro', 'kubernetes', 'ntp'}

BETA_PACKAGES = {'datadog_checks_dev', 'datadog_checks_downloader'}

NOT_CHECKS = {'datadog_checks_dev'}

# Some integrations do not have an associated tile, mostly system integrations
NOT_TILES = [
    'agent_metrics',
    'directory',
Esempio n. 30
0
def release_local(url, version='patch', base='master', integration=None, default_version='0.0.1', use_prefix=None):
    # type: (str, str, str, str, str, str) -> str
    """
    Tag given repository with a new semver tag (bump version),
    optionally merging a integration branch.

    This will:
        - clone the repository to temporary directory
        - checkout branch indicated via base argument
        - retrieve all the tags, sort them in natural order
        - retrieve the last tag and bump it to given version
        - merge integration branch, if defined
        - tag and push base branch back to origin

    If no tag is present and version argument is any of the bump arguments,
    default_version will be used

    :rtype: str
    :param url: URL of the repository
    :param version: specific version or one of: build, prerelease, patch, minor, major
    :param base: base branch to use, by default master
    :param integration: integration branch to use, by default none
    :param default_version: default version used for when there are no tags and no specific version, default 0.0.1
    :param use_prefix: use prefix for tags - sometimes, 'v',
    :return: newly released version string or None if can not tag
    """
    workspace = mkdtemp()
    repo = Repo.clone_from(url, workspace, progress=SimpleProgressPrinter())

    if repo.bare:
        print_err('Cloned a bare repository, can not release [???]')

    origin = repo.remote('origin')

    if repo.active_branch.name != base:
        origin.fetch('refs/heads/{0}:refs/heads/{0}'.format(base), progress=SimpleProgressPrinter())
        repo.heads[base].checkout()

    if integration is not None and integration in repo.heads:
        print_info('Found integration branch "{0}", fetching'.format(integration))
        origin.fetch('refs/heads/{0}:refs/heads/{0}'.format(integration), progress=SimpleProgressPrinter())
        print_info('Will now attempt fast-forward {0} to include {1}'.format(base, integration))
        print_git_output(repo.git.merge('--commit', '--no-edit', '--stat', '--ff-only', '-v', integration))

    head_tags = (tag for tag in repo.tags if tag.commit == repo.head.commit)
    sorted_head_tags = natsorted(head_tags, key=lambda t: t.path)

    if 0 != len(sorted_head_tags):
        print_info(
            'Not going to auto-tag already tagged HEAD, tagged with {0}'
                .format(
                str.join(', ', (t.path[10:] for t in sorted_head_tags))
            )
        )
        return None

    last_tag = None

    if repo.tags:
        sorted_tags = natsorted(repo.tags, key=lambda t: t.path)
        current_tag = sorted_tags[-1].path[10:]
        print_info('Current tag is {0}'.format(current_tag))
        if use_prefix is not None and current_tag.startswith(use_prefix):
            last_tag = current_tag[len(use_prefix):]
        else:
            last_tag = current_tag

    print_info('Last known version: {0}'.format(last_tag))

    if last_tag is None:
        print('Unknown last version, using default version {0}'.format(default_version))
        last_tag = default_version

    if 'build' == version:
        next_version = bump_build(last_tag)

    elif 'prerelease' == version:
        next_version = bump_prerelease(last_tag)

    elif 'patch' == version:
        next_version = bump_patch(last_tag)

    elif 'minor' == version:
        next_version = bump_minor(last_tag)

    elif 'major' == version:
        next_version = bump_major(last_tag)
    else:
        next_version = version

    print_info('Next version: {0}'.format(next_version))

    next_tag = next_version.strip()

    if use_prefix is not None:
        next_tag = use_prefix + next_version

    print_info('Next tag: {0}'.format(next_tag))

    print_info('Tagging and pushing version')

    release_tag = repo.create_tag(
        path=next_tag,
        ref=repo.heads[base],
        message='Release tag of {0}'.format(next_version)
    )

    origin.push([release_tag, repo.heads[base]], progress=SimpleProgressPrinter())

    print_info('Done, clearing workspace')
    rmtree(workspace)

    return next_version