Writing Commands Guide

Learn how to create powerful, maintainable command workflows

Command Basics

Commands are YAML files in your .project/ directory. The filename determines the command name.

File Naming: setup.yaml becomes ./project setup

Minimal Command

# .project/hello.yaml
help:
  short: Say hello

steps:
  - echo: "Hello, World!"

Complete Structure

help:
  short: One-line description
  long: |
    Multi-line detailed description.
    Explain usage, options, and examples.
  order: 10

context: outside-container

steps:
  - echo: "Starting..."
  - run: "npm install"
  - echo: "โœ“ Complete"

Help Metadata

The help section defines how your command appears.

Order Guidelines

1-10: Setup

Installation, initialization

11-50: Development

Daily development commands

51-89: Maintenance

Less frequent tasks

90-99: Cleanup

Teardown, removal

Documenting Options

help:
  short: Deploy the application
  long: |
    Deploy the application to specified environment.

    Options:
      --production  Deploy to production
      --staging     Deploy to staging
      --dry-run     Show what would happen
  order: 90

Conditional Logic

Option-Based Conditionals

steps:
  - echo: "Building..."

  - if-option: production
    then:
      - echo: "Production build"
      - run: "npm run build:prod"

  - if-no-option: production
    then:
      - echo: "Development build"
      - run: "npm run build:dev"

OR Logic

Use pipe (|) to check multiple options:

steps:
  - if-option: debug|trace|verbose
    then:
      - echo: "Detailed logging enabled"
      - run: "export DEBUG=*"

File-Based Conditionals

steps:
  - if-missing: node_modules
    then:
      - echo: "Installing dependencies..."
      - run: "npm install"

  - if-missing: .env
    then:
      - run: "cp .env.example .env"
      - echo: "โš ๏ธ  Please configure .env"

Nested Conditionals

steps:
  - if-option: production
    then:
      - echo: "Production deployment"

      - if-missing: dist
        then:
          - echo: "Building first..."
          - command: build

      - run: "./deploy.sh production"

Command Options

Users pass options with --flag syntax:

./project deploy --production --verbose
./project build --watch
./project test --unit --coverage

Example: Test Command

# .project/test.yaml
help:
  short: Run tests
  long: |
    Run the test suite with various options.

    Options:
      --watch      Watch for changes
      --coverage   Generate coverage report
      --unit       Run only unit tests
      --e2e        Run only E2E tests
  order: 30

steps:
  - echo: "๐Ÿงช Running tests..."

  - check-for: npm

  - if-option: unit
    then:
      - run: "npm run test:unit"

  - if-option: e2e
    then:
      - run: "npm run test:e2e"

  - if-no-option: unit|e2e
    then:
      - run: "npm test"

  - if-option: coverage
    then:
      - run: "npm run test:coverage"

  - echo: "โœ… Tests complete"

Docker Workflows

Project Actions has built-in Docker Compose support for container-based development.

Starting Services

# .project/up.yaml
help:
  short: Start the project
  long: |
    Start all services using docker-compose.

    Options:
      --fresh    Reset database and run migrations
      --build    Rebuild images before starting
  order: 10

context: outside-container

steps:
  - check-for: docker
    if-missing: "Install Docker from https://docker.com"

  - if-option: build
    then:
      - echo: "Building images..."
      - run: "docker-compose build"

  - action: compose-up

  - echo: "โณ Waiting for services..."
  - run: "sleep 3"

  - if-option: fresh
    then:
      - action: compose-exec
        service: web
        command: "php artisan migrate:fresh"
        interactive: false

  - echo: |
      โœ… Project is up!
      โ†’ Web: http://localhost:8000

Interactive Shell

# .project/console.yaml
help:
  short: Open shell in web container
  order: 50

context: outside-container

steps:
  - action: compose-exec
    service: web
    command: /bin/bash
    interactive: true

Stopping Services

# .project/down.yaml
help:
  short: Stop the project
  order: 99

context: outside-container

steps:
  - action: compose-down
    volumes: false

  - echo: "โœ“ Project stopped"

Best Practices

โœ“ Always Provide Help

Clear descriptions help team members understand what commands do.

help:
  short: Clear one-liner
  long: Detailed explanation with options

โœ“ Check Prerequisites

Fail fast with helpful messages.

steps:
  - check-for: docker
    if-missing: "Install Docker first"

โœ“ Provide Feedback

Let users know what's happening.

steps:
  - echo: "๐Ÿš€ Starting deployment..."
  - run: "./deploy.sh"
  - echo: "โœ… Deployment complete!"

โœ“ Handle Missing Dependencies

Auto-install when possible.

steps:
  - if-missing: node_modules
    then:
      - echo: "Installing..."
      - run: "npm install"

โœ— Don't Hardcode Paths

Use relative paths and environment variables.

โœ— Don't Skip Error Handling

Always check for required tools and files.


Complete Examples

Setup Command

# .project/setup.yaml
help:
  short: Setup the project
  long: |
    Initialize the project for local development.
    Checks dependencies, creates config files, and starts services.
  order: 1

context: outside-container

steps:
  - echo: "๐Ÿš€ Setting up project..."

  - check-for: docker
    if-missing: "Install Docker from https://docker.com"

  - check-for: node
    if-missing: "Install Node.js from https://nodejs.org"

  - if-missing: .env
    then:
      - run: "cp .env.example .env"
      - echo: "โš ๏ธ  Please configure .env"

  - if-missing: node_modules
    then:
      - echo: "Installing dependencies..."
      - run: "npm install"

  - command: up

  - echo: |
      โœ… Setup complete!

      Next steps:
        1. Configure .env with your settings
        2. Run: ./project migrate
        3. Visit: http://localhost:8000

Deployment Command

# .project/deploy.yaml
help:
  short: Deploy the application
  long: |
    Deploy to specified environment.

    Options:
      --production  Deploy to production (requires confirmation)
      --staging     Deploy to staging
      --dry-run     Show what would be deployed
  order: 90

steps:
  - echo: "๐Ÿš€ Starting deployment..."

  - check-for: git
  - check-for: docker

  - if-no-option: staging|production
    then:
      - echo: "โŒ Error: Specify --staging or --production"

  - if-option: staging
    then:
      - echo: "Deploying to STAGING"
      - run: "git pull origin staging"
      - run: "./deploy-staging.sh"

  - if-option: production
    then:
      - echo: "โš ๏ธ  PRODUCTION DEPLOYMENT"
      - run: "git pull origin main"
      - run: "./deploy-production.sh"

  - if-no-option: dry-run
    then:
      - echo: "โœ… Deployment complete!"

Learn More

Examples

Reference