In an Umbraco package, there have always been two versions that matter: the version of the NuGet package and the version of the Umbraco extension.
NuGet Package Version
The NuGet package version is displayed in a NuGet feed and is relevant for your .NET solution. It's easy to see the currently installed version and check if any updates are available using the Semantic Versioning (SemVer) scheme.
The version for the NuGet package is set in the project file. This can be done using different properties, like Version
, VersionPrefix
, PackageVersion
, and others, but for this example, I'll stick to the Version
property like this:
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
...
<Version>16.0.0</Version>
</PropertyGroup>
</Project>
For example, here are some custom packages in their NuGet feed showing their versions in Visual Studio:
Umbraco Extension Version
On the other hand, we have the version of the Umbraco extension. This is the version specified in the package.manifest
in Umbraco 13 or the umbraco-package.json
in Umbraco 16. This version number is displayed in the backoffice in the list of installed packages.
For example, this umbraco-package.json
:
{
"$schema": "../../umbraco-package-schema.json",
"id": "ProudNerds.Umbraco.ContentExpiration",
"name": "ProudNerds Content Expiration",
"version": "16.0.0",
"extensions": [
...
]
}
will be displayed in the backoffice of Umbraco 16 like this:
Why Keep Them the Same?
I believe these two versions should always be the same. It’s very convenient to check the version of a package directly in the backoffice.
Version Synchronization in Umbraco 13
In Umbraco 13, we actually had an option to take the assembly version and use that as the version of the Umbraco extension:
{
"name": "ProudNerds Content Expiration",
"id": "ProudNerds.Umbraco.ContentExpiration",
"versionAssemblyName": "ProudNerds.Umbraco.ContentExpiration",
...
}
By specifying the assembly that holds the NuGet version in the versionAssemblyName
property, the extension would automatically use the same version.
Version Synchronization in Umbraco 16
In Umbraco 16, this feature no longer exists. Because the backoffice is now a separate entity that has no knowledge of any backend C# code, there’s no easy way to read a version from an assembly.
The way I currently make sure that my extension version is the same as the NuGet version is by installing a small Umbraco NuGet package. Then I use a task that's in that package in an after-build event to update the version number in the umbraco-package.json
file. In this setup, the NuGet version is leading.
Step 1: Install the Helper Package
Install the NuGet package Umbraco.JsonSchema.Extensions
.
Its version is 0.3.0
at the time of writing, so it doesn’t feel like a finished product, but it does its job well — and Umbraco uses it themselves.
Step 2: Create an After-Build Event
Add the following target to your project file:
<!-- Updates the version in the umbraco-package.json file to match the NuGet package version -->
<Target Name="UpdateUmbracoPackageJsonVersion" AfterTargets="Build">
<PropertyGroup>
<!-- Change the path to your umbraco-package.json file -->
<UmbracoPackageJsonPath>$(ProjectDir)wwwroot\App_Plugins\ExamplePlugin\umbraco-package.json</UmbracoPackageJsonPath>
</PropertyGroup>
<Message
Text="Checking for umbraco-package.json at: $(UmbracoPackageJsonPath)"
Importance="High" />
<!-- This will use the Version property from the project file.
Change it here if you want to use VersionPrefix, for example. -->
<JsonPathUpdateValue
JsonFile="$(UmbracoPackageJsonPath)"
Path="$.version"
Value=""$(Version)""
Condition="Exists('$(UmbracoPackageJsonPath)')" />
<Message
Text="✅ Updated umbraco-package.json version to $(Version)."
Importance="High"
Condition="Exists('$(UmbracoPackageJsonPath)')" />
<Message
Text="⚠️ Skipped updating umbraco-package.json version - file not found at $(UmbracoPackageJsonPath)."
Importance="High"
Condition="!Exists('$(UmbracoPackageJsonPath)')" />
</Target>
This is all you need! On every build, you will now see the messages appear in your output on build:
Conclusion
By automatically updating the version in umbraco-package.json
after every build, you can ensure your Umbraco extension version stays in sync with your NuGet package version. This makes it easier to track versions across your solution and in the Umbraco backoffice without manual updates.
Top comments (1)
If you only work with C#, or wish to keep your registration in C#, you can add your own
IPackageManifestReader
and set the version directly from your assembly:Source: github.com/iOvergaard/umbraco-serv...
Note: I roll my own version — I do not use Umbraco's CMS versions, as my versions work with theirs.