Skip to content

Development

Logan McDuffie edited this page Dec 19, 2025 · 1 revision

Guide for contributing to n8n-cli.

Setup

# Clone the repository
git clone https://github.com/TidalStudio/n8n-cli.git
cd n8n-cli

# Create a virtual environment
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install in development mode with dev dependencies
pip install -e ".[dev]"

Running Tests

pytest

Run with verbose output:

pytest -v

Run a specific test file:

pytest tests/test_workflows.py

Linting and Type Checking

# Run linter
ruff check .

# Auto-fix linting issues
ruff check . --fix

# Run type checker
mypy src/

Project Structure

n8n-cli/
├── src/n8n_cli/
│   ├── main.py           # CLI entry point
│   ├── client.py         # Async HTTP client
│   ├── config.py         # Configuration management
│   ├── output.py         # Output formatting
│   ├── exceptions.py     # Custom exceptions
│   └── commands/         # Individual commands
│       ├── configure.py
│       ├── create.py
│       ├── delete.py
│       ├── disable.py
│       ├── enable.py
│       ├── execution.py
│       ├── executions.py
│       ├── trigger.py
│       ├── update.py
│       ├── update_node.py
│       ├── workflow.py
│       └── workflows.py
├── tests/                # Test suite
├── pyproject.toml        # Project configuration
└── README.md

Adding a New Command

  1. Create a new file in src/n8n_cli/commands/
  2. Define your command using Click decorators
  3. Import and register the command in src/n8n_cli/main.py
  4. Add tests in tests/

Example command structure:

import click
from n8n_cli.client import N8nClient
from n8n_cli.output import output_result

@click.command()
@click.argument("workflow_id")
@click.pass_context
def my_command(ctx: click.Context, workflow_id: str) -> None:
    """Description of my command."""
    client: N8nClient = ctx.obj["client"]

    async def run():
        result = await client.some_method(workflow_id)
        output_result(result, ctx.obj["format"])

    import asyncio
    asyncio.run(run())

Code Style

This project uses:

  • ruff for linting and formatting
  • mypy for type checking
  • pytest for testing

All code should pass ruff check . and mypy src/ before committing.

Release Process

  1. Update version in src/n8n_cli/__init__.py
  2. Update version in pyproject.toml
  3. Create a git tag: git tag v0.x.x
  4. Build: python -m build
  5. Upload: twine upload dist/*

Clone this wiki locally