CI started failing on every branch with an assembly load error out of NUKE's
project parsing, before any test ran:
InvalidProjectFileException: The expression
"[MSBuild]::GetTargetFrameworkIdentifier(net10.0)" cannot be evaluated.
Could not load file or assembly 'NuGet.Frameworks, Version=7.9.0.0'.
The located assembly's manifest definition does not match the assembly reference.
at Nuke.Common.ProjectModel.ProjectModelTasks.ParseProject
Nothing in the repo changed to cause it. pr.yml requests dotnet-version 10.x,
and the hosted runner moved from SDK 10.0.302 to 10.0.400. Measured, the two
SDKs ship different NuGet.Frameworks:
SDK 10.0.300 / 10.0.302 -> NuGet.Frameworks 7.6.0
SDK 10.0.400 -> NuGet.Frameworks 7.9.0
_build.csproj pinned NuGet.Packaging 7.6.0, which puts NuGet.Frameworks 7.6.0
in the NUKE output directory, where it shadows the SDK's own copy. The loader
accepts an assembly newer than the reference but not older, so once MSBuild
started asking for 7.9.0.0 the app-local 7.6.0 no longer satisfied it. The same
commits passed 19 hours earlier on 10.0.302.
The reference is not used by the build itself - there are no NuGet.* usages
anywhere in build/*.cs. It exists only as a transitive vulnerability override,
added in f5dc29cdc, so bumping it preserves the original intent while matching
what the current SDK ships. Staying loadable on 10.0.3xx follows from the same
newer-than-reference rule that broke the old pin.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Review caught that the contract advertised something that cannot work. It
offered handlers three ways to terminalize the faulted activity - cancel,
complete, or reschedule - but CompleteActivityAsync returns immediately unless
the activity is Running, and throughout the handler it is still Faulted, since
recovery runs only after the handler returns. Completing inline did nothing at
all, silently, leaving the child Running.
Measured, same container, handler completing the faulted child:
inline complete -> child Running, no output, Running/Suspended
TransitionTo(Running), complete -> child Completed, "after", Finished/Finished
So a supported path exists; it just needed writing down. Document it on
FaultSignal, note that it is not licence to call RecoverFromFault (which also
rewrites the fault counts), and note that cancelling and rescheduling need no
equivalent step. Cover it with an integration test asserting that completing the
child with a substitute result fires the container's completion callback and
resumes its sequencing.
Refs #7911
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Review raised that TrySendSignalAsync delivers to the faulting activity before
walking ancestors, so an activity that throws and also handles FaultSignal can
claim its own fault and suppress the incident strategy.
That is real, but it is the channel's existing dispatch, which #7911 chose
deliberately over a variant of it, and SignalContext.IsSelf exists so handlers
can discriminate. It also grants no capability: an activity that catches its own
exception never faults at all, ending Finished/Finished with zero incidents,
which is a cleaner suppression than self-handling (incident still recorded,
activity left Running, workflow suspended).
So dispatch is unchanged. What was missing is that none of this was written
down: the contract describes the handler as an enclosing container and never
mentioned self-receipt. Document it on FaultSignal, including how a handler
that wants ancestors-only semantics opts out, and add a test so the behavior is
pinned rather than incidental.
Refs #7911
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A container activity had no way to learn that one of its children faulted.
ExceptionHandlingMiddleware caught the exception, called context.Fault(e) and
handed off to the workflow-global IIncidentStrategy; the container's completion
callback never fired, because the child never completed.
Add a seam on the ancestor-bubbling signal channel that already exists:
- FaultSignal(Exception, ActivityExecutionContext), beside CancelSignal. Its XML
doc carries the contract, including why a handler must not call
RecoverFromFault and why the CompleteActivityAsync sweep is a backstop rather
than the mechanism.
- An internal bool-returning TrySendSignalAsync, since SignalContext
.StopPropagationRequested is internal and SendSignalAsync reported nothing.
SendSignalAsync keeps its public signature and delegates to it.
- ExceptionHandlingMiddleware sends the signal after faulting and, when an
ancestor stops propagation, calls RecoverFromFault once and returns instead of
raising an incident.
RecoverFromFault now transitions to Running only when the activity is still
Faulted. It is called after the handler runs, so the unconditional transition
would otherwise undo a handler that cancelled or completed the faulted child.
The counts are still reset unconditionally, and the one pre-existing caller is
unaffected.
Behavior is unchanged when nobody handles the signal: verified by running the
new unhandled-fault theory against the pre-change middleware, and by
IncidentStrategyTests and Primitives/FaultTests passing unmodified.
Refs #7911
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds a new `Elsa.Http.Webhooks` module, enabling workflows to receive incoming webhook events and dispatch outgoing webhooks. This integrates the WebhooksCore library.
Further improvements include:
- Enhanced validation for configured application instance names, providing clearer feedback, especially regarding Azure Service Bus entity name limits.
- Improved API error reporting for shell reload operations, distinguishing between blueprint not found (404) and other failures (503).
- Updated release announcement rendering to dynamically reference the correct major.minor release line for feedback messages.
Use the same structural and secret-binding assessment for management, discovery, and initiation so incomplete overrides are never advertised as available sign-in methods.
Introduce a new test `ValidateRequiresCompleteConfigurationAndReturnsMissingSecretDetails` to verify that a connection requires a complete configuration, including handling missing secret details. Adjust configuration to enforce `RequiresClientSecret`.
Detach the AsyncLocal scope synchronously so notifications published after an asynchronous flush are not re-buffered and discarded. Add regression coverage that forces the flush across an async boundary.