Bump Meziantou.Analyzer and 10 others - #48
Closed
dependabot[bot] wants to merge 1 commit into
Closed
dependabot[bot] wants to merge 1 commit into
dependabot[bot] wants to merge 1 commit into
Conversation
Bumps Meziantou.Analyzer from 3.0.200 to 3.0.222 Bumps Microsoft.Testing.Extensions.CodeCoverage from 18.10.0 to 18.11.0 Bumps Microsoft.Testing.Extensions.TrxReport from 2.3.3 to 2.4.0 Bumps Microsoft.Testing.Platform from 2.3.3 to 2.4.0 Bumps Quartz from 3.20.0 to 4.0.0 Bumps Quartz.Extensions.Hosting from 3.20.0 to 3.20.1 Bumps Quartz.Plugins from 3.20.0 to 4.0.0 Bumps Quartz.Plugins.TimeZoneConverter from 3.20.0 to 4.0.0 Bumps Quartz.Serialization.SystemTextJson from 3.20.0 to 3.20.1 Bumps TUnit from 1.65.68 to 1.66.16 Bumps TUnit.Playwright from 1.65.68 to 1.66.16 --- updated-dependencies: - dependency-name: Meziantou.Analyzer dependency-version: 3.0.222 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-remaining - dependency-name: Microsoft.Testing.Extensions.CodeCoverage dependency-version: 18.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-remaining - dependency-name: Microsoft.Testing.Platform dependency-version: 2.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-remaining - dependency-name: Microsoft.Testing.Extensions.TrxReport dependency-version: 2.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-remaining - dependency-name: Quartz dependency-version: 4.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: nuget-remaining - dependency-name: Quartz.Extensions.Hosting dependency-version: 3.20.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-remaining - dependency-name: Quartz.Plugins dependency-version: 4.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: nuget-remaining - dependency-name: Quartz.Plugins.TimeZoneConverter dependency-version: 4.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: nuget-remaining - dependency-name: Quartz.Serialization.SystemTextJson dependency-version: 3.20.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-remaining - dependency-name: TUnit dependency-version: 1.66.16 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-remaining - dependency-name: TUnit.Playwright dependency-version: 1.66.16 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-remaining ... Signed-off-by: dependabot[bot] <support@github.com>
Contributor
Author
|
Looks like these dependencies are updatable in another way, so this is no longer needed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Updated Meziantou.Analyzer from 3.0.200 to 3.0.231.
Release notes
Sourced from Meziantou.Analyzer's releases.
3.0.231
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.231
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.230...3.0.231
3.0.230
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.230
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.229...3.0.230
3.0.229
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.229
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.228...3.0.229
3.0.228
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.228
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.227...3.0.228
3.0.227
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.227
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.226...3.0.227
3.0.226
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.226
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.225...3.0.226
3.0.225
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.225
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.224...3.0.225
3.0.224
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.224
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.223...3.0.224
3.0.223
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.223
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.222...3.0.223
3.0.222
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.222
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.221...3.0.222
3.0.221
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.221
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.220...3.0.221
3.0.220
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.220
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.219...3.0.220
3.0.219
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.219
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.218...3.0.219
3.0.218
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.218
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.217...3.0.218
3.0.217
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.217
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.216...3.0.217
3.0.216
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.216
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.215...3.0.216
3.0.215
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.215
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.214...3.0.215
3.0.214
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.214
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.213...3.0.214
3.0.213
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.213
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.212...3.0.213
3.0.212
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.212
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.211...3.0.212
3.0.211
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.211
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.210...3.0.211
3.0.210
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.210
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.209...3.0.210
3.0.209
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.209
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.208...3.0.209
3.0.208
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.208
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.207...3.0.208
3.0.207
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.207
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.206...3.0.207
3.0.206
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.206
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.205...3.0.206
3.0.205
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.205
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.204...3.0.205
3.0.204
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.204
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.203...3.0.204
3.0.203
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.203
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.202...3.0.203
3.0.202
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.202
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.201...3.0.202
3.0.201
NuGet package: https://www.nuget.org/packages/Meziantou.Analyzer/3.0.201
What's Changed
Full Changelog: meziantou/Meziantou.Analyzer@3.0.200...3.0.201
Commits viewable in compare view.
Updated Microsoft.Testing.Extensions.CodeCoverage from 18.10.0 to 18.11.0.
Release notes
Sourced from Microsoft.Testing.Extensions.CodeCoverage's releases.
No release notes found for this version range.
Commits viewable in compare view.
Updated Microsoft.Testing.Extensions.TrxReport from 2.3.3 to 2.4.0.
Release notes
Sourced from Microsoft.Testing.Extensions.TrxReport's releases.
No release notes found for this version range.
Commits viewable in compare view.
Updated Microsoft.Testing.Platform from 2.3.3 to 2.4.0.
Release notes
Sourced from Microsoft.Testing.Platform's releases.
No release notes found for this version range.
Commits viewable in compare view.
Updated Quartz from 3.20.0 to 4.0.1.
Release notes
Sourced from Quartz's releases.
4.0.1
Quartz.NET 4.0.1 is a maintenance release about getting to 4.0: nothing about how a trigger fires changed, the public API is untouched (the baselines did not move), and the schema is 4.0's. Five days after 4.0.0 an audit of every public dependency-bot pull request that touched a Quartz package found two reasons an upgrade never got as far as compiling, both of them ours, both fixable in a patch — one gap in the migration guide for F# — and, found by the rc.1 security gate and moved forward, a cron calendar that could take a century to answer.
What changed
Microsoft.Extensions.*dependency at10.0.11, the newest patch on the day it was built, so a project pinned at 10.0.9 or 10.0.10 hitNU1605"detected package downgrade" before a line of source compiled. Every floor is now the lowest version of its major that the code compiles against and that carries no advisory:10.0.0for the framework extensions,13.0.2for Newtonsoft.Json (13.0.1 reflects overTimeOnlymember by member and a job data map loses its seconds — a test said so),1.15.3for OpenTelemetry.Extensions.Hosting (the first version whoseOpenTelemetry.Apicarries no advisory),3.0.0for StackExchange.Redis and7.0.0for TimeZoneConverter. The library is built against those floors, so the claim is checked on every build, and a test refuses a floor that creeps up. (#3717, c9ecf892bd)Quartz(Quartz.Extensions.DependencyInjection,Quartz.Extensions.Hosting,Quartz.Serialization.SystemTextJson, andQuartz.Serialization.Json, whose successor isQuartz.Serialization.Newtonsoft) had no 4.0.0, so a bot that groups Quartz with any of them resolved the group to the newest version every member has — 3.20.1 — and closed the 4.0.0 pull request it had already opened as superseded, with green checks. From 4.0.1 those four ids carry an empty package at every 4.x version: no assembly, one dependency on the replacement, a readme that says to remove the reference. The migration guide's instruction stands — remove them — but the upgrade is now offered.Quartz.OpenTracingandQuartz.OpenTelemetry.Instrumentationdeliberately have no such package: neither has a 4.x replacement, and an empty one would hide that. (#3717, c28f213cbd)CronCalendar.GetNextIncludedTimeUtcno longer walks a century one second at a time — it askedCronExpression.GetNextInvalidTimeAfterfor the end of an excluded run, and that method stepped through the run one second per full cron computation; for an expression that excludes everything (* * * * * ?) the walk ran to the give-up year, roughly three billion computations, on a public member. The next non-matching instant is now read off the expression's own field sets — second, minute, hour, day, month, year — with each skip verified against the time zone's clock so a repeated fall-back hour is never stepped over. An expression that fires every second answersnull, and the calendar turns that into aSchedulerExceptionnaming the expression instead of hanging. The unchanged next-fire-time path measures the same as before; the changed method is 76–86 % faster on the benchmark corpus. (#3690, a125809ba9, 4d60904c6f)GetNextInvalidTimeAfterreturnsnullwhere it used to return a valid instant after giving up, and aCronCalendarwhose expression excludes every instant now fails fast withSchedulerException.FS0856onIJob.Execute's arity,FS0041onScheduleJoboverload resolution,Async.AwaitTaskwith aValueTask,FS0039forStdSchedulerFactory), each quoted with its fix, and every sample is copied from a compiled example project the build keeps honest. (#3718, 1b97b49f41, aff4feac69)Upgrading
From 4.0.0:
dotnet add package Quartz --version 4.0.1; nothing else. From 3.x: the 4.x migration guide is unchanged in substance; if your bot has been landing 3.20.1 "upgrades", this is the release that lets it offer 4.x.Full changelog: quartznet/quartznet@v4.0.0...v4.0.1
4.0.0
Quartz.NET 4.0 targets
net10.0, is asynchronous and container-built throughout, and trims a public surface that had accumulated for a decade. It is a major version with extensive breaking changes and a mandatory schema migration. This page is the short form; the detail lives in the docs:Highlights
net10.0only — nonetstandard2.0build, no Full Framework, no.configsupport.Quartzpackage;StdSchedulerFactory,quartz.configdiscovery and the process-globalSchedulerRepository.Instance/DBConnectionManager.Instanceare gone. Flatquartz.*keys still work, translated to typed options by the one component that understands them, and a misspelled key is refused with a message rather than ignored. Options are validated at startup, so a bad value failsHost.Build()with every failure listed.IJob.Executetakes aCancellationToken,IJobFactoryhands out aJobScoperather than a bare instance, every publicTaskbecameValueTask, and every asynchronous member ends with a cancellation token.QueryJobs/QueryTriggersreturn aPagedResult<T>whose rows already carry what a listing needs, so a dashboard over a large schema no longer pays for the whole schema. The old call shapes remain as extension methods.TriggerState.Executingsays whether a trigger's job is running anywhere in the cluster; fire instances, cluster nodes, execution groups, misfires and history are listings that say which node they came from; the health check notices a node whose own check-in has stopped.ISchedulerclient over it (the replacement for .NET Remoting, which is gone), a dashboard, typed job input (IJob<TInput>;UsingInput(input)on a registration,ScheduleJob<TJob, TInput>(input, at)for a one-off), a retry policy a trigger carries — persisted, cluster-safe, never burning a repeat count — job execution middleware, a[JobTimeout]attribute, execution groups with per-node or cluster-wide limits, node affinity, and a firing that links back to the trace that scheduled it.0 15 10 1 * *is the 1st, not every day); a time the clocks skip fires when the gap ends; the parser refuses what it used to quietly reinterpret (1-5W,L-3in day-of-week,MON,FRI#3,MON/2, steps of zero); the five-field Unix form and the@daily-style macros work everywhere an expression is read.CalendarIntervalTriggerwithPreserveHourOfDayAcrossDaylightSavingssteps in local wall-clock time and no longer drifts in zones whose delta is not a whole hour; calendars mean the local day even where midnight itself moves. Review any schedule that crosses a transition.Quartz.Aspire:builder.AddQuartzPersistentStore("quartz")turns an Aspire connection name into a configured persistent store with its telemetry and health check, with noAspire.*dependency; a store can provision its own schema as it starts (ProvisionSchema()), safe under a cluster racing to start.MapQuartzHttpApi()andMapQuartzDashboard()refuse to start unless the endpoints carry authorization or an explicitAllowAnonymous(); a scheduler can be authorized on its own name, and every call the dashboard makes is authorized where it is made.ActivitySource("Quartz")andMeter("Quartz")(the names are public constants), nine instruments, spans on every store the same way, and every log line carrying a stable event id — 278 of them, catalogued on a generated page.QuartzdeclaresIsAotCompatible; a canary is published natively and run against a real store on three operating systems on every pull request; the remaining string-named paths are recorded and each has a documented alternative (#3341).RAMJobStore(numbers below).JobRunShellare internal, and non-public types are sealed. If something you relied on is gone, say so in an issue; these can be reopened.Breaking changes, the ten to know before the guide
net10.0only.Quartz.Extensions.DependencyInjection,Quartz.Extensions.HostingandQuartz.Serialization.SystemTextJsonare part ofQuartz;Quartz.Serialization.JsonisQuartz.Serialization.Newtonsoft;Quartz.OpenTracinghas no 4.x release, andOpenTelemetry.Instrumentation.Quartzproduces nothing on 4.x — subscribe to the source and meter directly. The first error a mixed project produces is CS0433 (a type in bothQuartz4 and a 3.x satellite): remove the three references.StdSchedulerFactory,DirectSchedulerFactoryandquartz.configare gone;AddQuartz(…)orQuartzSchedulerBuilder.Create(q => …)build a scheduler.Task→ValueTaskon nearly every member, and aCancellationTokenon every asynchronous one.Quartz.SpiisQuartz.Extensibility,Quartz.Simplmerged intoQuartz.Impl, the Newtonsoft types left the core namespaces. A string naming an old namespace still resolves, with a warning.*Supportbase classes are gone (every member has a default body); a listener with a 3.x signature is refused at registration.TimeOnlyandDateOnlyreplaceTimeOfDay;TimeProviderreplacesSystemTime; the semaphores are lock handlers.?in either day field) now parses, and two shapes fire on a different day than Cronos would — a bare digit in day-of-week (Quartz numbers Sunday1) and both day fields restricted (Quartz fires on the union). The guide's second audit finds them.Everything else — every renamed member, every sealed type, every removed constant — is in the guide, with the name you would have typed.
Fixes worth knowing about
The full list is spread over the six pre-release notes below. These change what a running cluster does without saying so, and most of them are as old as 3.x:
ResumeAllcould unpause real trigger groups: it deleted the all-groups sentinel with aLIKE, and the sentinel's four underscores are wildcards.... (truncated)
4.0.0-rc.2
The second release candidate. rc.1 was put to the test it was made for — a real application, on 3.19.1 in production, upgraded by the guide — and that upgrade found three things the pre-release gates had not. They are fixed here, and 4.0.0 is this commit once the same upgrade is repeated against it and comes back clean.
Changed since rc.1
RescheduleJobandUpdateTriggerDetailsresolved the job's class in order to decide whether the new trigger could run, and failed in a process without the assembly — theZeroSizeThreadPooladministration node, a web application that edits schedules the worker runs. Both now read the job's two attribute flags fromQRTZ_JOB_DETAILS.IS_NONCONCURRENTandIS_UPDATE_DATA, as every other read already did, and the decision is right without the class: a trigger stored for a[DisallowConcurrentExecution]job that is executing isBLOCKED, notWAITING. Such a process needs noITypeLoaderof its own and no placeholder type; every administration operation — read, query, pause, resume, reschedule, update, trigger, add a trigger, edit job data, delete — is pinned by a test that runs a worker and an administration node over one store with the class visible only to the worker. Only the firing path resolves a job's class.host.StopAsync()whilehost.RunAsync()is pending makes the generic host stop every hosted service twice concurrently;QuartzHostedServiceenumerated a list the other stop was clearing andRunAsyncthrewInvalidOperationException: Collection was modifiedsix runs in eight. There is now one stop, and a second caller joins it.1-7from Sunday) than in Cronos or NCrontab (0-6from Sunday). Cron expressions states the two divergences; the migration guide's second audit is a compiled sample that lists the stored expressions worth reading again.IgnoreDuplicates, without which every restart re-declared the trigger and scheduled it afresh.qsandfast-uriadvisories (#3704).Public API: unchanged from rc.1 — the baselines did not move. Schema: unchanged. Nothing in the packages' dependencies changed.
If you ran rc.1
Nothing to run. The schema and the configuration are rc.1's. If you had written a placeholder-type
ITypeLoaderfor an administration node, delete it: it was always a hazard, because whether the placeholder carried[DisallowConcurrentExecution]decided how a replacement trigger was stored for a job it was standing in for.If you ran an earlier pre-release
The migration guide's appendix If you ran a 4.0 pre-release lists every change between one build and the next, with the section that explains each; the rc.1 notes carry the "If you ran beta.1" list.
What stands behind this build
Everything rc.1's notes describe — the fresh-user journeys against the published packages, the security review, the stable-version pack, the rolling upgrade of a running 3.20 cluster on PostgreSQL and SQL Server, the clustered soaks on both — plus the published-rc.1 check, which built the six documented journeys from the published pages and verified every "If you ran beta.1" item against a beta.1-provisioned schema. The three findings above came from outside those gates: a production application, upgraded by the guide. That is the test 4.0.0 waits for.
Full changes: quartznet/quartznet@v4.0.0-rc.1...v4.0.0-rc.2
4.0.0-rc.1
Quartz.NET 4.0.0-rc.1 — the packages are on NuGet.
Beta.1 made the API a promise. This is the release candidate: 4.0.0 is this commit, tagged as soon
as the remaining hand-run gates are green and no later than a week from now. What changed between the
two is below; what will change between this and 4.0.0 is nothing but the release notes and the site.
The gates this build passed are the ones release day depends on, run against the published beta.1
packages and the documented pages rather than the tree: a developer building every documented journey
from scratch, every example project started, a security review of the HTTP API, the dashboard and the
client, a stable-version pack (this repository had never produced one), the 3.20 → 4.0 upgrade of a
running cluster through its mixed-version window by hand, and a clustered soak. They found things.
Every one is fixed here or named below.
Changed since beta.1
One security fix. With
QuartzDashboardOptions.SchedulerAuthorizationPolicyconfigured — themulti-tenant deployment that option exists for — a dashboard visitor authorized for one scheduler could
read another's job listing by switching the scheduler picker: the picker took the browser's value on
trust, pages already on screen re-read for it on a synchronous event, and the frame's access check
lagged behind on an asynchronous one. Both halves are closed: the picker refuses a name the filtered
listing did not carry, and every call through the dashboard's own
IQuartzApiClientis authorizedbefore the scheduler is looked up, where
ReadOnlywas already enforced. The same review found nohole an unauthenticated caller can reach; its "verified not an issue" list is on the pull request.
A job type named over the wire is a name, on both sides. Beta.1's contract types said a job type
that arrived in a request was stored unresolved and never probed;
JobBuilder.Build()resolved itanyway, on the request thread, and a test that claimed otherwise could not tell. Now: neither side
resolves a name while converting a DTO; the two attribute flags are optional on the wire — an omitted
concurrentExecutionDisallowedused to override[DisallowConcurrentExecution]on the real type withfalse— a job whose type resolves nowhere reads as200with the flags absent instead of a permanent500, a client can schedule a job whose type only the server has, a hostile server can no longerchoose an assembly name a client's runtime goes looking for, and a name is checked against
IJobbefore anything constructs it — a caller-named type used to have its static constructor, module
initializer and instance constructor run, with the scheduler scope's services injected, before the cast
refused it.
Scheduling.IgnoreDuplicates = trueon its own works. On beta.1 it was a startup error, becauseOverwriteExistingDatadefaults totrueand the validator refused the pair — the one-liner the guideitself recommended, and the one this repository's own Worker and ASP.NET Core examples wrote, so neither
example started. The default is a default rather than a statement now: setting
IgnoreDuplicatesturnsoverwriting off, and only writing both down is refused. The XML and JSON scheduling files follow the
same rule.
SendMailJobsends a container credential only to a host the container vouched for. The documentedmitigation — keep the SMTP password out of job data, register an
ICredentialsByHost— handed a bareNetworkCredentialto whateversmtp_hostthe job data named, as base64AUTH LOGIN, to whoever canschedule the job. A host-agnostic credential with a job-data host is refused, with the message naming
CredentialCacheand the host to bind it to; a bound cache answers for its host and nothing else.smtp_enable_sslis new and off by default, which isSmtpClient's own default.The shipped jobs look only where an application put something.
DirectoryScanJobfound its... (truncated)
4.0.0-beta.1
Quartz.NET 4.0.0-beta.1 — the packages are on NuGet.
Alpha.1 was the API becoming complete, alpha.2 the API being used, alpha.3 the release where Quartz is
operated, alpha.4 where it is integrated, alpha.5 where the API is finished. Beta.1 is the release where
the API is a promise: every public member has been read against the code it describes, every
documented behaviour has a test or a named caveat, the upgrade from 3.20 has been rehearsed on data a
released 3.20 wrote, and the operational defaults are safe rather than merely documented. It is the first
4.0 build we ask you to run in production — with the caveats list at the end of this page in hand.
Nobody outside this repository has run 4.0 in production yet: the five alphas total a few hundred
downloads and no external issue. Beta.1's validation is our own, which is why it is a beta. The API is
frozen from here to 4.0 — additive changes only, and any member added to a public interface arrives as a
default interface member. The schema is frozen once the 4.0 script has run. Stored blobs and the wire
format are frozen.
Changed since alpha.5
Six statements the frozen surface made were not true, and were corrected rather than documented around.
Each has a migration-guide row under Between the alphas and beta.1; coming from 3.x, read them as part
of 4.0.
MapQuartzHttpApi()andMapQuartzDashboard()refuse to start when nothing authorizes them. Analpha application that mapped either bare gets an
InvalidOperationExceptionat startup naming the threefixes:
RequireAuthorization()on the returned builder, the options' authorization policy, or an explicitAllowAnonymous(). Both surfaces schedule a job whose type is a string from the request; withQuartz.Jobson the path that is remote code execution, and an open endpoint is no longer the default.MapQuartzDashboard()returns anIEndpointConventionBuildercovering the pages and the SignalRhub, so one
RequireAuthorization()is the whole answer; the old return type protected the pages alone.IScheduler's mutation members raiseArgumentNullExceptionfor a null argument, as the extensionmethods on the same type always did;
SchedulerException("… cannot be null")is gone.CronExpression.TryParse(s, format, out)answersfalsefor aCronFormatit does not know ratherthan throwing out of a
Try; the constructor andParseagree onArgumentNullException.TriggerBase.FireInstanceId/IOperableTrigger.FireInstanceIdandDbMetadata.ParameterDbTypePropertyNamearestring?.QuartzHttpApiOptions.MaxPageSize(1000), and a500no longercarries the exception's message unless
IncludeStackTraceInProblemDetailsis on.Three more corrections change what a running program does without changing a shape:
Quartz:Schedulingrefuses
IgnoreDuplicateswhileOverwriteExistingDatais on (the pair was silently inert); ajob-data string written with a decimal comma (
"3,14") is unreadable by every numeric accessor insteadof reading as
314from the floating-point ones; and a persistent store refuses a repeat interval finerthan a millisecond instead of storing it as zero and wedging the trigger (#3673).
The upgrade is rehearsed
A console project on the released
Quartz3.20.0 packages seeds a database with every persistedtrigger family, blob-stored triggers, all six calendar kinds, a job data map of every admitted value type,
paused trigger and job groups with members added after the pause, and a firing abandoned by killing the
process; the 4.0 script runs over it; a 4.0 scheduler starts and checks every row against the manifest,
recovers the abandoned firing and fires everything. On every dialect, on every pull request. The blobs it
captured are now the unit fixtures the serializers are held to.
... (truncated)
4.0.0-alpha.5
Quartz.NET 4.0.0-alpha.5 — the packages are on NuGet. Alpha.1 was the API becoming
complete, alpha.2 the API being used, alpha.3 the release where Quartz is operated, alpha.4 where
it is integrated; alpha.5 is the release where the API is finished. This is the last alpha:
breaking changes end here, and what ships now is the shape 4.0 keeps.
Cron says what it means
The whole cron surface was put against Vixie cron and Cronos, and every place where Quartz silently
did something other than what the expression said is gone:
0 15 10 1 * *—the natural Unix spelling of "the 1st at 10:15" — used to fire every day of the month; it now
fires on the 1st. A field written
*or?restricts nothing (the two are now full synonymsthere); when both day fields name days, the union fires — the
crontab(5)rule, kept deliberatelywhere Cronos would AND.
IsSatisfiedByagrees it fired, which theold delta-shift could never manage. Fall-back behavior is unchanged from alpha.4's Cronos-aligned
rules.
1-5W(theWwas dropped),L-3inday-of-week (meant "Saturday"),
MON,FRI#3(the Friday was ignored),'C'(never implemented),steps of zero, and
MON/2— whose "every second week" had no stable phase and re-anchored on everymisfire, restart and failover. Fortnights belong to
RecurrenceScheduleBuilder; the migrationguide carries a pre-upgrade audit query for stored expressions.
CronExpression.Parse("30 4 * * 1", CronFormat.Unix)— day-of-week numbered 0–7 the crontab way, normalized to the canonical Quartzform. And the
@macros (@daily,@hourly,@weekly, …) work everywhere an expressionstring is read — code, JSON and XML files, the dashboard, the HTTP API — with no opt-in, including
through the hash-resolving paths.
Parse/TryParse/ParseWithHash/TryParseWithHashreplace fourvalidator members and two constructors that made
new CronExpression(expr, null)ambiguous;GetTimeBeforeis nowGetPreviousValidTimeBefore;GetExpressionSummary's internal-state dumpis gone.
A job's timeout is middleware
JobInterruptMonitorPlugin's stringly"AutoInterruptable"/"MaxRunTime"keys are retired. Atimeout is now
AddJobTimeout(TimeSpan)with a per-job[JobTimeout("00:05:00")]attribute; onexpiry the firing's own cancellation token fires through the standard interrupt path, and the
timeout reports as a retryable failure your
RetryPolicysees.The listener surface earns its place
IListenerManagerdrops its eight runtime matcher-mutation members (matchers are settled atregistration, and the notify path got faster for it); the three
Broadcast*listeners are gone (themanager already fans out);
TriggerMisfiredleads with its trigger like every sibling.Acquisition reads at the speed of its index
IDX_QRTZ_T_NFT_STnow carriesPRIORITY DESC, MISFIRE_INSTR: a 100k-trigger acquisition roundtrip drops from 21.6 ms to 589 µs on SQL Server (20,395 → 8 reads), with MySQL and Postgres wins to
... (truncated)
4.0.0-alpha.4
Quartz.NET 4.0.0-alpha.4
Alpha 4 is the integrator release: a framework that embeds Quartz — a message bus scheduling deferred
messages, a workflow engine firing timeouts, an application framework running background work — now
gets an integration surface designed for it rather than assembled from the app-facing API. The proof
is in this repository: MassTransit's Quartz integration, ported onto these primitives, lost 87 lines
and two whole classes, replaced three store round trips per upsert with one atomic call, and swapped
sixteen stringly-typed
JobDataMapkeys for one typed payload. A runnable Wolverine reference exampleships in the repo (
src/Quartz.Examples.Wolverine).Typed job input
IJob<TInput>— a job that takes a deserialized, typed payload; the input rides the trigger as asingle reserved string entry, survives every store and serializer, and is read back by static type
(#3521, #3540).
scheduler.ScheduleJob<TJob, TInput>(input, at | delay, options)— the one-liner: one durable jobper
TJob, one trigger per call, the trigger group as the correlation axis (#3522).IJobInputSerializerextensibility point; the default is System.Text.Json with the sametype-info-resolver registry the store serializer uses, so native AOT keeps working (#3540).
Scheduling as an integrator needs it
ScheduleJob(trigger, ScheduleJobOptions)replaces theExists → Unschedule → Scheduledance with one store operation under one lock (#3522).DeleteJobs(GroupMatcher<JobKey>)andUnscheduleJobs(GroupMatcher<TriggerKey>)return the removed keys; matching HTTP API endpoints(#3523, #3558).
QuartzHostedServiceOptions.AutoStart = false— the scheduler is built, boundand visible, and the embedding framework decides when it starts; the health check reports
Degraded, notUnhealthy, while it waits (#3525).Activityrecords the W3C tracecontext on the trigger; the firing's span links back to it — an
ActivityLink, not a week-longparent. On by default,
QuartzSchedulerOptions.PropagateTraceContextopts out (#3524, #3565).Job execution middleware
IJobExecutionMiddlewarewraps the execute call itself — something a listener structurally cannot do:open a scope around the job, translate exceptions, short-circuit. Registered per scheduler with
AddJobMiddleware<T>(), ordered, zero overhead when none are registered (#3526, #3553).Retry policy
Triggers carry a first-class retry policy:
TriggerBuilder.WithRetryPolicy(RetryPolicy.Exponential(5, TimeSpan.FromSeconds(30)))re-fires a failed job on its own schedule — persisted, cluster-safe,survives failover mid-wait and mid-execution, never burns a repeat count or an RRULE
COUNTslot,and yields to the next scheduled occurrence rather than double-firing. Exhaustion returns the trigger
to its ordinary schedule: one bad hour must not kill a cron trigger. A 15-case matrix pins the edge
cases on both stores;
quartz.trigger.retryjoins the meters.RefireImmediatelyremains what italways was — an in-process re-execution, not a retry (#3520, #3569).
... (truncated)
4.0.0-alpha.3
Quartz.NET 4.0.0-alpha.3 is the third pre-release of 4.0. Alpha.1 was the API becoming complete; alpha.2
was the API being used. This one is the release where Quartz is operated: a cluster can be read
from outside — its nodes, its execution groups, its misfires, its history and its meters all say which
node they came from; the persistent store is honest about what it stored and about what failed, and it
spends a statement on a set rather than on each of its members; the trimming and native AOT claim
stopped being a compile and became a scheduler that CI publishes natively and runs against a real
database; and the test suite now proves what the documentation had been promising — daylight saving end
to end, misfires through a store, clustering on every engine, and the job-store contract on every
dialect that ships.
This is still an alpha. There is no compatibility promise between pre-releases, and this one moves
several names and changes several behaviours. The
migration guide carries
every change with before and after; the sections named below are its.
There is no schema migration in this release. Nothing under
database/migrations/changed, so adatabase created or upgraded for alpha.2 needs nothing done to it. The fresh-install scripts under
database/tables/did change — all eight can now be told not to drop an existing schema — but thosebuild a new schema rather than upgrade one.
Before you start
An application written against alpha.2 will not build or start until these seven are dealt with.
A registered job may not take a scheduler's parts by constructor, and startup says so. A job type
the container holds is built by the container, which resolves constructor parameters without a
scheduler's service key — so a job on scheduler
acmetakingIScheduler,ISchedulerFactory,IJobStore,IThreadPoolor one of a scheduler's options types was handed the defaultscheduler's, or could not be built at all in a container holding only named schedulers. Options
validation now refuses it, naming the job, the parameter and the three ways to write it instead
(
IJobExecutionContext.Scheduler,IJobExecutionContextAccessor, orAddJobType<T>(provider => …)resolving the part by key). Every public constructor is examined, not the one the container would
pick, because which one that is depends on what else is registered.
TimeProviderandIServiceProviderare deliberately excluded.(closes #3388)
The semaphores are lock handlers. A semaphore is a counted permit; what Quartz has is a
mutual-exclusion lock over a named row, one holder, re-entrant per connection, released on the same
connection. The name came from the Java port rather than from anything the type does, and the builder
method (
UseLockHandler), the key (quartz.jobStore.lockHandler.type) and the how-to have said"lock handler" for as long as they have existed. The types now agree:
ISemaphoreILockHandlerISemaphore.ObtainLockILockHandler.AcquireLockSemaphoreContextLockHandlerContextDbSemaphoreDbLockHandlerSelectForUpdateSemaphoreSelectForUpdateLockHandlerUpdateRowSemaphoreUpdateRowLockHandlerSqlServerMemoryOptimizedUpdateRowSemaphoreSqlServerMemoryOptimizedUpdateRowLockHandler... (truncated)
4.0.0-alpha.2
Quartz.NET 4.0.0-alpha.2 is the second pre-release of 4.0. Alpha.1 was the API becoming complete; this one is
the API being used — by the dashboard's own tests, by trimmed and source-generated builds, by several
schedulers in one host — and reshaped where that use showed a seam. Most of what is below came out of an
audit of the alpha.1 surface and the multi-tenancy story, and a good part of it is fixes for things alpha.1
could not have known were broken.
This is still an alpha. There is no compatibility promise between pre-releases, and this one moves
several names that alpha.1 had. The migration guide
carries every change with before and after; the sections named below are its.
Before you start
QRTZ_PAUSED_JOB_GRPSrecords paused job groups(the ADO store could not answer
IsJobGroupPausedbefore). Re-rundatabase/migrations/4.0/schema_30_to_40_upgrade_<dialect>.sqlfor your database — the scripts are guarded and safe to run again — or run only its
QRTZ_PAUSED_JOB_GRPSstatement. See Database schema changes.ISchedulerListenermember andITriggerListener.TriggerMisfirednow takes the callingISchedulerfirst,and
SchedulerErrortakes aSchedulerErrorContext. Because the members have default bodies, a listenerthat kept the old signature would compile and silently never be called — so the registration now refuses
it with a message naming the member. Listeners are told which scheduler is calling.
IsStarted,InStandbyModeandIsShutdownare gone;IScheduler.Statusis the lifecycle, as oneSchedulerStatus. A scheduler's lifecycle is one value.IServiceProviderinto
scheduler.Context["Quartz.ServiceProvider"]; nothing does now. A plugin or listener that read it backout takes what it needs by constructor instead — it is built by the container. (see #3408)
Highlights
The scheduler's state is one value
IScheduler.Status(Created,Running,Standby,ShuttingDown,Shutdown,Unknown) replaces threebooleans that had to be read in a precedence order only one internal method knew — the reason the HTTP API
and the dashboard once disagreed about what a running scheduler is called.
SchedulerMetadatafollows.Start()on a running scheduler does nothing,Standby()on one that neverstarted does nothing,
Standby()after shutdown throws, and a shutdown no longer announces a standby it didnot enter. A scheduler that is draining reads
ShuttingDownfor as long as it drains, and a teardown thatthrows still ends in
Shutdown.Runningprobes the store,Standbyis Degraded, therest are Unhealthy with a message — and a check registered for a default scheduler in a container that has
only named ones reports Unhealthy instead of throwing out of the pipeline.
Listeners know who is calling
one, and as the first argument where there is not — all 23
ISchedulerListenermembers andTriggerMisfired. A shared listener in a host with several schedulers finally knows which one paused atrigger or raised an error. (closes #3063)
SchedulerErrorcarries aSchedulerErrorContext— message, exception, and the trigger, job and fireinstance the error was for, wherever the scheduler knew them.
... (truncated)
4.0.0-alpha.1
Quartz.NET 4.0 is the first major version since 3.0, and the first that assumes a modern .NET: it targets
net10.0only, it is asynchronous end to end, and the container builds the scheduler instead of a factory reading type names out of a string bag. A public surface that had grown for a decade got a full pass — one word per concept, one shape per operation, and nothing public that was never a contract.This is an alpha. It is complete enough to run and to port an application against, and the API is close to final, but it is a pre-release: names can still move if feedback says they should, and there is no compatibility promise between alpha builds. Do not put it in production yet. Do please try it against a real application and say what breaks or reads badly — that is what this build is for.
It is a major version with extensive breaking changes and a mandatory schema migration. This page is the short form; the detail lives in the docs:
Before you start
Four things have to be true before a 3.x application will build and run on 4.0:
net10.0. There is nonetstandard2.0build and no Full Framework.configsupport.QRTZ_TRIGGERSand one onQRTZ_FIRED_TRIGGERSwere optional in 3.x and are required now, so 4.0 does not probe for them.schema_30_to_40_upgrade_<dialect>.sqlfolds in everything from 3.17 onward.Quartz.Extensions.DependencyInjection,Quartz.Extensions.HostingandQuartz.Serialization.SystemTextJsonare part ofQuartznow.Quartz.Serialization.JsonisQuartz.Serialization.Newtonsoft, andQuartz.OpenTracingis dropped in favour ofOpenTelemetry.Instrumentation.Quartz.CalendarIntervalTriggerwithPreserveHourOfDayAcrossDaylightSavingssteps in local wall-clock time and no longer drifts in zones whose offset is not a whole hour. Any schedule that crosses a transition is worth re-checking.Highlights
The container builds the scheduler
Quartzpackage.StdSchedulerFactory,DirectSchedulerFactory,quartz.configfile discovery,SchedulerRepository.InstanceandDBConnectionManager.Instanceare gone. Flatquartz.*keys still work — they are translated into typed options by one component that understands them, and a misspelled key is rejected with a message rather than ignored.QuartzSchedulerBuilderis the DI-free entry point and is the same builderAddQuartzuses, so there is one configuration API rather than two that resemble each other. Its configuration members return the builder's own type, soCreate().UseInMemoryStore().BuildScheduler()is one expression.UseJobFactory,UseTypeLoader,UseThreadPool,UseJobStore,UseTimeProvider,UseInstanceIdGenerator— each with a type, an instance and a factory overload, and each keyed correctly for a named scheduler.ValidateOnStart, so a bad value failsHost.Build()with every failure listed instead of throwing later from inside a factory.ValidateOnBuilddoes not spin one up.Listings are queries
QueryJobs,QueryTriggers,QueryJobGroups,QueryTriggerGroupsandQueryCalendarNamestake a query record and return aPagedResult<T>withItems, an exactHasMoreand an optionalTotalCount. A table with a hundred thousand triggers no longer loads in one go.Takedefaults to 250; asking for everything is an explicitTake = int.MaxValue.JobHeaderandTriggerHeadercarry the name, group, state, fire times, priority, calendar and execution group a listing needs, so a dashboard page renders without deserializing a single job data map.=rather thanLIKE, so a group literally named50%matches itself.IsJobGroupPausedasks the store about one group instead of listing every paused group and searching it.GetJobDetails(keys)andGetTriggers(keys)turn N round trips into one, over ADO.NET and over HTTP alike.ISchedulerlisting members come back as extension methods with the same names and signatures, so existing call sites keep compiling. One behavioural difference: a null matcher now throws instead of silently narrowing the listing to theDEFAULTgroup.What is running, and what state it is in
TriggerState.Executingis reported directly, and with a persistent store it is visible from every node.Blockednarrows to its real meaning: a different trigger of the same[DisallowConcurrentExecution]job is running. (closes #1416)QueryFireInstances(FireInstanceQuery)returns aPagedResult<FireInstance>— fire instance id, trigger, job, node, state, scheduled and actual fire time, execution group — answered cluster-wide by a persistent store. It replacesGetCurrentlyExecutingJobs, which could only ever speak for the current process. There is an HTTP endpoint for it and the dashboard tile reads it. (closes #3205)JobInstantiationExceptioncarries the job detail, the trigger and the fire instance id rather than interpolating a key into a message.ISchedulerListener.TriggerInError/TriggersInErrorfire on every transition intoTriggerState.Error, including two in the ADO store that previously reached nothing at all.Scheduling
WithMisfireInstruction(SimpleTriggerMisfireInstruction.FireNow)instead of an untypedintand a method name per instruction. The stored numbers are unchanged.TimeOnlyandDateOnlyreplace Quartz's ownTimeOfDay, andTimeProviderreplacesSystemTime, so faking the clock in a test uses the BCL. The scheduler's clock is injected rather than ambient, andAddQuartzpicks up aTimeProviderregistered in the container.JobBuilder<TJob>andTriggerBuilder<TJob>letUsingJobDataname a job property with an expression instead of a string key, and the nineUsingJobDataoverloads collapse to one.WithIntervalper builder instead of the `WithInt...Description has been truncated