Skip to content

chore: merge main into version7 - #5834

Merged
jamescrosswell merged 36 commits into
version7from
ai/version7-merge-main-5832-0e1927
Oct 30, 2026
Merged

jamescrosswell merged 36 commits into
version7from
ai/version7-merge-main-5832-0e1927

Conversation

@jamescrosswell

@jamescrosswell jamescrosswell commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Merges the latest main (up to 5d33189, #5828) into version7, plus the commit from #5832 (Quartz3 API snapshots for MonitorAllJobs/ExcludedJobs) cherry-picked on top.

Merge with a merge commit, not squash, so version7 keeps main's individual commits.

Conflict resolutions

Fixes for main's new code on version7

The merge compiled cleanly, but some of main's new code broke against version7's API (d26b28a):

  • Sentry.Quartz.Tests set SentryLoggingOptions.InitializeSdk, which is now an error-level [Obsolete].
  • A new AttachmentSerializationTests case passed the logger as Envelope.FromEvent's second argument.
  • net11.0 API snapshots: StringOrRegex.Regex (Sentry), and a new one for Sentry.Quartz3.

#skip-changelog

🤖 Generated with Claude Code

ric-oliv and others added 30 commits October 22, 2026 10:10
Craft's nuget target is dropping --skip-duplicate (getsentry/craft#686). With our single nuget
target, a retry after a partly failed publish would stop at the first package that's already on
nuget.org. With workspaces enabled, craft splits the target into one target per package, in
dependency order, and a retry skips the packages that already went out.

Craft releases without workspace support pass the new keys through and keep publishing everything
as one target, so this is safe to merge before the craft release.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…5505)

---------

Co-authored-by: James Crosswell <jamescrosswell@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Dan Fuller <dfuller@sentry.io>
Co-authored-by: Ricardo Colombo Oliveira <github@ricoliv.com>
Co-authored-by: GitHub <noreply@github.com>
coverlet instruments the SDK assemblies again in every test host, and for each branch it
rescans the whole method for sequence points. [GeneratedRegex] turns the crontab pattern into
one TryMatchAtCurrentPosition method with 8,070 IL instructions, 682 branches and 1,968
sequence points, about 90% of the instruction x branch cost across Sentry.dll. That costs
about 35 s of CPU per test host before any test runs.

Excluding [GeneratedCode] skips the generated regex matchers and the System.Text.Json
source-generated context. Hand-written code keeps the same coverage, and
CodeCoverage.runsettings already excludes the same attribute for the Microsoft collector.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* chore: update modules/sentry-cocoa to 9.31.0

* chore: regenerate Cocoa bindings for 9.31.0

Cocoa 9.31.0 adds SentryObjCExperimentalOptions.metrickit, which returns SentryObjCMetricKitOptions. That type isn't in the patch script's KeepInterfaces list, so the regenerated bindings failed to compile with CS0246. .NET doesn't expose MetricKit, so drop the property alongside the other option properties that reference types we don't bind.

The rest is Objective Sharpie output: serializeScope: and serializeDebugMeta: on the internal serializer API, and the SentryObjCMetricKitHangReportingMode enum.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: GitHub <noreply@github.com>
Co-authored-by: Ricardo Colombo Oliveira <github@ricoliv.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…verify-api and format-code (#5758)

* ci: stop building the device test app in the macOS build job

The macOS leg of build.yml built Sentry.Maui.Device.TestApp for net9.0-android, net10.0-android
and net10.0-ios, and nothing in build.yml runs it. In the run for #5752 on version7 that was the
last 6 minutes of the 24.7-minute Build step, on the critical path. The Linux and Windows filters
already exclude the app, and both device test workflows build it themselves. The macOS leg of
verify-api builds the same filter, so it no longer builds the app either.

The device test path filters now also cover what the app compiles and they didn't list:
Sentry.Analyzers, Sentry.Testing.CrashableApp, the nested Directory.Build files and .editorconfig,
which can fail the build because warnings are errors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: serialize only the jobs that push in verify-api and format-code

Both workflows put the whole run in the pr-auto-commit concurrency group, so each waited for the
other to finish. On one PR, format-code started 35 minutes after its run was created, and on
another verify-api waited 13 minutes. The group exists to keep their git pushes apart, so it now
covers only accept-api-changes and the format-code job, and the API test matrix starts right
away. Both still push from the head they checked out and fail as non-fast-forward if the branch
moved in the meantime.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The Unsupported AOT jobs run after the whole build-sentry matrix, so their
time adds to every build. They only publish a console app against the
packages from the macOS job, but they ran the full Setup Environment with
Java, the Android SDK, Mono and workloads. version7 dropped that in #5746,
and this brings the same job to main.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: Use craft's built-in version bumping

Craft 3.0.0 bumps <VersionPrefix> in Directory.Build.props itself and
fails prepare if no version gets bumped (getsentry/craft#923), so the
custom bump-version script is no longer needed.

Co-Authored-By: Burak Yigit Kaya <burak.kaya@sentry.io>

* ci: Move to craft's changelog and versioning policy keys
Co-Authored-By: Burak Yigit Kaya <burak.kaya@sentry.io>

* ci: Use the craft v3 floating tag
Co-Authored-By: Burak Yigit Kaya <burak.kaya@sentry.io>

---------

Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
Co-authored-by: Burak Yigit Kaya <burak.kaya@sentry.io>
…ration tests (#5771)

Microsoft.Data.SqlClient 6.1.x pulls in Pkcs 9.0.4 on net10.0, which is
affected by GHSA-846f-f764-76mx and GHSA-2fmv-rv2c-59x7. No SqlClient
release floors Pkcs high enough to clear them yet.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: GitHub <noreply@github.com>
Co-authored-by: GitHub <noreply@github.com>
The macOS build job and the iOS device tests build the Cocoa SDK from the
sentry-cocoa submodule on every run. In the macOS Build step on main, that
takes 12.2 of 23.7 minutes on one MSBuild node, and the other two nodes go
idle waiting for the Cocoa bindings. version7 caches it since #5746, and
this brings the same steps to main.

The key covers the selected Xcode, build-sentry-cocoa.sh,
sentry-cocoa.xcconfig and the submodule commit. Pushes to main save the
cache, so pull requests restore it from there. Release branches still build
it from source, because it ships in the Sentry.Bindings.Cocoa package.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
---
updated-dependencies:
- dependency-name: sharpie.bind.tool
  dependency-version: 27.1.0.18
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…4 updates (#5780)

Bumps the github-actions group with 4 updates in the / directory: [getsentry/craft/.github/workflows/changelog-preview.yml](https://github.com/getsentry/craft), [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action) and [actions/setup-java](https://github.com/actions/setup-java).
Bumps the github-actions group with 1 update in the /.github/actions/environment directory: [actions/setup-java](https://github.com/actions/setup-java).


Updates `getsentry/craft/.github/workflows/changelog-preview.yml` from 2.34.1 to 2.35.1
- [Release notes](https://github.com/getsentry/craft/releases)
- [Changelog](https://github.com/getsentry/craft/blob/master/CHANGELOG.md)
- [Commits](getsentry/craft@3f2abdc...0ff7589)

Updates `github/codeql-action/init` from 4.38.3 to 4.39.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@24c5418...6f2ac81)

Updates `github/codeql-action/analyze` from 4.38.3 to 4.39.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@24c5418...6f2ac81)

Updates `actions/setup-java` from 6.0.1 to 6.1.0
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](actions/setup-java@de7274f...b843ebf)

Updates `actions/setup-java` from 6.0.1 to 6.1.0
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](actions/setup-java@de7274f...b843ebf)

---
updated-dependencies:
- dependency-name: getsentry/craft/.github/workflows/changelog-preview.yml
  dependency-version: 2.35.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: github/codeql-action/init
  dependency-version: 4.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: actions/setup-java
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: actions/setup-java
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* ci: stop installing Mono

Every Linux and macOS job installed Mono, but nothing runs it. #4545
added it for the net4-console integration test, which ran the .NET
Framework app through Mono there. Two weeks later #4461 made that test
Windows-only, and the logs show it skipped on Linux and macOS. The .NET
Framework unit tests only build on Windows too.

On Ubuntu the install downloads 53 MB from the package mirror. On
October 23 that download took 15 to 21 minutes in 4 linux-x64 legs and
1 Android device test job. The chmod after it only repaired the
/usr/share/dotnet permissions that installing Mono had changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: stop writing detailed text build logs

The Build step wrote a detailed text log next to the binlog, 1.9 GB on
macOS, and uploaded both. The binlog holds the same events and warnings,
and nothing reads the text log. The MSBuild job and the integration test
builds wrote one too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: install only the workloads each job needs

Setup Environment ran dotnet workload restore without a project, so it
evaluated every project in Sentry.slnx in every job. The Linux legs
without mobile targets installed android, maui-android, maui-tizen,
macos, wasm-tools and wasm-tools-net9, and Windows installed ios,
maccatalyst and macos.

The environment action now requires the solution filters or project
files the job builds, and restores only their workloads. dotnet workload
restore doesn't accept a solution filter, so the step passes the
projects in it, and names the filter if it finds none. Jobs that build
everything pass Sentry.slnx. The Android test app is restored only when
the job builds the tests that build it, and the legs without mobile
targets skip Java and the Android SDK. CodeQL, format-code and
verify-api no longer run a second, unfiltered workload restore after the
action. Jobs that build a MAUI project still get maui-tizen, because
dotnet workload restore adds it for every MAUI project.

Measured on top of the other CI changes, Setup Environment went from
about 190 to 89 seconds in the trim job and from 170-180 to 71-78 in
the Android device test build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Apply suggestion from @jamescrosswell

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: James Crosswell <jamescrosswell@users.noreply.github.com>
* ci: install tzdata in the Alpine CI image

The linux-musl CI image has no time zone database, so only UTC resolves
and tests that need a real IANA zone are skipped on musl.

Refs #5756

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Apply suggestion from @jamescrosswell

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: James Crosswell <jamescrosswell@users.noreply.github.com>
* ci: build the MSBuild job on all cores

msbuild.exe builds on one node unless it gets -m, while the dotnet CLI
passes -maxcpucount on its own. The MSBuild job's binlog shows 21.4
minutes on one node, 12.4 of them in Build. The win-x64 leg builds the
same solution filter with dotnet build in 3 to 4.5 minutes. -nr:false
keeps the worker nodes from staying around after the build, since
nothing later in the job uses them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: install .NET and NuGet packages on a faster drive on Windows

The Windows .NET legs spent about 12 minutes in Setup Environment and
Restore, against about 4.5 on Linux. setup-dotnet installed into
C:\Program Files\dotnet, where the SDK installs workloads as MSI
packages, and NuGet extracted packages into the user profile on C:.

On Windows, Setup Environment now starts by installing .NET and the
NuGet cache next to the workspace, where workloads install as plain
files. On the x64 runners that's on D:. The arm64 runners have no D:,
so there the NuGet packages and TEMP go on a Dev Drive, and .NET stays
next to the workspace on C:. Trusting the new drive is retried. If
setting it up fails anyway, the step warns and keeps the NuGet
packages next to the workspace, because the drive is a speedup.

Every Windows job that uses Setup Environment gets it. There
~/.nuget/packages isn't the NuGet cache anymore, so the integration
tests now clear the Sentry packages they push from NUGET_PACKAGES when
it's set.

In two probes of the win-arm64 leg, the job took 33.8 and 32.4 minutes
with the Dev Drive, against 37.2 and 35.8 without it, and 36.9 with
.NET on the drive too. On its own, the step took the MSBuild job's
Run MSBuild from 23-24 to 14.7 minutes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: restore in its own pass in the MSBuild job

The MSBuild job ran msbuild -t:Restore,Build,Pack. NuGet's docs say
restoring and building in one invocation is unpredictable and often
wrong: restore can bring in props and targets from packages, so the
build needs its own evaluation after it. -restore runs the restore as
a separate pass first, which is what the dotnet CLI does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: build the app samples in their own job

The app samples only check that they compile, but their Release builds
trim, AOT-compile and package each app. In the macOS leg that's about
13.7 of the Build step's 28.3 task-minutes, and it's the whole tail of
the step once the Cocoa SDK comes from the cache. On Windows, the MAUI
sample's Android build is the last thing the Build step finishes.

The Android, iOS, Mac Catalyst, macOS and MAUI samples now build in a
separate job that starts with the .NET legs: all of them on macOS, the
Android and MAUI samples on Linux, and the MAUI sample on Windows,
which is the only build of its Windows target. The legs' solution
filters no longer include them, and generated filters list them. The
samples job's Cocoa SDK steps match the macOS leg's.

So that msbuild.exe still builds an Android and a Windows app, the
MSBuild job builds the MAUI sample after the solution filter. That took
180 to 211 seconds on three runs, and the job still ended about 10
minutes before the slowest check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: run the integration tests in their own jobs

The build legs built, ran the unit tests, and then ran the integration
tests, one step after another. On macOS the MAUI cases in cli.Tests.ps1
took 8 to 10 of the leg's 13 to 15 integration test minutes, building
three Release apps for Android, iOS and Mac Catalyst, and the Windows
legs spent 12 to 16 minutes in the integration tests.

The MAUI cases move to cli-maui.Tests.ps1, unchanged except that
SKIP_MAUI_TESTS also skips them. A new integration-test job runs next
to the legs: on macOS it runs the MAUI cases, which the macOS leg now
skips, and on linux-x64, win-x64 and win-arm64 it runs every
integration test file, which those legs now skip. Each entry builds
and packs only the packages its tests use, from two generated solution
filters: Sentry-CI-IntegrationTest-macOS.slnf, which adds the Cocoa
bindings, and Sentry-CI-IntegrationTest.slnf. It packs with --no-build
like the legs, because packing Sentry.Maui while building it on macOS
fails with NU5026.

These packages aren't the ones the macOS leg publishes, but
CI_PUBLISHING_BUILD only adds the other desktop platforms' native
libraries and sentry-cli binaries, which these tests don't use. On
release branches the macOS leg runs the MAUI cases too, against the
packages it uploads for craft, so the packages we publish are still
the ones tested. The integration-test job runs them there as well,
which keeps the jobs the same on every branch.

On three runs with the other CI changes, the win-x64, linux-x64 and
win-arm64 legs took 15.0, 11.2 and 17.9 minutes, and their integration
jobs 18.5, 12.7 and 22.1. Before, the win-arm64 leg took 31 and was the
slowest job. The new jobs passed the same 69 tests and skipped the same
35 as the legs did before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: run the integration tests on linux-musl-x64 again

#4789 turned them off on linux-musl-x64 while they hung there without
an error, tracked in #4788. #4743 fixed the disk space problem behind
it, and #4788 was closed in December 2025, but the guard stayed. The
leg finishes in about 9 minutes without them, and the same tests take
about 6 on linux-musl-arm64, so the leg still ends well before the
slowest check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci: run the iOS integration tests in their own job

The iOS job ran the device tests and then the integration tests on one
Mac, about 42 minutes in all. The two build and run different apps and
share only the simulator, so the integration tests now run in a second
job at the same time.

ios.Tests.ps1 skips every case unless a simulator is already booted,
and xharness only boots one in the ios-tests job, so the new job boots
its own, with a 10-minute timeout. The boot takes about 2 minutes.
The job uploads no results, because ios.Tests.ps1 writes nothing to
the integration-test/mobile-app/test_output folder the old job
uploaded.

On its first run, the iOS workflow took 18 minutes, against 38.7 for
the single job the same night, and all 8 integration cases passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci: run the Android integration tests in their own job

Each Android emulator job ran the device tests, then Setup Environment,
then the integration tests, about 22 minutes after waiting 7.5 for the
device test app builds. The integration tests build their own app from
source and share only the emulator, so they now run in a second job
that starts with the workflow, on the same runners.

The new job drops "Select Java 21". #4559 added it as "Select Java
17", when Setup Environment ended on Java 11, and since #5060 Setup
Environment installs only Java 21.

The new job uploads integration-test/mobile-app/test_output, where
android.Tests.ps1 points xharness, without a warning when it's empty.
It was empty on every run so far.

On its first run, the Android workflow took 19.8 minutes instead of
30.1. The device test jobs took 3.6 to 3.8 minutes and the integration
jobs 12.0 to 19.7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The Unsupported AOT jobs waited for the whole build matrix to use the
macOS packages, but any leg's packages work. Every leg already packs
and runs aot.Tests.ps1 against its own. linux-arm now runs in the
linux-arm64 leg and win-x86 in the win-x64 leg, which removes two jobs
and the tail after the matrix.

Some arm64 hosts can't run 32-bit ARM binaries and failed with "Exec
format error", so QEMU runs them on every host. Its binfmt_misc handler
comes before the kernel's own loader, so it runs them even on hosts that
could. On the first runs a small uname program confirmed that: it
reported armv7l, which only QEMU does, on a host that runs 32-bit ARM
natively. The leg now only checks that the handler is enabled. The
action runs the tonistiigi/binfmt image privileged, so that image is
pinned by digest here and in alpine.yml, like the action itself.

On its first run, the AOT and container cases passed under QEMU in 38
seconds.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The emulator jobs ran on the ubuntu-latest-4-cores larger runner. #2139
moved them there in 2023 because the 2-core standard runners couldn't
run a hardware-accelerated emulator. Since April 2024 they can, with
the same KVM udev rule this workflow already sets, and on public
repositories ubuntu-latest now has 4 CPUs and 16 GB of RAM. Both the
device test and the integration test jobs move.

On the first runs the device tests took 2.5 to 4.5 minutes, against
2.3 to 4.4 on the larger runner, with the same 2,921 tests. The
standard runner listed less disk, but had 88 GB free at the start and
67 at the end.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Remove skip logic from tests and HasTimeZone helper method

* Use Fact and Theory for tests that no longer skip

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: GitHub <noreply@github.com>
generate-solution-filters.ps1 tries to install powershell-yaml up to 5
times, 10 seconds apart, but it sets $ErrorActionPreference to Stop,
so the first failed download ended the script. The PowerShell Gallery
failed that download twice in two days, failing test-solution-filters
on #5810 and #5808. A failed attempt now prints a warning and the loop
tries again. If every attempt fails, Import-Module still stops the
script.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* feat(hangfire): Send recurring job schedule as monitor config

Opt-in via UseSentry(o => o.SendRecurringJobSchedule = true). The
in-progress check-in of a recurring job carries the job's cron and time
zone so Sentry can create the monitor. Unsupported schedules fall back
to a check-in without config.

Co-Authored-By: Claude <noreply@anthropic.com>

* ref(hangfire): Validate the recurring job schedule before capturing

Check the crontab up front so the check-in goes out in a single call
instead of relying on the hub to swallow an exception from Interval.
The validator is shared with Sentry.Hangfire as a linked source file,
since the unsigned assembly can't see Sentry's internals.

Read the job through GetRecurringJobs, look up time zones with
FindSystemTimeZoneById on .NET 6+, and add tests for UTC, unknown
zones, deleted jobs, the UseSentry overload, and a real recurring job.

Co-Authored-By: Claude <noreply@anthropic.com>

* test(hangfire): Skip time zone tests when the zone is missing

The linux-musl CI containers have no time zone database, so lookups
of Europe/Berlin and Etc/UTC fail there.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(hangfire): Skip schedules Sentry would read differently

Hangfire runs a job only on days that match both the day-of-month and
day-of-week fields, while Sentry runs it on days that match either
unless one of them starts with '*'. Don't send those schedules, nor
ones with a reversed range such as 5-1 or SAT-SUN, which Sentry
rejects.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(hangfire): Send recurring job schedules by default

Jobs are only monitored when they have [SentryMonitorSlug], so sending
the recurring job's schedule lets Sentry create or update the monitor,
like the Spring and Quartz integrations. Set SendRecurringJobSchedule
to false to keep managing the schedule in Sentry.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(hangfire): Create the check-in ID before the in-progress check-in

The final check-in reused the ID returned for the in-progress one, which
is empty when that one isn't captured. Create the ID up front, send it
with the in-progress check-in, and store it in the job's items as before.

Co-Authored-By: Claude <noreply@anthropic.com>

* ref(hangfire): Rename SendRecurringJobSchedule to SendMonitorConfig

Matches SentryQuartzOptions.SendMonitorConfig.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(hangfire): Don't send a monitor config when recurring jobs share a slug with different schedules

* fix(hangfire): Don't treat a recurring job as conflicting with its own cached schedule

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(hangfire): Add an option to monitor every recurring job

MonitorAllRecurringJobs sends check-ins for recurring jobs without
SentryMonitorSlugAttribute, using the slugified recurring job ID as the
monitor slug. ExcludedRecurringJobs leaves out recurring jobs by ID.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(hangfire): Build recurring job slugs the way Sentry normalizes them

Collapse runs of hyphens and trim underscores, so IDs that Sentry would
store under the same slug also share one here and the conflicting
schedule check sees them.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(hangfire): Match Relay's slugify and accept regexes in ExcludedRecurringJobs

Adds a public StringOrRegex.Regex, since Sentry.Hangfire isn't strong-named
and can't see Sentry's internals.

Co-Authored-By: Claude <noreply@anthropic.com>

* ref(crons): Share one Relay-compatible slug helper between Hangfire and Quartz

Quartz now joins a job's group and name with a hyphen, since Relay drops dots.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: GitHub <noreply@github.com>
It was only used by SentrySdk.RunAsyncVoid, which was removed in #3466.

Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
…ll jobs (#5831)

MonitorAllRecurringJobs only covers recurring jobs whose schedule Sentry can
represent, matching Quartz and sentry-python. Jobs with SentryMonitorSlug keep
checking in without a config.
* feat: add Sentry.Quartz

* refactor: optimize cron information retrieval in SentryCronJobListener

* refactor: swap ILogger dependency from SentryCronJobListener with IDiagnosticLogger

* refactor: simplify Quartz configuration by removing redundant service dependencies and streamlining SentryCronJobListener options handling

* refactor: migrate to Quartz v4.0.0 with .NET 10

* feat: include Sentry.Quartz in solution filter and generation scripts

* feat: add Quartz sample showcasing Sentry integration

* fix: cursor github comments

* refactor: simplify Quartz configuration and update project to use Web SDK

* refactor: replace SentryCronJobListener with SentryCronJobMiddleware and update Quartz integration

* fix: handling issue where current region might throw a CultureNotFoundException

* fix: sample project has different nuget package version

* fix: skip middleware execution for non-cron triggers

* refactor: rename and update Quartz extension method to AddSentryCronJob

* feat: add SentryMetricsMiddleware to track Quartz job execution duration metrics

* refactor: simplify AddSentryCronJob method by removing unused service collection parameter and streamlining option configuration

* feat: add SentryScopeMiddleware and extend Quartz integration with AddSentryScope method, update SentryMetricsMiddleware to support configurable options

* refactor: move non-cron trigger check to StartQuartz method

* feat: add missing options parameter

* refactor: remove unused project reference to Sentry.AspNetCore in Sentry.Quartz

* fix: Quatz.Net and Sentry handling cron expression for days differently

* feat: add XML documenation

* feat: update Quartz to stable v4.0.0

* feat: add Quartz Dashboard and HTTP API integration, update launch URL

* feat: add customizable SentryMonitorOptions via callback

* style: apply dotnet format to Sentry.Quartz

The format-code workflow can't push its auto-fix to a fork branch, so it
fails the check instead. Applying the fix here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* ci(craft): add Sentry.Quartz to the release registry

Every package needs a name/packageUrl/mainDocsUrl entry so craft can create
its registry entry on first publish; a missing `name` fails the whole
registry target rather than just that package.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* test: add Sentry.Quartz.Tests

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* feat: add configurable SentryScopeMiddleware options

* refactor: migrate extension methods to extension block

* refactor: remove SentryMetricsMiddleware

* fix: use JobDetail.Key.ToString()

* fix: replace job type with job ID in SentryCronJobMiddleware dictionary key

* feat(quartz): Rework Sentry.Quartz into Sentry.Quartz4

Keeps the middleware design from #5505 and adds what the cron monitors
need on top:

- One AddSentry() entry point on IQuartzBuilder that registers the scope
  and check-in middleware with HubAdapter, so no IHub is needed in DI.
- The scope middleware starts a new trace per run and captures what the
  job throws inside the run's scope.
- Check-ins only for jobs with [SentryCronMonitorSlug]. The slug comes
  from the trigger or job data map, the attribute, or the slugified job
  key, so job keys sharing a class don't share a monitor.
- The monitor config is converted from cron and simple triggers, with
  the Quartz day-of-week shift, and left out when Sentry can't represent
  the schedule. SendMonitorConfig turns it off globally or per job.
- ConfigureMonitorOptions runs before the trigger's schedule is applied,
  so it can override it, and never breaks the check-in.
- The package is signed and restricted to Quartz [4.0.0,5.0.0).

The schedule conversion, slug and check-in logic live in Core/ so the
Quartz 3 package can compile the same files.

Co-Authored-By: Claude <noreply@anthropic.com>

* ref(quartz): Rename Sentry.Quartz4 to Sentry.Quartz

Sentry.Quartz3 keeps its name for Quartz.NET 3.x.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(quartz): Address review feedback on Sentry.Quartz

- Jobs built without an identity get a new GUID name on each start, so
  their monitor slug falls back to the job class name, with a warning.
  Two jobs that resolve to the same slug also log a warning.
- The scope middleware no longer captures exceptions. Quartz logs them,
  and the logging integration reports that. The cron middleware still
  sends an error check-in. In global mode the scope is left alone.
- Quartz 4 accepts '*' in both day fields and runs on either day when
  both restrict. Convert those expressions, spelling out a '*' step as a
  range so Sentry unions the fields too.
- ConfigureMonitorOptions takes the IJobExecutionContext and always runs
  while SendMonitorConfig is on. The trigger's schedule fills in when it
  sets none, and the config is only sent when it has a schedule.
- The check-in ID is created up front, so the final check-in matches the
  in-progress one even when that wasn't sent.

Co-Authored-By: Claude <noreply@anthropic.com>

* ref(quartz): Drop warn-once state and discard options from a failed callback

Log the unnamed-job fallback at debug level on each run instead of tracking
which jobs were warned about, and remove the shared-slug detection. If
ConfigureMonitorOptions throws, ignore what it set and use the trigger's schedule.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(quartz): Capture job exceptions in the job scope and rename the slug attribute

Quartz logs a job's exception only after the middleware chain has
returned, so the logged error lost the job's scope and trace. Capture it
inside the scope again; the SDK drops the duplicate from the log.

Rename SentryCronMonitorSlugAttribute to SentryMonitorSlugAttribute to
match Sentry.Hangfire.

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(quartz): Say that AddSentry captures job exceptions

The AddSentry() remarks still said job exceptions are left to the logging integration. The scope middleware has captured them again since 73e5551.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(quartz): Add an option to monitor every scheduled job

MonitorAllJobs sends check-ins for every job fired by a cron trigger or a
repeating simple trigger, with the slug of the job's key. ExcludedJobs
skips jobs by name, full key or regex. Jobs with SentryMonitorSlug keep
their settings.

Co-Authored-By: Claude <noreply@anthropic.com>

* ref(quartz): Remove a leftover comment from JobMonitor

* fix(quartz): Drop the schedule when jobs share a slug with different schedules

Reads every monitored trigger, cached for a minute, like Sentry.Hangfire. Replaces the check for jobs with several triggers.

* test(quartz): Skip the time zone test when there's no time zone database

* docs(quartz): Drop the stale warning from the slug attribute docs

A job without an identity has fallen back to its class name with a debug message, not a warning, since fe97276.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(quartz): Skip jobs whose type can't be resolved when reading triggers

A job left in a persistent store after its class was renamed or deleted
made the whole trigger read throw, so no monitored job sent its schedule.

Co-Authored-By: Claude <noreply@anthropic.com>

* test(quartz): Pin the order of the Sentry job middleware

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(quartz): Update the sample's comment on how job exceptions are captured

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(quartz): Capture each job exception once with the logging integration on

Quartz's ErrorLogger logs the exception again, wrapped in a
JobExecutionProcessException that the default DeduplicateMode doesn't
unwrap. AddSentry now adds a log entry filter for that entry, to
whichever SentryLoggingOptions the app uses (SentryAspNetCoreOptions
included), when the middleware captured the inner exception.

Co-Authored-By: Claude <noreply@anthropic.com>

* test(quartz): Check that AddSentry leaves unrelated options resolvable

Co-Authored-By: Claude <noreply@anthropic.com>

* Update src/Sentry.Quartz/QuartzErrorLogFilterSetup.cs

Co-authored-by: Ricardo Colombo Oliveira <github@ricoliv.com>

* ref(quartz): Drop the stale constraint wording and assertion for the log filter setup

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(quartz): Skip jobs with unsupported schedules when monitoring all jobs

MonitorAllJobs only covers runs whose trigger schedule Sentry can represent,
matching sentry-python. Jobs with SentryMonitorSlug keep checking in without
a config.

* fix(quartz): Skip default-monitored jobs whose triggers have different schedules

---------

Co-authored-by: Michael Mairegger <michael.mairegger@yahoo.de>
Co-authored-by: James Crosswell <jamescrosswell@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Ricardo Colombo Oliveira <github@ricoliv.com>
wedamija and others added 6 commits October 30, 2026 11:14
…5668)

* feat: add Sentry.Quartz

* refactor: optimize cron information retrieval in SentryCronJobListener

* refactor: swap ILogger dependency from SentryCronJobListener with IDiagnosticLogger

* refactor: simplify Quartz configuration by removing redundant service dependencies and streamlining SentryCronJobListener options handling

* refactor: migrate to Quartz v4.0.0 with .NET 10

* feat: include Sentry.Quartz in solution filter and generation scripts

* feat: add Quartz sample showcasing Sentry integration

* fix: cursor github comments

* refactor: simplify Quartz configuration and update project to use Web SDK

* refactor: replace SentryCronJobListener with SentryCronJobMiddleware and update Quartz integration

* fix: handling issue where current region might throw a CultureNotFoundException

* fix: sample project has different nuget package version

* fix: skip middleware execution for non-cron triggers

* refactor: rename and update Quartz extension method to AddSentryCronJob

* feat: add SentryMetricsMiddleware to track Quartz job execution duration metrics

* refactor: simplify AddSentryCronJob method by removing unused service collection parameter and streamlining option configuration

* feat: add SentryScopeMiddleware and extend Quartz integration with AddSentryScope method, update SentryMetricsMiddleware to support configurable options

* refactor: move non-cron trigger check to StartQuartz method

* feat: add missing options parameter

* refactor: remove unused project reference to Sentry.AspNetCore in Sentry.Quartz

* fix: Quatz.Net and Sentry handling cron expression for days differently

* feat: add XML documenation

* feat: update Quartz to stable v4.0.0

* feat: add Quartz Dashboard and HTTP API integration, update launch URL

* feat: add customizable SentryMonitorOptions via callback

* style: apply dotnet format to Sentry.Quartz

The format-code workflow can't push its auto-fix to a fork branch, so it
fails the check instead. Applying the fix here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* ci(craft): add Sentry.Quartz to the release registry

Every package needs a name/packageUrl/mainDocsUrl entry so craft can create
its registry entry on first publish; a missing `name` fails the whole
registry target rather than just that package.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* test: add Sentry.Quartz.Tests

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* feat: add configurable SentryScopeMiddleware options

* refactor: migrate extension methods to extension block

* refactor: remove SentryMetricsMiddleware

* fix: use JobDetail.Key.ToString()

* fix: replace job type with job ID in SentryCronJobMiddleware dictionary key

* feat(quartz): Rework Sentry.Quartz into Sentry.Quartz4

Keeps the middleware design from #5505 and adds what the cron monitors
need on top:

- One AddSentry() entry point on IQuartzBuilder that registers the scope
  and check-in middleware with HubAdapter, so no IHub is needed in DI.
- The scope middleware starts a new trace per run and captures what the
  job throws inside the run's scope.
- Check-ins only for jobs with [SentryCronMonitorSlug]. The slug comes
  from the trigger or job data map, the attribute, or the slugified job
  key, so job keys sharing a class don't share a monitor.
- The monitor config is converted from cron and simple triggers, with
  the Quartz day-of-week shift, and left out when Sentry can't represent
  the schedule. SendMonitorConfig turns it off globally or per job.
- ConfigureMonitorOptions runs before the trigger's schedule is applied,
  so it can override it, and never breaks the check-in.
- The package is signed and restricted to Quartz [4.0.0,5.0.0).

The schedule conversion, slug and check-in logic live in Core/ so the
Quartz 3 package can compile the same files.

Co-Authored-By: Claude <noreply@anthropic.com>

* ref(quartz): Rename Sentry.Quartz4 to Sentry.Quartz

Sentry.Quartz3 keeps its name for Quartz.NET 3.x.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(quartz): Address review feedback on Sentry.Quartz

- Jobs built without an identity get a new GUID name on each start, so
  their monitor slug falls back to the job class name, with a warning.
  Two jobs that resolve to the same slug also log a warning.
- The scope middleware no longer captures exceptions. Quartz logs them,
  and the logging integration reports that. The cron middleware still
  sends an error check-in. In global mode the scope is left alone.
- Quartz 4 accepts '*' in both day fields and runs on either day when
  both restrict. Convert those expressions, spelling out a '*' step as a
  range so Sentry unions the fields too.
- ConfigureMonitorOptions takes the IJobExecutionContext and always runs
  while SendMonitorConfig is on. The trigger's schedule fills in when it
  sets none, and the config is only sent when it has a schedule.
- The check-in ID is created up front, so the final check-in matches the
  in-progress one even when that wasn't sent.

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(quartz): Add Sentry.Quartz3 for Quartz.NET 3.x

Compiles the Sentry.Quartz core (schedule conversion, slugs, options and
check-ins) against Quartz 3.6+ and drives it from an IJobListener, since
Quartz 3 has no job middleware. Logs an error at startup when Quartz 4
is loaded, where the listener's Task methods would never be called.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(quartz): Apply the Sentry.Quartz review fixes to Sentry.Quartz3

Quartz 3 needs exactly one '?' day field, so only that form is converted.
ConfigureMonitorOptions gets the listener's IJobExecutionContext, and the
final check-in reuses the ID created for the in-progress one.

Co-Authored-By: Claude <noreply@anthropic.com>

* ref(quartz): Drop warn-once state and discard options from a failed callback

Log the unnamed-job fallback at debug level on each run instead of tracking
which jobs were warned about, and remove the shared-slug detection. If
ConfigureMonitorOptions throws, ignore what it set and use the trigger's schedule.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(quartz): Capture job exceptions in the job scope and rename the slug attribute

Quartz logs a job's exception only after the middleware chain has
returned, so the logged error lost the job's scope and trace. Capture it
inside the scope again; the SDK drops the duplicate from the log.

Rename SentryCronMonitorSlugAttribute to SentryMonitorSlugAttribute to
match Sentry.Hangfire.

Co-Authored-By: Claude <noreply@anthropic.com>

* ref(quartz): Rename SentryCronMonitorSlug to SentryMonitorSlug in Sentry.Quartz3

Co-Authored-By: Claude <noreply@anthropic.com>

* test(quartz): Reorder the Sentry.Quartz3 API snapshots after the attribute rename

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(quartz): Say that AddSentry captures job exceptions

The AddSentry() remarks still said job exceptions are left to the logging integration. The scope middleware has captured them again since 73e5551.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ref(quartz): Remove a leftover comment from JobMonitor

* fix(quartz): Drop the schedule when jobs share a slug with different schedules

Reads every monitored trigger, cached for a minute, like Sentry.Hangfire. Replaces the check for jobs with several triggers.

* test(quartz): Skip the time zone test when there's no time zone database

* docs(quartz): Drop the stale warning from the slug attribute docs

A job without an identity has fallen back to its class name with a debug message, not a warning, since fe97276.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Merge branch 'danf/quartz-5505-rebased' into danf/quartz-crons

Ports the shared slug check to Quartz 3: QuartzApi.GetTriggersAsync reads
each job and the triggers of each monitored one, since Quartz 3 has no
bulk lookups. The test shim gets the new ReturnsTriggers and
LookedUpTriggers, and HasSeveralTriggersAsync is gone.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(quartz): Skip jobs whose type can't be resolved when reading triggers

A job left in a persistent store after its class was renamed or deleted
made the whole trigger read throw, so no monitored job sent its schedule.

Co-Authored-By: Claude <noreply@anthropic.com>

* test(quartz): Pin the order of the Sentry job middleware

Co-Authored-By: Claude <noreply@anthropic.com>

* docs(quartz): Update the sample's comment on how job exceptions are captured

Co-Authored-By: Claude <noreply@anthropic.com>

* test(quartz): Fix the nullability of the Quartz 3 job detail stub

Co-Authored-By: Claude <noreply@anthropic.com>

* test(quartz): Ignore the nullability of the Quartz 3 job detail stub

Quartz 3 annotates GetJobDetail differently across target frameworks.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(quartz): Capture each job exception once with the logging integration on

Quartz's ErrorLogger logs the exception again, wrapped in a
JobExecutionProcessException that the default DeduplicateMode doesn't
unwrap. AddSentry now adds a log entry filter for that entry, to
whichever SentryLoggingOptions the app uses (SentryAspNetCoreOptions
included), when the middleware captured the inner exception.

Co-Authored-By: Claude <noreply@anthropic.com>

* test(quartz): Check that AddSentry leaves unrelated options resolvable

Co-Authored-By: Claude <noreply@anthropic.com>

* Update src/Sentry.Quartz/QuartzErrorLogFilterSetup.cs

Co-authored-by: Ricardo Colombo Oliveira <github@ricoliv.com>

* ref(quartz): Drop the stale constraint wording and assertion for the log filter setup

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(quartz3): Send an error check-in when a job is cancelled

Quartz 3 swallows a cancelled job's OperationCanceledException and calls
JobWasExecuted with no exception, so check the context's cancellation
token too. This matches SentryCronJobMiddleware in Sentry.Quartz.

* test(quartz): Only run the IANA time zone test on .NET 6+

.NET Framework on Windows can't resolve IANA time zone IDs, and the shared
JobMonitor tests run on net48 in Sentry.Quartz3.Tests.

---------

Co-authored-by: Michael Mairegger <michael.mairegger@yahoo.de>
Co-authored-by: James Crosswell <jamescrosswell@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Ricardo Colombo Oliveira <github@ricoliv.com>
…5828)

* perf: pushing a scope no longer eagerly allocates tags, extras, contexts and attachments

Scope.Clone runs on every ILogger.BeginScope call made while Sentry's logging
integration is registered. Every Scope eagerly allocated three
ConcurrentDictionary instances (tags, extras and the one inside SentryContexts),
which made up around 80% of the 4.4 KB each scope cost on a 20 core machine
(about 60% of 2.5 KB with 2 cores).

Create the tags, extras, contexts, attachments and SDK version lazily, and skip
copying them in Clone and Apply when the source has none. The public properties
still return the same live instance once created.

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>

* perf: cloning a scope copies its breadcrumbs without intermediate allocations

Scope.Clone enumerated the breadcrumbs of the source scope (which takes a
snapshot array) and enqueued them one by one into the clone, repeatedly growing
the clone's backing list. With the default of 100 breadcrumbs that was around
3 KB per clone.

Copy the items of the source queue directly into the clone with a single sized
allocation instead.

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>

* perf: SentryLogger only formats a log message once it knows it will be used

SentryLogger.Log invoked the formatter before checking whether the entry came
from the Sentry SDK itself, was an EF exception message or was excluded by a
log entry filter, so the message was formatted (and allocated) for every entry
that was then discarded. The filter check also allocated a closure for every
entry through LINQ's Any().

Move the formatting after those checks and replace the LINQ call with a loop.

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>

* refactor: address review feedback on lazy scope collections

Use LazyInitializer.EnsureInitialized for the lazily created collections of
Scope instead of hand-written compare-and-swap loops.

Assert in the Clone test that the contexts and attachments of a clone are
independent of the scope they were cloned from, and remove new tests that only
duplicate the coverage of existing tests.

Assisted-by: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>

---------

Co-authored-by: Claude Code <noreply@anthropic.com>
Conflict resolutions:
- build.yml: keep main's integration-test job and in-leg unsupported AOT
  steps; carry version7's .NET 11 container image pins and VS 2026 runners
  into them. The musl integration test step now covers linux-musl-x64 too,
  since main re-enabled it (#4788 is closed).
- cli.Tests.ps1: main moved the MAUI tests to cli-maui.Tests.ps1; version7's
  .NET 11 changes to them are applied there.
- verify-api.yml, environment/action.yml: version7's side.
- Scope.Apply: version7's SDK merge logic, guarded by main's lazy _sdk.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#5741 added these options to SentryQuartzOptions, and #5668 added
Sentry.Quartz3 (which compiles the same source) with snapshots that
predate them. Each PR was green on its own; together they broke main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Quartz: the logging integration no longer takes InitializeSdk.
- AttachmentSerializationTests: Envelope.FromEvent's logger is now the
  last, optional parameter.
- Add the net11.0 API snapshots for StringOrRegex.Regex and Sentry.Quartz3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
version7 renamed integration-test/net9-maui to maui-device.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.59041% with 51 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.76%. Comparing base (2194c92) to head (d28aa8b).
⚠️ Report is 8 commits behind head on version7.

Files with missing lines Patch % Lines
src/Sentry.Quartz/Core/JobMonitor.cs 89.14% 8 Missing and 11 partials ⚠️
src/Sentry.Quartz/Core/TriggerSchedule.cs 91.74% 3 Missing and 6 partials ⚠️
src/Sentry.Quartz3/SentryJobListener.cs 66.66% 7 Missing and 1 partial ⚠️
src/Sentry.Hangfire/SentryServerFilter.cs 85.18% 3 Missing and 1 partial ⚠️
src/Sentry.Quartz/SentryQuartzBuilderExtensions.cs 62.50% 3 Missing ⚠️
src/Sentry/Internal/MonitorSlug.cs 86.36% 3 Missing ⚠️
src/Sentry.Quartz/QuartzApi.cs 88.23% 1 Missing and 1 partial ⚠️
src/Sentry.Quartz/QuartzErrorLogFilterSetup.cs 80.00% 1 Missing ⚠️
src/Sentry.Quartz/SentryScopeMiddleware.cs 95.45% 1 Missing ⚠️
src/Sentry/Protocol/Envelopes/EnvelopeItem.cs 92.30% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           version7    #5834      +/-   ##
============================================
+ Coverage     76.17%   76.76%   +0.58%     
============================================
  Files           526      539      +13     
  Lines         19265    19694     +429     
  Branches       3729     3851     +122     
============================================
+ Hits          14676    15119     +443     
+ Misses         3734     3703      -31     
- Partials        855      872      +17     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jamescrosswell
jamescrosswell merged commit d28aa8b into version7 Oct 30, 2026
45 of 46 checks passed
@jamescrosswell
jamescrosswell deleted the ai/version7-merge-main-5832-0e1927 branch October 30, 2026 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants