SkillAgentSearch skills...

Actrun

GitHub Actions compatible local runner

Install / Use

/learn @mizchi/Actrun
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

actrun

A local GitHub Actions runner built with MoonBit. Run and debug GitHub Actions workflows locally with a gh-compatible CLI.

actrun keeps its release contract as close as possible to existing GitHub Actions semantics. Workflow YAML and action metadata stay on a GitHub-compatible surface, while WASM support is treated as a self-hosted runner optimization. See docs/public-api.md for the contract boundary and ADR 0001 for the rationale.

Install

# npx (no install required)
npx @mizchi/actrun workflow run .github/workflows/ci.yml

# curl (Linux / macOS)
curl -fsSL https://raw.githubusercontent.com/mizchi/actrun/main/install.sh | sh

# Docker
docker run --rm -v "$PWD":/workspace -w /workspace ghcr.io/mizchi/actrun workflow run .github/workflows/ci.yml

# npm global install
npm install -g @mizchi/actrun

# Nix (run without installing)
nix run github:mizchi/actrun -- workflow run .github/workflows/ci.yml

# Nix (install into profile)
nix profile install github:mizchi/actrun

# moon install
moon install mizchi/actrun/cmd/actrun

# Build from source
git clone https://github.com/mizchi/actrun.git && cd actrun
moon build src/cmd/actrun --target native

Nix

Run directly

nix run github:mizchi/actrun -- workflow run .github/workflows/ci.yml

Build from source

nix build github:mizchi/actrun
./result/bin/actrun workflow run .github/workflows/ci.yml

Development shell

<details> <summary>With direnv (recommended)</summary>

With direnv and nix-direnv:

echo "use flake" > .envrc
direnv allow
</details>

Or without direnv:

nix develop

Adding the overlay to your flake.nix

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    actrun.url = "github:mizchi/actrun";
  };

  outputs = { nixpkgs, actrun, ... }:
    let
      system = "aarch64-darwin"; # or "x86_64-linux"
      pkgs = import nixpkgs {
        inherit system;
        overlays = [ actrun.overlays.default ];
      };
    in
    {
      packages.${system}.default = pkgs.actrun;
      devShells.${system}.default = pkgs.mkShell {
        packages = [ pkgs.actrun ];
      };
    };
}

Quick Start

# Run a workflow locally
actrun workflow run .github/workflows/ci.yml

# Show execution plan without running
actrun workflow run .github/workflows/ci.yml --dry-run

# Skip actions not needed locally (e.g. setup tools already installed)
actrun workflow run .github/workflows/ci.yml \
  --skip-action actions/checkout \
  --skip-action extractions/setup-just

# Run in isolated worktree
actrun workflow run .github/workflows/ci.yml \
  --workspace-mode worktree

# Generate config file
actrun init

# View results
actrun run view run-1
actrun run logs run-1 --task build/test

Configuration

actrun init generates an actrun.toml in the current directory:

# Workspace mode: local, worktree, tmp, docker
workspace_mode = "local"

# Skip actions not needed locally
local_skip_actions = ["actions/checkout"]

# Trust all third-party actions without prompt
trust_actions = true

# Nix integration: "auto" (force), "off" (disable), or empty (auto-detect)
nix_mode = ""

# Additional nix packages
nix_packages = ["python312", "jq"]

# Container runtime: docker, podman, container, lima, nerdctl
container_runtime = "docker"

# Include uncommitted changes in worktree/tmp workspace
# include_dirty = true

# Default local GitHub context when `--event` is omitted
# [local_context]
# repository = "owner/repo"
# ref_name = "main"
# before_rev = "HEAD^"
# after_rev = "HEAD"
# actor = "your-name"

# Override actions with local commands
# [override."actions/setup-node"]
# run = "echo 'using local node' && node --version"

# Affected file patterns per workflow
# [affected."ci.yml"]
# patterns = ["src/**", "package.json"]

When --event is omitted, actrun auto-detects github.repository, github.ref_name, github.sha, and github.actor from the local git repository when possible. Use [local_context] only when you need to pin or override those values. See Local GitHub Context for precedence and examples.

CLI flags always override actrun.toml settings. See Cheatsheet for quick reference and Advanced Workflow for details.

CLI Reference

Workflow Commands

actrun workflow list                 # List workflows in .github/workflows/
actrun workflow run <workflow.yml>    # Run a workflow locally

Run Commands

actrun run list                      # List past runs
actrun run view <run-id>             # View run summary
actrun run view <run-id> --json      # View run as JSON
actrun run watch <run-id>            # Watch until completion
actrun run logs <run-id>             # View all logs
actrun run logs <run-id> --task <id> # View specific task log
actrun run download <run-id>         # Download all artifacts

Analysis Commands

# Lint: type check expressions and detect dead code
actrun lint                          # Lint all .github/workflows/*.yml
actrun lint .github/workflows/ci.yml # Lint a specific file
actrun lint --ignore W001            # Suppress a rule (repeatable)

# Visualize: render workflow job dependency graph
actrun viz .github/workflows/ci.yml              # ASCII art (terminal)
actrun viz .github/workflows/ci.yml --mermaid    # Mermaid text (for Markdown)
actrun viz .github/workflows/ci.yml --detail     # Mermaid with step subgraphs
actrun viz .github/workflows/ci.yml --svg        # SVG image
actrun viz .github/workflows/ci.yml --svg --theme github-light

Lint Diagnostics

| Rule | Severity | Description | |------|----------|-------------| | undefined-context | error | Undefined context (e.g. foobar.x) | | wrong-arity | error | Wrong function arity (e.g. contains('one')) | | unknown-function | error | Unknown function (e.g. myFunc()) | | unknown-property | warning | Unknown property (e.g. github.nonexistent) | | type-mismatch | warning | Comparing incompatible types | | unreachable-step | warning | Unreachable step (if: false) | | future-step-ref | error | Reference to future step | | undefined-step-ref | error | Reference to undefined step | | undefined-needs | error | Undefined needs job reference | | circular-needs | error | Circular needs dependency | | unused-outputs | warning | Unused job outputs | | duplicate-step-id | error | Duplicate step IDs in same job | | missing-runs-on | error | Missing runs-on | | empty-job | error | Empty job (no steps) | | uses-and-run | error | Step has both uses and run | | empty-matrix | warning | Matrix with empty rows | | invalid-uses | error | Invalid uses syntax | | invalid-glob | warning | Invalid glob pattern in trigger filter | | redundant-condition | warning | Always-true/false condition | | script-injection | warning | Script injection risk (untrusted input in run:) | | permissive-permissions | warning | Overly permissive permissions | | deprecated-command | warning | Deprecated workflow command (::set-output etc.) | | missing-prt-permissions | warning | pull_request_target without explicit permissions | | if-always | warning | Bare always() — prefer success() \|\| failure() | | dangerous-checkout-in-prt | error | Checkout PR head in pull_request_target | | secrets-to-third-party | warning | Secrets passed via env to third-party action | | missing-timeout | warning | No timeout-minutes (opt-in: --strict) | | mutable-action-ref | warning | Tag ref instead of SHA pin (opt-in: --online) | | action-not-found | error | Action ref not found on GitHub (opt-in: --online) |

Configure lint behavior in actrun.toml:

[lint]
preset = "default"  # default, strict, oss
ignore_rules = ["unknown-property", "unused-outputs"]

| Preset | Includes | |--------|----------| | default | All rules except missing-timeout and online checks | | strict | default + missing-timeout | | oss | strict + mutable-action-ref / action-not-found (network) |

Visualization Example

$ actrun viz .github/workflows/release.yml

┌───────┐    ┌────────┐
│ build │    │ docker │
└───────┘    └────────┘
    └┐
     │
┌─────────┐
│ release │
└─────────┘

Artifact & Cache Commands

actrun artifact list <run-id>                          # List artifacts
actrun artifact download <run-id> --name <name>        # Download artifact
actrun cache list                                      # List cache entries
actrun cache prune --key <key>                         # Delete cache entry

Workflow Run Flags

| Flag | Description | |------|-------------| | --dry-run | Show execution plan without running | | --skip-action <pattern> | Skip actions matching pattern (repeatable) | | --workspace-mode <mode> | worktree (default), local, tmp, docker | | --repo <path> | Run from a git repository | | --event <path> | Push event JSON file | | --repository <owner/repo> | GitHub repository name | | --ref <ref> | Git ref name | | --run-root <path> | Run record storage root | | --nix | Force nix wrapping for run steps | | --no-nix | Disable nix wrapping even if flake.nix/shell.nix exists | | --nix-packages <pkgs> | Ad-hoc nix packages (space-separated) | | --container-runtime <name> | Container runtime: docker, podman, container, lima, nerdctl | | --wasm-runner <kind> | Wasm runner kind: wasmtime, deno, v8 | | --affected [base] | Only run if files matching patterns changed (see below) | | --retry | Re-run only failed jobs from the latest run | | --include-dirty | Include uncommitted changes in worktree/tmp workspace | | --json | JSON output for read c

View on GitHub
GitHub Stars593
CategoryDevelopment
Updated4h ago
Forks10

Languages

MoonBit

Security Score

100/100

Audited on Mar 31, 2026

No findings