I've been using Semantic Versioning for a project I'm distributing with Nexus, and I've run into a conundrum. I need to release two different configurations for each version: Release and Debug. In general, the average consumer will use the Release artifact(s), but some will want/need the Debug artifact(s).
How can I consistently version the artifact(s) so the Release configuration takes precedence over the Debug configuration?
I could add an identifier for the Debug configuration, but then pre-release versions have the wrong precedence.
✓) 1.0.0-debug (Debug) < 1.0.0 (Release)
×) 1.0.0-alpha.debug (Debug) > 1.0.0-alpha (Release)
I could use metadata, but then the precedence is the same.
×) 1.0.0+debug (Debug) = 1.0.0 (Release)
×) 1.0.0+debug (Debug) = 1.0.0+release (Release)
Perhaps I'm simply approaching this the wrong way. If so, what's the right approach? A separate artifact?
First let us define some terminology. Most modern build systems have at least "Debug" and "Release" configurations for build output, but in SemVer terms, either of those types can be a "Release" version (X.0.0) or a "Prerelease" version (X.Y.Z-prereleaseTag). The same holds true for code coverage and profiling configurations as well.
A package may contain only one version of the product, but the number of configurations is potentially unlimited, so you can generally package all of your configurations in separate directories for a single version.
Example package layout:
MyLib.1.0.0
Debug
Docs
Bin
Include
Release
Docs
Bin
Include
The details are dependent on the package tooling you are using. Nuget and NPM both have their own standard layout conventions but allow you pretty much lay things out any way you want.
Related
I have updated to Azul Zulu 8u282 JRE and I noticed a new JAR file that wasn't there in the previous version I used (8u265). It's called 'crs-agent.jar' and the class files are all inside the package structure 'com.azul.crs.*'. When I decompile them with IntelliJ it looks like some diagnostic or reporting stuff and there's also networking at work.
I went through lot's of release notes of current and old releases on the Azul website but there is no information about this CRS. Wikipedia yields several results for that acronym with 'Carrier Routing System' making the most sense.
So what is this JAR for? Can I just delete it?
Yes, you can ignore/delete this file. It's not used and was added for experimental features that are turned off and are never used at the moment.
The latest release notes refer to this as:
New Experimental Features
Zulu includes optional experimental support for interaction with
connected runtime services through an emerging protocol. These
experimental capabilities are enabled by the -XX:+UseCRS flag and are
turned off by default. The -XX:+UnlockExperimentalVMOptions must also
be on for this option to work.
I want to know the differences between npm and maven respository
Same tool, different language?
Maven is the most popular build and dependency resolution tool for Java, just like NPM is for JS. But it's not just the same tool for a different language. There are obviously huge differences between Java and JS builds, and these differences are directly visible in the way Maven operates. For example, while many JS tools rely on Git to do some heavy-lifting, Maven works with custom filesystem-based Maven repositories, as Maven predates Git and needs to handle binary artifacts, which Git historically didn't handle well. In Maven there's a clear separation between sources and binaries, while they are often the same thing in JS world.
Maven basics
Maven in its purest form follows a declarative model, where pom.xml (similar to package.json) defines different properties of the build, but contains no scripts. The disadvantage is it can be a challenge to fine-tune some aspects of the build without using scripts as you have to rely on plugins. The advantage is it can be easier to understand other builds just by looking at pom.xml, as they usually follow the same approach without too much customization. Gradle is a popular Groovy-based tool built on top of Maven standards and conventions, and is specifically designed to simplify pom.xml and break this "no script" barrier.
Referencing your dependencies
Similarly to package.json, you don't work with pom.xml of your dependency directly, but rather define dependency coordinates and let your build tool handle the rest. In Maven the basic form of these coordinates is GAV (groupId, artifactId, version).
Flat dependency tree?
Based on comments in the other answer, Maven provides "flat dependency tree", not "nested dependency tree" that NPM provides by default. Maven does not allow multiple versions of the same dependency. If it happens that different versions are requested, Maven uses dependency resolution to pick a single version. This means that sometimes your transitive dependencies will get a different version than they require, but there are ways to manage this. However, this limitation comes from Java, not Maven, as (normally) in Java a class loader will only provide access to a single class definition even if multiple definitions are found on the classpath. Since Java is not particularly good at handling this, Maven tries to avoid this scenario in the first place.
Note: since npm v3 the dependencies are flatten. The alternative package manager yarn also does the same.
Maturity
Furthermore, Maven is considerably older than NPM, has a larger user base, huge number of custom plugins, and so far could probably be considered more mature overall. Sometimes Maven is used for non-Java or even polyglot projects, as there are plugins for handling other languages or specific environments, such as Android. There are plugins that bridge Maven and other build tools, such as frontend-maven-plugin that actually handles multiple JS build tools.
NPM is focused on JavaScript while Maven is focused on Java and JVM derived (that is Scala, Kotlin, Groovy).
So comparing them doesn't make sense at all as these are not concurrent.
While comparing Maven to Gradle (Java world concurrent) or NPM to Yarn (JavaScript world concurrent) makes more sense.
Now Maven and NPM have closed features. Which is not surprising : good recipes spread beyond a language.
Here are some common points/features:
- these are package(JavaScript term)/ dependency (Maven term) managers that works with local/remote repositories.
- these are also a way to manage dependencies in your projects and to execute build tasks for them.
I’m on a .net c# project composed by a solution with several class library projects.
The source control is managed by git using gitflow as branching model.
We have decided that we wanted to implement semantic versioning (http://semver.org/) of the project in order to follow a standard way to communicate our releases.
For that we are using GitVersionTask (via NuGet) which works pretty well with gitflow.
Every time we tag a release and we perform a build from the master branch the version of all assemblies are updated and a new release is out for delivery.
Only one of the assemblies has a public API, all the other are for internal consume. I would like to know if this is the correct way to manage the version of multiple assemblies of the same project I mean, isn’t it wrong to change the version of every assembly when only a couple (or even just one) was changed? To get thinks more complicated there is strong possibility that some of the “internal” assemblies will be used by other projects so I believe it not very wise to increment a major version of an assembly that didn’t suffer a change just because another assembly of the same project is promoting breaking changes. Should each assembly project be managed on its own repository?
Thanks in advance.
I know this is a bit of an old question, still:
I want to share a workaround that seems to be working:
GitVersion uses $(Build.SourcesDirectory) to see where the sources are located - src
We can change this using logging commands*
Workaround is to set the Build.SourcesDirectory before GitVersion task
Then gitVersion uses the GitVersion.yml from the project folder (Build.SourceDirectory) and voila - works
After that you might want to roll back the change or not - depending on your need. For me it seems it is nice to scope down to the only nuget package from the collection of nuget packages in our nugetPackages monorepo.
see GitVersion issue and comment
*Example Powershell command:
standard PowerShell task; set to inline script;
Write-Host "##vso[task.setvariable variable=Build_SourcesDirectory;]$(Build.SourcesDirectory)\$(NugetProjectName)"
There is certainly nothing in GitVersion that would help with having separate projects within the same repository. The guidance that we would offer here is that you should use different repositories for the different parts of your application. That way they can be versioned/updated at their own cadence.
When browsing the packagist.org repositories you see packages with these version numbers e.g. If you look at the Phpunit repo
There are a few instances
4.5.x-dev
4.3.x-dev
4.2.x-dev
Do these packages contain the current work the developers are performing towards basic updates, security and bugfixes etc on an otherwise basically stable package?
These are the dev branches. These are unstable and contain bug fixes, etc. This will eventually be released as 4.5.8 for instance (if the library is still supported).
You can get it by using 4.5.x-dev or 4.5.*#dev as version constraint.
I am in the process of introducing NuGet into our software dev process, both for external binaries (eg Moq, NUnit) and for internal library projects containing shared functionality.
TeamCity is producing NuGet packages from our internal library projects, and publishing them to a local repository. My modified solution files use the local repository for accessing the NuGet packages.
Consider the following source code solutions:
Company.Interfaces.sln builds Company.Interfaces.1.2.3.7654.nupkg.
Company.Common.sln contains a reference to Company.Interfaces via its NuGet package, and builds Company.Common.1.1.1.7655.nupkg, with Company.Interfaces.1.2.3.7654 included as a dependency.
The Company.DataAccess.sln uses the Company.Common nupkg to add
Company.Interfaces and Company.Common as references. It builds
Company.DataAccess.1.0.8.7660.nupkg, including Company.Common.1.1.1.7655 as a dependent component.
Company.Product.A is a website solution that contains references to all three library projects (added by selecting the
Company.DataAccess NuGet package).
Questions:
If there is a source code change to Company.Interfaces, do I always need to renumber and rebuild the intermediate packages (Company.Common and Company.DataAccess) and update the packages in Company.Product.A?
Or does that depend on whether the source code change was
a bug fix, or
a new feature, or
a breaking change?
In reality, I have 8 levels of dependent library packages. Is there tooling support for updating an entire tree of packages, should that be necessary?
I know about Semantic Versioning.
We are using VS2012, C#4.0, TeamCity 7.1.5.
It is a good idea to update everything on each check-in, in order to test it early.
What you're describing can be easily managed using artifact dependencies (http://confluence.jetbrains.com/display/TCD7/Artifact+Dependencies) and "Finish Build" build triggers (or even solely "Nuget Dependency Trigger").
We wrote our own build configuration on the base project (would be Company.Interfaces.sln in this case) which builds and updates the whole tree in one go. It checks in updated packages.config files and .nuspec files along the way. I can't say how much of a time-saver this ended up being for us, even if it might sound like overkill at the beginning.
One thing to watch out for: the script we wrote checks in the files even if the chain fails somewhere in between, to give us the chance of fixing it on our local machine, check in the fix and restart the publishing.