RepoPilotOpen in app →

bahdotsh/wrkflw

Validate and Run GitHub Actions locally.

Healthy

Healthy across all four use cases

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 2w ago
  • 4 active contributors
  • MIT licensed
Show all 7 evidence items →
  • CI configured
  • Tests present
  • Small team — 4 contributors active in recent commits
  • Single-maintainer risk — top contributor 97% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/bahdotsh/wrkflw)](https://repopilot.app/r/bahdotsh/wrkflw)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/bahdotsh/wrkflw on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: bahdotsh/wrkflw

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/bahdotsh/wrkflw shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • Last commit 2w ago
  • 4 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Small team — 4 contributors active in recent commits
  • ⚠ Single-maintainer risk — top contributor 97% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live bahdotsh/wrkflw repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/bahdotsh/wrkflw.

What it runs against: a local clone of bahdotsh/wrkflw — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in bahdotsh/wrkflw | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 46 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>bahdotsh/wrkflw</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of bahdotsh/wrkflw. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/bahdotsh/wrkflw.git
#   cd wrkflw
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of bahdotsh/wrkflw and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "bahdotsh/wrkflw(\\.git)?\\b" \\
  && ok "origin remote is bahdotsh/wrkflw" \\
  || miss "origin remote is not bahdotsh/wrkflw (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "crates/executor/src/engine.rs" \\
  && ok "crates/executor/src/engine.rs" \\
  || miss "missing critical file: crates/executor/src/engine.rs"
test -f "crates/parser/src/workflow.rs" \\
  && ok "crates/parser/src/workflow.rs" \\
  || miss "missing critical file: crates/parser/src/workflow.rs"
test -f "crates/models/src/lib.rs" \\
  && ok "crates/models/src/lib.rs" \\
  || miss "missing critical file: crates/models/src/lib.rs"
test -f "crates/executor/src/docker.rs" \\
  && ok "crates/executor/src/docker.rs" \\
  || miss "missing critical file: crates/executor/src/docker.rs"
test -f "crates/executor/src/expression.rs" \\
  && ok "crates/executor/src/expression.rs" \\
  || miss "missing critical file: crates/executor/src/expression.rs"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 46 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~16d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/bahdotsh/wrkflw"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

WRKFLW is a command-line tool and TUI application (written in Rust) that validates and executes GitHub Actions workflows locally without pushing to GitHub. It supports Docker/Podman-based execution, expression evaluation (${{ ... }} syntax), composite/reusable workflows, artifacts, caching, matrix builds, and secure secret management—letting developers test CI/CD pipelines on their machine before commit. Monorepo with 13 focused Rust crates: crates/parser (YAML→AST), crates/evaluator (expression engine), crates/executor (Docker/Podman orchestration), crates/models (shared types), crates/ui (TUI via ratatui), crates/secrets (multi-provider vault), crates/github and crates/gitlab (platform integration), plus utility crates. Main binary likely in root with crates linked via [workspace.dependencies].

👥Who it's for

DevOps engineers, CI/CD pipeline maintainers, and GitHub Actions workflow authors who need to iterate quickly on .github/workflows/ files without triggering expensive cloud CI runs or waiting for GitHub feedback loops.

🌱Maturity & risk

Actively developed (version 0.8.0 with workspace structure, tagged releases, and CI/CD via .github/workflows/ci.yml). Has comprehensive feature coverage (artifacts, caching, matrix builds, multiple secret providers) but explicitly documents limitations (no Windows/macOS runners, no service containers, no GitHub encrypted secrets). Production-ready for local validation and execution of most common GitHub Actions patterns.

Single-language Rust monorepo (low multi-language maintenance risk). Docker/Podman dependency required for execution (not included). No visible security audit documentation. BREAKING_CHANGES.md exists, suggesting API volatility. Limited test coverage visibility in provided file list—only crates/executor/src/docker_test.rs shown explicitly. Maintainer concentration risk typical of specialized dev tools.

Active areas of work

Latest tagged version is 0.8.0 (from Cargo.toml). Repository includes release machinery (release.yml, cliff.toml for changelog generation). CLAUDE.md and INDEX.md suggest active documentation effort. No specific PR/milestone data visible in provided file list, but CI workflow (ci.yml) and GitLab CI (.gitlab-ci.yml) are configured, indicating continuous testing.

🚀Get running

git clone https://github.com/bahdotsh/wrkflw.git
cd wrkflw
cargo build --release
./target/release/wrkflw --help

For TUI mode: ./target/release/wrkflw in a .github/workflows/ directory. Install Docker or Podman separately for execution backend.

Daily commands: Development: cargo build (debug) or cargo build --release (optimized). Run locally: cargo run -- <args> (in repo root, runs main binary). Tests: cargo test --workspace. Watch mode: embedded in TUI or use wrkflw --watch (if supported). Requires Docker daemon or Podman socket accessible at runtime.

🗺️Map of the codebase

  • crates/executor/src/engine.rs — Core execution engine that orchestrates workflow job running, dependency resolution, and container lifecycle management—understanding this is essential for any workflow execution changes.
  • crates/parser/src/workflow.rs — Primary workflow parsing logic that transforms YAML into internal models; essential for any changes to workflow validation or schema handling.
  • crates/models/src/lib.rs — Defines all core data structures (Workflow, Job, Step, Action) that flow through the entire system; changes here cascade across all crates.
  • crates/executor/src/docker.rs — Docker/container runtime implementation responsible for executing steps in isolated environments; critical for local execution reliability.
  • crates/executor/src/expression.rs — Handles GitHub Actions expression evaluation (contexts, conditionals, interpolation); core to step execution correctness.
  • crates/secrets/src/manager.rs — Secret masking and substitution logic that prevents credential leaks in logs; critical for security guarantees.
  • crates/trigger-filter/src/eval.rs — Evaluates workflow trigger conditions against event types and file diffs; enables watch-mode and skip-filtering functionality.

🛠️How to make changes

Add Support for a New Workflow Trigger Type

  1. Define trigger structure in crates/models/src/lib.rs (add new variant to Trigger enum if needed) (crates/models/src/lib.rs)
  2. Add parsing logic to crates/parser/src/workflow.rs to deserialize the new trigger from YAML (crates/parser/src/workflow.rs)
  3. Implement trigger matching logic in crates/trigger-filter/src/eval.rs to evaluate if trigger applies to current event (crates/trigger-filter/src/eval.rs)
  4. Add test cases in crates/trigger-filter/tests/ to verify matching behavior (crates/trigger-filter/src/lib.rs)

Add a New Context Type or Expression Function

  1. Define new context structure in crates/models/src/lib.rs (e.g., add field to Context struct or new context type) (crates/models/src/lib.rs)
  2. Implement expression evaluation in crates/executor/src/expression.rs (add parsing and evaluation for new function/context) (crates/executor/src/expression.rs)
  3. Populate context in crates/executor/src/engine.rs where context is built before step execution (crates/executor/src/engine.rs)
  4. Add integration tests in crates/executor/ to validate expression evaluation with new context (crates/executor/src/lib.rs)

Add a New Secret Provider (e.g., HashiCorp Vault)

  1. Create new provider file at crates/secrets/src/providers/vault.rs with SecretProvider trait implementation (crates/secrets/src/providers/mod.rs)
  2. Register provider in crates/secrets/src/providers/mod.rs module exports and manager routing (crates/secrets/src/providers/mod.rs)
  3. Add configuration struct in crates/secrets/src/config.rs for provider settings (endpoints, auth tokens) (crates/secrets/src/config.rs)
  4. Add integration tests in crates/secrets/tests/integration_tests.rs to verify secret loading and masking (crates/secrets/tests/integration_tests.rs)

Add a New Container Runtime Alternative (e.g., containerd)

  1. Create runtime implementation at crates/executor/src/containerd.rs mirroring docker.rs interface (crates/executor/src/docker.rs)
  2. Define ContainerRuntime enum in crates/models/src/lib.rs to support runtime selection (crates/models/src/lib.rs)
  3. Add runtime selection logic in crates/executor/src/engine.rs to dispatch to correct runtime based on config (crates/executor/src/engine.rs)
  4. Add CLI flag in main binary to allow --runtime=containerd selection and add tests (crates/executor/src/docker_test.rs)

🪤Traps & gotchas

  1. Docker daemon required: execution mode (--executor docker or podman) needs daemon accessible; local sandboxed emulation is alternative but has limitations. 2. No Windows/macOS runners: silently maps runs-on: windows-* / macos-* to container images, fails on hosts without full Windows/macOS image support. 3. SSH/Git auth: remote uses: (reusable workflows, actions) clone over unauthenticated HTTPS; private repos not supported without workaround. 4. Composite action inputs: must be manually cross-checked; validation in crates/validators/ may not catch all mismatches. 5. Service containers: services: is parsed but ignored (never started). 6. Matrix max-parallel: parsed but not enforced in execution. 7. Concurrency groups: parsed but not enforced; cancel-in-progress ignored.

🏗️Architecture

💡Concepts to learn

  • nektos/act — Direct competitor; GitHub Actions runner written in Go with similar feature set (local execution, Docker backend, expression eval). Most popular alternative.
  • actions/runner — Official GitHub Actions runtime; WRKFLW emulates its behavior (context, commands, outputs). Reference implementation for compatibility.
  • github/gitignore — Companion for workflow development; contains workflow templates and best practices that WRKFLW aims to validate locally.
  • hashicorp/vault — Integrated secret provider; WRKFLW supports Vault as secret backend via crates/secrets/. Users of WRKFLW with Vault deployments depend on this integration.
  • aws-actions/configure-aws-credentials — Common GitHub Actions integration for AWS; WRKFLW must handle this action's environment setup correctly (part of action resolver testing).

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive integration tests for docker.rs and podman.rs container backends

The executor crate has docker.rs and podman.rs modules that are critical for local workflow execution, but there are no visible integration tests validating container runtime compatibility. Adding tests would catch regressions when switching between Docker/Podman and ensure the executor properly handles container lifecycle (creation, execution, cleanup). This is high-value because container orchestration is core to the tool's functionality.

  • [ ] Create crates/executor/tests/docker_integration_test.rs with tests for image pulling, container creation, and execution flow
  • [ ] Create crates/executor/tests/podman_integration_test.rs with parallel test suite for Podman compatibility
  • [ ] Add test fixtures in crates/executor/tests/fixtures/ with minimal Docker images or mock workflows
  • [ ] Reference existing docker_test.rs patterns and expand coverage for error cases (missing images, container failures)
  • [ ] Update crates/executor/README.md with testing instructions for maintainers

Add expression evaluation unit tests for crates/executor/src/expression.rs

GitHub Actions uses complex expression syntax (contexts, functions, conditionals) that users rely on for conditional job execution and step filtering. The expression.rs module appears to handle this critical logic but lacks visible comprehensive unit tests. Adding tests would ensure expressions like ${{ github.event_name == 'pull_request' && matrix.os == 'ubuntu-latest' }} are correctly evaluated locally, preventing silent failures.

  • [ ] Create crates/executor/tests/expression_evaluation_test.rs with test cases for context variables (github., env., etc.)
  • [ ] Add test cases for built-in functions (contains(), startsWith(), endsWith(), format(), etc.)
  • [ ] Add test cases for operator precedence and boolean logic chains
  • [ ] Add edge cases: null/empty contexts, type coercion, malformed expressions
  • [ ] Document expression syntax support in crates/executor/README.md

Implement workflow_commands.rs test coverage for GitHub Actions commands (::set-output, ::add-mask, etc.)

The workflow_commands.rs module parses and processes special GitHub Actions commands (like echo '::set-output name=foo::bar'). These commands are essential for inter-step communication and secret masking in workflows. Without tests, regressions in command parsing could silently break workflows that rely on these features. This is a well-defined, contained module perfect for test-driven improvements.

  • [ ] Create crates/executor/tests/workflow_commands_test.rs
  • [ ] Add test cases for each command type: set-output, set-env, add-mask, add-path, debug, notice, warning, error
  • [ ] Add parsing edge cases: multiline outputs, escaped characters, invalid syntax
  • [ ] Add test cases for environment file interactions (github_env_files.rs integration)
  • [ ] Add tests validating that masked values are properly redacted in logs (cross-reference crates/logging)

🌿Good first issues

  • Add unit tests for crates/executor/src/substitution.rs (expression substitution in step contexts). Currently only docker_test.rs exists; substitution logic likely undercovered.: Critical path for variable interpolation; tests would catch edge cases in ${{ github.run_id }} and similar.
  • Document matrix build expansion logic in crates/matrix/README.md with examples of include, exclude, and max-parallel. Current README.md in root doesn't detail matrix semantics.: Matrix is complex feature; examples help maintainers and users understand interaction with fail-fast and job ordering.
  • Add validation test suite in crates/validators/ for composite action input cross-checking. File exists but test coverage unknown; add cases for missing required inputs, type mismatches.: Validation is a core feature (README lists 'composite action input cross-checking'); tests ensure schema enforcement.
  • Implement watch mode filtering based on on: block (already exists for non-watch execution in crates/trigger-filter/). Currently watch mode may re-run unrelated workflows.: Watch mode efficiency depends on this; avoids wasting developer time re-running unrelated jobs.
  • Add --dry-run flag that prints execution plan (job order, matrix expansions, action resolution) without running Docker. Useful for debugging before expensive execution.: Reduces iteration time for workflow authors; similar to Terraform plan model.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 2f2892b — docs: mention brew install in the README (bahdotsh)
  • 94adbd4 — Update GitHub Sponsors username in FUNDING.yml (bahdotsh)
  • e4384d8 — docs: stop lying in the README about what works (bahdotsh)
  • 5ac563d — Release 0.8.0 (bahdotsh)
  • 4a3c5b2 — docs: catch up on everything that landed after v0.7.3 (#107) (bahdotsh)
  • d2200a4 — docs: refresh demo.gif for the redesigned TUI (#106) (bahdotsh)
  • ebe8083 — feat(ui): ship screens 4, 7, 8 and the Tweaks overlay (#105) (bahdotsh)
  • 1824e73 — feat(ui): rebuild TUI to match the new design system (#104) (bahdotsh)
  • 7b2a27a — refactor(executor): separate user env from runner env in ExpressionContext (#102) (bahdotsh)
  • 74499d5 — feat(evaluator): make toJSON(matrix) return matrix object (#101) (bahdotsh)

🔒Security observations

  • High · Docker/Podman Execution with Potential Privilege Escalation — crates/executor/src/docker.rs, crates/executor/src/podman.rs, crates/runtime/src/container.rs. The codebase includes Docker and Podman execution capabilities (crates/executor/src/docker.rs, crates/executor/src/podman.rs). Running arbitrary workflows locally could allow privilege escalation if containers are executed with elevated privileges or if the Docker socket is exposed insecurely. Fix: Ensure containers are always run with minimal privileges, implement proper capability dropping, use read-only filesystems where possible, and document security requirements for Docker/Podman daemon access.
  • High · Secrets Management and Masking Implementation — crates/secrets/src/masking.rs, crates/secrets/src/manager.rs. The secrets crate (crates/secrets/) handles sensitive data masking and management. Improper implementation could lead to secrets exposure in logs or stdout. The masking logic needs careful review to prevent timing attacks or regex-based bypass vulnerabilities. Fix: Review masking implementation for edge cases, ensure constant-time comparisons where applicable, implement comprehensive logging security, and consider using established secret masking libraries.
  • High · Arbitrary Code Execution via Workflow Parsing — crates/parser/src/workflow.rs, crates/parser/src/schema.rs, crates/executor/src/expression.rs. The parser crate processes untrusted YAML/JSON workflow files. Unsafe deserialization or expression evaluation could allow arbitrary code execution through malicious workflow files. Fix: Implement strict schema validation, use sandboxed expression evaluation, avoid using eval-like functions, and validate all inputs against a whitelist of allowed operations.
  • High · Unvalidated Docker Image Resolution — crates/executor/src/action_resolver.rs. The action_resolver.rs handles Docker image resolution for GitHub Actions. Without proper validation, this could allow pulling malicious images or performing supply chain attacks. Fix: Implement image digest verification, use image signing (Cosign/Notary), maintain an allowlist of trusted registries, and validate image provenance before execution.
  • Medium · Temporary File Security — crates/executor/src/artifacts.rs, crates/runtime/src/sandbox.rs. The codebase uses tempfile crate for temporary file creation. If not properly cleaned up or secured, temporary files could expose sensitive workflow data, logs, or artifacts. Fix: Ensure temporary directories use restrictive permissions (0700), implement proper cleanup in error paths using RAII patterns, and consider using encrypted temporary storage for sensitive data.
  • Medium · Insufficient Input Validation in Substitution — crates/executor/src/substitution.rs. The substitution.rs module performs variable substitution which could be vulnerable to injection attacks if special characters or escape sequences are not properly validated. Fix: Implement strict input validation, use parameterized substitution where possible, escape special characters appropriately for the target context, and add comprehensive unit tests for edge cases.
  • Medium · GitHub Environment Files Processing — crates/executor/src/github_env_files.rs, crates/executor/src/workflow_commands.rs. The github_env_files.rs processes GitHub workflow command outputs. Improper parsing could lead to injection attacks through environment variable manipulation. Fix: Implement strict parsing with allowlist-based validation, sanitize all input from workflow commands, and avoid shell interpretation of environment values.
  • Medium · Insecure Emulation Mode — crates/runtime/src/secure_emulation.rs, crates/runtime/src/emulation.rs. The secure_emulation.rs provides an emulation sandbox mode. If the emulation layer is incomplete or poorly implemented, it could allow escaping the sandbox environment. Fix: Conduct thorough security audits of emulation logic, implement comprehensive system call filtering, use seccomp/AppArmor profiles, and test against known container escape techniques.
  • Medium · Dependency Chain Risk - Bollard Docker Library — undefined. The bollard crate (v0.14) is used for Docker interaction Fix: undefined

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · bahdotsh/wrkflw — RepoPilot