Repository navigation
feat: add remote action executor - #2167
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThis PR introduces a complete Dagu Actions system: a mechanism for DAGs to invoke other DAGs as reusable, parameterized actions. Actions can be resolved from GitHub repositories, local source directories, or official DaguCloud references, their inputs/outputs validated against JSON schemas, and their workspaces bundled and distributed for both local and coordinated execution. ChangesAction System & Distributed Execution
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
internal/runtime/workspacebundle/bundle.go (1)
451-454: 💤 Low valueNil receiver checks are unusual and may mask configuration bugs.
The
s == nilchecks inPutandGetreturn errors at runtime rather than failing fast during construction. If the store is not configured, this should ideally be caught earlier (e.g., at handler initialization) rather than silently failing on each call.This is acceptable if the store is intentionally optional, but consider documenting this behavior or validating configuration earlier.
Also applies to: 501-504
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/runtime/workspacebundle/bundle.go` around lines 451 - 454, The nil-receiver guards in Store.Put and Store.Get (methods on type Store) mask configuration bugs by returning runtime errors instead of failing fast; remove the s == nil checks from these methods and either (a) validate the Store during construction/initialization (e.g., in NewStore or the handler that receives *Store) and return an error or panic there if dir is empty/nil, or (b) explicitly document that the Store is optional and provide an IsConfigured/Enabled method callers must check before calling Put/Get; update Store.Put and Store.Get to only validate s.dir (or assume non-nil receiver) and rely on the constructor/initializer to enforce correctness.internal/service/coordinator/client.go (1)
833-879: 💤 Low valueUpload fails fast on any coordinator error, which may be overly strict.
The current implementation returns immediately if
hasWorkspaceBundleInMemberorputWorkspaceBundleToMemberfails for any coordinator. This ensures all coordinators have the bundle, but a single transient coordinator failure will abort the entire upload even if other coordinators could accept it.If the intent is "at least one coordinator must have the bundle," consider continuing on error and only failing if
satisfied == 0. If strict replication is required, the current behavior is correct but should be documented.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/service/coordinator/client.go` around lines 833 - 879, PutWorkspaceBundle currently aborts on the first error from hasWorkspaceBundleInMember or putWorkspaceBundleToMember which makes uploads fail-fast for transient coordinator errors; change PutWorkspaceBundle so that errors from hasWorkspaceBundleInMember and putWorkspaceBundleToMember do not immediately return but instead set lastErr and continue to the next member (increment satisfied only on success or when exists==true), and only return a composite error at the end if satisfied == 0; update the error wrapping to include member.ID and ensure getOrCreateClient and isHealthy behavior remains unchanged (symbols: PutWorkspaceBundle, hasWorkspaceBundleInMember, putWorkspaceBundleToMember, satisfied, lastErr).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/cmn/schema/dag.schema.json`:
- Around line 2147-2158: The schema block that applies when "type": "action"
currently only requires "with" and references actionExecutorConfig but allows
remote refs that normalizeStepExecutionRaw would reject; update this conditional
(the "if" / "then" for type: "action" in dag.schema.json) to enforce the same
remote-ref validation used by action: normalization—i.e., tighten the
regex/format constraints on the "with" / ref fields or reuse the exact validator
used by actionExecutorConfig/action normalization so that
isSafeActionVersion-equivalent checks are applied for steps declared with type:
action; ensure the change references actionExecutorConfig and aligns with
normalizeStepExecutionRaw and isSafeActionVersion behavior.
In `@internal/core/spec/step_v2.go`:
- Around line 189-195: The code treats any action starting with "source:" as
remote without validating the ref, which lets malformed or unsafe refs slip
through; update the logic in the isRemoteActionReference handling (and the
similar blocks referenced) to parse the ref via actionWith(raw) and then
validate the parsed ref's version using isSafeActionVersion (or return a clear
error) before calling normalizeRemoteAction; in other words, ensure
actionWith(raw) succeeds and the returned with.Version passes
isSafeActionVersion for the given action/normalized/action variables, and if
not, return an error here rather than letting normalizeRemoteAction/resolver
handle it downstream.
In `@internal/service/worker/action_workspace.go`:
- Around line 71-73: When workspacebundle.Extract fails, ensure the partially
materialized workDir is removed before returning so retries don't see stale
files: after the Extract call in the same block that currently returns
fmt.Errorf("extract workspace bundle %s: %w", desc.Digest, err), call
os.RemoveAll(workDir) (or equivalent cleanup) and handle any RemoveAll error
without masking the original Extract error (e.g., log or append cleanup error to
the returned error), then return the original wrapped extract error referencing
desc.Digest.
---
Nitpick comments:
In `@internal/runtime/workspacebundle/bundle.go`:
- Around line 451-454: The nil-receiver guards in Store.Put and Store.Get
(methods on type Store) mask configuration bugs by returning runtime errors
instead of failing fast; remove the s == nil checks from these methods and
either (a) validate the Store during construction/initialization (e.g., in
NewStore or the handler that receives *Store) and return an error or panic there
if dir is empty/nil, or (b) explicitly document that the Store is optional and
provide an IsConfigured/Enabled method callers must check before calling
Put/Get; update Store.Put and Store.Get to only validate s.dir (or assume
non-nil receiver) and rely on the constructor/initializer to enforce
correctness.
In `@internal/service/coordinator/client.go`:
- Around line 833-879: PutWorkspaceBundle currently aborts on the first error
from hasWorkspaceBundleInMember or putWorkspaceBundleToMember which makes
uploads fail-fast for transient coordinator errors; change PutWorkspaceBundle so
that errors from hasWorkspaceBundleInMember and putWorkspaceBundleToMember do
not immediately return but instead set lastErr and continue to the next member
(increment satisfied only on success or when exists==true), and only return a
composite error at the end if satisfied == 0; update the error wrapping to
include member.ID and ensure getOrCreateClient and isHealthy behavior remains
unchanged (symbols: PutWorkspaceBundle, hasWorkspaceBundleInMember,
putWorkspaceBundleToMember, satisfied, lastErr).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0c29f513-c2a2-444f-b736-1fae786a0185
⛔ Files ignored due to path filters (3)
proto/coordinator/v1/coordinator.pb.gois excluded by!**/*.pb.goproto/coordinator/v1/coordinator_grpc.pb.gois excluded by!**/*.pb.goproto/coordinator/v1/coordinator_protoopaque.pb.gois excluded by!**/*.pb.go
📒 Files selected for processing (25)
internal/cmd/coord.gointernal/cmd/retry.gointernal/cmn/schema/dag.schema.jsoninternal/core/spec/step_types.gointernal/core/spec/step_v2.gointernal/core/spec/step_v2_test.gointernal/core/step.gointernal/intg/action_test.gointernal/runtime/builtin/action/action.gointernal/runtime/builtin/action/action_test.gointernal/runtime/builtin/action/manifest.gointernal/runtime/builtin/action/resolver.gointernal/runtime/builtin/builtin.gointernal/runtime/executor/dag_runner.gointernal/runtime/executor/task.gointernal/runtime/workspacebundle/bundle.gointernal/service/coordinator/client.gointernal/service/coordinator/handler.gointernal/service/coordinator/workspace_bundle_handler.gointernal/service/worker/action_workspace.gointernal/service/worker/handler.gointernal/service/worker/remote_handler.gointernal/service/worker/worker.goproto/coordinator/v1/coordinator.protoscripts/installer.sh
💤 Files with no reviewable changes (1)
- scripts/installer.sh
Summary
Adds remote Dagu action execution with manifest-backed action DAGs and workspace bundle support for distributed workers.
Changes
Related Issues
N/A
Checklist