Skip to content

Instantly share code, notes, and snippets.

@nzakas
Created November 24, 2013 23:01
Show Gist options
  • Star 30 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save nzakas/7633640 to your computer and use it in GitHub Desktop.
Save nzakas/7633640 to your computer and use it in GitHub Desktop.
Versioning in a repo

Versioning in a Repository

Lately I've been doing a lot of thinking around versioning in repositories. For all the convenience and ubiquity of package.json, it does sometimes misrepresent the code that is contained within a repository. For example, suppose I start out my project at v0.1.0 and that's what's in my package.json file in my master branch. Then someone submits a pull request that I merge in - the version number hasn't changed even though the repository now no longer represents v0.1.0. The repository is actually now in an intermediate state, in between v0.1.0 and the next official release.

To deal with that, I started changing the package.json version only long enough to push a new release, and then I would change it to a dev version representing the next scheduled release (such as v0.2.0-dev). That solved the problem of misrepresenting the version number of the repository (provided people realize "dev" means "in flux day to day"). However, it introduced a yucky workflow that I really hated. When it was time for a release, I'd have to:

  1. Manually change the version in package.json.
  2. Tag the version in the repo.
  3. Publish to npm.
  4. Manually change the version in package.json to a dev version.
  5. Push to master.

There may be some way to automate this, but I couldn't figure out a really nice way to do it.

That process works well enough when you have no unplanned releases. However, what if I'm working on v0.2.0-dev after v0.1.0 was released, and need to do a v0.1.1 release? Then I need to:

  1. Note the current dev version.
  2. Manually change the version to v0.1.1.
  3. Tag the version in the repo.
  4. Publish to npm.
  5. Change the version back to the same version from step 1.
  6. Push to master.

Add on top of this trying to create an automated changelog based on tagging, and things can get a little bit tricky.

My next thought was to have a release branch where the last published release would live. Essentially, after v0.1.0, the release branch remains at v0.1.0 while the master branch becomes v0.2.0-dev. If I need to do an intermediate release, then I merge master onto release and change versions only in the release branch. Once again, this is a bit messy because package.json is guaranteed to have different versions on master and release, which always causes merge conflicts. This also means the changelog is updated only in the release branch. This solution turned out to be more complex than I anticipated.

I'm still not sure the right way to do this, but my high-level requirements are:

  1. Make sure the version in package.json is always accurate.
  2. Don't require people to change the version to make a commit.
  3. Don't require people to use a special build command to make a commit.
  4. Distinguish between development (in progress) work vs. official releases.
  5. Be able to auto-increment the version number (via npm version).

How about you? How do you deal with versions in your repository?

@onury
Copy link

onury commented Dec 22, 2017

Old post but anyway...

As Linus Torvalds talks and this GitHub guide explains it;

one rule: anything in the master branch should always be deployable.

Because of this, it's extremely important that your new branch is created off of master when working on a feature or a fix. Your branch name should be descriptive (e.g., refactor-authentication, user-content-cache-key, make-retina-avatars), so that others can see what is being worked on.

@gmoz22
Copy link

gmoz22 commented May 10, 2018

Indeed, sometimes you think you're just going to work on a patch and end up with a minor version, or from a minor version having to push out a major. You shouldn't have to worry about which type of version you will be pushing next.

Here's what I started doing:

  1. Start my project at 1.0.0 in package.json
  2. Initial dev work
  3. Push to develop branch
  4. Push to master branch
  5. Tag as v1.0.0
  6. Dev
  7. Push to 'feature/name-of-feature' or 'bug/name-of-bug' branches
  8. Merge pull request of feature and bug branches into develop
  9. When it's ready for release, determine the version number (1.0.1 or 1.1.0) and update package.json
  10. Push package.json to develop branch
  11. Merge develop into master
  12. Tag as v1.0.1 or v1.1.0
  13. Repeat from 6)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment