July 20, 2016

Version Number Strategy

Abstract

I am working on a new open source project named Riviera. The purpose of Riviera is to be a database versioning source code management tool. Riviera is a Java based implementation of the philosophy and practice of database version control written about by K. Scott Allen. But before Riviera can manage changing database versions, it first must know how those numbers are going to change. The purpose of this post is to define a clear strategy for understanding how version numbers change throughout the software development life cycle.

Numbers

Versions will consist of 4 integers separated by dots with an optional dash qualifier at the end. The format for a version number is A.B.C.D[-QUALIFIER]. Let’s take a look at what each of these numbers mean.

A

This represents a major version. This number is used by a project manager to track releases. How and when this number changes is up to the project. Most like to change this number when a significant change is made to the project. Others like to change this number on a yearly basis. Determine how you want to change this number and stay consistent. Major versions can’t get to production without planned releases, which is what’s next, B.

B

This represents a planned release of the major version. This value increments every planned release. A.B together are critical for project managers to plan, estimate, and track features in releases.
NOTE Planning releases? What about Scrum? What about development teams determining what to work on each sprint, scrum masters, and no project managers? Well, if you are working in an environment like this, congratulations! Now back to reality :)
Suppose a new project is spinning up. Project managers start planning for release “1.0” - which is the 1st planned release 0 of major version 1. This release will include features f1, f2, & f3.
While developers are working on “1.0”, project managers can start planning for release “1.1” - which is the 2nd planned release 1 of major version 1. This release will include features f4 & f5.
And so planning continues following this pattern. The scope of features for A.B is determined and the development team works on them. This planning works great until a bug is found in production. To get emergency bug fixes, C is needed.

C

This represents an emergency bug fix of a planned release. Recall that a planned release is represented by A.B. An emergency bug fix of A.B is represented by A.B.C. A.B.C together are critical for project managers to plan, estimate, and track bug fixes.
If a bug is found in “1.3”, and must be fixed in production immediately, the 1st bug fix of “1.3” will be “1.3.1”. Once “1.3.1” goes to production, the C version number keeps incrementing as more emergency bug fixes need to be made:
  • “1.3.1” – 1st emergency bug fix of “1.3”
  • “1.3.2” – 2nd emergency bug fix of “1.3”
  • “1.3.3” – 3rd emergency bug fix of “1.3”
  • “1.3.4” – 4th emergency bug fix of “1.3”
Project managers can plan releases all they want, but nothing will get done unless the software gets built. D makes sure builds can happen. Let’s take a look at D next.

D

This represents an incremental build number. This number is typically manged by some automated build system (Maven) and is used for internal purposes only.
The build number tracks the number of builds made of a planned release or an emergency bug fix. Let’s take a look at each of these.

Incremental build of a planned release.

Suppose the development team is working on planned release “1.3”. As features are finished, builds are made for testing. Each build increments the D value.
  • 1.3.0.0 – 1st build of planned release “1.3”
  • 1.3.0.1
  • 1.3.0.2
  • 1.3.0.3
  • 1.3.0.4
Ultimately, when “1.3” is finished and ready to go to production, the internally tracked build going to production may be 1.3.0.15.

Incremental build of emergency bug fix.

Suppose the development team is working on emergency bug fix “1.3.1”. As the bugs are fixed, builds are made for testing. Each build increments the D value.
  • 1.3.1.0 – 1st build of emergency bug fix “1.3.1”
  • 1.3.1.1
  • 1.3.1.2
  • 1.3.1.3
Ultimately, when the “1.3.1” is finished and ready to go to production, the internally tracked build going to production may be 1.3.1.4.

[-QUALIFIER]

This is an optional part of a version number. Maven uses -SNAPSHOT to represent non-official builds.

GIT, Subversion, CVS, etc.

Now that the format of the version number has been defined, let’s consider the effects on the change control system (GIT, Subversion, CVS, etc.). To do this, we’ll follow a hypothetical development time line. As you read through the time line, reference figure 1 to see how the trunk, branches, and tags change over time.

Time Line

  • Planning for the “1.0” release is complete. Development starts. Trunk is at 1.0.0.0 (a).
  • “1.0” features completed. A build is made for testing. Tag 1.0.0.0 is created from trunk. Trunk becomes 1.0.0.1 (b)
  • “1.0” features completed. A build is made for testing. Tag 1.0.0.1 is created from trunk. Trunk becomes 1.0.0.2 (c)
  • “1.0” features completed. A build is made for testing. Tag 1.0.0.2 is created from trunk. Trunk becomes 1.0.0.3 (d)
  • Planning for “1.1” release is complete. Branch 1.0.0 is created for ongoing “1.0” development. Trunk becomes 1.1.0.0 and “1.1” development starts on trunk. (e)
  • “1.0” features completed. A build is made for testing. Tag 1.0.0.3 is created from branch. Branch becomes 1.0.0.4. Changes from branch merged into trunk. (f)
  • “1.1” features complete. A build is made for testing. Tag 1.1.0.0 is created from trunk. Trunk becomes 1.1.0.1 (g)
  • “1.0” features completed. A build is made for testing. Tag 1.0.0.4 is created from branch. Branch becomes 1.0.0.5. Changes from branch merged into trunk. (h)
  • “1.1” features complete. A build is made for testing. Tag 1.1.0.1 is created from trunk. Trunk becomes 1.1.0.2 (i)
  • “1.0” FINISHED. Build 1.0.0.4 goes to production (j)
  • “1.1” features complete. A build is made for testing. Tag 1.1.0.2 is created from trunk. Trunk becomes 1.1.0.3 (k)
  • “1.1” features complete. A build is made for testing. Tag 1.1.0.3 is created from trunk. Trunk becomes 1.1.0.4 (l)
  • “1.1” features complete. A build is made for testing. Tag 1.1.0.4 is created from trunk. Trunk becomes 1.1.0.5 (m)
  • “1.0” EMERGENCY BUG FIX. Create branch from 1.0.0.4 tag (the build in production). Branch becomes 1.0.1.0 (n)
  • “1.0.1” EMERGENCY BUG FIX complete. A build is made for testing. Tag 1.0.1.0 is created from branch. Branch becomes 1.0.1.1. Changes in branch merged into trunk (o)
  • “1.0.1” EMERGENCY BUG FIX complete. A build is made for testing. Tag 1.0.1.1 is created from branch. Branch becomes 1.0.1.2. Changes in branch merged into trunk (p)
  • “1.1” features complete. A build is made for testing. Tag 1.1.0.5 is created from trunk. Trunk becomes 1.1.0.6 (q)
  • “1.0.1” EMERGENCY BUG FIX complete. A build is made for testing. Tag 1.0.1.2 is created from branch. Branch becomes 1.0.1.3. Changes in branch merged into trunk (r)
  • “1.0.1” FINISHED. Build 1.0.1.2 goes to production (s)
  • And it continues…

Figure 1 - Trunk, Branches, & Tags

 TRUNK
1.0.0.0------                                       (a)
   |         \
   |         TAG
   |       1.0.0.0                                  (b)
   |
1.0.0.1------                                       (b)
   |         \
   |         TAG
   |       1.0.0.1                                  (c)
   |
1.0.0.2------                                       (c)
   |         \
   |         TAG
   |       1.0.0.2                                  (d)
   |
1.0.0.3------                                       (d)
   |         \
   |       BRANCH
   |       1.0.0.3------                            (e)
   |          |         \
   |          |         TAG
   |          |       1.0.0.3                       (f)
   |          |
   |       1.0.0.4------                            (f)
   |          |         \
   |          |         TAG------
   |          |       1.0.0.4    \                  (h) (j)
   |          |                 BRANCH------
   |       1.0.0.5              1.0.1.0     \       (h) (n)
   |          |                    |        TAG
   |          -                    |      1.0.1.0   (o)
   |                               |
   |                            1.0.1.1------       (o)
   |                               |         \
   |                               |        TAG
   |                               |      1.0.1.1   (p)
   |                               |
   |                            1.0.1.2------       (p)
   |                               |         \
   |                               |        TAG
   |                               |      1.0.1.2   (r) (s)
   |                               |
   |                            1.0.1.3             (r)
   |
1.1.0.0------                                       (e)
   |         \
   |         TAG
   |       1.1.0.0                                  (g)
   |
1.1.0.1------                                       (g)
   |         \
   |         TAG
   |       1.1.0.1                                  (i)
   |
1.1.0.2------                                       (i)     
   |         \
   |         TAG
   |       1.1.0.2                                  (k)
   |
1.1.0.3------                                       (k)     
   |         \
   |         TAG
   |       1.1.0.3                                  (l)
   |
1.1.0.4------                                       (l)     
   |         \
   |         TAG
   |       1.1.0.4                                  (m)
   |
1.1.0.5------                                       (m)     
   |         \
   |         TAG
   |       1.1.0.5                                  (q)
   |
1.1.0.6                                             (q)

Summary

Handling version numbers is always a tricky thing, especially when you have multiple lines of development going on different branches and all the work needs to be coordinated and merged. This strategy seems to work well. The hard part is sticking to it!

References

Allen, S. (2008, February 4). Versioning Databases - Branching and Merging. Ode to Code. Retrieved from http://odetocode.com/blogs/all?page=75.

July 19, 2016

Welcome to Scrivener

Abstract

Begin typing your abstract paragraph here. This paragraph should not be indented. It should range between 150 and 250 words. This should be accurate, nonevaluative, readable, and concise. The reader should know exactly what this blog post is about.

Scrivener

Scrivener is a powerful writing tool which can be used for all kinds of writing. Originally developed for writing novels, Scrivener is now used for short stories, plays, scripts, theses, and lots of other kinds of writing including blogging.

Scrivener separates the content of what you write from its output format. Compiling is how to get the output format. For bloggers, Scrivener supports the markdown syntax. Let’s take a look at markdown.

Markdown

Markdown is a markup format for writers that’s easier than HTML, but is ultimately turned into HTML. A cheat sheet shows just how simple it is. Scrivener compiles a markdown formatted writing into HTML. After that, copy & paste the HTML into the HTML Editor of your blogging platform.

NOTE The HTML generated is quite simple. Your blog’s CSS will need to be updated to present it nicely. Typically somewhere in the settings you’ll find a spot to edit the contents of the blog template. It’s here you can add custom CSS to format the markdown-generated HTML.

Code

All technical blogs will need to show code. There will be int inlineCode = 1; examples. And there will be block code examples referred to by listings. Listing 1 is a Java block code example.

Listing 1 - Java Hello World

public static final void main(String [] args) {
  System.out.println("Hello world!");
}

Images

Images are also essential. Figure 1 is an example of an image. This image is not embedded in the blog. It is referencing an image from another website. This is a bit dangerous to do because if the website removes the image, it will no longer appear on the blog. An alternative is to upload images to the blog and reference the URLs created for those images. Or host the images on a site like Flickr. Or save the images to Dropbox and get a shared link to the image.

Figure 1 - Duke

Java Duke waving
Java Duke waving

Summary

It is always good to wrap up a blog posting with a summary of the contents. Sometimes blog posts are small quick tips and a summary is not necessary. But if the blog post is presenting lengthy contents, then a summary is good to help remind blog readers what they just read.

References

And don’t forget your references! People contribute a lot of information online, so it’s good to cite your sources.

Pritchard, A. (2016, February 26). Markdown Cheatsheet. Website Title. Retrieved from https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet