Skip to content

Add workflow run action#325

Merged
marccampbell merged 7 commits into
mainfrom
workflow-run-action
May 26, 2026
Merged

Add workflow run action#325
marccampbell merged 7 commits into
mainfrom
workflow-run-action

Conversation

@marccampbell

@marccampbell marccampbell commented May 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add on_enter.run support for workflow stages
  • execute run commands in the agent workspace for Daytona, Replicated, exe.dev, and noop test agents
  • add persisted trust-on-first-use SSH host key verification for server SSH paths
  • update the GitHub Issues workflow with a pre-commit Clawpatch stage

Tests

  • env GOCACHE=/private/tmp/elasticclaw-go-build go test ./pkg/hub/pipeline ./pkg/hub

@greptile-apps

This comment was marked as resolved.

Comment thread pkg/hub/pipeline_runner.go Outdated
@greptile-apps

greptile-apps Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

Reviews (2): Last reviewed commit: "Disable replicated workflow run actions" | Re-trigger Greptile

@greptile-apps

greptile-apps Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

Reviews (3): Last reviewed commit: "Trust SSH host keys on first use" | Re-trigger Greptile

Comment thread pkg/hub/pipeline_runner.go Outdated
@greptile-apps

greptile-apps Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Reviews (4): Last reviewed commit: "Honor replicated workflow run timeouts" | Re-trigger Greptile

@greptile-apps

greptile-apps Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Reviews (5): Last reviewed commit: "Stabilize Linear E2E workflow triggers" | Re-trigger Greptile

Comment thread pkg/hub/ssh_known_hosts.go Outdated
@greptile-apps

greptile-apps Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds on_enter.run support for workflow pipeline stages, allowing a shell command to execute in the agent workspace before the stage's inject and other on-enter actions proceed. It also replaces all InsecureIgnoreHostKey SSH usages with a trust-on-first-use store backed by a new ssh_known_hosts SQLite table, resolving the previously flagged host-verification gap using an INSERT OR IGNORE + SELECT pattern to handle concurrent first-use safely.

  • Pipeline run action: executePipelineRunAction dispatches to Daytona, exe.dev, Replicated (SSH), or a noop provider; runOnEnter runs the command synchronously before inject, and respects continue_on_error to either surface an error and abort or warn and continue.
  • SSH TOFU: verifySSHHostKeyOnce uses INSERT OR IGNORE to atomically handle concurrent first-use writes, then SELECT-compares the persisted key; a retry loop with back-off handles SQLite busy errors.
  • E2E test isolation: Linear E2E tests now create and clean up a per-run label, scoping issue triggers to avoid cross-run interference.

Confidence Score: 5/5

Safe to merge; all three previously flagged SSH and timeout issues are addressed, and no new blocking defects were found.

The InsecureIgnoreHostKey removals are complete across all four SSH call sites, the TOCTOU race is closed with INSERT OR IGNORE, and the replicated-provider timeout is now enforced via sshRunWithTimeout. The remaining findings are minor nits that do not affect correctness on the critical paths.

ssh_known_hosts.go (isSQLiteBusy coverage) and pipeline_runner.go (exedev timeout precision) are worth a quick second look, but neither blocks the change.

Important Files Changed

Filename Overview
pkg/hub/ssh_known_hosts.go New TOFU SSH host-key store using INSERT OR IGNORE to resolve the prior TOCTOU race; retry loop uses fragile string-based SQLite busy detection.
pkg/hub/pipeline_runner.go Adds executePipelineRunAction and runOnEnter.Run support; replicated and daytona paths enforce configured timeout precisely, but exedev receives timeout+30s via context instead of the exact configured duration.
pkg/hub/server.go sshRun refactored to delegate to new sshRunWithTimeout with a timer-based deadline; all four InsecureIgnoreHostKey usages replaced with sshHostKeyCallback.
pkg/hub/db.go Adds ssh_known_hosts table (host PRIMARY KEY, key_type, key_data, fingerprint, timestamps) in both the live-migration and the snapshot paths.
test/e2e/linear_test.go Adds label-scoped E2E isolation (create/delete label per run); deleteLabelsByName fetches all labels without pagination, which could miss stale labels in a workspace with many labels.
pkg/hub/pipeline/pipeline.go Adds RunAction struct and wires it into OnEnter YAML parsing; straightforward data-structure addition with a clean shadow-type unmarshal pattern.
pkg/hub/checkpoints.go Single-line change: replaces InsecureIgnoreHostKey with sshHostKeyCallback for the checkpoint-restore SSH path.
pkg/hub/ssh_known_hosts_test.go New tests cover first-use trust, same-key acceptance, changed-key rejection, and a concurrent 20-goroutine first-use race with a file-backed DB.
pkg/hub/pipeline_runner_test.go Updated to assert on the new bool return from transitionPipelineStageWithContext; concurrent test now counts successful transitions and asserts exactly one.
pkg/hub/pipeline/pipeline_test.go New TestParseRunAction covers command, continue_on_error, and timeout YAML parsing for the RunAction struct.
.elasticclaw/workflows/github-issue.yaml Adds pre_commit stage with clawpatch run (continue_on_error: true, 15m timeout) and inject to review and fix reported issues before the final commit.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Stage transition triggered] --> B[claimPipelineStageTransition]
    B -- duplicate --> C[return false]
    B -- claimed --> D{OnEnter.Run.Command set?}
    D -- no --> H
    D -- yes --> E[executePipelineRunAction]
    E --> F{provider}
    F -- daytona --> G1[ExecWithTimeout ctx+30s outer / timeout inner]
    F -- exedev --> G2[Exec ctx+30s outer only]
    F -- replicated --> G3[sshRunWithTimeout with timer = timeout]
    F -- noop --> G4[return success]
    G1 & G2 & G3 & G4 --> I{exit code 0 and no error?}
    I -- yes --> H[runOnEnter: send Inject, MoveIssue, etc.]
    I -- no, continue_on_error=true --> J[injectHubMessage: Warning] --> H
    I -- no, continue_on_error=false --> K[injectHubMessage: Error, return early]
    H --> L[transitionPipelineStageWithContext returns true]
    K --> L
    L --> M{Terminal stage?}
    M -- no --> N[Done]
    M -- yes --> O[Wait for streaming, checkpoint, delete claw]
Loading

Reviews (6): Last reviewed commit: "Avoid known host first-use race" | Re-trigger Greptile

@marccampbell marccampbell merged commit 99fbf11 into main May 26, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant