Contributing
This repository lives at https://git.techcraftsmen.net/artur-rios/dotnet-messaging; the GitHub repository is a read-only mirror of it, so clone from there and open pull requests there:
git clone https://git.techcraftsmen.net/artur-rios/dotnet-messaging.git
Prerequisites
- .NET SDK 10.0 or later
- Git
Use the official .NET CLI to build, test and publish the project. If you want, optional helper toolsets I built to facilitate these tasks are available:
Build
dotnet build src/ArturRios.Messaging.sln
Testing
The test suite is xUnit, and every test is named with the Given / When / Then pattern. Every test class
carries a Category trait, so the two kinds can be run — and reported — separately:
dotnet test src/ArturRios.Messaging.sln --filter "Category=Unit"
dotnet test src/ArturRios.Messaging.sln --filter "Category=Functional"
Unit tests exercise the code in isolation against test doubles.
Functional tests send through a real HTTP server on the loopback interface and inspect the request that arrives.
The test check runs the two one after the other, and both must pass before a pull request can be merged. It is ci/test.sh, which you can run on your machine
as well.
The check also fails when a test has no Category trait, since no run would include it, and when
dotnet format --verify-no-changes finds a file to reformat; run dotnet format src/ArturRios.Messaging.sln before pushing.
The coverage check (ci/coverage.sh) runs the tests with coverage collected and makes the HTML report that the docs site
serves at /coverage-report/.
Branching and pull requests
develop is the integration branch and the base for all new work; main only holds released code.
Branch off develop — feature/<name> for features, fix/<name> for fixes (lowercase letters, digits, ., _ and - in the
name) — and open a pull request back into develop. Renovate’s renovate/* dependency-update branches are accepted into
develop too, and main only receives release/<version> pull requests.
Pull requests into develop and main must pass the test and coverage checks and the branch policy check, which Jenkins runs
(yggdrasil.yml and ci/ describe them).
Commit messages follow Conventional Commits with a lowercase subject, e.g.
feat: make mailgun api version configurable or fix: stop writing the Mailgun key onto a shared client.
Record every change a package consumer would notice under ## [Unreleased] in CHANGELOG.md, in the
same pull request that makes it.
Versioning
The project follows Semantic Versioning. As a library, its contract is the
public API and the documented behavior of the ArturRios.Messaging package:
- Major: a change that can break a consumer — a public type or member removed, renamed or given a different
signature, or documented behavior changed in a way callers may rely on. Its CHANGELOG entry carries an
### Upgrading from <X>.x to <Y>.0subsection telling consumers what to change. - Minor: new public API, or a behavior change existing callers do not have to adapt to, dependency updates included.
- Patch: a fix or tweak that leaves the public API and the documented behavior as they are.
The version number lives in one place, <Version> in src/ArturRios.Messaging.csproj, which dotnet pack uses as the package
version. It is set by hand on develop just before a release (see Releasing), and CI holds it to the release: the branch
policy check (ci/branch-policy.sh) requires it to match the release/<version> branch name, and packing (ci/pack.sh)
requires it to match the tag.
Releasing
A release branch is a snapshot of
developand carries no commits of its own, so prepare the release ondevelopfirst, in afeature/orfix/branch merged like any other: set<Version>insrc/ArturRios.Messaging.csprojto the new version, rename## [Unreleased]in CHANGELOG.md to## [<version>] - <yyyy-mm-dd>above a fresh, empty## [Unreleased], and update the compare links at the bottom.Cut
release/<version>from the updateddevelop, push it and open a pull request intomain. Onlyrelease/*branches can be merged intomain, and the branch policy check rejects a branch that carries a commitdevelopdoes not have or whose<Version>in the csproj is not the branch’s version.Once its checks have passed, the owner merges it with a merge commit. Then tag the merge commit on
mainwith the version, annotated. Pushing the tag publishes the package to nuget.org:git switch main && git pull git tag -a <version> -m <version> && git push origin <version>Tag with the bare version, e.g.
1.3.0. Some older releases were tagged with avprefix (v1.1.0); those tags stay as they are, but new tags drop the prefix.
Only the repository owner can push version tags. Jenkins builds the tag, which must point at a commit on main, packs the library
with ci/pack.sh (it fails when the tag’s version differs from <Version> in the csproj) and pushes the package to nuget.org.