Codebasis als Dateien ins Arbeitsrepo statt als Gitlink

QuellCode/CentronERP war nur als Gitlink (Submodul-Referenz auf 79c1142)
getrackt, ohne .gitmodules und ohne erreichbares Remote. Der
Untersuchungsgegenstand der Versuchsreihe war damit nicht reproduzierbar
gesichert: Ein Klon haette ein leeres Verzeichnis erhalten, und die Belege
der 3.287 Anforderungen waeren nicht ueberpruefbar gewesen.

Umstellung:
- Historie nach c:\DEV\CentronERP_git_snapshot_79c1142 ausgelagert
  (vollstaendig lesbar, enthaelt 79c1142 und Vorgaenger 89ccfd6)
- Gitlink aus dem Index entfernt
- Dateiinhalt aufgenommen: 24.557 Dateien, rund 333 MB

Die verschachtelte .gitignore der Codebasis gilt weiter, Build-Artefakte
bleiben ausgeschlossen. Details in Versuche/Versuch_01/_Codebasis-Nachweis.md
This commit is contained in:
Christoph Schwörer
2026-08-26 07:43:51 +02:00
parent 18edae75b6
commit f045b99a25
24664 changed files with 5846716 additions and 1 deletions
@@ -0,0 +1,208 @@
# High level overview
There are a couple of different pieces involved in creating a build.
The most central piece is the **Centron.Scripts** project in this repository, it does most of the heavy work.
There is also the **azure-pipelines.yml** that specifies how Azure DevOps works with the Centron.Scripts project, and what to do with the resulting files.
The builds will be placed in our [software builds sharepoint](https://centrongmbh.sharepoint.com/sites/SoftwareBuilds/Shared%20Documents/Forms/AllItems.aspx).
If the build references one or multiple **c-entron Tickets**, these Tickets will automatically get the version number of that build, and the ticket will be forwarded to the quality-control department.
There is also a **downloader** that automatically downloads the latest versions of c-entron.NET and Web-Service from the sharepoint to our own internal network shares. This makes it easier for everyone working at NEXOWARE to access the latest versions.
We have two build servers:
**CS-UL-DEVOPS01** (hosted by celos) that has currently 3 build agents, and
**CS-UL-DEVOPS02** (hosted at celos) that has currently 3 build agents.
All of the users, passwords and other credentials that I talk about in this document are also available [in our password server]( https://83.169.12.81:10001/Account/SignIn).
# Centron.Scripts
The **Centron.Scripts project** knows how to build the c-entron.NET, the c-entron Web-Service, and also the installers for all of them.
It does a handfull of things:
- It creates the **version number**
- It **builds** the projects using dotnet.exe
- It **deletes unneeded files** from the build output
- It **signs** the applications and installers
- It **creates archives** of everything and moves them into the *[git repository root]/artifacts* directory
- It **runs the tests** and places the test result in the *[git repository root]/artifacts* directory
So when you run this project, after a couple of minutes you will end up with perfect installers for c-entron.NET and c-entron Web-Services without any more input required from you.
Also, you will get a result file of all the tests.
## Code signing
Code signing is optional - you can create a build without having our code signing certificate and password - it is of course still be recommended to do it.
You can activate code signing by setting two environment variables:
**CENTRON_BUILD_CODE_SIGNING_CERTIFICATE** and
**CENTRON_BUILD_CODE_SIGNING_CERTIFICATE_PASSWORD**
**CENTRON_BUILD_CODE_SIGNING_CERTIFICATE** should contain the path to the code signing certificate file.
**CENTRON_BUILD_CODE_SIGNING_CERTIFICATE_PASSWORD** should contain the password for that code signing certificate.
Right now, all of the following files for c-entron.NET are signed:
- c-entron 2.0.exe
- c-entron.NET Installer.msi
And these for the c-entron Web-Service:
- Centron.Host.WindowsService.exe
- c-entron Connection Manager.exe
- Centron.Interfaces.dll
- Centron.WebServices.Core.dll
- Centron.Core.dll
- c-entron Web-Service Installer.msi
If one of these environment variables is empty or not set, the applications and installers will not be signed at all.
You can read in the console output whether the files were signed or not.
## Automatic versioning
There is a **version.json** file in the root directory of the git repository.
This version specifies the first 3 parts of the version number, for example **2.0.2601**.
The last part will be automatically generated by using [Nerdbank.GitVersioning](https://github.com/AArnott/Nerdbank.GitVersioning).
Nerdbank.GitVersioning is a very feature rich library to automatically generate version numbers for your git repository, but we only use it in a very simplistic simple way.
It basically counts how many commits there have been in the repository, since the **version.json** file was last changed.
That count is the last part of the version number.
**For example:**
We change the version number in **version.txt** to **2.0.1911**, and then have 2 commits, the version number will be **2.0.1911.3**.
**Note:** It will be *3* and not *2* because it also counts the commit where the version.txt was changed.
This means that the version number is always increasing automatically.
# azure-pipelines.yml
The azure-pipelines.yml file contains a couple of tasks, some for **building** the project, others for **deploying** it.
## Tasks
So the tasks work roughly like this:
- **Authenticate** with the Azure DevOps **NuGet server for c-entron Office**
- It **downloads** our **code-signing certificate** from Azure DevOps (it's stored in `Azure DevOps` -> `c-entron.NET` -> `Pipelines` -> `Library` -> `Secure files` -> `c-entron code signing certificate.pfx`)
- It **updates** the **Azure DevOps version number** to show the version number of the build
- It then **runs** the **Centron.Scripts** and also sets the environment variables for code signing to work (by using the certificate file downloaded earlier, and the password that is added as a secure variable to the build pipeline)
- After the build succeeded, it will **upload all the created installer archives** (c-entron.NET Installer and c-entron Web-Service Installer) to our [Software Builds sharepoint documents](https://centrongmbh.sharepoint.com/sites/SoftwareBuilds/Shared%20Documents/Forms/AllItems.aspx).
They will be uploaded to "/`c-entron.NET` or `c-entron Web-Service`/v`first three parts of the version number`/v`complete version number`/`artifact name`".
So for example:
**/c-entron.NET/v2.0.1908/v2.0.1908.3/c-entron.NET Installer.zip** and
**/c-entron Web-Service/v2.0.1908/v2.0.1908.3/c-entron Web-Service Installer.zip**
**Note:** The upload to the [Software Builds sharepoint documents](https://centrongmbh.sharepoint.com/sites/SoftwareBuilds/Shared%20Documents/Forms/AllItems.aspx) is **only done for real builds**, it is **not done for pull request builds**.
# c-entron Tickets
If a **real build** was created, then c-entron Tickets that have been fixed or resolved by that **real build** will get the version number of that build, and also will be forwarded to our quality-control department.
This works by using so called [Web Hooks from Azure DevOps](https://docs.microsoft.com/en-us/azure/devops/service-hooks/services/webhooks?view=azure-devops). In our case: When a build finishes, a HTTP API will be triggered.
This HTTP API will then figure out which pull request was completed for that build, and whether this pull request references any c-entron Tickets.
To figure out which pull request was completed by the build, it calls the Azure DevOps API using an **API key** generated by the **build@c-entron.de** user.
It then searches for ticket numbers in the title and description of the pull request - the following formats are currently supported:
* Ticket 12345
* Ticket#12345
* Ticket #12345
* Ticket# 12345
* Ticket: 12345
When one or more ticket numbers were found, it will call our own c-entron API (https://c-suite.c-entron.de/CentronServiceProductive) to insert the build version into the ticket, and then forward it to the quality-control department (Personal I3D 372).
To call our own c-entron API the **sw_centron** AD user is used - that matches to the **TFS** user in our own c-entron database.
This user also has the email address **build@c-entron.de** to send out ticket forwarding emails.
It is possible to skip the forwarding by adding one of the following tags to the description of the PR:
* [skip-forwarding]
* [skip-fwd]
* [skip-forward]
If this is done it will only insert the build version into the ticket, but it does not forward the ticket. This allows you to link several PRs without the ticket getting send to QS before it is finished.
The HTTP API is currently running on our own web-server **CS-UL-ERPWEB01**, available at **https://erp.c-entron.de/DevOpsCentronTicketBridge** - you can enter this URL in the browser and should see a short message that the bridge is running.
It is running as the windows service **DevOpsCentronTicketBridge**, located at *C:\Program Files (x86)\DevOpsCentronTicketBridge*.
Basically everything about it can be configured in the **appsettings.json** file:
* The URL where it is available
* The Personal Access Token used to communicate with the Azure DevOps API
* The regular expressions that are used to find the ticket numbers in the title and description of the pull requests
These regular expressions should have **exactly one group** *(the round brackets)* where the number will be located.
For example: **Ticket ([0-9]{5,6})** or **Ticket#([0-9]{5,6})**
* Where the c-entron Web-Service is running at, and which user to login with
* To which user the tickets should be forwarded
The whole source-code of this web hook is available on our [Azure DevOps server too](https://dev.azure.com/CentronSoftware/DevOpsCentronTicketBridge).
# Azure DevOps setup
There are a couple of things configured in Azure DevOps to make this all work:
- The **azure-pipelines.yml** build pipelines is configured as a **branch policy** for the **master branch** and all release-branches (**release/vXYZ**) with trigger **automatic**.
This means the pipeline will be automatically executed for pull requests.
- There is a **secure variable** configured for the build pipeline called **codeSigningCertificatePassword**
- There is the code signing certificate added as a **secure file** called **c-entron code signing certificate.pfx**
- In `Project settings` -> `Service connections` is a connection for **Software Builds - Sharepoint** - it uses the **build@c-entron.de** user to authenticate
- In `Project settings` -> `Service hooks` is a **web hook** created to make the c-entron Ticket workflow possible.
It has a trigger of type **Build completed** and a couple filters:
Build pipeline = **c-entron.NET CI**
Build Status = **Succeeded**
It performs a **HTTP POST** to **https://erp.c-entron.de/DevOpsCentronTicketBridge** with:
Resource details to send = **All**
Resource version = **1.0**
# Azure DevOps Build Agents
We have two build-servers called **CS-UL-DEVOPS01** and **CS-UL-DEVOPS02**.
**CS-UL-DEVOPS01** is accessible with its full name **CS-UL-DEVOPS01.group.celos.de**
I have my own local admin account there **LocalAdminDH**, but _Celos Computer GmbH_ can add real accounts based on our windows accounts.
Stanislaus Lieb also can access this server.
There are currently **3 build agents installed** on that machine:
- E:/AzureDevOpsAgent1 called **CS-UL-DEVOPS01.1** and
- E:/AzureDevOpsAgent2 called **CS-UL-DEVOPS01.2** and
- E:/AzureDevOpsAgent3 called **CS-UL-DEVOPS01.3**
**CS-UL-DEVOPS02** is accessibly with its full name **CS-UL-DEVOPS02.group.celos.de**
Login same as **CS-UL-DEVOPS01**
There are currently **3 build agents installed** on that machine:
- E:/AzureDevOpsAgent1 called **CS-UL-DEVOPS02.1** and
- E:/AzureDevOpsAgent2 called **CS-UL-DEVOPS02.2** and
- E:/AzureDevOpsAgent3 called **CS-UL-DEVOPS03.3**
These build agents **connect** to Azure DevOps using **API keys** that were generated by the **build@c-entron.de** user.
All of them are configured to run as a **windows service** using the local user **AzureDevOpsAgentUser**.
This user is also an administrator on the machine (it has to be, otherwise the **deploy tasks** will fail).
We have a couple of **software requirements** for the **build server**:
- Visual Studio 2022 (authenticated with the **build@c-entron.de** user)
- Make sure to install all .NET Framework targeting packs, so building c-entron.NET will work correctly
- Install these workloads:
- ASP.NET and web development
- .NET Desktop development
- WIX 3 Toolset build tools (see [here](https://wixtoolset.org/docs/wix3/))
- WIX 3 Toolset Visual Studio 2022 Extension (also see [here](https://wixtoolset.org/docs/wix3/))
- .NET Core SDK 8.0.x (the latest one, see global.json) (get it [here](https://dotnet.microsoft.com/download))
- .NET Core SDK 7.0.3x (for c-entron Office) (get it [here](https://dotnet.microsoft.com/download))
- .NET Core SDK 6.0.1x (for Outlook Add-In) (get it [here](https://dotnet.microsoft.com/download))
- An SQL-Server for our end-to-end tests (MSSQL 2017 prefered right now)
- Make sure to set the environment-variables so the end-to-end tests can actually find the database. You can find the environment-variable names in the Database.cs file.
- As we are using the Azure DevOps task `razorspoint.rp-build-release-pnptasks.RP-PnPPowerShell.PnPPowerShell@3` to upload the finished versions to sharepoint, we have to make sure the SharePoint upload works correctly too.
Try running `Find-Module -Name "SharePointPnPPowerShellOnline" -RequiredVersion "3.23.2007.1"` on the build server.
If it works, you should be good to go. If it doesn't we might have to add NuGet as a PowerShell PackageProvider.
To do that, execute this command `Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force`
# Automatic downloader
We have an automatic downloader that downloads the latest versions of c-entron.NET and c-entron Web-Service every day at around 6 AM.
This downloader is running on the server **CS-UL-CENTRON** as the windows service **SharePointVersionDownloader**.
It is running as the user **svc_SoftwareCentron@group.celos.de** because the process needs write permissions to the network shares where the downloaded files will be placed.
On that server the downloader is located at _C:\Program Files (x86)\SharePointVersionDownloader_.
The downloader can be configured completely through the **appsettings.json** file.
If you want to download, for example, the latest 2.0.1908 version of c-entron.NET, then you have to add a job to the **appsettings.json** for that.
Another job will be required for the latest 2.0.1909 version, or for c-entron Web-Service versions.
For examples on how to configure these jobs, take a look at the current **appsettings.json** configuration, or even better, the source-code.
The source-code for this downloader is available on our [Azure DevOps server](https://dev.azure.com/CentronSoftware/SharePointVersionDownloader).
@@ -0,0 +1,47 @@
# How to release stop
## Bump the version.txt
Creating a release stop is pretty simple.
First, you have to bump the version number in the **version.txt** file.
For example, it's **currently at 2.0.1908**, and we would like to have a **release stop** for this **2.0.1908** release.
So what you do is you go ahead and **change it to 2.0.1909**.
Of course still use the usual workflow of separate branch, pull request, and merge.
After the change is merged into the `master` branch, every next version created, will have a **2.0.1909** version number.
## Create the release branch
Now you go ahead and **create a `release` branch based on the commit before the version bump.**
For example, the `master` branch after merging the version bump looks like this:
```
* <- Merged PR ABC: Version Bump [Current state of master, will create build 2.0.1909.2]
|\
| \
| * <- Version Bump to 2.0.1909 in the pull request branch [Commit in the PR]
| /
|/
* <- Merged PR XYZ: Some other thing [Commit before the version bump]
|\
| \
other commits...
```
Create a new branch named `release/v2.0.1908` based on `Merged PR XYZ: Some other thing`.
Push this branch to the Azure DevOps server, and then we have to configure some **branch policies**.
## Branch policies
The branch policies are setup automatically for all branches starting with `release/`, so there is nothing you have to do for the branch policies.
It is already taken care of.
## Automatic downloader
Now that the new version **2.0.1909** will be created, consider adding it to the **automatic downloader**.
This will allow everyone working at NEXOWARE to more easily get the latest builds of that version.
How to do that, and many more information on the automatic downloader are available in the [our build server and automated builds](./Our-build-server-and-automated-builds.md#automatic-downloader) page.
@@ -0,0 +1,136 @@
# How to update DevExpress in c-entron<span>.NET
Before your start, **please** talk to everyone who manages one of the other projects (Outlook Add-In, Service-Board, Virtual Mail Assistant, c-entron Agent, etc.) to make sure they can all update as well.
We have documentation for the other projects (even if they have their own wikis) here to consolidate the update process.
Projects that do not have documentation here are usually updated by their respective developers (ServiceBoard etc.) or have documentation in their git repo.
This'll take you a few hours to complete and you cannot just do it halfway (leaving projects unable to update their c-entron dlls), so make sure to leave enough time and preferably start in the morning.
*There __will__ be issues along the way, so be prepared!*
**Please note: this is a very delicate process and needs to be done very thoroughly. You cannot resonably test every project/ui to ensure it's working, so you'll have to make sure you do thing correctly.**
**Errors or missing updates will probably only be noticed once people install (even worse if its only noticed once released to customers) and will usually result in bad/cryptic error messages.**
**Always check all the changed files in your PRs, make sure everything that needs to be updated is updated and everything that doesnt need to be updated is not updated!**
## Branches & PRs
For consistency reasons it is advisable to use the same pattern of branchname, commitmessage and PR name everywhere.
where | pattern | example (for Version 22.1.3)
--|--|--
Branch | \<shortsign>/update_devexpress_to_\<versionnumber> | hay/update_devexpress_to_2213
Commit | Update devexpress to \<versionnumber> | Update devexpress to 22.1.3
PR | same as the commit message
# [c-entron.Help](https://dev.azure.com/CentronSoftware/c-entron%20Help)
`Solution` > `ContextMenu` > `Manage NuGet Packages for Solution...` to update the NuGet packages.
Package|Projects
--|--
`DevExpress.*` | `Centron.Help`
Update the version number for `Centron.Help` in the `.csproj` file. Put your changes into a PR and self approve and complete it.
Copy the nuget-package to `/nugets` in c-entron<span>.NET and c-entron Outlook AddIn solution.
[Reference PR](https://dev.azure.com/CentronSoftware/c-entron%20Help/_git/c-entron%20Help/pullrequest/12178)
# [c-entron<span>.NET](https://dev.azure.com/CentronSoftware/c-entron.NET)
There are two ways for you to do this, the offical way via nugget packages and the fast way.
Package|Projects
--|--
`DevExpress.*` | WPF, backend, webservice, shared **and Nexus (Blazor)** — all driven by the `NugetVersionDevExpress` variable (see below), you don't need to touch the individual `.csproj` files
`Centron.Help` | `Centron.WPF.UI`
## Updating DevExpress dlls (single source)
The DevExpress version lives in **one** file: **`DevExpress.Version.props`** (repo root), which holds `<NugetVersionDevExpress>`. It is imported by both the root `Directory.Build.props` (WPF/backend/webservice/shared) and `src/nexus/Directory.Build.props` (Nexus/Blazor). Just change the value there — every `DevExpress.*` `PackageReference` uses `Version="$(NugetVersionDevExpress)"`.
> History: Nexus used to hard-code its 6 DevExpress versions in `src/nexus/CentronNexus/CentronNexus.csproj`. Those were switched to `$(NugetVersionDevExpress)` and Nexus's own `Directory.Build.props` imports the shared file (it does not inherit the root props), so a version change is now a single edit.
## Obtaining & updating c-entron.Help (do this FIRST — it is a hard blocker)
`Centron.WPF.UI` references the `Centron.Help` NuGet, and that package is compiled against a specific DevExpress version. If it lags behind, the WPF **markup compiler fails** with `MC1000 … Could not find assembly 'DevExpress.Data.v<OLD>'` — because the new DevExpress ships `DevExpress.Data.v<NEW>` and the old versioned assembly no longer exists.
So **ask the c-entron.Help maintainer for a new `Centron.Help.1.0.xxxx.x.nupkg` built against the new DevExpress version** (see the c-entron.Help section above / its own repo). Then:
1. Copy the new `Centron.Help.1.0.xxxx.x.nupkg` into `/nugets` and delete the old one.
2. Bump the `Centron.Help` `PackageReference` `Version` in `src/centron/Centron.WPF.UI/Centron.WPF.UI.csproj`.
3. Clear the old extracted package from the NuGet cache if the version number was reused.
## Running tests
Some EndToEnd expected files contain RTF text with the DevExpress version that generated it, so they must be updated. This is **not just 2 tests** — there are roughly **20+** `*.expected.txt` files under `tests/Centron.Tests.EndToEnd/Tests/Settings/` and `tests/Centron.Tests.EndToEnd/Tests/Helpdesk/`.
You can either run the tests (`HelpdeskSettingsTests` / `SettingsTests`) so they regenerate, or bulk-replace the generator string across all files:
`..{\*\generator DevExpress Office File API/<OLD>.0}..`
to
`..{\*\generator DevExpress Office File API/<NEW>.0}..`
(e.g. old `25.2.6.0` → new `26.1.3.0`.) These files are UTF-8 **without BOM** and use **CRLF** — preserve both (use `perl -i -pe`, not an editor that rewrites line endings). Ignore the unrelated `9.2.x` strings (that is the c-entron ApplicationVersion) and any `*.actual.txt` (generated, gitignored).
## Breaking changes on major upgrades (e.g. 25.x → 26.x)
A minor bump is usually just the version + heatmaps. A **major** bump additionally tends to need:
- **Clear stale WPF build artifacts.** Delete `**/*_wpftmp.csproj` and the `obj`/`bin` folders of the WPF projects (`Centron.WPF.UI`, `Centron.WPF.UI.Extension`, `Centron.Controls`, `c-entron.misc.ConnectionManager`). They cache the old `DevExpress.*.v<OLD>` reference paths and keep reproducing the `MC1000` error even after the version bump.
- **Removed/changed API.** Fix compile errors from removed members. Example (26.1): `services.AddDevExpressBlazor(o => o.BootstrapVersion = BootstrapVersion.v5)` — `BootstrapVersion` was removed (Bootstrap 4 dropped, v5 is default) → use plain `services.AddDevExpressBlazor();` in `src/nexus/CentronNexus.Host/Program.cs`.
- **Version-hashed static assets.** DevExpress 26.1 no longer ships the internal `_content/DevExpress.Blazor/dx-blazor-<hash>.svg` sprite. Any custom `<use href="…#dx-editor-remove-tag">` (e.g. in `EmployeeTreeSelectionDropDown.razor`) breaks — replace with a self-contained inline SVG.
- Re-verify `wwwroot/css/devexpress-mods.css` overrides and any DevExpress `.Internal` namespace usages.
- **Restore first** (`dotnet restore Centron.sln`): a failed restore means the DevExpress feed/subscription does not cover the new (major) version — stop and clear that before anything else.
## Updating the heatmaps
The build might fail now, due to the installers not knowing about the new DevExpress DLLs.
To fix this, execute the following command line in the root of the git directory:
`dotnet run --project .\scripts\Centron.Scripts\Centron.Scripts.csproj -- update-installer-product-heat`
This will update the `CentronProductHeat.wxs` and the `WebServiceProductHeat.wxs` (once for c-entron WS) to include the new missing files.
*If only the minor version changes the heatmaps might not need an update.*
## Cleanup & PR
Updating the heatmaps re-touches the `Directory.Build.props` file (the `setup-versioning` step rewrites `<Version>` and `<GitCommitId>`). **Revert those two back** (`<Version>1.0.0.0</Version>`, empty `<GitCommitId>`). The DevExpress version itself now lives in `DevExpress.Version.props`, not here, so it is unaffected.
Now you can create the PR and wait for it to merge. Due to the changes to `.sln` and `.csproj` files, it'll need someone from the code-reviewer group.
[Reference PR](https://dev.azure.com/CentronSoftware/c-entron.NET/_git/c-entron.NET/pullrequest/12182)
# [c-entron Outlook AddIn](https://dev.azure.com/CentronSoftware/c-entron%20Outlook%20Add-In)
This only needs to be done in coordination with the maintainer of the Addin.
First you need to update the centron.Help nuget package, then update the packages themselves.
Package|Projects
--|--
`DevExpress.*` | `Centron.OutlookAddin` & `Centron.Tickets`
`Centron.Help` | `Centron.OutlookAddin` & `Centron.Tickets`
`Centron.Controls` | `Centron.OutlookAddin` & `Centron.Tickets`
As before you also need to update the product heat. (reference c-entron<span>.NET)
**Make sure to run the terminal as administrator, otherwise the build _will_ fail!**
`dotnet run --project .\scripts\Centron.OutlookAddin.Scripts\Centron.OutlookAddin.Scripts.csproj -- update-installer-product-heat`
[Reference PR](https://dev.azure.com/CentronSoftware/c-entron%20Outlook%20Add-In/_git/c-entron%20Outlook%20Add-In/pullrequest/9193?path=/src/Centron.Tickets/Centron.Tickets.csproj)
# Finishing touches
After you're done you should send a notification e-mail to all developers so they are aware of the update and can (if needed) update their own projects.
*If you notice any changes to this process, then please update this documentation.*
# Further reading
## Error uploading nuget packages
### Error
`##[error]The nuget command failed with exit code(1) and error(System.AggregateException: One or more errors occurred. ---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 403 (Forbidden - User 'ed8980f1-8a8a-4b5f-a522-5ca37b713bec' lacks permission to complete this action. You need to have 'AddPackage'. (DevOps Activity ID: 36B90B94-83BC-46CE-9349-5A4F110417E5)).`
### Fix
Ensure the nuget version in the build pipeline via the `NuGetToolInstaller@1` command. [Microsoft documentation](https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/tool/nuget?view=azure-devops)
If you get this error and have no idea what it means go talk to the grandmasters of the build pipelines and show them this