MSBuild Setup
Configure MSBuild properties in your .NET project to automatically use the Sentry CLI.
The Sentry CLI has many useful features that can improve your Sentry experience. For .NET, you can use it to upload debug information files, such as .NET PDB symbol files. This allows Sentry to show a more complete stack trace, including file names and line numbers. You can also use it to upload source code, which enables Sentry to display source context when viewing stack traces.
While you can always run sentry-cli from the command line manually, we've made it easier by including it in the Sentry NuGet package, and providing properties to enable it from your build.
For this feature to work, you must authenticate to Sentry on the machine that is performing your release builds.
Important
The Sentry auth token (or legacy API key) should always be treated as secret. Be careful not to commit authentication information to source control, or use it in any way that it would be written to log files.
Any of the authentication methods accepted by the Sentry CLI can be used. See Configuration and Authentication. However, we generally recommend the following:
If building your releases on a developer workstation, install the Sentry CLI and then call
sentry-cli loginto use the automatic configuration option. This will help you create an auth token and save it to the~/.sentryclircfile on the workstation.If building from a CI/CD server, use the secrets feature of your CI/CD platform to set the
SENTRY_AUTH_TOKENenvironment variable.For example, if using GitHub Actions, first set an encrypted secret and then pass the secret via the
SENTRY_AUTH_TOKENenvironment variable to the step performing your build action.Copiedsteps: - name: Build run: dotnet build -c Release env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}steps: - name: Build run: dotnet build -c Release env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}You do not need to separately install Sentry CLI on your build server, as it is already provided by the Sentry NuGet package.
If building inside a Docker container, use a BuildKit secret to pass the auth token securely. See Building with Docker below for a complete example.
In addition to authentication, you must configure your Sentry organization and project slugs. You may also want to configure other optional properties.
The slugs can be found in various places from the Sentry UI, such as in the URL after selecting a project. For example, the organization slug is example-org and the project slug is example-project in the following URLs:
https://example-org.sentry.io/projects/example-project/?project=1234567https://sentry.io/organizations/example-org/projects/example-project/?project=1234567
If you are self-hosting Sentry (rather than using sentry.io), then you will also need to provide the URL to your Sentry server.
Tip
Any of the Sentry CLI configuration values can be set via environment variables or in configuration files, such as shown in the above authentication steps.
However, other than authentication, you should consider setting configuration values via the MSBuild properties described below, such that they are part of your code that is committed to source control. This allows them to be consistent across environments, and also allows the settings to differ per each project in your solution, if desired.
If both MSBuild properties and environment variables are provided, the MSBuild properties will take precedence.
Sentry's MSBuild properties can be set in any MSBuild project file, such as those that are created by Visual Studio or the dotnet CLI (YourProject.csproj, YourProject.vbproj, Directory.Build.props, etc.). We recommend using a dedicated property group, so that you can control when these features are used.
In the following example, Condition="'$(Configuration)' == 'Release'" ensures that these features are enabled only for release builds. This is the usual recommendation, because sending data to Sentry during debug builds can slow down your development workflow.
Alternatively, you could control this using any MSBuild property or environment variable you like. For example, if you only want these features enabled in a GitHub Actions CI workflow, you could use Condition="'$(GITHUB_ACTIONS)' == 'true'".
<!-- We recommend only using these features for release builds. -->
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<!-- Configure Sentry org and project -->
<SentryOrg>___ORG_SLUG___</SentryOrg>
<SentryProject>___PROJECT_SLUG___</SentryProject>
<!--
Each of the below features are opt-in.
Enable the features you wish to use.
-->
<!-- Automatically creates a release when building your application. -->
<SentryCreateRelease>true</SentryCreateRelease>
<!-- Automatically associates commits with the release. -->
<SentrySetCommits>true</SentrySetCommits>
<!-- Optionally provide explicit flags to the set-commits command -->
<SentrySetCommitOptions>--local</SentrySetCommitOptions>
<!-- Sends symbols to Sentry, enabling symbolication of stack traces. -->
<SentryUploadSymbols>true</SentryUploadSymbols>
<!-- Sends sources to Sentry, enabling display of source context. -->
<SentryUploadSources>true</SentryUploadSources>
<!-- If you are targeting Android, sends proguard mapping file to Sentry. -->
<SentryUploadAndroidProGuardMapping
>true</SentryUploadAndroidProGuardMapping>
</PropertyGroup>
<!-- We recommend only using these features for release builds. -->
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<!-- Configure Sentry org and project -->
<SentryOrg>___ORG_SLUG___</SentryOrg>
<SentryProject>___PROJECT_SLUG___</SentryProject>
<!--
Each of the below features are opt-in.
Enable the features you wish to use.
-->
<!-- Automatically creates a release when building your application. -->
<SentryCreateRelease>true</SentryCreateRelease>
<!-- Automatically associates commits with the release. -->
<SentrySetCommits>true</SentrySetCommits>
<!-- Optionally provide explicit flags to the set-commits command -->
<SentrySetCommitOptions>--local</SentrySetCommitOptions>
<!-- Sends symbols to Sentry, enabling symbolication of stack traces. -->
<SentryUploadSymbols>true</SentryUploadSymbols>
<!-- Sends sources to Sentry, enabling display of source context. -->
<SentryUploadSources>true</SentryUploadSources>
<!-- If you are targeting Android, sends proguard mapping file to Sentry. -->
<SentryUploadAndroidProGuardMapping
>true</SentryUploadAndroidProGuardMapping>
</PropertyGroup>
Alternatively, they could be passed as parameters when building your project. For example:
dotnet build YourProject.csproj -c Release -p:SentryOrg=___ORG_SLUG___ -p:SentryProject=___PROJECT_SLUG___ -p:SentryUploadSymbols=true -p:SentryUploadSources=true
dotnet build YourProject.csproj -c Release -p:SentryOrg=___ORG_SLUG___ -p:SentryProject=___PROJECT_SLUG___ -p:SentryUploadSymbols=true -p:SentryUploadSources=true
Tip
You may have properties that are the same across multiple projects in your solution. Consider placing these properties in a Directory.Build.props file, so that they are shared with all projects automatically.
The following MSBuild properties will pass required information to the Sentry CLI:
SentryOrg
| Type | string |
|---|
The organization slug for your Sentry account.
SentryProject
| Type | string |
|---|
The project slug for the specific Sentry project you are using.
SentryUrl
| Type | string |
|---|
The URL to your Sentry server. Required only if self-hosting Sentry. (Do not use with sentry.io.)
There are a few additional properties available to control the Sentry CLI:
SentryCreateRelease
| Type | bool |
|---|---|
| Default | false |
Enable to automatically create release when building your application. Defaults to false (disabled).
Sentry will try to determine the release version automatically by checking the following sources in order:
- The
SENTRY_RELEASEenvironment variable, if set - The
AssemblyInformationalVersionAttribute, if defined - The version of the entry assembly for the project
- The version suggested by running
sentry-cli releases propose-version
SentrySetCommits
| Type | bool |
|---|
Enable SentrySetCommits to automatically associate commits with the release.
SentrySetCommitOptions
| Type | string |
|---|
By default, when SentrySetCommits is enabled, the SDK will set commits with the --auto flag. The optional SentrySetCommitOptions property allows you to override this to provide whatever flags you want to the set-commits CLI command.
SentryUploadSymbols
| Type | bool |
|---|---|
| Default | false |
Controls uploading symbols to Sentry during the build. Defaults to false (disabled).
Set this property to true to opt-in to sending symbols to Sentry as debug information files, which are used to perform symbolication of stack traces. This will allow you to view file names and line numbers within a stack trace, instead of just a function name.
SentryUploadSources
| Type | bool |
|---|---|
| Default | false |
Controls whether source code files are uploaded to Sentry during the build. Defaults to false (disabled).
Set this property to true to opt-in to sending source code to Sentry. This enables the display of source context when viewing stack traces.
If you are already embedding source code in your symbol files using EmbedAllSources, you do not need to upload them to Sentry separately. In other words, use either SentryUploadSources or EmbedAllSources, not both.
UseSentryCLI
| Type | bool |
|---|---|
| Default | true |
Controls whether the Sentry CLI is enabled in your build. Defaults to true if any of the individual features are enabled. Set to false to disable the Sentry CLI completely, ignoring the settings of each feature.
Important
There are two more properties, SentryAuthToken and SentryApiKey, that are available for authentication. However we recommend that they are used only for simple testing, and not for production. If you decide to use them, be very careful that their values are not committed to source control or appear in build logs. A more secure approach is to set authentication via environment variable or ~/.sentryclirc file,
When building inside a Docker container, there are two things to handle: passing the auth token securely, and avoiding errors in multi-stage builds.
Use Docker BuildKit's --secret flag to pass the auth token at build time. Unlike ARG/ENV, BuildKit secrets are never written to any image layer and do not appear in docker history.
Pass the secret when building the image:
docker build --secret id=sentry_auth_token,env=SENTRY_AUTH_TOKEN .
docker build --secret id=sentry_auth_token,env=SENTRY_AUTH_TOKEN .
In your Dockerfile, add a syntax directive at the top, then mount the secret for the RUN instruction that performs the build:
# syntax=docker/dockerfile:1
...
RUN \
dotnet build "MyWebApp.csproj" --no-restore -c Release
# syntax=docker/dockerfile:1
...
RUN \
dotnet build "MyWebApp.csproj" --no-restore -c Release
The env= option (available since Dockerfile syntax v1.10) exposes the secret as the SENTRY_AUTH_TOKEN environment variable for the duration of that RUN instruction only — exactly what the Sentry CLI needs — without persisting it to a layer. The # syntax= directive ensures Docker uses a frontend that supports env=, regardless of the Docker Engine version.
BuildKit is enabled by default in Docker 23.0 and later. For older versions, set DOCKER_BUILDKIT=1 in your environment before running docker build.
If your Dockerfile has separate stages for dotnet build and dotnet publish (a common pattern for ASP.NET Core apps), Sentry CLI only needs to run during the build stage, where the auth token is mounted.
By default, dotnet publish runs its own implicit build. That would invoke Sentry CLI again — and because the auth token is deliberately scoped to the build stage's RUN (so it never reaches the publish stage or the final image), the second run would fail. Pass --no-build --no-restore so dotnet publish reuses the build stage's output instead of recompiling, plus -p:UseSentryCLI=false as an extra safeguard:
RUN dotnet publish "MyWebApp.csproj" -c Release -o /app/publish --no-build --no-restore -p:UseAppHost=false -p:UseSentryCLI=false
RUN dotnet publish "MyWebApp.csproj" -c Release -o /app/publish --no-build --no-restore -p:UseAppHost=false -p:UseSentryCLI=false
The following is a complete multi-stage Dockerfile for an ASP.NET Core app. It assumes <SentryOrg>, <SentryProject>, <SentryUploadSymbols>, and <SentryUploadSources> are configured in your .csproj or Directory.Build.props.
# syntax=docker/dockerfile:1
# Build: docker build --secret id=sentry_auth_token,env=SENTRY_AUTH_TOKEN .
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
WORKDIR /app
EXPOSE 8080
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY ["MyWebApp.csproj", "./"]
RUN dotnet restore "MyWebApp.csproj"
COPY . .
# The secret is available only for this RUN instruction and is never written to a layer.
# Sentry CLI runs here and uploads debug symbols as part of the build.
RUN \
dotnet build "MyWebApp.csproj" --no-restore -c Release
# Reuse the build output; --no-build avoids recompiling, which would re-run Sentry CLI without the auth token.
FROM build AS publish
RUN dotnet publish "MyWebApp.csproj" -c Release -o /app/publish --no-build --no-restore -p:UseAppHost=false -p:UseSentryCLI=false
FROM base AS final
WORKDIR /app
COPY /app/publish .
ENTRYPOINT ["dotnet", "MyWebApp.dll"]
# syntax=docker/dockerfile:1
# Build: docker build --secret id=sentry_auth_token,env=SENTRY_AUTH_TOKEN .
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
WORKDIR /app
EXPOSE 8080
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY ["MyWebApp.csproj", "./"]
RUN dotnet restore "MyWebApp.csproj"
COPY . .
# The secret is available only for this RUN instruction and is never written to a layer.
# Sentry CLI runs here and uploads debug symbols as part of the build.
RUN \
dotnet build "MyWebApp.csproj" --no-restore -c Release
# Reuse the build output; --no-build avoids recompiling, which would re-run Sentry CLI without the auth token.
FROM build AS publish
RUN dotnet publish "MyWebApp.csproj" -c Release -o /app/publish --no-build --no-restore -p:UseAppHost=false -p:UseSentryCLI=false
FROM base AS final
WORKDIR /app
COPY /app/publish .
ENTRYPOINT ["dotnet", "MyWebApp.dll"]
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").