Practical Guide: AI-Assisted XP with Symfony & Roo Code in VSCode

This guide provides step-by-step instructions for setting up your development environment and a cheat sheet for common tasks when implementing Extreme Programming (XP) practices with Symfony, Roo Code (AI Assistant), and a specific PHP quality toolchain in VSCode.

(Assumption: Roo Code extension is already installed and configured with API keys/default models).

1. Initial Environment Setup

(Prerequisite: VSCode & Roo Code Installed/Configured)

Step 1.1: Recommend/Install VSCode Extensions

A consistent set of VSCode extensions is crucial for this workflow. You can ensure this in two ways:

Core Recommended Extensions:

Troubleshooting Tip: If extensions like PHP Intelephense, PHPStan, or ECS report errors finding tools, ensure VSCode can locate your PHP executable. You might need to configure the php.executablePath setting in VSCode or specific path settings within the extensions themselves, especially if using Docker or custom PHP installations.

2. Project Setup & Quality Toolchain (PHP)

(Prerequisite: Symfony Project Created)

Follow these steps to manually set up the PHP quality toolchain and related configurations.

(Note: Steps 2.1, 2.3, 2.4, 2.5, and 2.6 are largely automated by the optional script provided in Appendix A. Step 2.2 requires manual configuration regardless of using the script.)

Step 2.1: Install PHP Quality Tools & MakerBundle

Navigate to your project directory in the terminal and run:

composer require --dev symfony/maker-bundle rector/rector symplify/easy-coding-standard phpstan/phpstan nunomaduro/phpinsights phpunit/phpunit phpro/grumphp

Step 2.2: Configure PHP Tool Configuration Files

(Required even if you use the script in Appendix A)

Create or modify the configuration files for each tool in your project root:

(Crucial Step): Remember that you must manually define your specific rules, standards, analysis levels, and configurations within rector.php, ecs.php, phpstan.neon, and phpinsights.php according to your project's needs. Refer to the official documentation for each tool.

Step 2.3: Define Composer Scripts (composer.json)

Add/modify the scripts section in your composer.json:

{
  "scripts": {
    "rector": "rector process --dry-run",
    "ecs": "ecs check src tests",
    "ecs-fix": "ecs fix src tests",
    "phpstan": "phpstan analyse --error-format=table",
    "phpstan-baseline": "phpstan analyse --generate-baseline",
    "insights": "phpinsights --no-interaction --ansi --min-quality=85",
    "insights-baseline": "phpinsights --baseline",
    "rector-upgrade": "rector process --config rector.php",
    "phpunit": "phpunit",
    "quality": [
        "@rector",
        "@ecs",
        "@phpstan",
        "@insights",
        "@phpunit"
    ]
  }
}

(Run composer install if you modified composer.json)

Step 2.4: Configure VSCode Workspace (.vscode/)

Create the .vscode directory if it doesn't exist. Inside it, create/edit:

  1. extensions.json (Recommended Extensions):

    {
      "recommendations": [
        "bmewburn.vscode-intelephense-client",
        "TheNouillet.symfony-vscode",
        "mblode.twig-language-2",
        "xdebug.php-debug",
        "eamodio.gitlens",
        "RooVeterinaryInc.roo-cline",
        "GitLab.gitlab-workflow",
        "GitHub.vscode-pull-request-github"
        // Optional: Add azdanov.vscode-easy-coding-standard, swordev.phpstan here too
      ]
    }
    
  2. settings.json (Workspace Settings):

    {
      "[php]": {
        "editor.defaultFormatter": "azdanov.vscode-easy-coding-standard", // Assumes extension is installed
        "editor.formatOnSave": true
      },
      "easyCodingStandard.executablePath": "./vendor/bin/ecs", // Path for ECS extension
      "phpstan.executablePath": "./vendor/bin/phpstan", // Path for PHPStan extension
      "phpstan.level": 6, // Match your phpstan.neon level
      "phpstan.autoAnalysis": "onSave", // Enable live analysis (requires PHPStan extension)
      "phpstan.memoryLimit": "1G", // Adjust as needed
      "editor.formatOnSave": true // Enable format on save globally
    }
    

Step 2.5: Configure VSCode Tasks (.vscode/tasks.json)

Create/edit .vscode/tasks.json to provide easy access to run Composer scripts via the Command Palette (Ctrl+Shift+P > Run Task):

{
  "version": "2.0.0",
  "tasks": [
    { "label": "rector-dry-run", "type": "shell", "command": "composer", "args": ["rector"], "problemMatcher": [] },
    { "label": "ecs-check",      "type": "shell", "command": "composer", "args": ["ecs"],    "problemMatcher": [] },
    { "label": "ecs-fix",        "type": "shell", "command": "composer", "args": ["ecs-fix"],"problemMatcher": [] },
    { "label": "phpstan",        "type": "shell", "command": "composer", "args": ["phpstan"],"problemMatcher": [] },
    { "label": "phpinsights",    "type": "shell", "command": "composer", "args": ["insights"],"problemMatcher": [] },
    { "label": "phpunit",        "type": "shell", "command": "composer", "args": ["phpunit"],"problemMatcher": [] },
    {
      "label": "quality-all",
      "dependsOn": ["rector-dry-run","ecs-check","phpstan","phpinsights", "phpunit"],
      "dependsOrder": "sequence",
      "group": { "kind": "build", "isDefault": true }, // Default build task (Ctrl+Shift+B)
      "problemMatcher": []
    }
  ]
}

Step 2.6: Set Up Git Hooks with GrumPHP

  1. Configure GrumPHP: Run vendor/bin/grumphp configure to create grumphp.yml.

  2. Edit grumphp.yml: Add tasks for your quality tools.

    # grumphp.yml
    grumphp:
        tasks:
            rector:
                config: rector.php
                triggered_by: ['php']
            ecs:
                config: ecs.php
                triggered_by: ['php']
            phpstan:
                configuration: phpstan.neon
                level: 6
                triggered_by: ['php']
            phpinsights:
                config: phpinsights.php
                min_quality: 85
                triggered_by: ['php']
            phpunit: ~
    
  3. Initialize Hooks: Run vendor/bin/grumphp git:init.

3. Configuring Roo Code for XP Tasks

Tailor Roo Code's behavior for specific XP workflows using Custom Modes and Instructions.

Step 3.1: Create Custom Modes

Choose one method:

Detailed Example Mode Definitions:

Here are more detailed configurations for the example modes:

XP TDD Assistant (PHPUnit)

Example Instructions (Place in .roo/rules-xp-tdd-assistant-phpunit/01-phpunit-guidelines.md):

- Given a class/method or user story, generate concise, failing PHPUnit test stubs focusing on one behavior at a time.
- When given a failing test, provide the *simplest possible* PHP code to make it pass.
- Suggest relevant edge cases or assertions.
- Adhere strictly to project coding standards (enforced by ECS, defined in ecs.php).
- Use `composer phpunit` or `vendor/bin/phpunit` to run tests when requested via the terminal tool.

XP Refactoring Helper (PHP/Rector)

Example Instructions (Place in .roo/rules-xp-refactoring-helper-php/01-refactoring-rules.md):

- Analyze the provided PHP/Symfony code and identify opportunities for refactoring based on principles like DRY, SOLID, and simple design.
- Suggest specific refactorings (e.g., extract method, simplify conditional, introduce dependency injection).
- Identify applicable Rector rules for automated refactoring (referencing rector.php).
- Explain the rationale for each suggestion.
- If requested to perform a manual refactoring, provide a diff preview before modifying files.
- Ensure refactored code passes existing tests and PHPStan checks (assume tests/checks will be run manually using `composer phpunit` and `composer phpstan`).

Symfony Best Practice Advisor

Example Instructions (Place in .roo/rules-symfony-advisor/01-symfony-focus.md):

- Answer questions and review code related to Symfony best practices.
- Focus on correct usage of the service container, Doctrine ORM patterns, controller design, security components, form handling, Twig templating, and MakerBundle usage.
- Explain concepts clearly with reference to Symfony documentation principles.
- Ensure suggestions align with PHPStan level 6+ checks (referencing phpstan.neon).

Coding Standards Enforcer (ECS)

Example Instructions (Place in .roo/rules-ecs-enforcer/01-ecs-tasks.md):

- Format the provided PHP code according to the project's ECS configuration (ecs.php).
- Identify and report any style violations based on configured ECS rules.
- Use `composer ecs-fix` to apply fixes when requested via the terminal tool.

Step 3.2: Set Custom Instructions

Provide specific guidelines for Roo Code beyond the mode definitions.

(Store team-wide instructions in .roo/rules/ under version control.)

Step 3.3: Configure MCP Servers (Optional Advanced)

Model Context Protocol (MCP) allows Roo Code to connect to external tools and services. This is an advanced feature; configure it if you have specific MCP servers you need to integrate.

  1. Find/Install Servers: Roo Code doesn't come with MCP servers. You need to find community servers (e.g., on GitHub) or build your own using the MCP SDK.

  2. Configure:

    • Global: Edit mcp_settings.json via Roo Code MCP settings (⚙️ icon).
    • Project: Create/edit .roo/mcp.json in your project root (also accessible via Roo Code MCP settings). Project settings override global ones.
  3. Settings Format (JSON):

    {
      "mcpServers": {
        "your-server-name": {
          // --- STDIO (Local Server) Example ---
          // "command": "node",
          // "args": ["/path/to/server.js"],
          // "cwd": "/optional/working/dir",
          // "env": { "API_KEY": "some_key" },
    
          // --- SSE (Remote Server) Example ---
          "url": "https://your-remote-server.com/mcp",
          "headers": { "Authorization": "Bearer your-token" },
    
          // --- Common Settings ---
          "alwaysAllow": ["tool1_from_this_server"], // Tools to auto-approve
          "disabled": false // Set to true to disable
        }
        // Add more server configurations here
      }
    }
    
  4. Enable/Disable: You can enable/disable MCP globally or per-server via the Roo Code MCP settings view (⚙️ icon). Disabling reduces token usage if MCP is not needed.

(Refer to the Roo Code documentation for detailed MCP configuration, transport types (STDIO/SSE), and SDK information.)

4. XP Workflow Cheat Sheet with Roo Code

Use Roo Code and your configured tools to streamline XP practices.

Generating Boilerplate (MakerBundle + Roo Code)

  1. Prompt (Generate): Use a general mode with command access. Prompt: Run the command 'php bin/console make:controller ProductController' to create a new controller. (Roo Code executes the command). MakerBundle might ask interactive questions in the terminal; you may need to answer them there or pre-configure defaults.
  2. Prompt (Flesh Out): After MakerBundle creates the file, prompt Roo Code (e.g., using 'code' mode): In the generated ProductController.php, implement the 'index' action to fetch all products from the ProductRepository and render the 'product/index.html.twig' template with the products.
  3. Action (Review): Review the combined result (MakerBundle structure + Roo Code logic).

TDD Cycle (PHPUnit)

  1. Prompt (Red): Select the 'XP TDD Assistant (PHPUnit)' mode. Prompt: Generate a failing PHPUnit test for [behavior] in [TestClass.php].
  2. Action (Verify Fail): Run the specific test using VSCode Test Explorer or terminal (composer phpunit --filter=…).
  3. Prompt (Green): Prompt: The test [testName] is failing. Write the simplest code in [SourceClass.php] to make it pass.
  4. Action (Review/Format): Review AI code. Save the file (Ctrl+S) - ECS formats, PHPStan analyzes (check Problems panel).
  5. Action (Verify Pass): Re-run the test.
  6. Prompt/Action (Refactor):
    • Prompt (using 'XP Refactoring Helper' mode): Review the new code in [SourceClass.php] and test in [TestClass.php]. Suggest refactorings for simplicity/clarity.
    • OR Perform manual refactoring.
    • OR Use Rector (composer rector-upgrade).
  7. Action (Verify Refactor): Run all relevant tests (composer phpunit).

Refactoring

  1. Prompt (Suggest): Select 'XP Refactoring Helper' mode. Prompt: Analyze [ClassOrMethod] for refactoring opportunities based on SOLID/DRY principles.
  2. Prompt (Perform): Prompt: Extract the selected logic into a new private method named [newMethodName]. or Rename the variable $oldName to $newName throughout this class. (Roo Code will show diffs).
  3. Action (Automate): Run composer rector-upgrade to apply configured Rector rules.
  4. Action (Verify): Crucially, run tests (composer phpunit) and static analysis (composer phpstan) after any refactoring.

Coding Standards (ECS/PHPStan)

  1. Action (Auto-Format): Save PHP files (Ctrl+S) - ECS formats automatically if configured via settings.json.
  2. Prompt (Format File): Select 'Coding Standards Enforcer (ECS)' mode. Prompt: Format the file [FilePath.php] according to ecs.php.
  3. Action (Check): Run composer ecs and composer phpstan manually or via VSCode Tasks (Ctrl+Shift+B if quality-all is default).
  4. Action (Fix Style): Run composer ecs-fix to automatically fix ECS violations.
  5. Action (Pre-commit): git commit - GrumPHP hook runs checks automatically.

Debugging

  1. Action (Identify): Run code/tests, get the exact error message and stack trace.
  2. Prompt (Fix): Use a general Roo Code mode (like 'code' or 'debug'). Prompt: Fix this error in [FilePath.php]: [Paste full error message and stack trace]. The error occurs when [describe action triggering error]. Check if [suggest specific area, e.g., variable is initialized].
  3. Action (Review & Test): Review the proposed fix (diff). Apply it. Re-run the code/test to verify. Iterate prompt if needed.

Generating Code (Simple Design - Post-MakerBundle)

(Assuming MakerBundle created the initial file)

  1. Prompt (Iterate): Use a general mode. Prompt: In the 'ProductController' created by MakerBundle, add validation to the 'new' and 'edit' actions. Ensure the 'name' field is not blank using Symfony's Validator component. (Build incrementally on the boilerplate).
  2. Action (Review): Review generated code for correctness, adherence to Symfony practices, and simplicity.

Understanding Code

  1. Prompt (Explain): Use the 'ask' mode or a general mode. Select code or reference a file/method. Prompt: Explain what this code does: [paste snippet or reference file/method]. or Explain the purpose of the [ClassName] class.

Complex Workflow (Orchestrator Mode / Boomerang Tasks)

Use the built-in 🪃 Orchestrator mode to break down complex tasks and delegate to specialized modes.

  1. Prompt (Overall Goal): Select the 🪃 Orchestrator mode. Prompt: Implement a new feature: Allow users to upload a profile picture. This involves updating the User entity, creating a controller action, handling the file upload, saving the path, and writing tests.
  2. Action (Approve Subtask 1 - Test): Roo Code (Orchestrator) might suggest a subtask: "Create failing tests for profile picture upload using PHPUnit." It will propose delegating this to the XP TDD Assistant (PHPUnit) mode. Approve the subtask.
  3. Action (Interact with Subtask 1): The context switches to the TDD Assistant mode. Interact with it (provide details, review generated tests) until the tests are created. Approve completion when done.
  4. Action (Resume Orchestrator): The Orchestrator mode resumes, receiving a summary (e.g., "Tests created in tests/Controller/ProfileControllerTest.php").
  5. Action (Approve Subtask 2 - Implementation): Orchestrator suggests the next subtask: "Implement the controller action and upload logic." It proposes delegating to the code mode (or a custom Symfony implementation mode). Approve.
  6. Action (Interact with Subtask 2): Context switches to code mode. Guide the implementation (review code, provide specifics). Approve completion.
  7. Action (Resume & Continue): Orchestrator resumes with a summary. It might suggest further subtasks (e.g., updating the entity using code mode, refactoring using XP Refactoring Helper mode) until the overall goal is achieved.

Key Points for Orchestrator Mode:

5. Key Reminders & Best Practices

This guide provides a starting point. Adapt the configurations and workflows to your specific project needs and team practices. Happy AI-assisted XP development!

Appendix A: Automated Setup Script

This script automates the installation and configuration of the PHP quality tools, Symfony MakerBundle, Composer scripts, VSCode settings (including recommended extensions), GrumPHP, and a basic GitHub Actions workflow. Use this as an alternative to the manual steps in Section 2.

Prerequisites for Script: bash, composer, jq, awk.

Script:

#!/usr/bin/env bash
#
# Automate the “PHP Quality Toolchain – Rector → ECS → PHPStan → phpinsights” + MakerBundle + VSCode Recs
# Safe to run repeatedly: skips steps that are already in place.
# ---------------------------------------------------------------
set -euo pipefail
IFS=

### How to Use the Script

1. Save the script content to a file in your project root, for example, `setup_quality_tools.sh`.
2. Make it executable: `chmod +x setup_quality_tools.sh`.
3. Run it from your project root: `./setup_quality_tools.sh`.

### Important Notes

- **Review Before Running:** Understand what the script does before executing it.
- **Project Root:** Run the script from the root directory of your Symfony project (where `composer.json` is located).
- **Idempotent:** The script tries to be safe to run multiple times (it checks if configurations exist before adding them), but it might overwrite `grumphp.yml` if it exists but wasn't created by the script initially. It skips creating `tasks.json`, `extensions.json`, and the GitHub workflow if they already exist.
- **Tool Configuration:** The script _does not_ configure the specific rules within `rector.php`, `ecs.php`, `phpstan.neon`, or `phpinsights.php`. You still need to define your desired rulesets and configurations in these files manually (Step 2.2).
- **PHPUnit:** The script includes `phpunit/phpunit` in composer require, adds a `phpunit` script to `composer.json`, includes it in the `quality` script, adds a VSCode task for it, includes it in `grumphp.yml`, and adds a step to the GitHub workflow.
- **MakerBundle:** The script adds `symfony/maker-bundle` to the dev dependencies.
- _**Script Logic:**_ _The script uses `jq` to check if certain key configurations already exist before attempting to add them. If you have unusual partial configurations, review the script's additions manually._
\n\t'

## ---------- helpers ---------------------------------------------------------
log() { printf "\e[36m▶ %s\e[0m\n" "$*"; }
warn(){ printf "\e[33m⚠ %s\e[0m\n" "$*"; }
die() { printf "\e[31m✖ %s\e[0m\n" "$*" ; exit 1; }

require_cmd() {
  command -v "$1" >/dev/null 2>&1 || die "Missing dependency: $1"
}

json_add_if_missing() {
  # $1=file  $2=jq filter to test  $3=jq snippet to add  $4=description
  # Check if the specific key exists using the filter $2
  if jq -e "$2" "$1" >/dev/null; then
    log "$4 already present or structure exists"
  else
    log "Adding $4"
    tmp=$(mktemp)
    # Apply the addition using the snippet $3
    jq "$3" "$1" >"$tmp" && mv "$tmp" "$1" || { rm "$tmp"; die "Failed to update $1"; }
  fi
}

## ---------- sanity checks ----------------------------------------------------
require_cmd composer
require_cmd jq
require_cmd awk
[ -f composer.json ]         || die "Run from project root (composer.json not found)"

## ---------- 1. Composer dev tools -------------------------------------------
log "1. Ensuring dev dependencies (Quality Tools + MakerBundle)"
composer require --no-interaction --dev \
  symfony/maker-bundle \
  rector/rector \
  symplify/easy-coding-standard \
  phpstan/phpstan \
  nunomaduro/phpinsights \
  phpunit/phpunit \
  phpro/grumphp

## ---------- 2. Composer scripts ---------------------------------------------
log "2. Patching composer.json scripts"
# Check specifically for the 'quality' script key
json_add_if_missing composer.json \
  '.scripts.quality' \
  '.scripts += {
      "rector":        "rector process --dry-run",
      "ecs":           "ecs check src tests",
      "ecs-fix":       "ecs fix src tests",
      "phpstan":       "phpstan analyse --error-format=table",
      "phpstan-baseline":"phpstan analyse --generate-baseline",
      "insights":      "phpinsights --no-interaction --ansi --min-quality=85",
      "insights-baseline":"phpinsights --baseline",
      "rector-upgrade":"rector process --config rector.php",
      "phpunit":       "phpunit",
      "quality":       [
          "@rector",
          "@ecs",
          "@phpstan",
          "@insights",
          "@phpunit"
        ]
    }' \
  "composer scripts (rector, ecs, phpstan, insights, phpunit, quality)"

## ---------- 3. VS Code configuration -------------------------------------
log "3. VS Code configuration (.vscode/)"
mkdir -p .vscode

# extensions.json
EXTENSIONS=.vscode/extensions.json
if [ ! -f "$EXTENSIONS" ]; then echo '{"recommendations":[]}' > "$EXTENSIONS"; fi # Ensure base object exists
# Check if recommendations array exists and add if not
json_add_if_missing "$EXTENSIONS" \
  '.recommendations' \
  '.recommendations = [
      "bmewburn.vscode-intelephense-client",
      "TheNouillet.symfony-vscode",
      "mblode.twig-language-2",
      "xdebug.php-debug",
      "eamodio.gitlens",
      "RooVeterinaryInc.roo-cline",
      "GitLab.gitlab-workflow",
      "GitHub.vscode-pull-request-github"
      // Optional: Add azdanov.vscode-easy-coding-standard, swordev.phpstan here too
    ]' \
  "VS Code recommended extensions"

# settings.json
SETTINGS=.vscode/settings.json
if [ ! -f "$SETTINGS" ]; then echo '{}' > "$SETTINGS"; fi
# Check specifically for the ECS formatter setting within [php]
json_add_if_missing "$SETTINGS" \
  '."[php]".editor.defaultFormatter == "azdanov.vscode-easy-coding-standard"' \
  '. += {
    "[php]": {
      "editor.defaultFormatter": "azdanov.vscode-easy-coding-standard",
      "editor.formatOnSave": true
    },
    "easyCodingStandard.executablePath": "./vendor/bin/ecs",
    "phpstan.executablePath": "./vendor/bin/phpstan",
    "phpstan.level": 6,
    "phpstan.autoAnalysis": "onSave",
    "phpstan.memoryLimit": "1G",
    "editor.formatOnSave": true # Ensure global formatOnSave is also considered
  }' \
  "VS Code PHP formatter & PHPStan settings"

# tasks.json
TASKS=.vscode/tasks.json
if [ ! -f "$TASKS" ]; then
  log "Creating VS Code tasks.json"
  cat > "$TASKS" <<'JSON'
{
  "version": "2.0.0",
  "tasks": [
    { "label": "rector-dry-run", "type": "shell", "command": "composer", "args": ["rector"], "problemMatcher": [] },
    { "label": "ecs-check",      "type": "shell", "command": "composer", "args": ["ecs"],    "problemMatcher": [] },
    { "label": "ecs-fix",        "type": "shell", "command": "composer", "args": ["ecs-fix"],"problemMatcher": [] },
    { "label": "phpstan",        "type": "shell", "command": "composer", "args": ["phpstan"],"problemMatcher": [] },
    { "label": "phpinsights",    "type": "shell", "command": "composer", "args": ["insights"],"problemMatcher": [] },
    { "label": "phpunit",        "type": "shell", "command": "composer", "args": ["phpunit"],"problemMatcher": [] },
    {
      "label": "quality-all",
      "dependsOn": ["rector-dry-run","ecs-check","phpstan","phpinsights", "phpunit"], # Added phpunit
      "dependsOrder": "sequence",
      "group": { "kind": "build", "isDefault": true },
      "problemMatcher": []
    }
  ]
}
JSON
else
  warn "VS Code tasks.json exists – skipped (merge manually if needed)"
fi

## ---------- 4. GrumPHP git hook --------------------------------------------
log "4. GrumPHP pre-commit hook"
if [ ! -f grumphp.yml ]; then
  # Run configure first to create basic structure if needed
  vendor/bin/grumphp configure --no-interaction || true
  # Overwrite with desired tasks
  cat > grumphp.yml <<'YAML'
# grumphp.yml
grumphp:
  tasks:
    rector:
      config: rector.php
      triggered_by: ['php']
    ecs:
      config: ecs.php
      triggered_by: ['php']
    phpstan:
      configuration: phpstan.neon
      level: 6 # Match VSCode setting
      triggered_by: ['php']
    phpinsights:
      config: phpinsights.php
      min_quality: 85 # Match composer script/CI
      triggered_by: ['php']
    phpunit: ~ # Basic PHPUnit task
YAML
  # Initialize git hooks
  vendor/bin/grumphp git:init
  log "GrumPHP configured and hooks initialized"
else
  warn "grumphp.yml already present – skipped GrumPHP setup"
fi

## ---------- 5. GitHub Actions workflow --------------------------------------
# Note: This workflow assumes a reusable action '.github/actions/composer-install' exists.
# You might need to replace that with direct PHP setup and composer install steps.
log "5. GitHub Actions workflow"
WF_DIR=".github/workflows"
WF_FILE="$WF_DIR/quality-gate.yml"
if [ ! -f "$WF_FILE" ]; then
  mkdir -p "$WF_DIR"
  log "Creating GitHub workflow $WF_FILE"
  cat > "$WF_FILE" <<'YML'
name: Quality-Gate

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # Replace this with actual PHP setup + composer install if needed
      # Example using shivammathur/setup-php:
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2' # Adjust version as needed
          extensions: mbstring, xml, ctype, iconv, intl, gd, zip # Add necessary extensions
          tools: composer:v2
      - name: Install Dependencies
        run: composer install --prefer-dist --no-progress --no-interaction

      - name: Rector (Dry Run)
        run: vendor/bin/rector process --dry-run

      - name: Easy Coding Standard (ECS)
        run: vendor/bin/ecs check src tests # Adjust paths

      - name: PHPStan
        run: vendor/bin/phpstan analyse --error-format=github --no-progress

      - name: PHP Insights
        run: |
          mkdir -p build # Ensure build directory exists
          vendor/bin/phpinsights \
            --no-interaction \
            --min-quality=85 \
            --min-complexity=90 \
            --min-architecture=80 \
            --format=json > build/phpinsights.json # Adjust thresholds

      - name: Upload PHP Insights Artifact
        uses: actions/upload-artifact@v4
        with:
          name: insights-${{ github.sha }}
          path: build/phpinsights.json

      - name: PHPUnit Tests # Added PHPUnit step
        run: vendor/bin/phpunit

YML
else
  warn "Workflow $WF_FILE already exists – skipped"
fi

## ---------- 6. Final advice --------------------------------------------------
log "Setup script finished!"
log "Review generated/modified files: composer.json, .vscode/, grumphp.yml, $WF_FILE"
log "Configure tool specifics in: rector.php, ecs.php, phpstan.neon, phpinsights.php"
log "Run \`composer quality\` or press Ctrl+Shift+B in VS Code to validate."

How to Use the Script

  1. Save the script content to a file in your project root, for example, setup_quality_tools.sh.
  2. Make it executable: chmod +x setup_quality_tools.sh.
  3. Run it from your project root: ./setup_quality_tools.sh.

Important Notes