# Using Act's Watch Mode to Auto-Re-Run Workflows: A Complete Guide

> Learn to use act watch mode to auto re-run workflows. This guide explains how act monitors changes and re-executes workflows efficiently.

- Repository: [nektos/act](https://github.com/nektos/act)
- Tags: how-to-guide
- Published: 2026-03-03

---

**Act's watch mode (`-w`/`--watch`) continuously monitors your repository for file changes and automatically re-executes workflows using the go-fswatch library, respecting `.gitignore` patterns and polling every 2 seconds.**

The `nektos/act` CLI tool provides a powerful watch mode that eliminates manual re-invocation during GitHub Actions workflow development. By enabling the `--watch` flag, developers can iterate rapidly on workflows while Act handles automatic detection and re-execution whenever files change in the local repository.

## Enabling Watch Mode with the `--watch` Flag

In [`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go), the watch functionality is exposed through a Boolean flag registered at line 68:

```go
rootCmd.Flags().BoolP("watch", "w", false, "watch the contents of the local repo and run when files change")

```

When executing a workflow, the application checks this flag at lines 93-95:

```go
if watch, err := cmd.Flags().GetBool("watch"); err != nil { … } else if watch {
    err = watchAndRun(ctx, r.NewPlanExecutor(plan))
    …
}

```

If enabled, control passes to the `watchAndRun` helper instead of single execution.

## The watchAndRun Implementation

The `watchAndRun` function, located in [`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go), orchestrates the continuous monitoring and execution cycle.

### Initial Execution

Before monitoring begins, the function executes the workflow immediately to provide baseline feedback (lines 84-86):

```go
if err := fn(ctx); err != nil { return err }

```

### File System Watcher Setup

The function initializes a `FolderWatcher` from the go-fswatch library (lines 74-78):

```go
folderWatcher := fswatch.NewFolderWatcher(dir, true, ignore.MatchesPath, 2)

```

This configuration watches the current working directory (`dir`), respects `.gitignore` patterns via the `ignore.MatchesPath` callback, and polls every **2 seconds** for changes.

### Gitignore Integration

Act automatically detects and compiles `.gitignore` rules to prevent unnecessary re-runs (lines 65-72):

```go
ignoreFile := filepath.Join(dir, ".gitignore")
if info, err := os.Stat(ignoreFile); err == nil && !info.IsDir() {
    ignore, err = gitignore.CompileIgnoreFile(ignoreFile)
}

```

### The Watch Loop

The core monitoring loop (lines 92-102) blocks on change notifications and triggers re-execution:

```go
for folderWatcher.IsRunning() {
    select {
    case <-earlyCancelCtx.Done(): return nil
    case changes := <-folderWatcher.ChangeDetails():
        log.Debugf("%s", changes.String())
        if err := fn(ctx); err != nil { return err }
    }
}

```

Graceful shutdown is handled via `defer folderWatcher.Stop()` (lines 81-83), ensuring the watcher terminates cleanly when the user aborts with Ctrl-C.

## Performance and Resource Management

Watch mode optimizes performance by reusing resources across executions:

- **Plan reuse**: The workflow plan is built once before the loop begins, and `r.NewPlanExecutor(plan)` returns an executor that is invoked repeatedly
- **Persistent services**: Cache servers, artifact servers, and background services remain active throughout the watch session
- **Container optimization**: When combined with `--reuse`, Docker containers persist between executions, reducing startup overhead

## Practical Usage Examples

Activate watch mode using these command patterns:

```bash

# Monitor and auto-re-run the default push workflow

act --watch

# Watch a specific event type

act push --watch

# Combine with performance flags for rapid iteration

act --watch --quiet --reuse

```

The `--quiet` flag suppresses verbose output, while `--reuse` maintains containers between runs for faster feedback loops.

## Summary

- **Flag location**: The `-w`/`--watch` flag is defined in [`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go) at line 68 and consumed at lines 93-95
- **Core implementation**: The `watchAndRun` function handles continuous execution using the go-fswatch library
- **Polling behavior**: File system checks occur every 2 seconds with automatic `.gitignore` respect
- **Initial run**: Workflows execute immediately upon starting watch mode before monitoring begins
- **Resource efficiency**: Plan executors and background services persist across re-runs during the watch session

## Frequently Asked Questions

### Does watch mode rebuild the workflow plan on every change?

No. According to the source code in [`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go), the plan is constructed once before entering the watch loop. The `watchAndRun` function receives a pre-built plan executor (`r.NewPlanExecutor(plan)`) and invokes it repeatedly, minimizing overhead to container re-execution only.

### How does Act avoid infinite loops from generated files or logs?

Act respects your repository's `.gitignore` patterns. As implemented in [`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go) lines 65-72, the watcher compiles the `.gitignore` file and uses `ignore.MatchesPath` as a filter when creating the `FolderWatcher`, ensuring that build artifacts and ignored paths do not trigger re-runs.

### Can I use watch mode with specific workflow events or job filters?

Yes. The `--watch` flag operates after standard workflow selection. You can combine it with event specifiers like `act pull_request --watch` or job filters, and these selections persist for every automatic re-execution during the watch session.

### What happens to running containers when I press Ctrl-C during watch mode?

The implementation uses an `earlyCancelCtx` context and `defer folderWatcher.Stop()` to ensure graceful shutdown. When you interrupt the process, the file system watcher stops immediately and the application exits cleanly without orphaning the background services that were started at the beginning of the session.