Skip to content

Latest commit

 

History

History
265 lines (195 loc) · 7.65 KB

File metadata and controls

265 lines (195 loc) · 7.65 KB

Advanced Workflow

Affected Runs

Like turborepo and nx, actrun can skip workflows when no relevant files have changed since the last successful run. This is useful in monorepos or projects where different workflows cover different parts of the codebase.

Configuration

Define file patterns per workflow in actrun.toml:

[affected."ci.yml"]
patterns = ["src/**", "*.toml", "Cargo.lock"]

[affected."lint.yml"]
patterns = ["src/**", "*.config.js"]

[affected."docs.yml"]
patterns = ["docs/**", "README.md"]

The key after affected. matches the workflow filename (basename, not full path).

Usage

# Compare against last successful run
actrun workflow run .github/workflows/ci.yml --affected

# Compare against a specific revision
actrun workflow run .github/workflows/ci.yml --affected HEAD~3
actrun workflow run .github/workflows/ci.yml --affected abc123

Pattern Fallback

If no [affected."<workflow>"] section is defined in actrun.toml, actrun falls back to the on.push.paths patterns from the workflow file itself. This means many workflows work with --affected out of the box.

How It Works

  1. Find the base revision: use the explicit rev argument (e.g. HEAD~3), or find the latest successful run's after_sha
  2. Compute changed files: git diff --name-only <base_rev> HEAD + uncommitted/untracked files
  3. Resolve patterns: use actrun.toml [affected."<workflow>"] patterns, or fall back to on.push.paths from the workflow
  4. If any changed file matches the patterns, run the workflow
  5. If no files match, skip with a message
# No changes in src/ since last success
$ actrun ci.yml --affected
affected: no changes match patterns for ci.yml (since run-1)

# After editing src/main.rs
$ actrun ci.yml --affected
affected: changes detected for ci.yml (since run-1)
run_id=run-2
...

# First run (no history) always executes
$ actrun ci.yml --affected
affected: no previous successful run found, running

Glob Patterns

Pattern Matches
src/** All files under src/ recursively
src/* Direct children of src/ only
*.rs Files ending with .rs in the root
**/*.rs Files ending with .rs at any depth
README.md Exact match
docs/** All files under docs/ recursively

Retry Failed Runs

When a workflow partially fails, --retry re-runs only the failed jobs, skipping jobs that already succeeded. This saves time by not re-executing expensive build steps.

Usage

# First run: build succeeds, test fails
$ actrun workflow run ci.yml
run_id=run-1
state=partial_failed
build/step_1: success
test/step_1: failed

# Retry: only test job runs, build is skipped
$ actrun workflow run ci.yml --retry
retry: re-running failed jobs from run-1:
  - test
retry: skipping successful jobs:
  - build
run_id=run-2
state=completed
test/step_1: success

# No more failures to retry
$ actrun workflow run ci.yml --retry
retry: last run run-2 was successful, nothing to retry

How It Works

  1. Find the latest run for this workflow (success or failure)
  2. If the latest run was successful, print "nothing to retry" and exit
  3. Extract failed job IDs from the run record
  4. Filter out succeeded jobs from the workflow
  5. Execute only the remaining (failed) jobs

Notes

  • --retry looks at the latest run regardless of success/failure status
  • Jobs are the unit of retry. If a job has 5 steps and the 3rd fails, the entire job is re-run (all 5 steps)
  • --retry can be combined with --skip-action and other flags
  • Skipped jobs and re-running jobs are logged before execution

Combining Affected and Retry

These features work independently and can be used in sequence:

# Normal development loop
actrun ci.yml --affected          # Skip if nothing changed
actrun ci.yml --retry             # Re-run only failed jobs after fixing

# CI-like workflow
actrun ci.yml --affected --local  # Run only if relevant files changed

Local Skip Actions

local_skip_actions in actrun.toml specifies actions to skip when running locally. This is the primary mechanism for using host-installed toolchains instead of GitHub Actions setup actions.

# Generated by: actrun init (auto-detects installed tools)
local_skip_actions = [
  "actions/checkout",
  "actions/setup-node",
  "actions/setup-python",
]

When actions are skipped, actrun logs each one before execution:

skip  build/actions/checkout@v4 (actions/checkout@v4)
skip  build/Setup Node (actions/setup-node@v4)
run_id=run-1
...

Validation with doctor

actrun doctor validates that skipped setup actions have corresponding local tools:

$ actrun doctor
...
=== actrun.toml ===
  local_skip_actions:
    - actions/checkout
    - actions/setup-node
    - actions/setup-python
ok  skip actions/setup-node: local node found (v24.12.0)
ok  skip actions/setup-python: local python3 found (Python 3.14.2)

With Nix

When combined with nix integration, local_skip_actions skips the GitHub setup actions while nix provides the toolchains:

local_skip_actions = ["actions/checkout", "actions/setup-node"]
nix_mode = ""   # auto-detect flake.nix

The workflow's actions/setup-node@v4 is skipped, and the run: steps execute inside nix develop where node is provided by the flake.

Local GitHub Context

When --event is omitted, actrun first tries to infer common GitHub context values from the local git repository. If you need stable local values, add [local_context] to actrun.toml:

[local_context]
repository = "owner/repo"
ref_name = "feature/local-demo"
before_rev = "HEAD^"
after_rev = "HEAD"
actor = "your-name"

This fills missing values for github.repository, github.ref_name, github.sha, github.actor, and the matching GITHUB_* variables. For precedence details and a runnable example, see Local GitHub Context.

Full actrun.toml Example

# Workspace
workspace_mode = "local"

# Skip setup actions — use local (or nix) toolchain
local_skip_actions = [
  "actions/checkout",
  "actions/setup-node",
  "actions/setup-python",
]

# Trust third-party actions
trust_actions = true

# Optional local GitHub context override
# [local_context]
# repository = "owner/repo"
# ref_name = "main"
# before_rev = "HEAD^"
# after_rev = "HEAD"
# actor = "your-name"

# Nix (auto-detected from flake.nix)
# nix_mode = ""
# nix_packages = ["python312", "jq"]

# Container runtime
# container_runtime = "docker"

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

[affected."lint.yml"]
patterns = ["src/**", "*.config.*"]

[affected."docs.yml"]
patterns = ["docs/**", "*.md"]

Cloud-Only Features

Some GitHub Actions features are designed for cloud execution and have no local equivalent. actrun handles these gracefully:

OIDC (OpenID Connect)

Workflows using OIDC for cloud authentication (permissions: id-token: write) work without errors — permissions blocks are silently ignored. However, ACTIONS_ID_TOKEN_REQUEST_URL and ACTIONS_ID_TOKEN_REQUEST_TOKEN are not set, so steps calling getIDToken() will fail.

Recommended approach: skip or override OIDC-dependent steps:

# actrun.toml
[override."aws-actions/configure-aws-credentials"]
run = "echo 'using local AWS credentials'"

Or use if: ${{ !env.ACTRUN_LOCAL }} in the workflow:

- uses: aws-actions/configure-aws-credentials@v4
  if: ${{ !env.ACTRUN_LOCAL }}
  with:
    role-to-assume: arn:aws:iam::123456:role/deploy

Permissions and Concurrency

  • permissions: Silently ignored. Local execution uses host user permissions.
  • concurrency: Silently ignored. Local execution is sequential.