# How to Version Control Maestro YAML Flows: A Complete Git Workflow Guide

> Master your Maestro YAML flows with Git. Learn to version control, validate syntax, and organize flows using workspaces for efficient mobile automation.

- Repository: [Maestro/Maestro](https://github.com/mobile-dev-inc/Maestro)
- Tags: how-to-guide
- Published: 2026-03-20

---

**Maestro YAML flows are plain text files that you version control using standard Git workflows, validating syntax with `maestro check-syntax` before committing and organizing related flows into workspaces with [`config.yaml`](https://github.com/mobile-dev-inc/Maestro/blob/main/config.yaml) files.**

Maestro defines mobile test scenarios as human-readable YAML flow files that integrate seamlessly with Git-based version control systems. Because these flows are stored as plain text in the **mobile-dev-inc/Maestro** repository, teams can apply standard software engineering practices—including code review, branching strategies, and CI validation—to their mobile testing infrastructure.

## Repository Structure and File Locations

Maestro recognizes flow files by their `.yaml` extension and expects them to live within your project's directory tree, while excluding runtime-generated data.

### Flow File Patterns

Store your flow definitions in directories that match your project's organization:

- **`recipes/**/*.yaml`** – Example flow collections demonstrating specific testing patterns (e.g., [`recipes/web/xmas.yaml`](https://github.com/mobile-dev-inc/Maestro/blob/main/recipes/web/xmas.yaml) in the Maestro repository)
- **`maestro-test/src/test/resources/**/*.yaml`** – Test-specific flows used by the CLI and Studio
- **`my-feature/*.yaml`** – Custom directories containing feature-specific test scenarios

### Excluding Runtime Artifacts

The `.maestro/` directory is created at runtime to store sessions, generated screenshots, and execution logs. According to the source code, this folder should never be committed to version control.

Add this entry to your `.gitignore` file:

```gitignore

# Maestro runtime data – should not be versioned

.maestro/

```

## Git Workflow for Maestro Flows

Treat flow files exactly like source code by isolating changes in feature branches and validating before merging.

1. **Create a feature branch** – Isolate new flows or modifications using `git checkout -b feat/add-login-flow`.

2. **Add flow files** – Stage your YAML files with `git add path/to/login_flow.yaml`.

3. **Validate locally** – Run `maestro check-syntax path/to/login_flow.yaml` to catch errors before committing. This command is implemented in [`maestro-cli/src/main/java/maestro/cli/command/CheckSyntaxCommand.kt`](https://github.com/mobile-dev-inc/Maestro/blob/main/maestro-cli/src/main/java/maestro/cli/command/CheckSyntaxCommand.kt).

4. **Commit with context** – Use descriptive messages: `git commit -m "Add login flow for Android with env placeholders"`.

5. **Push and open PR** – Submit for team review via `git push origin feat/add-login-flow`.

6. **Tag releases** – For stable flow sets, create annotated tags: `git tag -a v2.5.0 -m "Release flows for v2.5"` and push with `git push --tags`.

## Validating Flow Syntax Before Committing

The Maestro CLI provides static analysis capabilities to prevent broken flows from entering your repository.

The **`maestro check-syntax`** command uses `MaestroFlowParser` defined in [`maestro-orchestra/src/main/java/maestro/orchestra/yaml/MaestroFlowParser.kt`](https://github.com/mobile-dev-inc/Maestro/blob/main/maestro-orchestra/src/main/java/maestro/orchestra/yaml/MaestroFlowParser.kt) to parse YAML structures and validate command syntax. For batch validation in CI environments, use:

```bash
maestro check-syntax $(git ls-files '*.yaml')

```

This command delegates to `YamlCommandReader.readCommands` (located in [`maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlCommandReader.kt`](https://github.com/mobile-dev-inc/Maestro/blob/main/maestro-orchestra/src/main/java/maestro/orchestra/yaml/YamlCommandReader.kt)) to process each file and return command objects.

## Organizing Flows with Workspaces

Workspaces enable you to version control logical collections of flows together—such as a complete feature set or regression suite—using a [`config.yaml`](https://github.com/mobile-dev-inc/Maestro/blob/main/config.yaml) file.

### Workspace Configuration

The CLI reads workspace configuration via `MaestroFlowParser.parseWorkspaceConfig` (referenced at line 450 of the parser source). A typical workspace structure looks like this:

```

my-feature/
├─ config.yaml          # defines tags, inclusion patterns, env vars

├─ login_flow.yaml
├─ purchase_flow.yaml
└─ logout_flow.yaml

```

### Sample config.yaml

```yaml

# workspace/config.yaml

include:
  - "**/*.yaml"          # include all flows in this directory

exclude:
  - "**/archived/**"     # ignore deprecated flows

tags:
  - login
  - signup
env:
  USERNAME: test_user
  PASSWORD: secret123

```

Execute the entire workspace atomically:

```bash
maestro test ./my-feature   # reads config.yaml and executes matching flows

```

## Versioning Strategies for Flow Evolution

Manage flow changes using semantic versioning principles to prevent breaking downstream CI pipelines.

**Non-breaking changes** (adding optional commands or new flows) can merge directly to the main branch after review.

**Breaking changes** (renaming required parameters or removing commands) require a new major version tag (e.g., `v3.0.0`). Downstream projects can pin to specific tags to avoid accidental breakage.

**Deprecated flows** should remain in the repository with a top-level comment `# DEPRECATED – use new_flow.yaml` or move to an `archived/` folder excluded from CI execution.

## Securing Sensitive Data

Maestro flow YAML files never store secrets directly. Use the `env:` block within flows to reference environment variables, keeping actual values in CI secret stores.

```yaml

# example flow snippet

- launchApp: com.example.app
- setLocation:
    latitude: ${LATITUDE}
    longitude: ${LONGITUDE}

```

This approach complies with the repository's security rules and prevents credential leakage into version history.

## CI/CD Integration

Automate validation by adding a GitHub Actions workflow that checks every YAML file on push or pull request. The CLI internally uses `YamlCommandReader.readCommands` to parse each flow during validation.

```yaml
name: Validate Maestro Flows
on: [push, pull_request]
jobs:
  check-syntax:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Install Maestro CLI
        run: curl -fsSL "https://get.maestro.mobile.dev" | bash
      
      - name: Validate all YAML flows
        run: maestro check-syntax $(git ls-files '*.yaml')

```

## Summary

- Store Maestro flows as `.yaml` files anywhere in your repository except the `.maestro/` runtime directory
- Validate syntax locally using `maestro check-syntax` before committing, which executes logic from [`CheckSyntaxCommand.kt`](https://github.com/mobile-dev-inc/Maestro/blob/main/CheckSyntaxCommand.kt)
- Group related flows into workspaces using [`config.yaml`](https://github.com/mobile-dev-inc/Maestro/blob/main/config.yaml) files parsed by `MaestroFlowParser.parseWorkspaceConfig`
- Use Git tags (e.g., `v2.5.0`) to lock specific flow versions for downstream consumption
- Never commit secrets to flow files; use environment variables and CI secret stores instead
- Add CI validation steps that invoke the CLI to check all tracked YAML files automatically

## Frequently Asked Questions

### How do I exclude the .maestro directory from Git tracking?

Add `.maestro/` to your `.gitignore` file. This directory contains runtime cache, session data, and generated screenshots created when flows execute locally. According to the Maestro source code, these artifacts are regenerated during each test run and should never be versioned.

### What command validates Maestro YAML syntax before I commit?

Use `maestro check-syntax <file.yaml>` to validate individual flows, or `maestro check-syntax $(git ls-files '*.yaml')` to validate all tracked YAML files at once. This command is implemented in [`maestro-cli/src/main/java/maestro/cli/command/CheckSyntaxCommand.kt`](https://github.com/mobile-dev-inc/Maestro/blob/main/maestro-cli/src/main/java/maestro/cli/command/CheckSyntaxCommand.kt) and uses `MaestroFlowParser` to detect structural errors.

### How do I version a collection of related Maestro flows together?

Create a workspace by placing a [`config.yaml`](https://github.com/mobile-dev-inc/Maestro/blob/main/config.yaml) file in a directory alongside your flow files. The CLI reads this configuration via `MaestroFlowParser.parseWorkspaceConfig` to determine which flows to include, exclude, or tag. Commit the entire directory as a single atomic unit, then tag the repository to version the complete workspace.

### Can I store API keys or passwords directly in Maestro flow files?

No. Maestro flows support environment variable substitution using `${VAR_NAME}` syntax. Store sensitive values in your CI system's secret store or local environment, reference them in the `env:` block or inline in commands, and keep the flow files themselves free of credentials.