Semantic Versions and Releases for Publishing
Over the last few weeks, I've been tweaking my publishing process. I think I have something pretty stable and started using it for my next novel. After talking about it on social networks, a number of people suggested I write up what I've learned.
Much of how I manage writing projects is to treat them like software. It works well for framing what I have done, need to get done, and what the end goal is. Because of this, I use various features of GitLab pretty heavily: issue tracking for arcs, issues for the publication process, and even more to remind me to order books; milestones to keep me encouraged; continuous integration (CI) to simplify the production of EPUB, MOBI, and PDF versions of the file.
I've also written a number of framework tools such as MfGames Writing to work with CI services for the publication or help me manage stuff (
Recently, I got into a discussion about treating novels as software. Some of the things I do are... strict and not everyone will care for them, but I like to think I'm making my reader's lives easier by the little details that go into my processes.
Somewhere in 2014 or so, I fell in love with semantic versioning. Semantic versioning is a movement to create a common understanding (a grammar) of version numbers that can be understood by anyone to understand the significance of any given release.
A semantic version comes in three parts: major.minor.patch.
- If a major number increases, it means there was a "breaking change". In writing terms, it would be rewriting sections, changing motivations, removing scenes, and generally changing the meaning of the novel. I would say adding a new epilogue would be reasonably called a major change because it changes the meaning and plot of the novel.
- A minor version is adding features or improvements. As I see it, a minor version is one that I would be adding details to clarify a scene, make it more obvious or more understandable. Maybe adding a paragraph or so would be a minor change.
- Finally, there is a patch. This is fixing typos, character names, or the missing quotes. Sadly, I seem to have a lot of patches as I write, because I only notice those annoying little things days or weeks later.
I put the version on the legal page so it is present but not obvious unless one is looking for it. There are a number of reasons I do this. The biggest is The Deeds of Paksenarrion by Elizabeth Moon. I have two copies of this omnibus book, mainly because I love it so much. They are two different printings. One of them had a few typos in it that they corrected with a later printing. Having an indicator that there were changes (in this case, a "patch") would tell me there is something different about these two books.
Lucas, with his reworking of the first three Star Wars movies, would have either new features (the new crowd scenes at the end of The Return of the Jedi) or breaking changes (Greedo shooting first). An example of a patch is redoing the unintended transparency of the X-Wing dash during the fight scenes or reworking the undercarriage of the hover car in the desert (Vaseline verses CGI).
I want to know those changes so when I look at a copy and notice that only the last number changed, it just means there were some typo fixes. If the first, then I start to ask questions, why?
This is also important because some authors will rewrite their books after publication. I also use it when sending books out to alpha and beta readers. Since I get the responses in a semi-random order, it is easier to know that I'm getting feedback from version 0.4.0 instead of 0.5.0. With Git, I can create a branch, manually handle the edits, and then pull them back into the master branch which will then help me consolidate changes between two versions.
Figuring out what goes where (major, minor, or patch) can be a rough.
In Sand and Blood, I'm on version 3.1.0. I switched to version 2.0.0 when I made the book Creative Commons. A license change (from "All Rights Reserved") felt like a breaking change. I bumped to 3.0.0 when I realized there was a major plot hole about how the clans dealt with the dead (they don't talk about it), so I removed some conversations because I had a better understanding of the world after Sand and Ash.
There is an important part about version numbers: why. Knowing that someone bought version 1.1.2 of a book and now I'm on 3.1.0 would beg the question: what major changes have happened.
That is where the change log comes in. I'm still working on the format, but I try to document every version of the book, from major to minor to patch. That way, someone can look at the versions and decide for themselves if they want a copy (or to ask for a replacement, which I've done also).
Of course, the problem with change logs is that they require some effort to maintain. Over the last year, I stumbled on the concept of a semantic-release. A semantic release is an extension of the version but it automates much of the processes that are involved with figuring out what type of number has to be bumped in the version and creating the appropriate log entries.
One of the goals is to be unromantic about version numbers. I'll admit, I've been romantic about the versions up to this point, but there is something about the systems approach to versions that takes the human factor out and reduces the amount of work.
Basically, semantic-release is a workflow for NPM packages (and novels in my case) that automates the calculations of verison numbers and also updates the change. It has plugins for publishing that I could use to update my website with the latest versions whenever I make a minor change.
It also means that the versions are much smaller. Instead of having 5-10 items in a release, there is probably just one change between versions.
Since I work with Git, there is one component that needs to be done to make semantic-release: conventions. In specific, I use conventional commits which is a standards to identify if something is a minor (a "feature") or a patch ("fix"). These are done by a convention of the commit messages:
- feat: integrated edits from Marta B
- fix: fixed a typo with Rutejimo's missing accent
- ci: trying to get it to build on GitLab
The semantic-release package parses the commit messages (in specific, the Angular conventions) and figures out if it should be releases (any "BREAKING CHANGES", "feat:", or "fix:" that it sees). Other commits don't bump up the version but still give me the ability to make changes.
I like the structure of using conventional commits and having it automatically feed into new version numbers and creating the change log. Later, it can be used to automate my website and maybe even publish books on various vendors.
This automation is also important for authors published by the various Typewriter Press imprints. All of them have access to their source files in GitLab. They can make changes without me approving of them. If they follow the same conventions, then it will bump up to the versions for their corrections without me tracking them or asking what changed. In that way, it allows non-technical writers to also participate in this process; all without getting overwhelmed by the technical details while still not requiring them to keep track of changes.
Since the version number is pulled into the legal page, it also means that I can easily manage alpha and beta readers, different rounds of editors, and even coordinate changes after giving out multiple copies at the same time (my alpha and beta readers are concurrent).
Much of these concepts also apply to my tools, so I also switched all of MfGames Writing tools to use semantic-release and automate the deployment. Like writing, it lets me focus on what I want to do (write) and automate the tedious stuff (release management).