Reference & Guide

Everything you need to know about commands, actions, and the CLI.

Installation

Quick Install

Run this command in your project directory:

terminal
curl -fsSL https://project-actions.org/install.sh | bash

With Starter Commands

Include example commands to get started quickly:

terminal
curl -fsSL https://project-actions.org/install.sh | bash -s -- --with-starter-commands

What Gets Installed

  • .project/ — Directory for your commands
  • .project/.runtime/ — Runner binaries (auto-downloaded)
  • project — Executable wrapper script

Requirements

  • macOS (Intel or Apple Silicon) or Linux
  • Bash shell
  • curl or wget
  • Internet connection (for initial download)

Command Structure

Commands are YAML files in the .project/ directory:

.project/command-name.yaml
# .project/command-name.yaml
help:
  short: One-line description (required)
  long: |
    Multi-line detailed description (optional)
    Shown when user runs: project command-name --help
  order: 10  # Display order (optional)

context: outside-container  # or inside-container:service

steps:
  - echo: "Hello World"
  - run: "echo 'Shell command'"

Help Section

  • short — Required. Brief one-line description
  • long — Optional. Detailed multi-line description
  • order — Optional. Controls display order (1–99)

Context

  • outside-container — Run on host machine
  • inside-container:service — Run inside Docker container

Primitives

Primitives are always available and use shorthand syntax — the YAML key is the step type.

echo

Print messages to the console.

command.yaml
steps:
  - echo: "Simple message"

  - echo: |
      Multi-line message
      with multiple lines

run

Execute shell commands. Fails the step on non-zero exit.

command.yaml
steps:
  - run: "npm install"

  - run: |
      echo "Running multiple commands"
      npm test
      echo "Tests complete"

<args> — Argument Interpolation

Use <args> anywhere in the command string to pass all positional CLI arguments through to the shell command. Individual arguments are accessible as <args.0>, <args.1>, etc. Use <args.length> to get the argument count.

.project/commands/run.yaml
steps:
  - run: <args>               # ./project run foo bar        → foo bar
  - run: php <args>          # ./project run artisan migrate → php artisan migrate
  - run: composer <args>     # ./project run install        → composer install

If <args> or <args.N> is present but the required arguments are not given, the runner exits with a usage error. <args.length> never errors — it evaluates to 0 when no arguments are given.

Context-Aware Routing

When a command declares context: inside-container:<service>, run: steps automatically route through docker-compose exec when the runner is outside the container. This applies to all run: steps in the command, not just steps using <args>.

Condition Execution
No service set, or already inside container sh -c "<cmd>"
Outside container, service set docker-compose exec <service> sh -c "<cmd>"
.project/commands/run.yaml
help:
  short: Run a script or binary inside the web container

context: inside-container:web

steps:
  - run: <args>

Usage: ./project run artisan migrate, ./project run composer install, etc. Add this command with ./project init docker.

command

Call other Project Actions commands.

command.yaml
steps:
  - command: setup
  - command: build

check-for

Verify that a tool exists in PATH.

command.yaml
steps:
  - check-for: docker
    if-missing: |
      Docker is required but not found.
      Install from https://docker.com

Conditionals

Conditional primitives use the same shorthand syntax and control which steps execute based on CLI flags or filesystem state.

if-option

Execute steps when a command-line option is provided.

command.yaml
steps:
  - if-option: production
    then:
      - echo: "Production mode"
      - run: "npm run build:prod"

  # OR logic with pipe
  - if-option: debug|trace|verbose
    then:
      - echo: "Debug logging enabled"

Usage: ./project command-name --production

if-no-option

Execute steps when an option is NOT provided.

command.yaml
steps:
  - if-no-option: skip-tests
    then:
      - echo: "Running tests..."
      - run: "npm test"

if-missing

Execute steps when a file or directory doesn't exist.

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

  - if-missing: .env
    then:
      - run: "cp .env.example .env"

Nested Conditionals

Conditionals can be nested for complex logic.

command.yaml
steps:
  - if-option: production
    then:
      - echo: "Production deployment"

      - if-missing: dist
        then:
          - echo: "Building..."
          - run: "npm run build"

Docker Integration

Built-in actions are shipped with the runner and invoked via the action: key.

compose-up

Start Docker Compose services.

command.yaml
steps:
  - action: compose-up
    detached: true  # default

compose-stop

Stop Docker Compose services (without removing).

command.yaml
steps:
  - action: compose-stop

compose-down

Stop and remove Docker Compose services.

command.yaml
steps:
  - action: compose-down
    volumes: false  # Keep volumes (default)

  - action: compose-down
    volumes: true   # Remove volumes too

compose-exec

Execute commands in running containers.

command.yaml
steps:
  # Interactive shell
  - action: compose-exec
    service: web
    command: /bin/bash
    interactive: true

  # Non-interactive command
  - action: compose-exec
    service: web
    command: "php artisan migrate"
    interactive: false

CLI Reference

terminal
./project

List all available commands

terminal
./project <command>

Run a specific command

terminal
./project <command> --option

Run command with options

terminal
./project <command> --help

Show help for a command

terminal
./project --version

Show version information


Troubleshooting

Command not found

Make sure the command file exists in .project/ and has a .yaml or .yml extension.

terminal
ls -la .project/*.yaml

Permission denied

Ensure the project script is executable:

terminal
chmod +x ./project

Runner download fails

Check your internet connection and ensure curl or wget is installed:

terminal
which curl wget

Docker commands fail

Verify Docker is installed and running:

terminal
docker --version
docker-compose --version

YAML parsing errors

Check your YAML syntax. Common issues:

  • Incorrect indentation (use spaces, not tabs)
  • Missing colons after keys
  • Unquoted strings with special characters

Need More Help?

Community Support

Documentation