Last updated 2026-05-07
Marketplace Actions
The runner can run any marketplace action: composite, Node.js, or Docker. Common setup actions are intercepted with built-in shims so you don't need cloud GitHub Actions infrastructure to use them.
Resolution flow
When a step has uses: owner/repo@ref:
- Check the built-in shim table for
owner/repo. If present, generate a local composite action. - Check the local cache at
~/.local/share/local-runner/actions-cache/owner/repo/ref/. - If the cache is fresh (< TTL), use it directly.
- Otherwise
git clone --depth 1 --branch reffrom GitHub. - Falls back to
git clone --no-checkout --filter=blob:none+git checkout reffor SHA refs. - Removes
.git/, writes a freshness marker, returns the path.
Subpath actions (owner/repo/subpath@ref) are supported —
the runner clones the repo and returns the subpath within it.
Cache settings
| Setting | Default | Env var |
|---|---|---|
| Actions cache directory | ~/.local/share/local-runner/actions-cache/ | RUNNER_ACTIONS_CACHE |
| Cache TTL | 24 h | RUNNER_CACHE_TTL_MS (ms) |
| Skip cache entirely | off | RUNNER_NO_CACHE=1 |
Built-in shims
These actions are intercepted and replaced with local equivalents:
| Action | Shim behaviour |
|---|---|
actions/checkout | No-op. Workspace is already mounted. Supports ref for branch switching. |
actions/upload-artifact | Copies files to $WORKSPACE/.artifacts/<name>/. |
actions/download-artifact | Copies files from $WORKSPACE/.artifacts/<name>/. |
actions/cache | Filesystem cache at ~/.local/share/local-runner/cache/. Supports key, restore-keys, prefix matching. |
actions/setup-python | Detects Python via pyenv or PATH. Outputs python-version, python-path. |
actions/setup-java | /usr/libexec/java_home, SDKMAN, Homebrew, system paths, or JAVA_HOME. Sets JAVA_HOME, PATH. |
actions/setup-ruby / ruby/setup-ruby | rbenv, rvm, or system. Optionally bundle install. |
actions/setup-go | goenv, PATH, Homebrew. Sets GOPATH. |
actions/setup-dotnet | PATH or common locations. Disables telemetry. |
actions/setup-gradle / gradle/actions/setup-gradle | Gradle wrapper, PATH, Homebrew, SDKMAN. Soft-fail. |
actions/setup-xcode / maxim-lobanov/setup-xcode | xcode-select; supports version selection from /Applications/Xcode_*.app. |
subosito/flutter-action | PATH, common locations, or fvm. |
Action types
Composite
Recursively executed step-by-step in the same shell environment.
runs: using: composite steps: - run: echo "hello" shell: bashNode.js
The runner spawns node with the action's
main, pre, and post scripts and
populates the @actions/core environment
(INPUT_*, $GITHUB_OUTPUT,
$GITHUB_ENV, $GITHUB_PATH).
runs: using: node20 main: dist/index.js pre: dist/pre.js post: dist/post.jsDocker
The runner builds (or pulls) the image and runs it as a container with the same env contract.
runs: using: docker image: docker://alpine:3.19 args: ["echo", "hello"]Private repos
Set GITHUB_TOKEN or GH_TOKEN in the runner's
environment. The runner injects it into clone URLs as
x-access-token.
Force re-download
RUNNER_NO_CACHE=1 npm run dev# orRUNNER_NO_CACHE=1 stax runner startAdding your own shim
For a language/tool setup, add to
src/actions/shim-definitions.ts:
'owner/action-name': { name: 'My Tool (local shim)', description: 'Local runner shim for my-tool', inputs: { 'version': { description: 'Tool version', default: '' }, }, outputs: { 'version': { description: 'Installed version' }, }, detect: [ { name: 'PATH', detect: [ 'if command -v my-tool &>/dev/null; then', ' TOOL_FOUND="path"', 'fi', ].join('\n'), }, ], setup: [ 'MY_VER=$(my-tool --version)', 'echo "version=$MY_VER" >> $GITHUB_OUTPUT', ].join('\n'), notFoundMessage: 'my-tool not found. Install with: brew install my-tool',},Then register it in src/actions/resolver.ts:
'owner/action-name': langShim('owner/action-name'),