I am building a system for tracking the lifecycle of it systems. It must be possible to lookup every old version of a system.
The version-system must be able to handle following use-cases:
UC1: The User wants the current version of a system identified by it's hostname
UC2: The User wants the current Version and every future Version
UC3: The User wants the whole lifecycle of a System identified by it's hostname
In our company it is possible that two systems share the same hostname, but than one is old and not running anymore.
When changes are made than there are two possible actions: the system is changing, maybe more diskspace or it is shut down, than we need a new version. Otherwise, if there is incorrect data in a version, than the user is able to correct this version and doesn't get a new version.
In the current model there is a combined primary key of guid and version, in some of the cases this is very useful because there will be ralations where the version matters and there will be somme where the version doesn't matter.
I've read about a model which works like a block-chain, so a new version has a parent ID of his privious version. But I think it is expensive if you have a relation to an old version and want to load the newest version.
On the other hand it could be possible that we have to insert a version between other versions, e.g. we have a shutdown version in 6 month and before that we need more disk space.
I'm totally unsure how the versioning could be possible without slowing down the database.
Related
My company is developing a system for 10 years. This system has 15 subsystems that are almost independent (they may use same libraries or packages or DBs), and these subsystems are building locally in separate teams, also a main simple system is developed to read subsystem configs and build a page with menu and submenu from configs(with shortcuts). Our company's product is the exe of this main system.
Unfortunately, we do not use a standard version numbers in our company. Now, we decided to force a standard in company, and I found Semantic Versioning a satisfactory standard, but I have some questions in our case:
How would the changes on subsystem version increase the main system version? Often, after even Major changes in a subsystem, the code of main system remains unaffected. I think changes in the main system should shape the version number of that system, but in this case it does not make sense. Is there any solution for versioning of large applications that consist of multiple subsystems?
You gave a link to MAJOR.MINOR.PATCH, and increment the
MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner,
PATCH version when you make backwards-compatible bug fixes
Any change in a subsystem might make the main system incompatable: Too much to keep track of.
Each subsystem should use their own version. In the main system you should have an overview of the dependencies and the own versioning.
You can manage this in different ways. One way would be using Maven and pom.xml files. Another way would be using a config file with the different versions.
Each team can develop their own code independent and assign Semantic versions.
Maybe some day you will put the shared libraries, packages and DBs in a repository and all teams can refer to them with their own pom.xml.
You are flexible this way. You might even want to make a second main system (for top clients or for free accounts?) and can change the pom.xml including/excluding subsystems. The second main system will have its own versioning.
From the SemVer FAQ:
What should I do if I update my own dependencies without changing the public API?
That would be considered compatible since it does not affect the public API. Software that explicitly depends on the same dependencies as your package should have their own dependency specifications and the author will notice any conflicts. Determining whether the change is a patch level or minor level modification depends on whether you updated your dependencies in order to fix a bug or introduce new functionality. I would usually expect additional code for the latter instance, in which case it's obviously a minor level increment.
I would apply this to your scenario as follows: If your main application takes upgrades of its dependent subsystems without having to make major changes in itself, it should increase either the minor or the patch version. You shouldn't need to increment the major version, as its own public API is still considered compatible.
If the main application makes use of new features added to the subsystems, it should be a minor version increase.
Otherwise, it should be a patch version increase.
I think you're on the right track for this - literally treat everything with a SemVer version as it's own thing.
If you need to rebuild an updated linked dependency then at the least it'd be a patch version update - if they're simply soft links (ie, someone can update the subsystem without rebuilding or needing fixes) then it's purely a case of wanting a version number of when it was changed.
Keeping to the SemVer idea, if things cause incompatible changes then pulling the highest change out could make sense. Ie - updating 5 subsystems at the same time, 4 are patch updates, and one a minor - you'd update the minor version of the main system only (and put them all into that single change). Same with major changes etc.
The other similar idea is to drop the changes slightly if the main build is purely an interface on top - any minor or patch changes would only cause a minor on it, and any major subsystem changes would cause a minor - that way you can keep the major for breaking front end changes etc.
Something to bear in mind is that you don't have to follow SemVer perfectly - consistency is the key for something like this - so you could update the patch level for when subsystem changes are merged in, and never reset it, while updating the minor and major versions only for the main system. (There are a couple of open source projects that work this way, I just can't remember which ones off the top of my head).
Not sure if it's any use, but you could look at some of the nodejs packages around and how they update their versions with differing dependency versions - they all include a list of what they use in a package.json file with the version listed in a certain format (ie, exactly x.y.z or >x.y.z etc - https://docs.npmjs.com/files/package.json#dependencies)
We are building a webapp which is shipped to several client as a debian package. Each client runs his own server. But the update and support is done by us.
We make regular releases of the product, with a clean version number. Most of the users get an automatic update (by Puppet), some others don't.
We want to keep a trace of the version of the application (in order to allow the user to check the version in an "about" section, and for our support to help the user more accurately).
We plan to store the version of the code and the version of the base in our database, and to keep the info up to date automatically.
Is that a good idea ?
The other alternative we see is a file.
EDIT : The code and database schema are updated together. ( if we update to version x.y.z , both code and database go to x.y.z )
Using a table to track every change to a schema as described in this post is a good practice that I'd definitely suggest to follow.
For the application, if it is shipped independently of the database (which is not clear to me), I'd embed a file in the package (and thus not use the database to store the version of the web application).
If not and thus if both the application and the database versions are maintained in sync, then I'd just use the information stored in the database.
As a general rule, I would have both, DB version and application version. The problem here is how "private" is the database. If the database is "private" to the application, and user never modifies the schema then your initial solution is fine. In my experience, databases which accumulate several years of data stop being private, it means that users add a table or two and access data using some reporting tool; from that point on the database is not exclusively used by the application any more.
UPDATE
One more thing to consider is users (application) not being able to connect to the DB and calling for support. For this case it would be better to have version, etc.. stored on file system.
Assuming there are no compelling reasons to go with one approach or the other, I think I'd go with keeping them in the database.
I'd put them in both places. Then when running your about function you quickly check that they are both the same, and if they aren't you can display extra information about the version mismatch. If they're the same then you will only need to display one of them.
I've generally found users can do "clever" things like revert databases back to old versions by manually copying directories around "because they can" so defensively dealing with it is always a good idea.
WARNING: LONG QUESTION.
[QUESTION]
If the strategy is to have a branch per database, as described in the problem below, where scripts are version controlled.
How do you manage the data migration issues when trying to consolidate to fewer branches?
Is it just a cost you incur as part of data migration?
Essentially transform scripts will have to be created at the time of migration.
Is there a better way?
Can we have both issues resolved at the same time?
What is the best practice?
[BACKGROUND]
At my work place we have a product which has 3 branches. Mainline having the "LATEST AND GREATEST" changes which is not necessary ready for release.
Version B (names have been changed to protect the guilty)
Version A (names have been changed to protect the guilty)
Mainline
Because of these branches there is effectively 3 versions of the database.
Code version control is fairly easy however database version control seems difficult.
Having read Do you use source control for your database items?
it seems the best way is to export all the create scripts for each object/table.
NOTE: How you manage it, in one big script or multiple scripts or a hybrid, is your preference according to the article.
I agree with this and have inquired as to why it's not done.
Currently the DBAs refuse to branch the scripts into branches.
Aside from laziness as an excuse the reason is to save time with data migration.
Effectively the database changes are forcibly maintained across all versions.
All the scripts are version controlled and maintain only in mainline.
Version A and Version B have their own special file that states which change scripts to run on their respective branch. The problem arises when there is a change script, for instance applied to Version A but Version B only requires part of the changes. It is up to the developer to inform the DBAs to update the file which indicates which patches to apply for each branch. For change scripts which does too much manual intervention is needed to manually apply part of the change script.
To update a database on Version A all patches are extracted with Version A's which patch to apply file.
[SCENARIO]
The 3 versions above exist.
Database changes occur to Version A.
Branch consolidation where the code is merged from Version B to A so that Version B can be removed.
The same needs to happen with the database.
Hope this makes sense.
Take a look at Chapter 8 in Eric Sink's Source Control HOW TO. It's a great resource for understanding the ins and outs of source control.
We currently have many office products and a embedded product. They all have the same version scheme major.minor.build number.svn revision. With nightly and manual builds incrementing the build number.
From a development support front this makes it really easy to manage 'correct version', but the in-field support guys panic when one tool changes from v10 to v200 and we say there's no changes.
Are there any problems with this scheme (all in sync) that we are missing due to our love for it?
Update:
It's the build number that is increasing by leaps, the major minor are only changed on a yearly type scale.
the svn revision is the same for all files at time x, but the nobody really pays that attention.
All .exe's and .dll's etc have the same X.Y.W.Z number. So the office product go from 1.1.10.1234 to 1.1.132.4321 when we do lots of work on the embedded product.
I wouldn't really say this is an issue as long as they can easily look up the change log to see whats changed.
Logically thinking though, if no libraries have been updated in any of the products, nor have there been any changes to the product itself the version number should stay the same.
The only suggestion I could make is moving to a dated version number so that the major and minor versions don't change so rapidly. Something like 9.0417.yyyy.xxxx would be the 17th of April 2009 release with the build number of yyyy and xxxx as the svn revision. If you don't want to change the major number and want to keep the date in the minor you could use Microsoft's versioning style. There's a good blog article on how Microsoft do their versioning at http://blogs.msdn.com/jensenh/archive/2005/11/11/491779.aspx.
I've used an aggregate versioning scheme. So you say you have many products that each share the same revision number if the deployed field versions - I'm assuming this means if you update your embedded libraries, that the office products do not use the libraries for, the office products still get a new revision number, even though no code has changed in them.
So in an aggregate scheme, the SYSTEM has one big version number, and each sub system has their own. I'm using clearcase notation because I don't know the terminology for the equivelant in svn: The top level component has all sub components under it in a hiearchy (think of a component is like a folder with code in it such that everything in that folder shared the same version, or "baseline", as clearcase calls it).
If I make a new baseline (version) in a top level system component, it tags it with the new version, and all sub components get a new version also (possibly with a different versioning scheme), but only if they've changed.
We use a date-time baseline, and a "release number", for the top level system version. Then, each sub system has the major/minor/build/svn in it. Also, we don't show the svn and build number in the "about->help" or equivelant, only if you go deep into some "system config" file can you pull out the actual build/svn number (like, by looking at the meta data in the executble). That way, users only see major/minor version, and not the gobbledigook of build and svn numbers.
I have been struggling with versioning software for a while now.
I'm not talking about a naming convention, I'm talking about how to actually apply a version in a build system all the way through to a release.
I generally use major.minor.maintenance-[release type]
i.e. 1.0.2-rc1
The problem is managing the version number. I've tried many ways (sticking it in a build file, a properties file, a database, etc,etc) but I haven't found anything that really works well.
The closest thing I came up with is using Jira which I documented here:
http://blog.sysbliss.com/uncategorized/release-management-with-atlassian-bamboo-and-jira.html
I'm wondering if anyone has any good ideas about this.
Also, wondering how people handle releasing a version.... i.e. If I release/deploy version 1.0.0-rc1 do bugs found in this release then get logged into 1.0.0 (the next/production release).
Microsoft uses <major>.<minor>.<patch>-<build number> (or a variation).
I like using <major>.<minor>.<buildnumber>
Where I'm working we use the Maven system: artifact[-major-minor-revision][-SNAPSHOT] which allows us to develop "in progress" versions that change at a moments notice (SNAPSHOT) and those which have been formally released. Some examples are:
email-services-1.0.0-SNAPSHOT.jar
email-web-2.3.11.war
crm-2.5.0.ear
If it has SNAPSHOT in it then it hasn't passed the full suite of tests or is just a developer experiment. If it doesn't have SNAPSHOT then it is a release candidate. We maintain a repository of release candidates and the most recent is sent for deployment once the testers are happy with it.
All of this can be managed with a few simple entries in a build file under Maven. See Maven2 tutorial
This is probably a dead post now, but I'll add my two cents anyways. I'm of the opinion that build numbers should mean something to everyone who sees it. So I personally think that this is a good way to name versions:
major.minor.patch.revision - e.g. 1.1.4.2342
Major/minor numbers are pretty self-explanatory. But from the perspective of the 3rd number, it still needs to mean something to the customer. I've released this new version to you, Mr. Customer, but it wasn't worth a new minor number since we just fixed some bugs. So we've incremented the patch number.
The 4th number usually means absolutely NOTHING to the customer, so you might as well make it useful to you and anyone else in your company that sees it. So for us, that number is the SVN revision number. It tells us exactly which revision was responsible for that version so that we can pull it out any any time to recreate it. Branching code obviously achieves this too, but not to 100% certainty.
Also, another advantage with an all-numeric version number is that it easily integrates into nearly every continuous build system.
Anyways, that's my two cents.
+1 on the Jira/Bamboo solution. The only additional information about the build I would include (for my purposes) is the Subversion Release, although the Tagging operation is 80% of what I want.
Manually maintaining the release/version information is a royal pain. Letting JIRA drive it is a great idea.
On the final question, about where bugs/defects get logged and releasing a version:
Defect/Issue is logged against the release where it appears. A defect in 1.0.0-rc1 gets logged against 1.0.0-rc1
JIRA has (or maybe we added) a 'Fix-For' field that would have the planned release, in this case 1.0.0
If the defect/issue is severe enough, it may be necessary to add another 'rc' release.
The release is made when there are no outstanding critical defects/issues and the customer (or management) agrees that any remaining issues can be deferred
The beauty of managing this through JIRA is that adding releases, generating change-logs, etc. is automated fairly well.
We also use <major>.<minor>.<buildnumber> and we manage this with CruiseControl/(.Net) on our build server. And use Wix and CruiseControl Config to manage the Major minor numbers - still increment those by hand - but the build number happens automatically when on the build server. You could set up a rule an increment the major/minor automatically too I believe - we just have like to do that manually so that it takes concious thinking by a dev when it is time to name a particular release level.
Major.Minor.BuildDateNumber.DailyBuildNumber
Major and Minor are set by us, manually incrementing them as we see fit.
BuildDateNumber is the number of months since the project start multiplied by 100, plus the day number of the current month.
DailyBuildNumber is incremented for every build after midnight each day, starting at zero.
E.g. 4th build of release 5.2 on 10 July, where the project started 1 Jan that year, would have version number
5.2.710.3
This is all calculated for us by the Version task in Nant.
This keeps the version numbers unique and also allows us to quickly calculate when an installation was built.