How to handle project versioning for pre production? - version

My team and I have been working on a project that is due to release early next year. A burning question that has been plaguing us is how to handle preproduction releases. For example, we have dev and staging environments that we deploy to semi-regularly so management and QA can take a peek at the progress of our project.
Since we have a few separate systems, we're trying to sync and schedule releases between systems so things operate smoothly. In production, we'd take a versioning approach to this, but we aren't at that stage yet.
How do teams handle pre-production releases? My first instinct was to just utilize semver but avoid any major bumps (e.g 1.X.X would be the production release)
Any opinions or advice on this is highly appreciated

You may use SemVer technique appended with a "snapshot" followed by a timestamp. For example if the pilot version in production is 1.0.0 the pre production version can be 1.0.0-SNAPSHOT+'TIMESTAMP'. Where TIMESTAMP="The time whenever the package was generated". In this way the developer(s) will be aware of the feature that was deployed in the staging environment(s).
Let me know if this answers your question.

TLDR
Keep using 0.y.z while in development phase (and your API is not in prod), worry about it when in Production
Long Story
If you DO want to follow semver:
Btw, the answer is based on https://semver.org/:
SemVer 2.0 is designed as set of rules to clearly communicate the nature of the changes contained in your new release.
X.Y.Z
X - changes here represent no backward compatibility
Y - backward compatible new features
Z - backward compatible bugfixes
But it also says on item 4:
"4. Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable."
You may mark your version with a pre-release tag after the version, as suggested by Rohit, (you may, but you don't have to). The full spec could be:
<version core>"-"<pre-release>"+"<build>
Where:
<version core>: X.Y.Z (as stated before)
<pre-release>: your pre-release tag (check semver site for details on what it should contain)
<build>: build identifier
The spec also gives you some hints on how to deal with versioning during development phase in the FAQ:
How should I deal with revisions in the 0.y.z initial development phase?
The simplest thing to do is start your initial development release at 0.1.0 and then increment the minor version for each subsequent release.
"How do I know when to release 1.0.0?If your software is being used
in production, it should probably already be 1.0.0. If you have a
stable API on which users have come to depend, you should be 1.0.0. If
you’re worrying a lot about backwards compatibility, you should
probably already be 1.0.0."
Doesn’t this discourage rapid development and fast iteration? Major
version zero is all about rapid development. If you’re changing the
API every day you should either still be in version 0.y.z or on a
separate development branch working on the next major version.
This basically says that you can stay on 0.y.z if you don't have heavy dependency on your API. If your clients treat your API as their "production" or "production ready", maybe you should move to 1.0.0 and follow the rules.
The moment you go to production you should be already on 1.0.0

Related

Using semver, should pre-release versions be based off the previous version number, or the next version number?

Doing a pseudo-CD strategy for dev environments and we want to make sure all interim builds are tagged and versioned in a way that provides traceability but also conforms to semver so that helm etc doesn't yell at us and also I can sleep at night knowing I've bikeshedded correctly. I was thinking about the semantics of semver and how intra-release builds/versions might be tagged.
Assuming our process doesn't provide sufficient reliability for a "look-ahead" version (e.g. I don't know if our next release is going to be a major, minor, or patch increment), what would the best practice be for applying versions to builds between releases.
e.g.
Given last release of 1.2.3
Given a timestamp postfix for build metadata (e.g. a build might be called {version}-1668519441 )
Given that I don't know if the next official release is going to be 2.0.0, 1.3.0, or 1.2.4
Do I:
Apply the build number to the previous versionto generate the build version? 1.2.3-1668519441
this feels kinda yucky because technically it's the build of the next alpha version, not a build of the previous release version
Apply the build number to my best guess next version to generate the build version? 1.3.0-alpha-1668519441
this feels better, but we get burned if we guess wrong
simply weep, because the answer is "there's no one right answer" and now I have to make my own decisions?
;-;
Reasonable smart will be "modified 1" (because "internal builds" are just builds, for which we have to have "some id", which must just allow internal
identification of it and nothing more):
with something like git describe HEAD you'll get 1.2.3--14-g2414721, 1.2.3-21-g975b, 1.2.3-25-g2dc6 etc and any of these builds later according to (existing, I hope) Release Policy may become 1.2.4, 1.3.x or even 2.x.x (see idea of conventional commits and versioning of releases based on it), "just because..."
Answer 3 is daring and unequivocal version, but it's bad, because it does not answer the question and does not give at least a mediocre solution to the problem, but it's bad, because it does not answer the question and does not give at least a mediocre solution to the problem

Release life cycle and version numbers

I'm working on a lot of small utility scripts for users in my office, and I want to develop a release cycle/version number system to use when testing and distributing these tools to users. I'm not sure what the relationship should be between release cycles stages (alpha, beta, release candidate) and version numbers (1.0.1, 1.1.0, 1.2.1 etc).
Say I release version 0.1.0 of a tool. I call it 0.1.0-beta and give it to some users to test. They don't find any problems, so I don't need to make any changes to the code. Do I then just say that 0.1.0 is no longer a beta release, or do I make a new version number?
According to Semantic Versioning 2.0.0-rc.1 (see that version number there) the short answer is you would simply name the released version 0.1.0 which would be considered greater than 0.1.0-beta.
The full nitty gritty is here: http://semver.org
I cannot comment on personal experience with using this approach but it seems reasonably thought through, and there's a discussion relating to it over on its github issues page: https://github.com/mojombo/semver/issues

does appengine have a pointer to the latest deployed application

I want to test my thick client against my RESTful appengine application. I regularly increment the appengine version number so I need to keep updating my test config. Is there the equivalent of http://latest.application.appspot.com that I could point my config too?
Thanks
Skirting around your question, but in my head, I've stopped thinking of the "version" in the typical software release version (which like you, I started out thinking), but rather, it's "a different application using the same datastore".
I found out the software release version (1.0, 1.1, 1.2 etc) doesn't make much sense because 1) I don't tend to use older versions 2) my main usage would be to regression test, but this doesn't work well, because it's quite possible for a change in your model in v1.1 to break the code in v1.0.
The versions feature comes in hand to have different functional versions. For example, maybe the default application.appspot.com runs production level code, but debug.application.appspot.com has more logging enabled. Perhaps a third version has administrator functionality enabled, etc.
No, there's no way to do this. Versions aren't sequenced - they're all entirely distinct deploys, only one of which is set as the default.
What you are likely looking for is the CURRENT_VERSION_ID environment variable. It stores the deployment revision as dot-separated string: version_name.deployment_revision, e.g. staging.12345678910111213141516. You could just use it directly in your config:
import os
API_VERSION = os.environ['CURRENT_VERSION_ID'].split('.')[1]

Delivering hot fixes using Flyway

Let's consider the What is the best strategy for dealing with hot fixes? question from the Flyway FAQ section. In this question:
Application version 7 (and DB version 7) is deployed in production
Work starts on app version 8
DB version 8 is developed and deployed in the acceptance test environment
Bug is identified in production
DB version 7.1 is developed and must be acceptance-tested
When flyway:migrate will be invoked against the acceptance test environment, it will notice that v8 has already been executed and so that there is no need to execute v7.1.
On one side it makes sense since v7.1 might not be compatible with v8, and it is not up to Flyway to analyze this. Fail-fast is entirely understandable.
On the other side, the only way to deploy v7.1 to the acceptance test environment is to clean the database and run flyway:migrate with target = v7.1, thereby discarding data that might have had its use.
Is there a feature I'm not aware of that handles this case or is clean + migrate.target=v7.1 the only option?
More than a different feature, it's about a different process.
If you do wish to keep your data in your acceptance environment, I would recommend shipping v8 of the database with the hotfix and the actual change can then be v8.1. The features of the v8 schema might remain unused until the corresponding code gets deployed. In most cases however, this causes no harm.

How to do version numbers? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
My company is building a product. It's going to be versioned by SVN. It's a webapp so basically there will never be a version out which doesn't have some features in them and thus could always be labeled as beta. But since it's going to be a corporate product I really don't want the "unstable watchout" on there. So how would you go about versioning? Is 1.0 stable? Should the build date be in the version number? Tell me what you guys think!
[major].[minor].[release].[build]
major: Really a marketing decision. Are you ready to call the version 1.0? Does the company consider this a major version for which customers might have to pay more, or is it an update of the current major version which may be free? Less of an R&D decision and more a product decision.
minor: Starts from 0 whenever major is incremented. +1 for every version that goes public.
release: Every time you hit a development milestone and release the product, even internally (e.g. to QA), increment this. This is especially important for communication between teams in the organization. Needless to say, never release the same 'release' twice (even internally). Reset to 0 upon minor++ or major++.
build: Can be a SVN revision, I find that works best.
Examples
My current chrome: 83.0.4103.61
x.y.z.g
increments in g are unstable. (or RCs)
increments in z are stable and mean bug fixes.
increments in y are stable and mean new features.
increments in x are stable, major release without 100% backward compatibility.
I once wrote an elaborate "versioning style guide" for a large project of mine. The project failed to materialize, but the style guide is still available online. It's my personal opinion, perhaps it is helpful (or inspirational) to you.
Beware, it's a long text, and goes into component versioning vs. product versioning and stuff like that. It also expresses strong opinions on some versioning schemes popular in the OSS community, but I have them, so I express them. ;-)
I disagree with using the Subversion revision number, for example. You might want to maintain a released version while continuing development in TRUNK, so you'll set up a maintenance branch - and your revision number versioning goes down the drain.
Edit: As a summary, it distinguishes between versioning source files, components, and the overall product. It uses a system of seperate x.y versoning for components and the product, with a nice interdependency between the two that makes tracing which component version belongs to which product version trivial. It also talks about how to handle alpha / beta / release / patch cycles without breaking the system. Actually, it's a modus operandi for the whole development cycle, so you might want to cherry-pick. ;-)
Edit 2: As enough people found my article useful to make this a "Nice Answer", I started working on the article again. PDF and LaTeX versions are now available, a complete rewrite including better language and explanatory graphics will follow as soon as I can find the time. Thank you for your votes!
Get yourself some inspiration from Wikipedia: "Software versioning"
Another "new" and "relatively popular" option is Semantic Versioning
Summary:
Given a version number MAJOR.MINOR.PATCH, increment the:
MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner, and
PATCH version when you make backwards-compatible bug fixes.
Additional labels for pre-release and build metadata are available as
extensions to the MAJOR.MINOR.PATCH format.
a.b.c.d
Increments : when
- d: bug fixes
- c: maintenance, e.g. performance improvement
- b: new features
- a: architecture change
The mandatory is the most left one e.g. if there are for example a new feature and a bug fixed then you only have to increment b.
Based on my experience with complex enterprise platform level dependency management and release versioning I've come to recommend an approach I like to call Semi-Semantic Versioning.
Basically it builds off of Semantic Versioning 2.0 but is not quite as strict.
Semi-Semantic Version Segments:
<primary.release.segment>[-<pre.release.segment>][+<post.release.segment>]
Primary Release Segment Format:
MARKETTING.MAJOR.MINOR.PATCH
Each segment should allow alphanumerics, but pure numerics are recommended for logical incremental changes.
Like SemVer, I recommend Major, Minor, and Patch components to represent reverse compatibility tiers, but I also recommend prepending a Marketing component. This allows product owners, feature epics/groups, and business concerns to bump the primary component independent of technical compatibility concerns.
Unlike other answers, I don't recommended appending a Build number to the primary segment. Instead, add a Post-Release Segment following a '+' (ex: 1.1.0.0+build.42). SemVer calls this build metadata, but I think Post-Release Segment is clearer. This segment is great for declaring the suffix data as not related to the compatibility info in the primary Release Segment. Your continuous integration builds can then be given the previous release number appended with an incremental build number that resets after each primary release (ex: 1.1.0.0 -> 1.1.0.0+build.1 -> 1.1.0.0+build.2 -> 1.1.0.1 ). Some people alternately like to put the svn revision number here or the git commit sha to make it easy to tie to the code repository. Another option is to use the post-release segment for hotfixes and patches, tho it might be worth considering adding a new primary release component for that. It can always get dropped when the patch component is incremented, since the versions are effectively left-aligned and sorted.
In addition to the release and post-release segments, people often want to use a Pre-Release Segment to indicate almost-stable pre-releases like alphas, betas and release candidates. The SemVer approach to this works well, but I recommend separating numerical components from alpha-numeric classifiers (ex: 1.2.0.0+alpha.2 or 1.2.0.0+RC.2). Normally you would bump the release segment at the same time as adding the post-release segment and then drop the pre-release segment when you next bump them primary release segment (ex: 1.0.1.2 -> 1.2.0.0-RC.1 -> 1.2.0.0). Pre-release segments get added to indicate that the release version is coming up, usually just a fixed set of features for more in-depth testing and sharing that doesn't change minute to minute based on more commits.
The beauty of having all of this semantically defined in a way that covers almost all use-cases is that you can parse, sort, compare and increment them in a standard way. This is especially important when using CI systems for complex applications with lots of small independently versioned components (like micro-services) each with their own managed dependencies.
If you're interested, I wrote a semi-semantic parser in ruby. I needed to not just use this pattern but be able to manage other apps that used it.
"Version numbers" are a matter for your internal version control system. Release numbers are a different matter (and should be KEPT different).
Stick to a simple MAJOR.MINOR release system (like v1.27), where MAJOR is the compatibility level (version 2.x is incompatible with or at least majorly different from version 1.x) and MINOR is your bugfix releases or minor enhancements. As long as you follow the X.Y format, you can also use other systems like YEAR.MONTH (2009.12) or YEAR.RELEASE (2009.3). But really you're probably best sticking to MAJOR.MINOR unless you have a good reason not to.
Definitely don't use anything that doesn't fit the X.Y format, as it'll make it tough for distros, announcement websites, etc. to work with you, and that alone could seriously affect your project's popularity.
Use branches and tags in your (preferably distributed) version control system to mark specific internal version numbers as relating to MAJORS and MINORS respectively.
And yes, 1.0 should be stable. All releases should be stable, unless they're marked alpha, beta, or RC. Use Alphas for known-broken-and-incomplete. Betas for known-broken. RCs for "try it; you'll probably spot things we missed". Anything without one of these should (ideally, of course) be tested, known good, have an up to date manual, etc.
Version scheme: [major].[minor].[devrel][mark]
[major]: increment if you have a drastic change in development.
[minor]: increment if you have a minor change in development.
[devrel]: increment if you have a bug fix. Reset to zero if major++ or minor++.
[mark]: a, b or rc: a is an alpha release, b is beta release, and rc is a release candidate. Note that versions like 1.3.57a or 1.3.57b or 1.3.57rc is before the version 1.3.57. Start at 0.0.0.
It's pretty popular these days to just use the Subversion revision number.
If it's in SVN then why not use the SVN revision number?
If you look at the bottom right of this web page you'll see the Stack Overflow version number which is the SVN revision number.
Versioning is up to you; I'd put 1.0 on the first version I was confident in. You may want to follow it up quickly with other versions, since some software vendors have given 1.0 a bad reputation.
You do want some way of tying the version number to the exact build used, but you probably want it to be nice and simple for your end users. Consider using standard version numbers, and tagging the SVN repository with the version number included.
While just going with the Subversion revision number is nice and simple, it does remove information from the version number. Users might consider this a bad thing.
I assume that your webapp will have some kind of deployment procedure, so that not each revision in Subversion is actually published. Since it is impossible from the "outside" (from the user's perspective) to determine when releases are being made, and how many revisions the code will undergo between them, it makes the numbers almost random. They will be increasing, and I guess it's possible to surmise some kind of distance from comparing two revisions, but not much.
Classical version numbers tend to "dramatize" releases, so that users can build some kind of expectation. It is easier to think "I have version 1.0, now version 1.1 is out adding this and that, that sounds interesting" than to think "yesterday we ran SO revision 2587, today it's 3233, it must be lots better!".
Of course, this dramatization can be inflated too, with companies picking version numbers that are meant to sound more interesting than is motivated by the actual differences in the product, I guess going with the revision number counters this a bit.
We've spent way too much time deciding when to increment the major version. Some shops would rarely do it so you would have releases like 1.25.3 and others would do it for ever release giving you 15.0
I got fed up with that and convinced everyone the major release number is just the year and the minor is just a sequential release within the year. The users seemed to like it and it's a no-brainer to come-up with the next version number.
Year.Release.build
year = current year
release = sequence # of public releases with
new functionality - reset to 1 every
year
build = incremented for bug
fixes and internal releases
EDIT
** Now this was for an internal app that was continually enhanced **
This would probably not work for commercial apps where it's important to have major releases at different times of the year for marketing and financial purposes.
The reason why this question exists is because we don't have a single agreed upon way to do configuration management.
The way I like to do version number is just increment integer from 1. I don't want a multi part version number that I will have to explain or document. And I don't want to use SVN rev number as that will require some explaining as well.
You would need some release scripts on top of SVN to make this happen
I have very little experience in the area. However, here's what I'd do:
Choose a scheme for numbering revisions and stick to it. Be consistent.
Each version change should represent a significant change. How small a change is significant and the levels of change that are reflected in the version number are up to you.
Of course, you can just use the svn revision number --- like many others have suggested!!!
I hope this helps.
We use a simple major.minor.julian_date syntax.
Where;
major - First release is 1 and then when we introduce major new features or changes so significant they are not backwards compatible increase this number.
minor - The major milestone releases. For each build pushed by production this number increases.
julian_date - The Julian Day the build was pushed to QA.
Example of the first release pushed to QA on 1/15 is -> 1.0.015
Example of the first release pushed to Production on 3/4 is -> 1.1.063
It's not perfect, but handy as we push builds to QA near daily.
Some good info here:
When to Change File/Assembly Versions
First of all, file versions and assembly versions need not coincide with each other. I recommend that file versions change with each build. But, don’t change assembly versions with each build just so that you can tell the difference between two versions of the same file; use the file version for that. Deciding when to change assembly versions takes some discussion of the types of builds to consider: shipping and non-shipping.
Non-Shipping Builds
In general, I recommend keeping non-shipping assembly versions the same between shipping builds. This avoids strongly-named assembly loading problems due to version mismatches. Some people prefer using publisher policy to redirect new assembly versions for each build. I recommend against that for non-shipping builds, however: it doesn’t avoid all of the loading problems. For example, if a partner x-copies your app, they may not know to install publisher policy. Then, your app will be broken for them, even though it works just fine on your machine.
But, if there are cases where different applications on the same machine need to bind to different versions of your assembly, I recommend giving those builds different assembly versions so that the correct one for each app can be used without having to use LoadFrom/etc.
Shipping Builds
As for whether it’s a good idea to change that version for shipping builds, it depends on how you want the binding to work for end-users. Do you want these builds to be side-by-side or in-place? Are there many changes between the two builds? Are they going to break some customers? Do you care that it breaks them (or do you want to force users to use your important updates)? If yes, you should consider incrementing the assembly version. But, then again, consider that doing that too many times can litter the user’s disk with outdated assemblies.
When You Change Your Assembly Versions
To change hardcoded versions to the new one, I recommend setting a variable to the version in a header file and replacing the hardcoding in sources with the variable. Then, run a pre-processor during the build to put in the correct version. I recommend changing versions right after shipping, not right before, so that there's more time to catch bugs due to the change.
Or to use your 'thought' version number comma subversion number..
z.B.:
1.0.101 // revision 101, release
or 1.0.101-090303 // with release date, i use this

Resources