fix: resolve SonarCloud findings across the codebase and enforce style rules#4990
Merged
Conversation
arturcic
force-pushed
the
fix/sonar-fixes
branch
2 times, most recently
from
June 29, 2026 12:02
4505e75 to
0720553
Compare
arturcic
added a commit
to arturcic/GitVersion
that referenced
this pull request
Jun 29, 2026
- Revert the ConfigurationSerializer static conversion: making the methods static required explicit interface implementations, which Sonar then flagged for S2325 anyway (an explicit interface impl cannot be static). S2325 on IConfigurationSerializer implementations is not actionable and is dispositioned as False Positive instead. Restores ConfigurationHelper, WorkflowManager and the test call sites to their original form. - GitRepositoryInfo: pass separators directly to Split's params overload instead of an array literal (S3878), keeping the [^1] indexing that resolved S6608. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
arturcic
force-pushed
the
fix/sonar-fixes
branch
from
June 29, 2026 12:39
24c797a to
1268597
Compare
Resolve Sonar issue by replacing inline Regex compilation with a centralized cache to improve performance and resource usage.
Reorder declarations so method overloads sit together (no behavior change): - Equals overloads in SemanticVersion, ReferenceName, and the LibGit2Sharp Branch/Commit/RefSpec/Remote/Tag wrappers - Exclude overloads in PathFilter - FindMergeBase overloads in RepositoryStore - NormalizeGitDirectory overloads in GitPreparer Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- S112: throw InvalidOperationException instead of NullReferenceException
(repo not initialized) and bare Exception (remote 401/403/404/unknown)
- S6608/S3220: use Split(['/','\\'])[^1] instead of Split('/','\\').Last()
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- S112: throw InvalidOperationException instead of bare Exception when the APPVEYOR_API_URL env var is missing (AppVeyor) - S1125: '== true' -> 'is true' on nullable bool (AzurePipelines) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- S131: add default case (*) to the test shell scripts' argument parsing - S4663: replace empty comment with rationale in MsBuildAppender's catch - S1118: make the integration test Program class static Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Create the log file via CreateText().Dispose() instead of an empty using block (S108) - Replace the empty comment in the log-write catch with the rationale for swallowing (S4663) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ConfigurationProvider: default the Provide override parameter to null (S1006) and filter overrides with OfType instead of a foreach + null check (S3267) - ConfigurationSerializer: make Serialize/Deserialize/ReadConfiguration static with explicit interface implementations (S2325); update call sites in ConfigurationHelper, WorkflowManager and tests - BranchConfigurationBuilder: assign directly instead of calling the params overload (S3220) - ConfigurationException: drop [Serializable] (S3925) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ProjectFileUpdater: fold projectFile.FullName into a Select instead of a per-iteration local (S3267) - WixVersionFileUpdater: make wixVersionFile a local variable instead of a field (S1450) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the AttributeClass?.TypeArguments.Any() is true check with a
null-safe { Length: > 0 } property pattern, removing the boolean literal.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Convert the public fields on the Options DTOs (GitVersionOptions, AssemblySettingsInfo, ConfigurationInfo, RepositoryInfo, Settings, WixInfo) to auto-properties, matching their 'Gets or sets' documentation, and drop two redundant '= false' initializers. PublicAPI baseline updated to the corresponding get/set entries. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…VersionService (S1006) Add the '= null' defaults declared on ITaggedSemanticVersionService to the four public implementing methods so the implementation and interface agree. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rename the object Equals override parameter from 'other' to 'obj' to match System.Object.Equals, updating the PublicAPI baseline accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- SourceBranchFinder: seal the private SourceBranchPredicate class (S3260) - Simplify foreach+if loops with LINQ Where/Select (S3267) in RepositoryStore, TaggedSemanticVersionService, VersionFieldExtensions and VersionInBranchNameVersionStrategy - Add comparison operators to ReferenceName and SemanticVersionWithTag, which implement IComparable<T> (S1210); PublicAPI baseline updated S3220 in GitVersionCacheKeyFactory is dispositioned as False Positive (the collection expression call is not actually ambiguous); S4136 in this project was already resolved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Normalize the casing of diagnostic IDs for consistency and set IDE0305 (collection expressions) to error severity.
- EffectiveConfiguration: InvalidOperationException for the 'should not happen' configuration invariant checks - GitPreparer: DirectoryNotFoundException when the .git directory can't be found; InvalidOperationException for invalid dynamic-repository configuration Also simplify a VersionStrategiesConverter array creation to a collection expression (IDE0305) which surfaced in the build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Seal SemanticVersion, SemanticVersionBuildMetaData, ReferenceName and NextVersion. They override Equals/operators and implement IEquatable<T>; none are subclassed, so sealing avoids the subclass-equality pitfall S4035 warns about. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
arturcic
force-pushed
the
fix/sonar-fixes
branch
from
June 29, 2026 14:15
e8819a5 to
6aef2ab
Compare
Apply the repo's new collection-expression rule to the build/ci solution: PackageChocolatey, ContextExtensions and DockerContextExtensions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Drop [Serializable] from GitVersionException and WarningException (S3925) - Replace nested ternaries with if/else or extracted locals in GitPreparer, SemanticVersionPreReleaseTag and MainlineVersionStrategy (S3358) - Merge nested if in GitPreparer (S1066) S2589 x3 in TaggedSemanticVersionRepository dispositioned False Positive (isCached flips to false inside the GetOrAdd factory on a cache miss; Sonar can't model that). S107 on the GitPreparer constructor accepted (DI constructor; parameter-object bundles declined). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Update .editorconfig to require braces for all code blocks (csharp_prefer_braces = true) with error severity to address Sonar linting issues.
Set csharp_prefer_braces = true:error in .editorconfig and add braces to all if/else/for/foreach/while/using statements across the src, new-cli and ci solutions via dotnet format. Purely syntactic; no behaviour change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Repeated literals in the test scenarios (branch names, versions, config keys) are intentional test data; suppress the rule for *.Tests projects via editorconfig. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
arturcic
force-pushed
the
fix/sonar-fixes
branch
from
June 29, 2026 16:05
950ce44 to
b02f15e
Compare
arturcic
added a commit
to arturcic/GitVersion
that referenced
this pull request
Jun 29, 2026
- GitRepositoryInfo: Split('/', '\\') bound to Split(char, int count) because '\\'
implicitly converts to int (count=92), so it split by '/' only instead of both
separators. Use a cached char[] separator field so it binds to Split(params char[])
unambiguously (fixes the latent bug and S3220).
- AzurePipelines: replace '?.StartsWith(...) is true' with an explicit null check to
drop the redundant boolean literal (S1125).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- GitRepositoryInfo: Split('/', '\\') bound to Split(char, int count) because '\\'
implicitly converts to int (count=92), so it split by '/' only instead of both
separators. Use a cached char[] separator field so it binds to Split(params char[])
unambiguously (fixes the latent bug and S3220).
- AzurePipelines: replace '?.StartsWith(...) is true' with an explicit null check to
drop the redundant boolean literal (S1125).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
arturcic
force-pushed
the
fix/sonar-fixes
branch
from
June 29, 2026 16:42
c1e80d0 to
9ff7871
Compare
Contributor
|
Thank you @arturcic for your contribution! |
|
arturcic
added a commit
that referenced
this pull request
Jun 29, 2026
…e rules (#4990) * fix(src): use Regex cache in PathFilter Resolve Sonar issue by replacing inline Regex compilation with a centralized cache to improve performance and resource usage. * fix(src): make overloaded methods adjacent (S4136) Reorder declarations so method overloads sit together (no behavior change): - Equals overloads in SemanticVersion, ReferenceName, and the LibGit2Sharp Branch/Commit/RefSpec/Remote/Tag wrappers - Exclude overloads in PathFilter - FindMergeBase overloads in RepositoryStore - NormalizeGitDirectory overloads in GitPreparer Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(src): resolve LibGit2Sharp Sonar issues - S112: throw InvalidOperationException instead of NullReferenceException (repo not initialized) and bare Exception (remote 401/403/404/unknown) - S6608/S3220: use Split(['/','\\'])[^1] instead of Split('/','\\').Last() Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(src): resolve BuildAgents Sonar issues (S112, S1125) - S112: throw InvalidOperationException instead of bare Exception when the APPVEYOR_API_URL env var is missing (AppVeyor) - S1125: '== true' -> 'is true' on nullable bool (AzurePipelines) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: resolve assorted Sonar issues - S131: add default case (*) to the test shell scripts' argument parsing - S4663: replace empty comment with rationale in MsBuildAppender's catch - S1118: make the integration test Program class static Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(app): resolve FileAppender Sonar issues (S108, S4663) - Create the log file via CreateText().Dispose() instead of an empty using block (S108) - Replace the empty comment in the log-write catch with the rationale for swallowing (S4663) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(config): resolve assorted Sonar issues - ConfigurationProvider: default the Provide override parameter to null (S1006) and filter overrides with OfType instead of a foreach + null check (S3267) - ConfigurationSerializer: make Serialize/Deserialize/ReadConfiguration static with explicit interface implementations (S2325); update call sites in ConfigurationHelper, WorkflowManager and tests - BranchConfigurationBuilder: assign directly instead of calling the params overload (S3220) - ConfigurationException: drop [Serializable] (S3925) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(output): resolve Sonar issues (S3267, S1450) - ProjectFileUpdater: fold projectFile.FullName into a Select instead of a per-iteration local (S3267) - WixVersionFileUpdater: make wixVersionFile a local variable instead of a field (S1450) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(new-cli): resolve CommandBaseGenerator Sonar issue (S1125) Replace the AttributeClass?.TypeArguments.Any() is true check with a null-safe { Length: > 0 } property pattern, removing the boolean literal. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(core): encapsulate public Options fields as properties (S1104) Convert the public fields on the Options DTOs (GitVersionOptions, AssemblySettingsInfo, ConfigurationInfo, RepositoryInfo, Settings, WixInfo) to auto-properties, matching their 'Gets or sets' documentation, and drop two redundant '= false' initializers. PublicAPI baseline updated to the corresponding get/set entries. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(core): match interface default parameter values in TaggedSemanticVersionService (S1006) Add the '= null' defaults declared on ITaggedSemanticVersionService to the four public implementing methods so the implementation and interface agree. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(core): rename NextVersion.Equals parameter to match base (S927) Rename the object Equals override parameter from 'other' to 'obj' to match System.Object.Equals, updating the PublicAPI baseline accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(core): resolve MINOR Sonar issues (S3260, S3267, S1210) - SourceBranchFinder: seal the private SourceBranchPredicate class (S3260) - Simplify foreach+if loops with LINQ Where/Select (S3267) in RepositoryStore, TaggedSemanticVersionService, VersionFieldExtensions and VersionInBranchNameVersionStrategy - Add comparison operators to ReferenceName and SemanticVersionWithTag, which implement IComparable<T> (S1210); PublicAPI baseline updated S3220 in GitVersionCacheKeyFactory is dispositioned as False Positive (the collection expression call is not actually ambiguous); S4136 in this project was already resolved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style: update editorconfig rules and enforce collection expressions Normalize the casing of diagnostic IDs for consistency and set IDE0305 (collection expressions) to error severity. * fix(core): throw specific exceptions instead of System.Exception (S112) - EffectiveConfiguration: InvalidOperationException for the 'should not happen' configuration invariant checks - GitPreparer: DirectoryNotFoundException when the .git directory can't be found; InvalidOperationException for invalid dynamic-repository configuration Also simplify a VersionStrategiesConverter array creation to a collection expression (IDE0305) which surfaced in the build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(core): seal equality types (S4035) Seal SemanticVersion, SemanticVersionBuildMetaData, ReferenceName and NextVersion. They override Equals/operators and implement IEquatable<T>; none are subclassed, so sealing avoids the subclass-equality pitfall S4035 warns about. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style(build): use collection expressions in ci solution (IDE0305) Apply the repo's new collection-expression rule to the build/ci solution: PackageChocolatey, ContextExtensions and DockerContextExtensions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(core): resolve MAJOR Sonar issues (S3925, S3358, S1066) - Drop [Serializable] from GitVersionException and WarningException (S3925) - Replace nested ternaries with if/else or extracted locals in GitPreparer, SemanticVersionPreReleaseTag and MainlineVersionStrategy (S3358) - Merge nested if in GitPreparer (S1066) S2589 x3 in TaggedSemanticVersionRepository dispositioned False Positive (isCached flips to false inside the GetOrAdd factory on a cache miss; Sonar can't model that). S107 on the GitPreparer constructor accepted (DI constructor; parameter-object bundles declined). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style: enforce braces for all control flow statements Update .editorconfig to require braces for all code blocks (csharp_prefer_braces = true) with error severity to address Sonar linting issues. * style: enforce braces on control-flow statements (IDE0011) Set csharp_prefer_braces = true:error in .editorconfig and add braces to all if/else/for/foreach/while/using statements across the src, new-cli and ci solutions via dotnet format. Purely syntactic; no behaviour change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style: disable S1192 (duplicate string literals) in test projects Repeated literals in the test scenarios (branch names, versions, config keys) are intentional test data; suppress the rule for *.Tests projects via editorconfig. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: resolve remaining PR #4990 Sonar issues (S3220, S1125) - GitRepositoryInfo: Split('/', '\\') bound to Split(char, int count) because '\\' implicitly converts to int (count=92), so it split by '/' only instead of both separators. Use a cached char[] separator field so it binds to Split(params char[]) unambiguously (fixes the latent bug and S3220). - AzurePipelines: replace '?.StartsWith(...) is true' with an explicit null check to drop the redundant boolean literal (S1125). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Member
Author
|
🎉 This issue has been resolved in version 6.8.0 🎉 Your GitReleaseManager bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Comprehensive SonarCloud cleanup across
src,new-cli, and thebuild/cisolutions, plus two style-policy additions to.editorconfig. Code fixes are in this PR; analyzer false-positive / won't-fix dispositions were applied on SonarCloud directly.Code fixes
GitVersion.Core
Optionsfields (GitVersionOptions,Settings,RepositoryInfo, …) encapsulated as auto-propertiesTaggedSemanticVersionService,ConfigurationProvider)InvalidOperationException/DirectoryNotFoundExceptioninstead of bareSystem.Exception(EffectiveConfiguration,GitPreparer)SemanticVersion,SemanticVersionBuildMetaData,ReferenceName,NextVersionforeach+ifsimplified with LINQWhere/Selectif/elseor locals[Serializable](GitVersionException,WarningException)IComparable<T>types (ReferenceName,SemanticVersionWithTag)ifmerged, private class sealedOther projects
Split('/', '\\')overload bug where'\\'bound to theint countparameter; now uses a cachedchar[]separator)Style policy (
.editorconfig)*.Testsprojects — repeated literals there are intentional test dataDispositions on SonarCloud (not code)
extensionblocks;ArgumentParserS2259/S2325 (null-safestring?extension members; instance-method call);ConfigurationSerializerS2325 ×2 (interface implementations can't be static);TaggedSemanticVersionRepositoryS2589 ×3 (isCachedflips inside theGetOrAddfactory);GitVersionCacheKeyFactoryS3220 (collection-expression call is not actually ambiguous);JsonPropertyDescriptionAttributeS3903;GitVersionInformationtemplate S1199Out of scope (deferred)
Verification
dotnet build— 0 warnings / 0 errors onsrc,new-cli, andbuild/CIsolutionsdotnet format --verify-no-changes— clean on all three solutions🤖 Generated with Claude Code