Is semantic versioning strictly followed by libraries published at Maven Central? - versioning

The recommended version strategy in Maven Central Repository is Semantic Versioning 2.0.0, which is pretty strict about how a major version should be affected on any incompatible change (using MUST from RFC 2119 regarding this requirement).
Let's say any method signature is changed, thus a library major version must be updated. That may be happening relatively frequent in libraries that are under development.
That makes me wonder is it actually true for the libraries published in Maven Central, or such a recommendation is not strictly followed?

SemVer is all about developers conveying the level of effort or risk involved in taking one of their updates. If you make any breaking change and fail to bump the Major version number, you are not following Semantic Versioning 2.0.0 and therefore not following the recommendations of the Maven Central Repository.
It's all about your reputation. Forced re-compiles or cascading upgrades, broken systems that wouldn't have been broken if you followed the rules, these are apparent behaviors that mark a developer's products for replacement. Given the quality of the code floating around out there, I'd say that not following the standards is common enough, but probably not beneficial to anyone, including the lazy bums that fail to meet even the most minimal standards.

No, semantic versioning doesn't seem to be followed rigorously.
The analysis done in a research Semantic versioning versus breaking changes: A study of the Maven Repository concludes:
The introduction of breaking changes is widespread: Around one third
of all releases introduce at least one breaking change.
While semantic versioning prescribes that breaking changes are only
permitted in major releases, we see little difference between these
two: One third of the major as well as one third of the minor releases
introduce at least one breaking change.
Moreover, according to the data provided in the article, in 23.8% cases at least one backward incompatible change introduced in on a patch version update.

Related

What does "pure upstream" mean?

I see the term "pure upstream" used a lot describing different software packages/distributions. I get that "upstream" in the context of open source refers to a code base from which a certain software package was forked. But what does it mean to say that a certain software package is "pure upstream"?
I think the “pure” part of "pure upstream" means that the codebase remains unencumbered with changes that are custom changes needed for a particular application use or environment which isn’t applicable to most users. Some projects may want to evolve to become more of a Swiss army knife of an application but some may decide to keep to a small coherent functional space. How purity rules apply is a judgement call for the maintainers of the upstream project.
An example of a non-pure fork could be a proprietary extension that could cause vendor lock-in. Take a look at this article about Kubernetes: https://technative.io/kubernetes-must-stay-pure-upstream-open-source/

LaunchDarkly: multi-platform feature flagging and branching questions

Looking at LaunchDarkly for feature flagging across our enterprise apps.
Two questions:
1) I'm concerned about being able to effectively flag features across our Java back end and React front ends (2 of them). What are some strategies that people use to define features appropriately so that they are easy to manage across multiple applications/platforms?
2) Have you replaced most/all of your git / Bitbucket / ?? branching workflow with feature flags and purely trunk - based development? If not, have you made significant changes to your existing git / Bitbucket branching strategy?
Disclamer: I work at DevCycle
I'm a few years late, but, I really wanted to make sure anyone finding their way to this question has a little more information.
1) While levlaz provided an answer explaining that you should put your management as far up the stack as possible, I don't necessarily agree that this is the best approach to consider first.
Consider this: A simple setup of a single feature across multiple platforms
Within DevCycle (and others), when you create a Feature, it is available across all platforms and the API.
You simply request the features for a user on any platform, and if the user qualifies, you'll receive it. There is no extra setup necessary to enable it on various platforms.
This means that if a feature is meant to be accessed on either your Java backend or React frontend, you can be guaranteed that the feature will be available at the correct times for the correct user/service regardless of where you call it from.
In short: one single Feature is managed across all platforms in one spot, with one toggle (if desired).
Another Approach: A single feature across multiple platform with different toggles or use cases.
You could very easily simply create multiple flags for each individual platform a feature is meant to be available on, and manage each individually. However, this isn't entirely necessary!
Within a feature setup, you can simply have two separate rules defining different variations being delivered to each platform. For example, you can set up a simple rule which ensures that Java will receive the feature, but React would not.
A unique DevCycle approach: Managing multiple platforms independently.
Here is something DevCycle offers that would may handle your use case in a unique way:
Imagine every single time you create a feature, both a Java and React version of that feature are created.
These platforms would be managed separately within each feature, meaning that there is no potential of any accidental feature data bleeding between platforms in event that a feature doesn't exist on one platform but it does on another.
You can set up each platform as an entirely separate entity, meaning they would use different SDK keys, and all targeting will always be separate.
In the example above for example, the feature would be entirely disabled and not available in any Java SDKs calling out to DevCycle, but it would be available in React.
tl;dr
It's up to you how you want to manage things across platforms. DevCycle makes it easy to do this however you'd like: have all features across all platforms, splitting up your platforms, or just choosing to target differently depending on the feature.
2) Like levlaz said, that is the ideal, but you'll likely never want to achieve fully trunk-based nirvana, as there are a lot of use cases for having various environments and paths for your team to take in various scenarios.
That said, we've seen a lot of folks successfully get REALLY close by using Feature Flags.
I wouldn't suggest removing your build pipelines and CI/CD in favor of feature flags, instead, feature flags enhance those.
For example, with feature flags, you can remove the concept of feature branches and large feature pull requests. Instead, ensure that everything that ever gets put into production is always behind a feature flag. To ensure this happens, you can use workflow tools like github actionsthat do these safety checks for you. With these guards in place, you should now always be able to simply push through to prod without any concerns and run your deploy scripts on each merge. Then you can just target your internal / QA users for testing, and not worry about things hitting prod users!
You may still want to have some sort of disaster recovery environment and local environments, so never truly hitting a pure trunk, but you can get close!
[Disclamer: I work at LaunchDarkly]
For your first question, my general recommendation is to put flags as "high up on the stack" as possible. At the end of the day, you are making a decision somewhere. Where you put that decision point is entirely up to you. Within LaunchDarkly the flags are agnostic to the implementation so a single flag can live on the server, mobile, and client-side without any issues. Keep things simple.
For your second question, in practice, it is very rare to see teams fully make the switch to trunk-based development. This is the goal of 99% of the teams that I work with but depending on if you have a greenfield or a brownfield project the complexity of making the switch can be not worth the effort.
Lastly, Our CTO wrote a book this year called "Effective Feature Management"[1]. If you have not heard of this, I would recommend you take a look. I think you'll find some great insights there.
https://launchdarkly.com/effective-feature-management-ebook/

Choosing best branching model for common framework based different applications development

I was reading many articles about version control systems like SVN, Git and various branching models (feature based, release based and others) but none of them did not seem to fit our project requirements.
We (team) are going to develop a framework, which will be used as core for different applications. So, there will be one framework and more than one different applications built on that framework. Each application will have usual project cycle: builds, releases... Framework itself won't be released but may have tagged different versions. During the development of application, we want to commit some common features to the framework (if we see that feature is great and future applications should have it).
So each application is like a separate branch of framework, but it will never be fully merged back (because it's a separate application) and there is need do some commits to framework (trunk). Some online articles such commits (without merging whole branch to trunk) gives as negative examples, so we are confused.
What version control system and branching model do you recommend for such development cycle?
So each application is like a separate branch of framework, but it
will never be fully merged back (because it's a separate application)
and there is need do some commits to framework (trunk). Some online
articles such commits (without merging whole branch to trunk) gives as
negative examples, so we are confused.
This part scares me a bit. If you are going to have a framework, then you need to take care of it like any other lump of code, and you don't want multiple versions running around for any reason except maintenance of existing releases or work on future releases. So each of your "application" projects can have a branch where they modify the framework as required for the application, but I recommend the framework trunk be updated often so that it evolves in a way that best serves the needs of all of your applications. In general, when branching for code going forward, you want to sync up with the master and put code back into the master as quickly as possible to avoid lots of work handling merges and also give others the benefit of the work.
You should put your framework in a separate area (or repository if you are using a DVCS like git or hg) so that it's distinct and may have its own release cycle if necessary.
The DVCSs are all the rage these days, git and hg being the most popular, so you should look into them. They have different ways of handling branching. Their power lies in the fact that there is no centralized repository so it's more flexible and reliable for larger teams.

Pros and cons of different version schemes

There are many different version schemes, and it seems like every major software company uses a different scheme, but I would like to know which scheme is best for mISV.
Also, if you can, I would like you to write which scheme do you use in your company, pros and cons of such scheme, and why you have chosen that scheme.
Related Questions
Deciding on version numbers
How to do version numbers?
How do you know what version number to use?
What is your preferred style of product version number and why? (this answers my second question)
Versioning Style Guide
Semantic Versioning (this is probably the best versioning scheme for components, not sure about applications for end-users)
Hints
This is a list of hints I've found on the internet:
Use at least three-part version numbers (2.9.0, 2.10.0) so it is obvious they are not decimals.
Use date/time based versiong (source)
Method to extract compile time from .NET automatic version scheme
Automatic versioning using MSBuild.Community.Tasks
mISV programs can be characterize by a high release rate, and at least by a high build rate (up to several builds a day).
In that context, it can be interesting to monitor:
a build Id (which can be the SVN id or a Git or Mercurial SHA1)
a classic Major.Minor.Build version
For the team, you can communicate in term of build id, while in term of release management for the client, a more classic version schemes is in order.
Quite frankly, I think this one is solved. Use date and time stamps. You're version numbers then turn into readable strings that people understand.
In the off chance that you have many different builds out in the wild, each should be tagged as such. Besides a version number (which is a date and time stamp) you'd have a simple tag. Mostly these are simply debug and release. But there are a variety of other such tags that make sense, such as staging, testing, or feature/branch specific tags.
If you wanna embed metadata about your build process/environment I consider that going beyond simple versioning numbers but sometimes, very helpful.
That's about it.

In a distributed architecture, why is it difficult to manage versions?

I see this time and time again. The UAT test manager wants the new build to be ready to test by Friday. The one of the first questions asked, in the pre-testing meeting is, "what version will I be testing, against?" (which is a fair question to ask). The room goes silent, then someone will come back with, "All the assemblies have their own version, just right-click and look at the properties...".
From the testing managers point-of-view, this is no use. They want a version/label/tag across everything that tells them what they are working on. They want this information easily avaialble.
I have seen solutions where the version of diffierent areas of a system being stored in a datastore, then shown on the main application's about box. Problem is, this needs to be maintained.
What solutions have you seen that gets around this on going problem?
EDIT. The distributed system covers VB6, Classic ASP, VB.Net, C#, Web Services (accross departments, so which version are we using ?), SQL Server 2005.
I think the problem is that you and your testing manager are speaking of two different things. Assembly versions are great for assemblies, but your test manager is speaking of a higher-level version, a "system version", if you will. At least that's my read of your post.
What you have to do in such situations is map all of your different component assemblies into a system version. You say something along the lines of "Version 1.5 of the system is composed of Foo.Bar.dll v1.4.6 and Baz.Qux.dll v2.6.7 and (etc.)". Hell, in a distributed system, you may want different versions for each of your services, which may in and of themselves, be composed of different versions of .dlls. You might say, for example: "Version 1.5 of the system is composed of the Foo service v1.3, which is composed of Foo.dll v1.9.3 and Bar.dll v1.6.9, and the Bar service v1.9, which is composed of Baz.dll v1.8.2 and Qux.dll v1.5.2 and (etc.)".
Doing stuff like this is typically the job of the software architect and/or build manager in your organization.
There are a number of tools that you can use to handle this issue that have nothing to do with your language of choice. My personal favorite is currently Jira, which, in addition to bug tracking, has great product versioning and roadmapping support.
Might want to have a look at this page that explains some ways to integrate consistent versioning into your build process.
There are a number of different things that contribute to the problem. Off of the top of my head, here's one:
One of the benefits of a distributed architecture is that we gain huge potential for re-use by creating services and publishing their interfaces in some form or another. What that then means is that releases of a client application are not necessarily closely synchronized with releases of the underlying services. So, a new version of a business application may be released that uses the same old reliable service it's been using for a year. How shall we then apply a single release tag in this case?
Nevertheless, it's a fair question, but one that requires a non-trivial answer to be meaningful.
Not using build based version numbering for anything but internal references. When the UAT manager asks the question you say "Friday's*".
The only trick then is to make sure labelling happens reliably in your source control.
* insert appropriate datestamp/label here
We use .NET and Subversion. All of our application assemblies share a version number, which is derived from a manually updated major and minor revision numbers and the Subversion revision number (<major>.<minor>.<revision>). We have a prebuild task that updates this version number in a shared AssemblyVersionInfo.vb file. Then when testers ask for the version number, we can either give them the full 3-part number or just the subversion revision. The libraries we consume aren't changing or the change is not relevant to the tester.

Resources