# Nodarx Module Install Action Install custom PHP/Vue modules from git repositories with automatic dependency resolution. This GitHub Action clones module repositories, resolves dependencies, and installs both PHP (Composer) and Node.js (npm) dependencies in the correct order. ## Features - 🔗 **Dependency Resolution**: Automatically orders modules based on their dependencies - 📦 **Multi-Language Support**: Handles both PHP (Composer) and Node.js (npm) projects - 🔄 **Flexible**: Support for custom branches, tags, or commits - ✅ **Validation**: Detects circular dependencies and validates module configuration - 🎯 **Simple**: Just provide a JSON array of modules and their dependencies ## Quick Start ```yaml name: Deploy with Modules on: [push] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # Install server environment (PHP + Node.js) - uses: Nodarx/action-server-install@v1 with: install-php: 'true' install-node: 'true' php-version: '8.5' node-version: '24' server-path: './server' # Install modules with dependencies - uses: Nodarx/action-module-install@v1 with: modules: | [ {"name": "mail_manager", "repo": "https://git.ktrix.dev/Nodarx/mail_manager"}, {"name": "provider_jmapc", "repo": "https://git.ktrix.dev/Nodarx/provider_jmapc"}, {"name": "mail", "repo": "https://git.ktrix.dev/Nodarx/mail", "dependencies": ["mail_manager", "provider_jmapc"]} ] ``` ## Inputs | Input | Description | Required | Default | |-------|-------------|----------|---------| | `modules` | JSON array of modules to install (see [Module Schema](#module-schema)) | Yes | - | | `install-path` | Base directory where modules will be installed | No | `./modules` | | `skip-dependencies-check` | Skip dependency validation (not recommended) | No | `false` | ## Outputs | Output | Description | Example | |--------|-------------|---------| | `installed-modules` | Comma-separated list of installed module names in installation order | `mail_manager,provider_jmapc,mail` | | `install-path` | Path where modules were installed | `./modules` | | `status` | Installation status | `success` | ## Module Schema Each module in the `modules` array should follow this structure: ```json { "name": "module-name", // Required: Unique module identifier "repo": "https://...", // Required: Git repository URL "branch": "main", // Optional: Branch, tag, or commit (default: main) "dependencies": ["module1"] // Optional: Array of module names this module depends on } ``` ### Module Schema Examples **Minimal Module (No Dependencies)** ```json { "name": "standalone-module", "repo": "https://git.ktrix.dev/Nodarx/standalone" } ``` **Module with Branch Specification** ```json { "name": "beta-module", "repo": "https://git.ktrix.dev/Nodarx/beta", "branch": "develop" } ``` **Module with Dependencies** ```json { "name": "mail", "repo": "https://git.ktrix.dev/Nodarx/mail", "branch": "main", "dependencies": ["mail_manager", "provider_jmapc"] } ``` ## Usage Examples ### Single Module ```yaml - uses: Nodarx/action-module-install@v1 with: modules: | [ {"name": "auth", "repo": "https://git.ktrix.dev/Nodarx/auth"} ] ``` ### Linear Dependencies (A → B → C) ```yaml - uses: Nodarx/action-module-install@v1 with: modules: | [ {"name": "core", "repo": "https://git.ktrix.dev/Nodarx/core"}, {"name": "api", "repo": "https://git.ktrix.dev/Nodarx/api", "dependencies": ["core"]}, {"name": "web", "repo": "https://git.ktrix.dev/Nodarx/web", "dependencies": ["api"]} ] ``` Installation order: `core` → `api` → `web` ### Diamond Dependencies (A,B → C; C → D) ```yaml - uses: Nodarx/action-module-install@v1 with: modules: | [ {"name": "utils", "repo": "https://git.ktrix.dev/Nodarx/utils"}, {"name": "storage", "repo": "https://git.ktrix.dev/Nodarx/storage"}, {"name": "database", "repo": "https://git.ktrix.dev/Nodarx/database", "dependencies": ["utils", "storage"]}, {"name": "api", "repo": "https://git.ktrix.dev/Nodarx/api", "dependencies": ["database"]} ] ``` Installation order: `utils,storage` → `database` → `api` ### Mail System Example (Real-World) ```yaml - uses: Nodarx/action-server-install@v1 with: install-php: 'true' install-node: 'true' php-version: '8.5' node-version: '24' - uses: Nodarx/action-module-install@v1 id: modules with: modules: | [ { "name": "mail_manager", "repo": "https://git.ktrix.dev/Nodarx/mail_manager", "branch": "main" }, { "name": "provider_jmapc", "repo": "https://git.ktrix.dev/Nodarx/provider_jmapc", "branch": "stable1" }, { "name": "mail", "repo": "https://git.ktrix.dev/Nodarx/mail", "branch": "main", "dependencies": ["mail_manager", "provider_jmapc"] } ] install-path: './modules' - name: Verify installation run: | echo "Installed: ${{ steps.modules.outputs.installed-modules }}" ls -la ./modules/ ``` ### Different Branches per Module ```yaml - uses: Nodarx/action-module-install@v1 with: modules: | [ {"name": "core", "repo": "https://git.ktrix.dev/Nodarx/core", "branch": "v2.0"}, {"name": "plugin", "repo": "https://git.ktrix.dev/Nodarx/plugin", "branch": "develop"}, {"name": "theme", "repo": "https://git.ktrix.dev/Nodarx/theme", "branch": "stable1"} ] ``` ### Custom Install Path ```yaml - uses: Nodarx/action-module-install@v1 with: install-path: './custom/modules/directory' modules: | [ {"name": "module1", "repo": "https://git.ktrix.dev/Nodarx/module1"} ] ``` ## How It Works 1. **Validation**: Validates JSON structure and checks that all dependencies are defined 2. **Dependency Resolution**: Uses topological sort to determine correct installation order 3. **Cloning**: Clones each module repository in dependency order 4. **Installation**: Auto-detects and runs: - `composer install` for modules with `composer.json` - `npm install` or `npm ci` for modules with `package.json` 5. **Verification**: Verifies all modules installed successfully ## Dependency Resolution The action automatically determines the correct installation order: ``` Input modules: - mail (depends on: mail_manager, provider_jmapc) - mail_manager (no dependencies) - provider_jmapc (no dependencies) Installation order: 1. mail_manager 2. provider_jmapc 3. mail ``` Dependencies are installed **before** their dependents, ensuring all required modules are available when needed. ## Error Handling The action will fail with descriptive errors for: - ❌ **Invalid JSON**: Syntax errors in modules input - ❌ **Missing Fields**: Modules without `name` or `repo` - ❌ **Circular Dependencies**: A → B → A - ❌ **Missing Dependencies**: Module depends on undefined module - ❌ **Clone Failures**: Repository not accessible or branch doesn't exist - ❌ **Install Failures**: Composer or npm installation errors - ❌ **Missing Prerequisites**: PHP/Composer or Node/npm not installed ## Prerequisites Before using this action, ensure PHP and/or Node.js are installed: ```yaml - uses: Nodarx/action-server-install@v1 with: install-php: 'true' # If modules use Composer install-node: 'true' # If modules use npm ``` Or use standard setup actions: ```yaml - uses: actions/setup-node@v4 with: node-version: '24' - uses: shivammathur/setup-php@v2 with: php-version: '8.5' tools: composer:v2 ``` ## Troubleshooting ### Circular Dependency Error ``` Error: Circular dependency detected. Cannot determine installation order. ``` **Solution**: Review your dependencies to remove circular references. Example: ``` ❌ moduleA depends on moduleB, moduleB depends on moduleA ✅ moduleA depends on moduleB, moduleB has no dependencies ``` ### Missing Dependency Error ``` Error: The following dependencies are referenced but not defined: module_x ``` **Solution**: Add the missing module to your modules array: ```json [ {"name": "module_x", "repo": "https://..."}, {"name": "dependent", "repo": "https://...", "dependencies": ["module_x"]} ] ``` ### Composer/npm Not Found ``` Error: composer not found. Please ensure PHP and Composer are installed ``` **Solution**: Install PHP/Node.js before this action: ```yaml - uses: Nodarx/action-server-install@v1 with: install-php: 'true' install-node: 'true' ``` ### Clone Failed (Branch Not Found) ``` Error: Failed to clone module_name from https://... (branch: xyz) ``` **Solution**: Verify the branch exists in the repository. Use `main`, `master`, or a valid branch/tag name. ## Complete Workflow Example ```yaml name: Deploy Application with Modules on: push: branches: [ main ] jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup server environment uses: Nodarx/action-server-install@v1 with: install-php: 'true' install-node: 'true' php-version: '8.5' node-version: '24' server-path: './server' - name: Install application modules id: install-modules uses: Nodarx/action-module-install@v1 with: modules: | [ { "name": "mail_manager", "repo": "https://git.ktrix.dev/Nodarx/mail_manager", "branch": "main" }, { "name": "provider_jmapc", "repo": "https://git.ktrix.dev/Nodarx/provider_jmapc", "branch": "stable1" }, { "name": "mail", "repo": "https://git.ktrix.dev/Nodarx/mail", "branch": "main", "dependencies": ["mail_manager", "provider_jmapc"] }, { "name": "calendar", "repo": "https://git.ktrix.dev/Nodarx/calendar", "branch": "main", "dependencies": ["mail_manager"] } ] install-path: './server/modules' - name: Display installation results run: | echo "Installation Status: ${{ steps.install-modules.outputs.status }}" echo "Installed Modules: ${{ steps.install-modules.outputs.installed-modules }}" echo "Install Path: ${{ steps.install-modules.outputs.install-path }}" echo "" echo "Module directories:" ls -la ${{ steps.install-modules.outputs.install-path }} - name: Run application tests run: | cd ./server npm test ``` ## License MIT License - see [LICENSE](LICENSE) file for details. ## Author Created by [Nodarx](https://github.com/Nodarx)