Configure Renovate to handle nuspec files
Tags: dotnet, renovate, csharp, security
Published: 2024-05-04 20:34:27

I [recently mentioned that Renovate's NuGet manager only supports certain files by default](https://anthonysimmon.com/nuget-version-range-updates-dotnet-renovate/), and `.nuspec` files are not among them. These are [XML manifests that describe the metadata of a NuGet package](https://learn.microsoft.com/en-us/nuget/reference/nuspec). Although nowadays, [SDK-style projects](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#project-files) are sufficient for most cases to describe and generate NuGet packages, there are still many very popular projects that rely on `.nuspec` files, as shown by this [search on GitHub](https://github.com/search?q=path%3A*.nuspec&type=code).

`.nuspec` files can contain references to dependencies, making them important to consider in the Renovate update process, primarily for security reasons. Once again, we will use Renovate's extensibility with regular expressions to enable it to handle these files.

## Renovate configuration for handling nuspec files

The following Renovate configuration:

1. Detects files with the `.nuspec` extension,
2. Uses a regex to parse the dependencies and their versions,
3. Applies the update management that would be used for NuGet.

```json
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:best-practices"
  ],
  "enabledManagers": [
    "nuget",
    "custom.regex"
  ],
  "customManagers": [
    {
      "description": "Nuspec files manager",
      "customType": "regex",
      "fileMatch": ["\\.nuspec$"],
      "matchStringsStrategy": "any",
      "matchStrings": [
        "<dependency\\s+id=\"(?<depName>.*?)\"\\s+version=\"(?<currentValue>.*?)\"\\s*\\/>"
      ],
      "datasourceTemplate": "nuget",
      "versioningTemplate": "nuget"
    }
  ]
}
```

## Testing the configuration

We can validate this configuration against a `.nuspec` file containing a reference to an old version of the C# MongoDB driver which contains a security vulnerability:

```xml
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
  <metadata>
    <id>MyLibrary</id>
    <version>$version$</version>
    <description>Example nuspec file with an outdated, vulnerable dependency</description>
    <authors>johndoe</authors>
    <dependencies>
      <dependency id="MongoDB.Driver" version="2.18.0" />
    </dependencies>
  </metadata>
</package>
```

When [running Renovate locally](https://anthonysimmon.com/locally-test-validate-renovate-config-files/), we can see that the `MongoDB.Driver` dependency is detected and Renovate recommends updating it to version `2.25.0`:

```
DEBUG: packageFiles with updates (repository=local)
       "config": {
         "regex": [
           {
             "deps": [
               {
                 "depName": "MongoDB.Driver",
                 "currentValue": "2.18.0",
                 "datasource": "nuget",
                 "versioning": "nuget",
                 "replaceString": "<dependency id=\"MongoDB.Driver\" version=\"2.18.0\" />",
                 "updates": [
                   {
                     "bucket": "non-major",
                     "newVersion": "2.25.0",
                     "newValue": "2.25.0",
                     "releaseTimestamp": "2024-04-12T21:27:47.967Z",
                     "newMajor": 2,
                     "newMinor": 25,
                     "updateType": "minor",
                     "branchName": "renovate/mongo-csharp-driver-monorepo"
                   }
                 ],
                 "packageName": "MongoDB.Driver",
                 "warnings": [],
                 "sourceUrl": "https://github.com/mongodb/mongo-csharp-driver",
                 "registryUrl": "https://api.nuget.org/v3/index.json",
                 "homepage": "https://www.mongodb.com/docs/drivers/csharp/",
                 "currentVersion": "2.18.0",
                 "isSingleVersion": true,
                 "fixedVersion": "2.18.0"
               }
             ],
             "matchStrings": [
               "<dependency\\s+id=\"(?<depName>.*?)\"\\s+version=\"(?<currentValue>.*?)\"\\s*\\/>"
             ],
             "matchStringsStrategy": "any",
             "datasourceTemplate": "nuget",
             "versioningTemplate": "nuget",
             "packageFile": "MyLibrary.nuspec"
           }
         ]
       }
```

## References

- [nuspec File Reference for NuGet](https://learn.microsoft.com/en-us/nuget/reference/nuspec)
- [Renovate's NuGet manager documentation](https://docs.renovatebot.com/modules/manager/nuget/)