Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Scotty Laravel Package

spatie/scotty

Scotty is a beautiful SSH task runner. Define tasks in a Scotty.sh file (bash with annotations) and run them on remote servers over SSH with clear, readable output. Compatible with Laravel Envoy, so you can use it as a drop-in replacement.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install Scotty (preferred as a PHAR):

    curl -L https://github.com/spatie/scotty/releases/latest/download/scotty -o scotty
    chmod +x scotty
    

    Or globally:

    composer global require spatie/scotty
    
  2. Create a Scotty.sh file in your project root with a basic server definition:

    #!/usr/bin/env scotty
    # @servers remote=deployer@your-server.com
    
  3. Test SSH connectivity:

    ./scotty doctor
    
  4. Write your first task (e.g., pullCode):

    # @task on:remote
    pullCode() {
        cd /var/www/my-app
        git pull origin main
    }
    
  5. Run the task:

    ./scotty run pullCode
    

First Use Case

Replace manual SSH deployments with a scripted workflow. For example, automate a Laravel deploy:

# @macro deploy pullCode runMigrations restartWorkers
# @task on:remote
pullCode() { cd /var/www/my-app && git pull origin main; }
# @task on:remote
restartWorkers() { php artisan horizon:terminate; }

Run with:

./scotty run deploy

Implementation Patterns

Workflows

  1. Macro-Based Deploys

    • Group tasks into logical sequences (e.g., deploy, rollback).
    • Example:
      # @macro deploy pullCode installDeps migrate restartServices
      
    • Run with:
      scotty run deploy
      
  2. Environment-Specific Scripts

    • Use @option to handle environment variables dynamically:
      # @option env=production
      # @task on:remote
      deploy() { php artisan deploy --env=$ENV; }
      
    • Run with:
      scotty run deploy --env=staging
      
  3. Local/Remote Hybrid Tasks

    • Combine local and remote tasks using @task on:local and @task on:remote:
      # @task on:local
      buildAssets() { npm run build; }
      
      # @task on:remote
      deployAssets() { rsync -avz ./public/ user@server:/var/www/my-app/; }
      
  4. Conditional Execution

    • Use if statements in tasks to handle edge cases:
      # @task on:remote
      backupDatabase() {
          if [ "$ENV" = "production" ]; then
              mysqldump -u user -p$db_password db_name > backup.sql
          fi
      }
      

Integration Tips

  • Laravel Artisan Integration Embed Scotty tasks in Laravel’s artisan commands for seamless CLI workflows:

    // app/Console/Commands/DeployCommand.php
    public function handle() {
        $this->call('scotty:run', ['macro' => 'deploy']);
    }
    
  • CI/CD Pipelines Use Scotty in GitHub Actions/GitLab CI:

    # .github/workflows/deploy.yml
    jobs:
      deploy:
        runs-on: ubuntu-latest
        steps:
          - run: ./scotty run deploy --branch=${{ github.ref_name }}
    
  • Shared Scripts Store Scotty.sh in your repo to ensure consistency across environments. Use .gitignore to exclude sensitive data (e.g., SSH keys).

  • SSH Config Reuse Leverage ~/.ssh/config for complex SSH setups (e.g., jump hosts, proxies):

    # @servers production=prod-server
    # ~/.ssh/config:
    Host prod-server
        HostName example.com
        User deployer
        ProxyCommand ssh -W %h:%p jump-host
    

Gotchas and Tips

Pitfalls

  1. SSH Key Management

    • Scotty uses the default SSH key (~/.ssh/id_rsa). Specify custom keys via ~/.ssh/config or pass them via CLI:
      scotty run deploy --ssh-key=/path/to/key.pem
      
  2. Task Dependencies

    • Scotty stops on the first failure by default. Use --continue to bypass this:
      scotty run deploy --continue
      
  3. Blade vs. Bash Format

    • Scotty supports both Blade and Bash formats. Bash format (Scotty.sh) is preferred for simplicity and better IDE support (syntax highlighting, autocompletion).
    • Blade format lacks @option support (CLI flags are passed as Blade variables).
  4. Variable Scope

    • Variables defined in tasks (e.g., APP_DIR) are local to the task unless exported:
      # @task on:remote
      pullCode() {
          export APP_DIR="/var/www/my-app"  # Explicitly export
          cd $APP_DIR
          git pull origin $BRANCH
      }
      
  5. Pretend Mode Quirks

    • --pretend shows SSH commands but does not validate syntax. Always test with real runs after major changes.
  6. Pause/Resume Conflicts

    • Pressing p pauses execution but does not stop background processes (e.g., git pull or composer install). Use Ctrl+C to force-stop.

Debugging

  1. Verbose Output Enable debug mode for detailed logs:

    scotty run deploy --verbose
    
  2. Dry Run with --pretend Simulate execution to catch errors:

    scotty run deploy --pretend
    
  3. SSH Debugging Use GIT_SSH_COMMAND or SSH_DEBUG to debug SSH issues:

    SSH_DEBUG=1 scotty run deploy
    
  4. Task Isolation Test tasks individually to isolate failures:

    scotty run pullCode
    scotty run runMigrations
    

Tips

  1. Use scotty tasks List available tasks/macros to avoid memorizing them:

    scotty tasks
    
  2. Alias Scotty Add an alias to your shell config (~/.bashrc or ~/.zshrc):

    alias scotty='./scotty'
    
  3. Template Files Start with a template Scotty.sh and customize it per project:

    scotty init --format=bash --server=deployer@server.com
    
  4. Environment Variables Pass sensitive data via environment variables (e.g., DB_PASSWORD):

    export DB_PASSWORD="secret"
    scotty run deploy
    
  5. Parallel Tasks Use GNU Parallel or & for parallel execution (not natively supported in Scotty):

    # @task on:remote
    backup() {
        mysqldump db_name > backup.sql &
        php artisan optimize &
        wait
    }
    
  6. Error Handling Add checks in tasks to fail gracefully:

    # @task on:remote
    deploy() {
        if ! git pull origin $BRANCH; then
            echo "Git pull failed!" >&2
            exit 1
        fi
    }
    
  7. Logging Redirect output to a log file for auditing:

    scotty run deploy --log-file=deploy.log
    
  8. Multi-Server Workflows Run tasks on multiple servers in sequence:

    # @servers web-1=deployer@1.1.1.1 web-2=deployer@2.2.2.2
    # @macro deploy deployToWeb1 deployToWeb2
    # @task on:web-1
    deployToWeb1() { ... }
    # @task on:web-2
    deployToWeb2() { ... }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata