In recent years, in Blexin we designed a very modular CMS with high performances, which allows the simplification of the web portals’ development, regardless of the storage used for data persistence. WebRight, this is the CMS name, uses different plugins, depending on functionalities needed in the portal. The storage abstraction is possible thanks to Raptor, another framework also developed by Blexin.
During the development of these products, we felt the need to have a good process to version the dependences between the plugins, to avoid winding up in the classic problem of dependency hell (more info at this link). In this article, I would like to explain how we start versioning the dependences of our frameworks. In the next articles, we will see instead different practices we adopted to arrive at the process we use for the versioning of our software.
How to establish a versioning process
During software development, versioning is usually a hot topic. Generally, the software versioning makes sense when we distribute libraries, or we expose API. It can happen, however, to extend this concept to all our software, even though in some cases (i.e. a web application) it may make no sense, since the main user of our product (the customer) has no real interest in the number of versions. During the development of WebRight and Raptor framework, we establish immediately a versioning method for our plugins’ releases and, much important, for libraries shared between the two frameworks. We start to define a process to do that: in particular, we need to create rules to generate version number. Once we identify and share them, we start with the versioning of our libraries, with the use of the attribute AssemblyVersion in the class AssemblyInfo.cs:
// Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyFileVersion("1.0.*")]
We choose to use the following rules:
- Major is for us a number that will be incremented in event of a breaking change, something that is not compatible with previous versions of the library;
- Minor is for us a new feature, that doesn’t break with previous versions, or is a bugfix.
In this context, the asterisk permits to generate the Build and Revision values automatically, release us from the task. We start with the manually set of these values in the class and, even if this might let you turn up your nose, you need to understand that there’s nothing wrong in doing it, provided that you’ll do it with a criteria and with a well defined process. Of course, once the process has been established, it would be silly not to automate it with a build pipeline, to totally benefit from it.
How to make the versioning of a NuGet package
As we adopt this process, it was then easy to make and share the NuGet packages within the team. For example, it is possible to use NuGet Package Explorer or Nuget CLI to simplify the whole procedure. Once we added all the details of our project to the flle AssemblyInfo.cs and compiled it, we can generate the file nuspec in the same folder and use the CLI with the following command:
Once the nuspec has been created, we can execute the following command to create the NuGet package:
nuget pack nome_progetto.csproj -IncludeReferencedProjects
In particular, the flag -IncludeReferencedProjects allows us to include all the dependences in the final package. Through the NuGet Package Explorer we may even open the NuGet package generated, to verify the content:
Once the definition stage is completed, we are ready to share our package on a NuGet feed.
How to push a package on NuGet
If we use Azure DevOps we can easily create a NuGet feed inside the Artifacts section.
Once the feed has been created, we need to generate a token in our account settings to connect and push the packages. Inside the page of connection to the feed, is possible to find all information and even commands needed to make the push:
We only need now to upload the package, using the command:
NuGet push -Source "<Source>" -ApyKey <Key> nome_package.nupkg
As soon as we created our package, we can find different options:
IIn the end, we can connect to the feed from Visual Studio from Tools Menu -> NuGet Package Manager -> Package Manager Settings and, when we search for a package, we can display both packages coming from our feed and those coming from others and we can import them in our projects.
In this article, I describe the first step we did in our company to arrange the versioning of our NuGet packages. In the next article, we will discover how the use of git and more specifically GitFlow helped us to simplify this process.