English | Português (Brasil)
Thank you for contributing to ComplexityAnalysis.Analyzers. Keep changes focused, reviewable, and aligned with the analyzer's public diagnostics, compatibility guarantees, and conservative analysis model.
By participating in this project, you agree to follow CODE_OF_CONDUCT.md.
Install:
- .NET SDK 10, or a compatible SDK selected by
global.json; - Git.
No globally installed .NET tool should be required for the standard development workflow.
From the repository root:
dotnet tool restore
dotnet restore ComplexityAnalysis.Analyzers.slnxUse the canonical release-quality policy to classify the change and decide which evidence applies:
Validation is proportional to risk. Documentation-only changes can stay light; analyzer behavior, performance-sensitive, Roslyn/dependency, packaging, CI, and release changes need the focused evidence listed in the policy.
Before opening a pull request, run the checks required by the change type. For broad analyzer, build, package, or repository changes, the common core path is:
dotnet build ComplexityAnalysis.Analyzers.slnx --configuration Release --no-restore
dotnet test ComplexityAnalysis.Analyzers.slnx --configuration Release --no-build
dotnet pack src/ComplexityAnalysis.Analyzers/ComplexityAnalysis.Analyzers.csproj --configuration Release --no-build -p:PackageVersion=0.0.0-local --output artifacts/local-packagesFor docs-only changes, record the lighter review that applies, such as Markdown
review, link review, git diff --check, and no analyzer behavior impact.
When a change touches formatting or analyzer style rules, also run the repository formatting checks configured by the project.
A contribution should address one cohesive concern. Avoid mixing unrelated refactors, formatting changes, dependency updates, documentation rewrites, and feature work unless they are required by the same change.
Prefer the smallest change that solves the problem while preserving analyzer correctness, package compatibility, build performance, and conservative Unknown behavior for unsupported cases.
Changes that affect complexity estimation or diagnostics should preserve the project's semantic-analysis principles:
- use Roslyn syntax, symbols, and semantic information rather than text-only matching;
- prefer
Unknownover an unsafe or unproven complexity estimate; - keep source-method traversal and recurrence solving bounded;
- avoid analyzer hot-path I/O, network access, process execution, or heavyweight reflection;
- preserve compatibility with supported compiler/SDK hosts.
When adding or changing a public diagnostic:
- add or update tests for triggering and non-triggering cases;
- update
src/ComplexityAnalysis.Analyzers/AnalyzerReleases.Unshipped.mdwhen required by analyzer release tracking; - update the analyzer catalog under
docs/en/analyzers.mdanddocs/pt-BR/analyzers.md; - document any new
.editorconfig/analyzer-config option in both configuration guides.
Behavior changes should be covered by tests. Bug fixes should include a regression test when practical. Analyzer rules should normally test both positive and negative cases to reduce false positives.
Changes to interprocedural analysis, recurrence solving, caching, budgets, or package loading should also consider the existing compatibility and performance test suites described by the canonical DoD.
Do not weaken existing validation merely to make a change pass.
Roslyn analyzers execute inside compiler and IDE hosts, so performance regressions can affect every consumer build.
For changes to analysis hot paths, caching, recursion, interprocedural traversal, or known-operation resolution, run the relevant performance tests and review allocation/complexity implications. Avoid broad scans when demand-driven analysis is sufficient.
Microsoft.CodeAnalysis.CSharp is intentionally pinned to the repository's selected Roslyn compatibility baseline. Do not upgrade the Roslyn compiler API package as a routine dependency update; such changes require explicit compatibility evaluation across supported hosts.
Do not introduce Microsoft.CodeAnalysis.Workspaces or runtime dependencies unless the feature clearly requires them and the architectural/package impact has been reviewed.
Production analyzer releases are created manually through the Release GitHub
Actions workflow in .github/workflows/release.yml; the CLI and MCP use the
independent workflows documented below.
Pull requests that change the release workflow or package-relevant files run only the build-and-pack path with a synthetic CI version. This dry run exercises package validation and SBOM generation without creating tags, publishing packages, generating attestations, or creating a GitHub Release.
Run the workflow from the main branch and provide only the semantic package version, without a v prefix:
1.0.0
The workflow derives the Git tag automatically:
1.0.0 -> v1.0.0
Prerelease versions are also supported, for example:
1.1.0-beta.1 -> v1.1.0-beta.1
The release pipeline:
- validates the semantic version and requires execution from
main; - restores, builds, tests, packs, and validates
ComplexityAnalysis.Analyzers; - generates and validates an SPDX 2.3 SBOM from the exact final
.nupkg; - creates the corresponding
v<version>Git tag, or verifies it when safely retrying the same release; - publishes the same
.nupkgto NuGet.org using Trusted Publishing and GitHub OIDC; - publishes the same
.nupkgto GitHub Packages using the workflowGITHUB_TOKEN; - creates GitHub build-provenance and SBOM attestations for the release package;
- creates or refreshes the GitHub Release and attaches both the package and its SPDX SBOM.
The NuGet.org Trusted Publishing policy must match the workflow identity exactly:
Repository owner: rodri-oliveira-dev
Repository: complexity-analyzers
Workflow file: release.yml
Environment: release
Package: ComplexityAnalysis.Analyzers
The NuGet publishing job uses the GitHub environment named release and id-token: write; no long-lived NuGet API key should be stored in repository secrets.
Release provenance and the SBOM can be verified locally with GitHub CLI. See Repository Security Baseline.
Do not manually move, reuse, or recreate an existing release tag for a different commit. Release tags are intended to be immutable.
The CLI has an independent release line. .github/workflows/release-tool.yml
publishes only ComplexityAnalysis.Tool, receives the production version as a
manual input, and derives tool-v<version> tags. It does not change or publish
the analyzer package. Pull requests run only its build, package-install, smoke,
and SBOM path; publication jobs run only for a manual dispatch from main.
Before the first 1.0.0 release, complete these external settings:
- In NuGet.org Trusted Publishing, create a GitHub policy owned by
rodri-oliveira-devfor repositorycomplexity-analyzers, workflow filerelease-tool.yml, and environmentrelease. Scope it to push new packages and package versions matching exactlyComplexityAnalysis.Tool. - In GitHub, ensure the
releaseenvironment permits deployments only frommainand configure the intended required reviewers. Do not add a NuGet API key; the publish job exchanges GitHub OIDC for a temporary credential. - Extend the repository tag ruleset to protect
tool-v*. Prevent deletion, force updates, and tag recreation while allowing the release workflow'scontents: writejob to create a new tag after validation. - Confirm GitHub Packages is enabled and repository Actions may write packages
with the workflow
GITHUB_TOKEN. - Recheck that
ComplexityAnalysis.Tooland the intended version are still available on NuGet.org. Availability before the first publish does not reserve the ID.
After approval and merge, select Release ComplexityAnalysis.Tool in GitHub
Actions, choose main, enter 1.0.0, and review the release environment
deployment. Do not pre-create the tag. A safe retry accepts an existing
tool-v1.0.0 only when it points at the same validated commit; package pushes
use skip-duplicate semantics and GitHub Release assets are never replaced.
The MCP server has a third independent release line.
.github/workflows/release-mcp.yml publishes only ComplexityAnalysis.Mcp,
accepts a manual semantic version, and derives mcp-v<version> tags. Pull
requests run its build, tests, package install, real MCP client contract, and
SBOM path without publication. Production jobs require a manual dispatch from
main. MCP GitHub Releases are explicitly not marked as the repository's
generic latest release, so analyzer release identification remains stable.
Before the first 1.0.0 release, complete these external settings:
- In NuGet.org Trusted Publishing, create a GitHub policy with owner
rodri-oliveira-dev, repositorycomplexity-analyzers, workflowrelease-mcp.yml, and environmentrelease. Authorize exactly package IDComplexityAnalysis.Mcpwith scope Push new packages and package versions. - Ensure the GitHub
releaseenvironment permits deployments only frommainand uses the intended required reviewers. Do not add a long-lived NuGet API key; the workflow exchanges GitHub OIDC for a temporary credential. - Extend the tag ruleset to protect
mcp-v*against deletion, force updates, and recreation while allowing the workflow's post-validation tag creation. - Confirm GitHub Packages is enabled and Actions may write packages with
GITHUB_TOKEN. - Recheck the availability of
ComplexityAnalysis.Mcpand version1.0.0on NuGet.org immediately before the first publish. - Confirm that GitHub OIDC for this repository can claim the
io.github.rodri-oliveira-dev/complexity-analysisnamespace in the Official MCP Registry. The Registry job usesid-token: writein the same protectedreleaseenvironment; do not configure a PAT or persistent Registry secret.
After approval and merge, select Release ComplexityAnalysis.Mcp, choose
main, enter 1.0.0, and review the protected deployment. Do not pre-create
the tag. The workflow publishes the exact artifact validated and installed in
the first job; it never generates release notes by comparing analyzer, CLI,
and MCP tag namespaces. After NuGet.org and the GitHub Release complete, it
publishes the synchronized .mcp/server.json through a pinned,
Sigstore-verified mcp-publisher and verifies the resulting Registry entry.
Registry failure is visible on the run but does not remove already published
artifacts; retry the same version only when its immutable metadata is compatible.
See the official Registry Actions guide.
Pull requests should:
- explain what changed and why;
- link the relevant issue when one exists;
- identify the change type from the canonical DoD;
- describe how the change was validated;
- call out diagnostic, compatibility, package, performance, or security impact;
- update English and Portuguese documentation together when public behavior changes;
- keep generated or unrelated files out of the diff.
Reviewers may request smaller changes, additional tests, clearer documentation, or compatibility evidence before approval.
Address review feedback with additional commits while the pull request is open. Resolve discussions only after the concern has been addressed or agreement has been reached.
A pull request is ready to merge when the intended behavior is clear, required checks pass, documentation matches the implementation, and no known analyzer-loading, compatibility, security, or performance issue is left unexplained.