We love receiving PRs from the community with features and fixed. For a big feature it's advised to raise an issue to discuss it first.
- Please avoid mixing changes needed for a feature with other changes such as refactors, automated IDE changes like adding BOM characters, empty lines, etc.
- Feel free to start with a draft PR, while you work on it. You can ask pointed questions by reviewing your own code this way, while signaling to the reviewer that the PR isn't ready for review just yet.
- Mark the PR ready for review once you've completed the change, including:
- The description should link to relevant context such as tickets, discussions or previous PRs. Consider screenshots of the events in Sentry or other relevant visual things.
- Add tests that verify your change. The repo has lots of examples of Unit and integration tests. Including device tests that run on Android and iOS.
- CI should be green.
- The ideal state is where a reviewer approves and merges it immediately. But on more complex changes, some back and forth during reviews is expected.
We prefer code that explains itself, so comments should be kept to a minimum:
- When code needs explaining, prefer refactoring it (better variable and method names, clearer structure) over adding a comment.
- Where a comment is genuinely needed, keep it short and to the point.
- Detailed context belongs in the pull request description rather than inline. When a comment does need lengthy background, reference the relevant PR instead of inlining the explanation.
- Install the .NET SDKs
- Install PowerShell
- Install Xcode
- Check out the submodules:
git submodule update --init --recursive - Restore workloads with
dotnet workload restore(needssudoon a Mac) - To quickly get up and running, you can just run
dotnet build SentryNoMobile.slnf(you're skipping the mobile targets) - To run a full build in Release mode and test, before pushing, run
./build.shor./build.cmd
-
The latest versions of the following .NET SDKs:
Technically, you only need the full SDK installation for the latest version. If you like, you can install the smaller ASP.NET Core Runtime packages for older versions. However, installing the full SDKs will also give you the runtimes.
-
pwshCore version 6 or later on PATH. -
CMakeon PATH. On Windows you can install the C++ CMake tools for Windows. On macOS and Linux you can use your favourite package manager (e.g.brew install cmakeorapt install cmake). -
On Windows:
- .NET Framework 4.6.2 or higher.
Sentry.DiagnosticSource.IntegrationTests.csprojuses SQL LocalDb - download SQL LocalDB 2019. To avoid running these tests, unloadSentry.DiagnosticSource.IntegrationTests.csprojfrom the solution.
-
On macOS/Linux
- Mono 6 or higher to run the unit tests on the
net4xtargets.
- Mono 6 or higher to run the unit tests on the
To build any of Sentry.Maui, Sentry.Maui.Tests, or Sentry.Samples.Maui, you'll need to have the MAUI workloads installed. You can do so by running dotnet workload restore from the root of the SDK's repository (or sudo dotnet workload restore on macOS/Linux).
See https://docs.microsoft.com/dotnet/maui/ for details. JetBrains also have a great blog post if you're developing on a Mac: https://blog.jetbrains.com/dotnet/2022/05/25/macos-environment-setup-for-maui-development/
Basically, if you can build and run the MyMauiApp example you should also be able to build and run the Sentry MAUI sample app.
- Targeting the mobile platforms requires aditional dependencies.
Javais required for building the Android bindings. If you're building Sentry using an IDE you provide the path to your Java installation via the IDE settings (open the settings for Visual Studio or Rider and search for "android"). Building Sentry from the command line (usingdotnet build) requiresJAVA_HOMEto be available on the environment.- Compiling for iOS and Mac Catalyst happens on macOS only.
Although the files in /src/Sentry/Platforms/ are part of the Sentry project, they are conditionally targeted when the platform is Android, iOS, or Mac Catalyst. We build for Android on all platforms.
<!-- Platform-specific props included here -->
<Import Project="Platforms\Android\Sentry.Android.props" Condition="'$(TargetPlatformIdentifier)' == 'android'" />
<Import Project="Platforms\Cocoa\Sentry.Cocoa.props" Condition="'$(TargetPlatformIdentifier)' == 'ios' Or '$(TargetPlatformIdentifier)' == 'maccatalyst'" />These *.props files are used to add platform-specific files, such as references to the binding projects for each native SDK. These binding projects are .NET wrappers around native Android or Cocoa SDK functions.
Also note /Directory.Build.targets contains some convention-based rules to exclude code that is not relevant for the target platform. Developers using Visual Studio will need to enable Show All Files in order to be able to see these files, when working with the solution.
When debugging a legacy ASP.NET application with project references to Sentry.AspNet, you may need the following workarounds to tooling issues:
TLDR; when working with the Sentry codebase, you should use the solution filters (not the solutions).
Full explanation:
The Sentry.slnx solution contains all of the projects required to build Sentry, it's integrations and samples for every platform. However, the repository contains various solution filters that will be more practical for day-to-day tasks.
These solution filters get generated automatically by /scripts/generate-solution-filters.ps1 so, although you can certainly create your own solution filters and manage these how you wish, don't try to modify any of the *.slnf files that are committed to source control. Instead, changes to these can be made by modifying /scripts/generate-solution-filters-config.yaml and re-running the script that generates these.
Also note that script generates a .generated.NoMobile.slnx solution, which is an identical copy of Sentry.slnx. Again, we don't recommend opening this directly. It exists as a round about way to conditionally set build properties based on the solution name in certain solution filters. You should instead use those solution filters (e.g. SentryNoMobile.slnf) when working in the Sentry codebase.
To automatically check and fix code formatting before committing, you can set up a pre-commit hook:
./dev.cs setup-hooksBefore each commit, the hook runs dotnet format against your staged .cs files and auto-fixes any formatting issues. If fixes were applied, the commit is blocked — just stage the fixes and try again:
git add -u
git commitNote: the hook skips automatically if you have unstaged changes, to avoid touching work in progress.
To opt out at any time:
./dev.cs remove-hooksNote: You can also bypass the hook for a specific commit using git commit --no-verify if needed.
This repository uses Verify to store the public API diffs in snapshot files. When a change involves modifying the public API area (by for example adding a public method), that change will need to be approved, otherwise the CI process will fail.
To do that, run the build locally (i.e: ./build.sh or build.cmd) and commit the verify files that were changed.
We'd love for users to update the SDK everytime and as soon as we make a new release. But in reality most users rarely update the SDK.
To help users see value in updating the SDK, we maintain a changelog file with entries split between headings such as ### Features and ### Fixes.
Do not edit CHANGELOG.md manually. The changelog is generated automatically at release time by craft (changelogPolicy: auto in .craft.yml) from the pull requests merged since the previous release. Entries are categorized from your commit message / PR title (e.g. a feat: PR becomes a Feature, a fix: PR becomes a Fix), so there's nothing to add by hand.
If the PR title doesn't capture the change well — you want more detail, or a single PR should produce several entries — add a ### Changelog Entry section to the PR description. craft uses the text under that heading verbatim instead of the PR title. See Custom changelog entries from PR descriptions.
If the change isn't user-facing and you'd rather it not appear in the changelog at all, add the skip-changelog label to the PR or write #skip-changelog in the PR description.
Ideally we like tests to be named following the convention Method_Context_Expectation.
[Fact]
public void PushScope_BreadcrumbWithinScope_NotVisibleOutside()Some tests use Verify to check returned objects against snapshots that are part of the repo. In case you're making code changes that produce many (intended) changes in those snapshots, you can use accept-verifier-changes.ps1 like this:
dotnet test
pwsh ./scripts/accept-verifier-changes.ps1You may need to run this multiple times because dotnet test stops after a certain number of failures.
Directory ./integration-test contains Pester-based integration tests.
These tests create sample apps with dotnet new and run against local nuget packages (.nuget files).
In CI, these packages are expected to be present, while locally, scripts will run nuget pack automatically.
You can run individual tests either via Pester integration (e.g. in VS Code), or from command line: ./integration-test/cli.Tests.ps1. Consult Pester docs for details on how to write tests.
Because these tests rely on a Sentry server mock (Invoke-SentryServer) from https://github.com/getsentry/github-workflows/tree/main/sentry-cli/integration-test, you need to check out getsentry/github-workflows as a sibling directory next to your getsentry/sentry-dotnet checkout.
This repo uses a variety of techniques to vendor in third party code without creating external dependencies. One of those is submodules.
One of those submodules is Ben.Demystifier, which was originally written by Ben Adams. Attempts to contact Ben in recent years have been unsuccessful, so we've started maintaining a permanent fork of the project at:
Any significant changes to the submodule should be made in a branch and merged into the submodule's main branch.
However, many of the Ben.Demystifier members are public. That makes sense if people are using Ben.Demystifier as a
library, but in this repo we want to keep those members internal.
Once changes to Ben.Demystifier have been merged into the main branch then, the internal branch of Ben.Demystifier
should be updated from the main branch and the modules/make-internal.sh script run again (if necessary). This repo
should reference the most recent commit on the internal branch of Ben.Demystifier then (functionally identical to the
main branch - the only difference being the changes to member visibility).
Sentry.Bindings.Cocoa always builds the Sentry Cocoa SDK from source, from the
getsentry/sentry-cocoa submodule at
modules/sentry-cocoa (scripts/build-sentry-cocoa.sh, invoked automatically by
the build). Pre-built release artifacts can't be used: the SentryObjC hybrid-API
frameworks are only published as self-contained bundles that would embed a second
copy of the SDK alongside Sentry.framework (see
#5331).
To build against a different Cocoa SDK version, check out the desired ref in the
submodule and stage it — the solution build automatically runs
git submodule update (see before.Sentry.sln.targets), which reverts the
submodule to the pinned commit unless the index already records your ref:
$ git -C modules/sentry-cocoa fetch origin
$ git -C modules/sentry-cocoa checkout <tag-or-sha>
$ git add modules/sentry-cocoa # otherwise the build restores the pinned commit
$ dotnet build ... # rebuilds the Cocoa SDK from the new refSimilarly, by default, Sentry.Bindings.Android downloads a pre-built Sentry Android SDK from
Maven. The version is specified in the SentryAndroidSdkVersion build property in Sentry.Bindings.Android.csproj.
If you want to build an unreleased Sentry Android SDK version from source instead, you'll need to clone both the sentry-java and the sentry-native repositories and publish these locally:
$ cd $(LocalSentryJavaRepoDir) && ./gradlew publishToMavenLocal
$ cd $(LocalSentryNativeRepoDir)/ndk && ./gradlew publishToMavenLocalYou'll also need to set <UseLocalSentryMavenRepo>true</UseLocalSentryMavenRepo> and <SentryNativeNdkVersion>{whatever_version_you_checked_out}</SentryNativeNdkVersion>
in the Sentry.Bindings.Android.csprojfile.
To switch back again, simply revert those two build properties to their original values.
We guide coding agents via the AGENTS.md file. See also https://agents.md/.
And yes, Sentry has a Skill to maintain the AGENTS.md file.
We use dotagents as a package manager for agent skills and more. See agents.toml for our current configuration.
We use Warden as a tool to run Agent Skills against code changes, both locally and in CI. See warden.toml for our current configuration.