{ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": ["config:recommended"], "labels": ["dependencies"], "semanticCommits": "enabled", "semanticCommitType": "chore", "semanticCommitScope": "deps", "commitMessageTopic": "{{depName}}", "rebaseWhen": "behind-base-branch", "automerge": true, "automergeType": "pr", "platformAutomerge": true, "minimumReleaseAge": "3 days", "dependencyDashboard": true, "lockFileMaintenance": { "enabled": false }, "ignorePaths": [ "**/node_modules/**", "decompiled/**", "sub_modules/**", "tools/.playground/**", "docker/modern/**" ], "packageRules": [ { "description": "server — SMAPI mod: mod/JunimoServer + JunimoServer.Shared (NuGet).", "matchManagers": ["nuget"], "matchFileNames": [ "mod/JunimoServer/JunimoServer.csproj", "mod/JunimoServer.Shared/JunimoServer.Shared.csproj" ], "semanticCommitScope": "deps/server", "groupName": "server" }, { "description": "steam-service — standalone Steam auth sidecar and its unit tests (NuGet).", "matchManagers": ["nuget"], "matchFileNames": [ "tools/steam-service/SteamService.csproj", "tests/SteamService.Tests/SteamService.Tests.csproj" ], "semanticCommitScope": "deps/steam-service", "groupName": "steam-service" }, { "description": "discord-bot — Discord integration bot (bun.lock).", "matchManagers": ["bun"], "matchFileNames": ["tools/discord-bot/package.json"], "semanticCommitScope": "deps/discord-bot", "groupName": "discord-bot" }, { "description": "test-runner — E2E harness: JunimoServer.TestRunner + JunimoServer.Tests, grouped so xunit.v3 (Tests) and xunit.v3.runner.utility (TestRunner) move in lockstep (NuGet).", "matchManagers": ["nuget"], "matchFileNames": [ "tests/JunimoServer.TestRunner/JunimoServer.TestRunner.csproj", "tests/JunimoServer.Tests/JunimoServer.Tests.csproj" ], "semanticCommitScope": "deps/test-runner", "groupName": "test-runner" }, { "description": "test-client — E2E automation mod: JunimoTestClient (NuGet).", "matchManagers": ["nuget"], "matchFileNames": ["tests/test-client/JunimoTestClient.csproj"], "semanticCommitScope": "deps/test-client", "groupName": "test-client" }, { "description": "test-ui — Vue test monitoring UI (bun.lock).", "matchManagers": ["bun"], "matchFileNames": ["tests/test-ui/package.json"], "semanticCommitScope": "deps/test-ui", "groupName": "test-ui" }, { "description": "tools — low-traffic helpers (dll-patcher, openapi-generator, netdebug) plus solution CLI tools (.config/dotnet-tools.json: csharpier, trxtoextentreport) (NuGet).", "matchManagers": ["nuget"], "matchFileNames": [ "tools/dll-patcher/SDVPatcher.csproj", "tools/openapi-generator/openapi-generator.csproj", "tools/netdebug/NetDebug.csproj", ".config/dotnet-tools.json" ], "semanticCommitScope": "deps/tools", "groupName": "tools" }, { "description": "project — repo tooling: commitlint, lefthook, pako (package-lock.json).", "matchManagers": ["npm"], "matchFileNames": ["package.json"], "semanticCommitScope": "deps/project", "groupName": "project" }, { "description": "docs — VitePress site (bun.lock).", "matchManagers": ["bun"], "matchFileNames": ["docs/package.json"], "semanticCommitScope": "deps/docs", "groupName": "docs" }, { "description": "docker — base images (dockerfile) plus custom Dockerfile download-URL/ARG pins, SMAPI + tmux (custom.regex).", "matchManagers": ["dockerfile", "custom.regex"], "semanticCommitScope": "deps/docker", "groupName": "docker" }, { "description": "github-actions — all workflow action bumps.", "matchManagers": ["github-actions"], "semanticCommitScope": "deps/github-actions", "groupName": "github-actions" }, { "description": "dotnet-sdk — the .NET SDK version pinned via dotnet-version in .github/workflows/*.yml (the custom.regex manager below). Standalone, not folded into the docker or github-actions groups, so an SDK bump lands as one visible PR that runs full CI before automerge — the point of pinning the SDK instead of floating on 10.0.x. Must come after the docker group rule (last-match-wins) so it overrides that rule's custom.regex match, which would otherwise misroute the bump to deps/docker.", "matchManagers": ["custom.regex"], "matchPackageNames": ["dotnet-sdk"], "semanticCommitScope": "deps/dotnet-sdk", "groupName": "dotnet-sdk" }, { "description": "PIN — test-client mod-builder .NET 6 must match the game's runtime. Scoped to tag 6.0 in this file only; the 10.0 stages here and in docker/Dockerfile stay updatable.", "matchManagers": ["dockerfile"], "matchFileNames": ["docker/Dockerfile.test-client"], "matchPackageNames": ["mcr.microsoft.com/dotnet/sdk"], "matchCurrentValue": "6.0", "enabled": false }, { "description": "PIN — SteamKit2 at exactly 2.4.1 in the SMAPI mod (net6.0); 2.5.0+ and the 3.x major are incompatible with the in-game runtime. Scoped to JunimoServer.csproj only, so tools/steam-service/SteamService.csproj (on 3.x) stays updatable. versioning:semver is required — under the default nuget scheme allowedVersions silently no-ops for SteamKit2 because its version list interleaves prereleases (2.5.0-beta, 3.0.0-alpha); semver evaluates the constraint correctly. =2.4.1 (not bare 2.4.1, which semver reads as a >= floor).", "matchManagers": ["nuget"], "matchFileNames": ["mod/JunimoServer/JunimoServer.csproj"], "matchPackageNames": ["SteamKit2"], "versioning": "semver", "allowedVersions": "=2.4.1" }, { "description": "PIN — NSwag.Core at exactly 14.2.0 in the SMAPI mod (net6.0) and the openapi-generator tool. 14.3.0+ pulls NJsonSchema's transitive System.Text.Json above the game's net6 6.0.0 line (8.0.5, then 9.0.9 at 14.7.1), which drags in System.IO.Pipelines and reintroduces the net6 build warning. Both files are pinned in lockstep because the generator reflectively loads JunimoServer.dll and receives an NSwag.OpenApiDocument across the assembly boundary — the NSwag type identity must match. versioning:semver — the default nuget scheme can silently no-op allowedVersions for packages with interleaved prereleases. =14.2.0 (not bare, which semver reads as a >= floor).", "matchManagers": ["nuget"], "matchFileNames": [ "mod/JunimoServer/JunimoServer.csproj", "tools/openapi-generator/openapi-generator.csproj" ], "matchPackageNames": ["NSwag.Core"], "versioning": "semver", "allowedVersions": "=14.2.0" }, { "description": "PIN — Grpc.Net.Client at exactly 2.71.0 in the SMAPI mod (net6.0). Inert guard: the package is not currently referenced, but 2.72.0+ pulls Microsoft.Extensions.Logging.Abstractions/DependencyInjection.Abstractions to 8.0.0, whose ServiceCollection collides with the mod's DI assembly (CS0433) and sits above the game's loaded 5.0.0.0 line. Pinning pre-emptively documents the net6 boundary so a future re-add can't silently regress. versioning:semver. =2.71.0 (not bare, which semver reads as a >= floor).", "matchManagers": ["nuget"], "matchFileNames": ["mod/JunimoServer/JunimoServer.csproj"], "matchPackageNames": ["Grpc.Net.Client"], "versioning": "semver", "allowedVersions": "=2.71.0" }, { "description": "PIN — Microsoft.Extensions.DependencyInjection at exactly 5.0.2 in the SMAPI mod (net6.0). The game ships Microsoft.Extensions.DependencyInjection.Abstractions.dll at AssemblyVersion 5.0.0.0 in its root folder and SMAPI loads that copy first; a mod that hard-references Abstractions 6.0.0.0 (which DI 6.x pulls transitively) is skipped with FileLoadException at mod-load time. DI must therefore track the version that yields Abstractions 5.0.0.0 — the 5.x line (5.0.2 is the terminal 5.x stable). Scoped to the mod csproj only; net10 projects (tests/runner/tools) keep their own Microsoft.Extensions.* versions. Lift only if the game's bundled Abstractions version changes (re-pin to match). versioning:semver — the default nuget scheme can silently no-op allowedVersions for packages with interleaved prereleases. =5.0.2 (not bare, which semver reads as a >= floor).", "matchManagers": ["nuget"], "matchFileNames": ["mod/JunimoServer/JunimoServer.csproj"], "matchPackageNames": ["Microsoft.Extensions.DependencyInjection"], "versioning": "semver", "allowedVersions": "=5.0.2" }, { "description": "CAP — Websocket.Client below 5.0 in the SMAPI mod (net6.0). 4.x depends only on System.Reactive + System.Threading.Channels; 5.x adds Microsoft.Extensions.Logging.Abstractions 8.x, which transitively pulls DependencyInjection.Abstractions 8.0.0.0. That collides with the pinned DI 5.0.2 (CS0433 on ServiceCollection) and sits above the game's loaded 5.0.0.0 Abstractions line — same boundary as the DI/Grpc pins. The cap still allows safe 4.x patch bumps (4.x stays on the no-Microsoft.Extensions graph). Lift only as part of moving the whole mod off the Abstractions-5.0.0.0 floor. versioning:semver — the default nuget scheme can silently no-op allowedVersions for packages with interleaved prereleases.", "matchManagers": ["nuget"], "matchFileNames": ["mod/JunimoServer/JunimoServer.csproj"], "matchPackageNames": ["Websocket.Client"], "versioning": "semver", "allowedVersions": "<5.0.0" }, { "description": "CAP — Microsoft.OpenApi below 2.0 in the test-client. The 2.0/3.x rewrite changes Type (string→JsonSchemaType enum), makes SerializeAsJson/Yaml async, and redesigns OpenApiReference/OperationType, so OpenApiGenerator.cs would not compile. Lift once OpenApiGenerator.cs is ported to the 2.x model. versioning:semver — the default nuget scheme can silently no-op allowedVersions for packages with interleaved prereleases.", "matchManagers": ["nuget"], "matchFileNames": ["tests/test-client/JunimoTestClient.csproj"], "matchPackageNames": ["Microsoft.OpenApi"], "versioning": "semver", "allowedVersions": "<2.0.0" }, { "description": "CAP — Microsoft.NET.Test.Sdk below 18.0 in the xunit.v3 test projects. 18.x bundles Microsoft Testing Platform v2.0, but the default xunit.v3 package targets MTP v1, so the pair fails at runtime with TypeLoadException for IDataConsumer (xunit#3416, by design). Lift only as part of a coordinated migration to the xunit.v3.mtp-v2 packages and matching coverlet 10 (coverlet.collector is left ungated so it can move with that migration).", "matchManagers": ["nuget"], "matchFileNames": [ "tests/JunimoServer.Tests/JunimoServer.Tests.csproj", "tests/JunimoServer.UnitTests/JunimoServer.UnitTests.csproj", "tests/SteamService.Tests/SteamService.Tests.csproj" ], "matchPackageNames": ["Microsoft.NET.Test.Sdk"], "versioning": "semver", "allowedVersions": "<18.0.0" }, { "description": "CAP — xunit.v3 stack below 4.0 (coordinated MTP-v2 major, deferred alongside the Test.Sdk 18 cap above). xunit.v3 (Tests, UnitTests, SteamService.Tests) + xunit.v3.runner.utility (TestRunner) must move together — split majors fail restore (NU1107, mismatched xunit.v3.runner.common) — and 4.x drops AssemblyRunnerOptions.ParallelizeTestCollections, set in TestRunner/Program.cs. xunit.runner.visualstudio is deliberately NOT capped: it has no xunit.v3 package dependency, and 4.0.0 runs xunit.v3 3.2.2 projects under VSTest (verified: SteamService.Tests 7/7 green on the runner-4.0 Renovate PR). versioning:semver — nuget silently no-ops allowedVersions on interleaved prereleases.", "matchManagers": ["nuget"], "matchFileNames": [ "tests/JunimoServer.Tests/JunimoServer.Tests.csproj", "tests/JunimoServer.TestRunner/JunimoServer.TestRunner.csproj", "tests/JunimoServer.UnitTests/JunimoServer.UnitTests.csproj", "tests/SteamService.Tests/SteamService.Tests.csproj" ], "matchPackageNames": ["xunit.v3", "xunit.v3.runner.utility"], "versioning": "semver", "allowedVersions": "<4.0.0" }, { "description": "CAP — SixLabors.ImageSharp below 4.0 in the E2E test project, pending a Six Labors license key in CI. 4.0 is the first release to enforce a build-time license key for direct package dependencies, so merging it breaks the build until the (free-to-apply for OSS) key is provisioned. Lift once the key is wired into the build. versioning:semver — the default nuget scheme can silently no-op allowedVersions for packages with interleaved prereleases.", "matchManagers": ["nuget"], "matchFileNames": [ "tests/JunimoServer.Tests/JunimoServer.Tests.csproj" ], "matchPackageNames": ["SixLabors.ImageSharp"], "versioning": "semver", "allowedVersions": "<4.0.0" }, { "description": "CAP — SixLabors.ImageSharp.Drawing below 3.0 in the E2E test project, lockstep with the ImageSharp <4.0 cap above. Drawing 3.0.0 depends on ImageSharp >=4.0.0, so bumping it forces a 4.0 downgrade conflict (NU1605) against the pinned 3.1.x. The 2.1.x line targets ImageSharp 3.1.x. Lift together with the ImageSharp cap once the license key is wired in. versioning:semver — the default nuget scheme can silently no-op allowedVersions for packages with interleaved prereleases.", "matchManagers": ["nuget"], "matchFileNames": [ "tests/JunimoServer.Tests/JunimoServer.Tests.csproj" ], "matchPackageNames": ["SixLabors.ImageSharp.Drawing"], "versioning": "semver", "allowedVersions": "<3.0.0" }, { "description": "CAP — typescript below 7.0 in test-ui and docs. TS 7 is the Go-native port: its npm package ships a platform binary plus a version stub (lib/ holds only tsc.js and version.cjs, and exports[\".\"] maps to lib/version.cjs), so the compiler JS API is gone until the API planned for 7.1. vue-tsc's engine @volar/typescript consumes that API, so `vue-tsc --noEmit` dies with ERR_PACKAGE_PATH_NOT_EXPORTED on './lib/tsc' — breaking `bun run build` in test-ui, which gates `make build-test-ui` and the Build test-UI SPA step in e2e-tests.yml. Verified against vue-tsc 3.3.9. vue-tsc's peer range (>=5.0.0) accepts 7.x, so nothing warns at install time. docs is capped in lockstep: its tsconfig includes .vitepress/**/*.vue, which tsgo cannot check, and vitepress build never invokes tsc — 7.x is all risk and no gain there. No versioning:semver here, unlike the nuget caps above: the bun manager uses npm versioning, which evaluates <7.0.0 correctly. Lift once Volar runs on the TS 7.1 API (vuejs/language-tools#5381).", "matchManagers": ["bun"], "matchFileNames": [ "tests/test-ui/package.json", "docs/package.json" ], "matchPackageNames": ["typescript"], "allowedVersions": "<7.0.0" }, { "description": "MAJOR — every major update gets its own PR, no exceptions. Clears the per-module groupName for any major bump (last-match-wins), so each major lands standalone. Must stay last to override every group above.", "matchUpdateTypes": ["major"], "groupName": null } ], "customManagers": [ { "customType": "regex", "description": "SMAPI — version ARG in docker/Dockerfile and docker/Dockerfile.test-client. Pattern excludes docker/modern/** (out of scope) — anchored so the modern/ path segment doesn't match, independent of ignorePaths.", "managerFilePatterns": ["/^docker/Dockerfile(\\.[^/]+)?$/"], "matchStrings": ["ARG SMAPI_VERSION=(?[0-9.]+)"], "depNameTemplate": "Pathoschild/SMAPI", "datasourceTemplate": "github-releases", "versioningTemplate": "semver" }, { "customType": "regex", "description": "tmux — version ARG TMUX_VERSION in docker/Dockerfile; referenced via ${TMUX_VERSION} in the install RUN so one bump propagates to URL and tarball name alike. Uses 'deb' versioning so the letter-suffix tags (3.6a < 3.6b) order correctly — semver and the other schemes don't order the trailing letter.", "managerFilePatterns": ["/^docker/Dockerfile(\\.[^/]+)?$/"], "matchStrings": ["ARG TMUX_VERSION=(?[0-9.]+[a-z]?)"], "depNameTemplate": "tmux/tmux-builds", "datasourceTemplate": "github-releases", "extractVersionTemplate": "^v(?.+)$", "versioningTemplate": "deb" }, { "customType": "regex", "description": "dotnet-sdk — the pinned dotnet-version in .github/workflows/*.yml. Matches both quote styles and captures only a concrete version (e.g. 10.0.400), never a floating 10.0.x. datasource dotnet-version resolves depName dotnet-sdk against Microsoft's SDK release index; it has no default versioning, so semver is set explicitly (SDK versions order correctly under it, and config:recommended's ignoreUnstable keeps previews out).", "managerFilePatterns": ["/^\\.github/workflows/[^/]+\\.ya?ml$/"], "matchStrings": ["dotnet-version:\\s*[\"'](?\\d+\\.\\d+\\.\\d+)[\"']"], "depNameTemplate": "dotnet-sdk", "datasourceTemplate": "dotnet-version", "versioningTemplate": "semver" } ] }