Skip to content

v1.5.2 — runner and nested-action fixes

Choose a tag to compare

@aemadrid-twx aemadrid-twx released this 22 Oct 21:58
· 87 commits to main since this release
76f3d76

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 aggregate ci check that main requires.
  • 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.md and the Claude skill.

Fixed

  • A failed transactional action inside an outer transaction no longer
    commits its writes.
    It joined the outer transaction, whose commit ignored
    the action's rollback, so a recorded Failure still committed its rows
    (measured on ActiveRecord 8.1 + SQLite). Inside an open transaction the action
    now takes its own savepoint (requires_new: true) unless requires_new: is
    given; requires_new: false keeps 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_step methods work. The definition check
    already accepted them, but the step then raised NoMethodError; 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
    DefinitionError up front instead of calling Kernel.

  • Action.input without a block reads the schema instead of replacing it
    with an empty one, matching output.

  • A step that assigns @result gets a clear DefinitionError instead of a
    NoMethodError deep in the runner.

  • History#to_json requires Oj itself rather than relying on another file
    having loaded it.

  • A bang verb inside a lifecycle hook now sets the result. fail!,
    skip! or succeed! in a hook used to be dropped: fail! in on_success
    returned Success, committed a transactional action 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/skip kwargs survive lifecycle hooks. After any hook
    refreshed the output, the kwargs were lost: a required field set only by
    kwarg turned the run into Failure(:invalid_output), and a kwarg that
    overrode an ivar silently reverted to the ivar's value. Present since 1.0.0.
    A Failure(: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.