GithubHelp home page GithubHelp logo

shradej1 / semver-vcs Goto Github PK

View Code? Open in Web Editor NEW

This project forked from ajoberstar/reckon

0.0 2.0 0.0 640 KB

Infer a project's version from the state of your VCS.

License: Apache License 2.0

Java 35.97% Groovy 64.03%

semver-vcs's Introduction

semver-vcs

Bintray Travis Maintainer Status GitHub license

Why do you care?

Get that version number out of my build file!

Most build tools and release systems require you to hardcode a version number into a file in your source repository. This results in commit messages like "Bumping version number.". Even if you don't have to do this manually, your release plugin probably modifies your build file and commits the new version.

However, the version control system (VCS) already contains tags with a version number pointing to a specific commit. Git illustrates the power of this with the git describe command that creates a version number based on the amount of change since the previous tag (e.g. v0.1.0-22-g26f678e).

Your VCS also contains branches that indicate specific stages of development or indicate maintenance for a specific subset of versions.

With this much information available to the VCS, there's very little the user should have to provide to get the next version number. And it certainly doesn't need to be hardcoded anywhere.

What does this version number mean?

Semantic versioning is the best answer to this question so far. It specifies a pretty stringent meaning for what a consumer of an API should expect based on the difference between two versions numbers.

Additionally it describes methods for encoding pre-release and build-metadata and how those should be sorted by tools.

With that specification and some conventions related to encoding your stage of development into the pre-release information, you can end up with a very easy to understand versioning scheme.

For example, this API's scheme includes four stages:

  • final (e.g. 1.0.0) the fully-tested version ready for end-user consumption
  • rc (e.g. 1.1.0-rc.1) release candidates, versions believed to be ready for release with final testing
  • milestone (e.g. 1.1.0-milestone.4) versions containing a significant piece of functionality on the road to the next version
  • dev (e.g. 1.1.0-dev.2 or 1.1.0-milestone.4.dev.6) development versions happening in-between more formally defined stages (this is a floating stage, in semver-vcs parlance)

What is it?

semver-vcs is two things:

  • an VCS-agnostic API that can calculate your next version
  • a collection of implementations for various VCSs and tools (typically, build tools)

Version Components

As specified by SemVer, a version consists of three primary components: <normal>[-<prerelease>][+<buildmetadata>].

  • normal your typical <major>.<minor>.<patch> scheme
  • pre-release any set of dot-separated alphanumeric identifiers used to indicate progress towards the normal
  • build-metadata any set of dot-separated alphanumeric identifiers used to indicate information about the current build, which should not be used to sort versions

Scope

semver-vcs describes changes in the normal as the scope of the change, being one of major, minor, or patch. The scope indicates which component of the version should be incremented, with the components to the right being zeroed out. For example, with a previous version of 1.2.3 a minor scope change would result in 1.3.0.

Stage

In order to provide more structure to pre-release information and simplify the minutiae of pre-release precedence, the concept of a stage of development is used. Stages can be of a few different flavors:

  • final a special stage indicating no pre-release information should be used
  • fixed indicating significant steps along the way to the final release and will always consist of <stage name>.<incremented count> (e.g. beta.2).
  • floating indicating intermediate steps after another stage. To comply with SemVer precedence rules a floating stage can result in:
    • <stage name>.<incremented count> as long as the stage name is of higher precedence than the previous stage. For example, if milestone was a floating stage and the prior version was 1.0.0-dev.1 it would result in 1.0.0-milestone.1.
    • <previous stage>.<stage name>.<incremented count> if the stage name is of lower precedence than the previous stage. For example, if dev was a floating stage and the prior version was 1.0.0-milestone.2 it would result in 1.0.0-milestone.2.dev.1.

For compatibility with Maven workflows, semver-vcs also provides a SNAPSHOT stage with no incrementing count.

Build Metadata

Currently, build metadata is not a first-level concept in semver-vcs, but that will be addressed in #13.

Versioners

Even though semver-vcs promotes the concepts of scope and stage, the API does not depend on them. The actual inference is performed by a versioner, which is just a function that takes both the version determined so far and the VCS being used and returns the next version to use.

semver-vcs provides versioner implementations optimized for scope and stage schemes, but you are free to provide your own versioner function that produces a valid semantic version in any way you please.

Current Support

VCSs

Tooling

Usage

NOTE: All semver-vcs modules require Java 8 (or higher).

Gradle & Git

Apply the plugin:

buildscript {
	repositories { jcenter() }
	dependencies { classpath 'org.ajoberstar:semver-vcs-gradle-grgit:<version>' }
}

apply plugin: 'org.ajoberstar.semver-vcs-grgit'

semver {
	// optionally configure how the version will be calculated
}

See SemverVcsExtension for details on the configuration options.

When you run Gradle, pass in any of the following properties to influence the version being inferred:

  • semver.scope - one of major, minor, or patch to specify which component of the previous release should be incremented
  • semver.stage - (by default, one of final, rc, milestone, or dev) to specify what phase of development you are in
  • semver.base - for your first version, if you don't want to start from 0.0.0
  • semver.force - if you're in a bind and just need a specific version to be used

For example if the previous release was 1.2.4:

./gradlew build -Psemver.scope=minor -Psemver.stage=milestone
Inferred version 1.3.0-milestone.1
...

Direct API Usage

The four basic steps are:

  1. Construct a Version to use as a base, if one isn't found in the VCS.
  2. Construct a Vcs using one of the available providers.
  3. Build a Versioner which is a function of (Version, Vcs) -> Version. This does all of the work of inferring the version. The Versioners class provides some common Versioner implementations that can be composed as needed.
  4. Call the Versioner with the base Version and the Vcs.

For example:

import com.github.zafarkhaja.semver.Version;
import org.ajoberstar.semver.vcs.*;
import org.ajoberstar.semver.vcs.grgit.GrgitVcs;
import org.ajoberstar.grgit.Grgit;

Version base = Version.forIntegers(0, 0, 0);
Vcs vcs = new GrgitVcs(Grgit.open()));
Versioner versioner = Versioners.forScopeAndStage(Scope.MINOR, Stage.finalStage());
Version inferred = versioner.infer(base, vcs);

Implementing

Modules

Implementing a Vcs

A Vcs implementation will literally just need to implement the Vcs interface.

See the Grgit module in this repo for further guidance.

Implementing a Tool

See the example in Direct API Usage above for a basic example and the implementation of the Gradle modules in this repo as further guidance.

Questions, Bugs, and Features

Please use the repo's issues for all questions, bug reports, and feature requests.

Contributing

Contributions are very welcome and are accepted through pull requests.

Smaller changes can come directly as a PR, but larger or more complex ones should be discussed in an issue first to flesh out the approach.

If you're interested in implementing a feature on the issues backlog, add a comment to make sure it's not already in progress and for any needed discussion.

Acknowledgements

Thanks to everyone who contributed to previous iterations of this library and to Zafar Khaja for the very helpful jsemver library.

semver-vcs's People

Contributors

ajoberstar avatar

Watchers

 avatar  avatar

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.