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>
Unquoted aliases in SELECT … FROM DUAL caused ORA-00904 because Oracle
uppercases bare identifiers. All aliases, ON condition, UPDATE SET, and
INSERT/VALUES column references are now double-quoted to match the
case-sensitive names EF Core migrations produce.
NVARCHAR2 columns additionally required an explicit CAST because ODP.NET
cannot infer bind parameter types from a FROM DUAL subquery and defaults
to VARCHAR2. CAST(:p AS NVARCHAR2(n)) with length extracted from the EF
column type string resolves the datatype mismatch.
Both fixes are required — neither alone produces working Oracle persistence.
All other providers are unchanged.
fixes Fixes#7755
Use LINQ for the case-insensitive payload property lookup and keep CShells package source mapping deterministic by mapping CShells packages only to nuget.org.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Map CShells package IDs to NuGet.org as well as the CShells Feedz source so solution restore can resolve published CShells packages when the Feedz source has no matching package.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Make the PublishEvent payload assertion case-insensitive so it tolerates JsonPayloadSerializer camelCase output after a JSON round trip.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Configured stable application instance names that exceed the Azure Service Bus transport entity limit are now shortened deterministically instead of failing startup. The same configured value resolves to the same shortened name across restarts, preserving stable per-instance transport identity while supporting normal Kubernetes pod names.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Make validation constants internal and expose via InternalsVisibleTo so tests reference single source of truth
- Add empty-string guard to IsValidConfiguredInstanceName to prevent IndexOutOfRangeException
- Add ClusteringFeature_UsesConfiguredInstanceNameProvider test for Features.ClusteringFeature to match existing ShellFeatures coverage
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Forward-port the opt-in stable application instance name support from PR #7734 so clustered deployments can reuse per-instance transport entities across restarts while preserving random names by default.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>