Repository navigation
v1.5.2 — runner and nested-action fixes
Runner and nested-action fixes: hooks that halt, kwargs that survive hooks,
nested actions that neither wipe parent ivars nor commit failed writes.
Requires field_struct 0.11.0 or later.
Changed
- Requires field_struct >= 0.11. It is the release whose numeric and input
fixes this one is tested against; CI now pins it by tag. - CI runs Ruby 3.2, 3.3, 3.4 and 4.0 (was 3.3.6 only), plus the docs guard,
behind one aggregatecicheck thatmainrequires. - The packaged gem leaves out contributor-only files (
.claude/,
CLAUDE.md,docs/origin/, Rakefile/Steepfile/lint config). It still ships
lib/,sig/, the user docs,AGENTS.mdand the Claude skill.
Fixed
-
A failed
transactionalaction inside an outer transaction no longer
commits its writes. It joined the outer transaction, whose commit ignored
the action's rollback, so a recordedFailurestill committed its rows
(measured on ActiveRecord 8.1 + SQLite). Inside an open transaction the action
now takes its own savepoint (requires_new: true) unlessrequires_new:is
given;requires_new: falsekeeps the old joining behaviour. -
A nested action no longer wipes parent ivars it never set. Absorbing a
successful or skipped child copied every declared output field, so a field
the child left nil (or at its default) overwrote the parent's value. Only
fields the child actually set are absorbed now;expose:still narrows them. -
Private step, hook and
case_stepmethods work. The definition check
already accepted them, but the step then raisedNoMethodError; they are
now called like guards are. A step or hook named after a method the action
only inherits from Ruby's core (step :puts,always :exit) raises
DefinitionErrorup front instead of callingKernel. -
Action.inputwithout a block reads the schema instead of replacing it
with an empty one, matchingoutput. -
A step that assigns
@resultgets a clearDefinitionErrorinstead of a
NoMethodErrordeep in the runner. -
History#to_jsonrequires Oj itself rather than relying on another file
having loaded it. -
A bang verb inside a lifecycle hook now sets the result.
fail!,
skip!orsucceed!in a hook used to be dropped:fail!inon_success
returnedSuccess, committed atransactionalaction and acked the job.
The hook's result is now adopted before the halt stops the remaining hooks,
as the docs always said. This includes a nested action used as a hook
(on_success ChildAction): a failing child now fails the run and stops the
remaining hooks. -
succeed/skipkwargs survive lifecycle hooks. After any hook
refreshed the output, the kwargs were lost: a required field set only by
kwarg turned the run intoFailure(:invalid_output), and a kwarg that
overrode an ivar silently reverted to the ivar's value. Present since 1.0.0.
AFailure(:invalid_output)also keeps the output that failed validation
across hooks instead of having it rebuilt from ivars. -
No spurious
errors[:output]on a failure or skip. The best-effort,
unvalidated output of a non-typed failure or skip added
output: ["is invalid"]to the result's errors. It no longer does; errors
the failure recorded itself are kept.