# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Act is a tool to run GitHub Actions locally. It reads `.github/workflows/` files, builds an execution plan, and uses Docker to run containers for each action. Written in Go 1.24+. ## Common Commands - `make build` — build binary to `dist/local/act` - `make test` — run `go test ./...` and the act CLI - `make lint-go` — run `golangci-lint run` - `make format` — run `go fmt ./...` - `make tidy` — run `go mod tidy` - `make pr` — full PR checklist: tidy, format-all, lint, test - `go test ./pkg/runner/...` — run tests for a single package - `go test ./pkg/runner/ -run TestRunEvent` — run a single test ## Architecture ### Execution Flow 1. **CLI** (`cmd/root.go`) — Cobra-based CLI parses flags into an `Input` struct 2. **Planner** (`pkg/model/planner.go`) — parses workflow YAML into a `Plan` containing `Stage`s (serial) with `Run`s (parallel jobs) 3. **Runner** (`pkg/runner/runner.go`) — converts the Plan into composable `Executor` chains 4. **RunContext** (`pkg/runner/run_context.go`) — holds all state for a job execution (env vars, matrix, containers, expressions) 5. **Steps** (`pkg/runner/step.go`) — each step type (action, docker, script) implements the `step` interface ### Core Abstraction: Executor Pattern The `Executor` type (`pkg/common/executor.go`) is a `func(ctx context.Context) error` used throughout the codebase. Executors compose via: - `.Then()`, `.Finally()`, `.OnError()` — chaining - `NewPipelineExecutor()` — serial execution - `NewParallelExecutor()` — parallel execution - `.If()`, `.IfNot()` — conditional execution ### Key Packages - **`pkg/model/`** — workflow YAML parsing, plan creation, action definitions - **`pkg/runner/`** — core execution engine, expression evaluation, step types (local/remote/docker/composite actions, reusable workflows) - **`pkg/container/`** — Docker API wrapper, container and host execution environments - **`pkg/common/`** — Executor pattern, context utilities, logging - **`pkg/exprparser/`** — GitHub Actions `${{ }}` expression language interpreter - **`pkg/artifacts/`** and **`pkg/artifactcache/`** — artifact upload/download and caching server ## Linting Rules Configured in `.golangci.yml`: - Use `errors` from stdlib, not `github.com/pkg/errors` - Use `github.com/sirupsen/logrus` (aliased as `log`), not stdlib `log` - Use `github.com/stretchr/testify` for tests, not `gotest.tools/v3` - Max cyclomatic complexity: 20 - Import aliases enforced: `logrus` → `log`, `testify/assert` → `assert` ## Testing - Tests use `testify/assert` and `testify/mock` - Table-driven tests are common in `pkg/model/` and `pkg/exprparser/` - Test fixtures live in `testdata/` directories alongside their packages - `pkg/runner/testdata/` contains extensive sample GitHub Actions workflows used as integration test fixtures