GithubHelp home page GithubHelp logo

semtag's Introduction

Semtag

Semantic Tagging Script for Git

[Version: v0.1.2]

Notes: This script is inspired by the Nebula Release Plugin, and borrows a couple of lines from Semver Bash Tool (mostly the version comparison and the semantic version regex).

A quick history of this script

This is a script to help out version bumping on a project following the Semantic Versioning specification. It uses Git Tags to keep track the versions and the commit log between them, so no extra files are needed. It can be combined with release scripts, git hooks, etc, to have a consistent versioning.

Why Bash? (and requirements)

Portability, mostly. You can use the script in any project that uses Git as a version control system. The only requirement is Git.

Why not use the Nebula-release plugin?

Nebula Release is for releasing and publishing components and tries to automate the whole process from tagging to publishing. The goal of the semtag script is to only tag release versions, leaving the release process up to the developer.

Plus, the semtag sctipt doesn't depend on the build system (so no need to use Gradle), so it can be used in any project.

Usage

Copy the semtag script in your project's directory.

Semtag distinguishes between final versions and non-final versions. Possible non-final versions are alpha, beta and rc (release candidate).

Starts from version 0.0.0, so the first time you initialize a version, it will tag it with the following bumped one (1.0.0 if major, 0.1.0 if minor, 0.0.1 if patch)

Use the script as follows:

$ semtag <commdand> <options>

Info commands:

  • getfinal Returns the current final version.
  • getlast Returns the last tagged version, it can be the final version or a non-final version.
  • getcurrent Returns the current version, it can be the tagged final version or a tagged non-final version. If there are unstaged or uncommitted changes, they will be included in the version, following this format: <major>.<minor>.<patch>-dev.#+<branch>.<hash>. Where # is the number of commits since the last final release, branch will be the current branch if we are not in the default branch (master, main, or other) and hash is the git hash of the current commit.
  • get Returns both last tagged version and current final version.

Versioning commands:

  • final Bumps the version top a final version
  • alpha Bumps the version top an alpha version (appending -alpha.# to the version.
  • beta Bumps the version top a beta version (appending -beta.# to the version.
  • candidate Bumps the version top an release candidate version (appending -rc.# to the version.

Note: If there are no commits since the last final version, the version is not bumped.

All versioning commands tags the project with the new version using annotated tags (the tag message contains the list of commits included in the tag), and pushes the tag to the origin remote.

If you don't want to tag, but just display which would be the next bumped version, use the flag -o for showing the output only.

For specifying the scope you want to bump the version, use the -s <scope> option. Possible scopes are major, minor and patch. There is also auto which will choose between minor and patch depending on the percentage of lines changed. Usually it should be the developers decisions which scope to use, since the percentage of lines is not a great criteria, but this option is to help giving a more meaningful versioning when using in automatic scripts.

If you want to manually set a version, use the -v <version> option. Version must comply the semantic versioning specification (v<major>.<minor>.<patch>), and must be higher than the latest version. Works with any versioning command.

Usage Examples

See the release script as an example. The script gets the next version to tag, uses that version to update the README.md file (this one!), and the script's. Then commits the changes, and finally tags the project with this latest version.

Gradle example

For setting up your project's version, in your build.gradle file, add the following:

version=getVersionTag()

def getVersionTag() {
  def hashStdOut = new ByteArrayOutputStream()
  exec {
    commandLine "$rootProject.projectDir/semtag", "getcurrent"
    standardOutput = hashStdOut
  }

  return hashStdOut.toString().trim()
}

This way, the project's version every time you make a build, will be aligned with the tagged version. On your CI script, you can tag the release version before deploying, or alternatively, before publishing to a central repository (such as Artifactory), you can create a Gradle task tagging the release version:

def tagFinalVersion() {
  exec {
    commandLine "$rootProject.projectDir/semtag", "final", "-s minor"
    standardOutput = hashStdOut
  }

  doLast {
    project.version=getVersionTag()
  }
}

artifactoryPublish.dependsOn tagFinalVersion

Or create your own task for tagging and releasing. The goal of this script is to provide flexibility on how to manage and deal with the releases and deploys.

How does it bump

Semtag tries to guess which is the following version by using the current final version as a reference for bumping. For example:

$ semtag get
Current final version: v1.0.0
Last tagged version:   v1.0.0
$ semtag candidate -s minor
$ semtag get
Current final version: v1.0.0
Last tagged version:   v1.1.0-rc.1

Above it used the v1.0.0 version for bumping a minor release candidate. If we try to increase a patch:

$ semtag candidate -s patch
$ semtag get
Current final version: v1.0.0
Last tagged version:   v1.1.0-rc.2

Again, it used the v1.0.0 version as a reference to increase the patch version (so it should be bumped to v1.0.1-rc.1), but since the last tagged version is higher, it bumped the release candidate number instead. If we release a beta version:

$ semtag beta -s patch
$ semtag get
Current final version: v1.0.0
Last tagged version:   v1.1.1-beta.1

Now the patch has been bumped, since a beta version is considered to be lower than a release candidate, so is the verison number that bumps up, using the provided scope (patch in this case).

Forcing a tag

Semtag doesn't tag if there are no new commits since the last version, or if there are unstaged changes. To force to tag, use the -f flag, then it will bump no matter if there are unstaged changes or no new commits.

Version prefix

By default, semtag prefixes new versions with v. Use the -p (plain) flag which to create new versions with no v prefix.

License

Copyright 2020 Nico Hormazábal

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

semtag's People

Contributors

abaird-wavefin avatar asveepay avatar estandiaa avatar mahirchavda avatar nico2sh avatar polbreachity avatar robinbowes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

semtag's Issues

Make git fetch toggleable

Sometimes, you'd rather not have semtag automatically perform a git fetch and would like it to work with the currently cloned repo alone.

Proposal: add a flag to disable the git fetch in init.

Do you have any preferences for what the flag should be?

How to maintain several major releases?

I have to maintain two different versions - v2.* and v1.* (for legacy and bug-fixes).

Now I got "Version can't be lower than last version: v2.0.0" if I try to release into v1:

semtag final -v v1.23.0 -f

Any ideas? Or workarounds?

Make main branch more dynamic

Hello,

It appears that there are quite a few hardcoded references to the master branch in this tool.

Github has been working on moving the default branch name from master to main. It seems like this will begin breaking on more and more people's repositories. Thoughts on making the branch name configurable? Or releasing a new version where it's defaulted to main instead?

How to disable semver without "v" prefix

Is there any way to disable something like this,
I hope something like 0.0.1-alpha.2, without "v" prefix (v0.0.1-alpha.2)

semtag alpha -s patch
2021-01-25T03:31:53Z
v0.0.1-alpha.2

Feature request: tag current branch

Hi,
currently it looks like tag is done based on main branch tag. It would be nice to have a feature to make a tag on current branch, e.g., release branch has it's own version lifecycle, different from main branch version.

Sample:
main branch: version 2.0.0
release branch: version 1.5.0

So tagging on release branch would increase 1.5.0, not 2.0.0 version (as it is now)

Feature Request: Multiple remotes

Hi Nico, first thanks for the tool, very useful.

Could you consider adding support for the use case where multiple remotes are defined. I imagine lots of developers will follow a origin / fork strategy. At the moment, the remote check 'git remote' can return a list, which will fail in the following git push.

It would be useful to support pushing to one or more remotes.

Thanks,
Damian.

Integrity checking

Hi,

Would it be possible for you to publish/release an integrity check of some kind? Like either md5, sha256sum, whatever you'd like... You could release it along with your semtag.tar.gz / zip files.

Would be of huge help, I can help you write the code if you'd like, we could put the repo on CircleCI or TravisCI for free?

Thanks again!!

Semtag does not fail if git tag command fails to tag the commit

There are some cases where a tag already exists, so when the git tag command tries to tag HEAD, it fails with the message fatal: tag '' already exists. However, the script doesn't exit 1 so the CI pipeline continues.

% bash semtag final -s patch
fatal: tag 'v0.0.4' already exists
v0.0.4 pushed to origin

This is a very simple fix: just add || exit 1 to the git tag -a $__version -m "$__message" command on line 516:

semtag/semtag

Line 516 in f5b2c67

git tag -a $__version -m "$__message"

git tag -a $__version -m "$__message" || exit 1

Git's error message is satisfactory so no need for additional logic just for a custom messages.

There is another option: add set -o errexit to the top of semtag. However, I believe this will require additional changes to the semtag to make it work correctly.

Non-master default branches

Github is in the process of switching to using main as the default for a default branch. This breaks with semtag as there are some occurrences of hard-coding master in the code.

The default branch can be retrieved programmatically using git symbolic-ref refs/remotes/origin/HEAD | sed "s@^refs/remotes/origin/@@".

line 479 __verbose improvement if use set -Eeou pipefail inside release.sh script

If you use inside release.sh script: set -Eeou pipefail

  • semtag line:479 => local __verbose=${2:-''}

By the way the release.sh could be changed to work outside the source code and and .gitignore "semtag*" or similar. Improvement would be rewrite to script to change version in all files recursive in an given release folder - but its questionary to change always the source code to add the version number.

tag version > 10

I have a tag that semtag has just moved to v19.1.1-beta.10. This is generated with

source semtag beta

I have since done a few commits, when I run the semtag command it wont move passed 10. Have you previously seen an example > 10?

Thanks,
Damian.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.