- Introduced multiple new markdown files covering API and routing, application architecture, deployment architecture, database patterns, frontend patterns, and security practices. - Established guidelines for development workflows, testing strategies, and continuous improvement of rules. - Enhanced project overview and technology stack documentation to provide clarity on Coolify's features and architecture.
		
			
				
	
	
		
			654 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			654 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
---
 | 
						|
description: 
 | 
						|
globs: 
 | 
						|
alwaysApply: false
 | 
						|
---
 | 
						|
# Coolify Development Workflow
 | 
						|
 | 
						|
## Development Environment Setup
 | 
						|
 | 
						|
### Prerequisites
 | 
						|
- **PHP 8.4+** - Latest PHP version for modern features
 | 
						|
- **Node.js 18+** - For frontend asset compilation
 | 
						|
- **Docker & Docker Compose** - Container orchestration
 | 
						|
- **PostgreSQL 15** - Primary database
 | 
						|
- **Redis 7** - Caching and queues
 | 
						|
 | 
						|
### Local Development Setup
 | 
						|
 | 
						|
#### Using Docker (Recommended)
 | 
						|
```bash
 | 
						|
# Clone the repository
 | 
						|
git clone https://github.com/coollabsio/coolify.git
 | 
						|
cd coolify
 | 
						|
 | 
						|
# Copy environment configuration
 | 
						|
cp .env.example .env
 | 
						|
 | 
						|
# Start development environment
 | 
						|
docker-compose -f docker-compose.dev.yml up -d
 | 
						|
 | 
						|
# Install PHP dependencies
 | 
						|
docker-compose exec app composer install
 | 
						|
 | 
						|
# Install Node.js dependencies
 | 
						|
docker-compose exec app npm install
 | 
						|
 | 
						|
# Generate application key
 | 
						|
docker-compose exec app php artisan key:generate
 | 
						|
 | 
						|
# Run database migrations
 | 
						|
docker-compose exec app php artisan migrate
 | 
						|
 | 
						|
# Seed development data
 | 
						|
docker-compose exec app php artisan db:seed
 | 
						|
```
 | 
						|
 | 
						|
#### Native Development
 | 
						|
```bash
 | 
						|
# Install PHP dependencies
 | 
						|
composer install
 | 
						|
 | 
						|
# Install Node.js dependencies
 | 
						|
npm install
 | 
						|
 | 
						|
# Setup environment
 | 
						|
cp .env.example .env
 | 
						|
php artisan key:generate
 | 
						|
 | 
						|
# Setup database
 | 
						|
createdb coolify_dev
 | 
						|
php artisan migrate
 | 
						|
php artisan db:seed
 | 
						|
 | 
						|
# Start development servers
 | 
						|
php artisan serve &
 | 
						|
npm run dev &
 | 
						|
php artisan queue:work &
 | 
						|
```
 | 
						|
 | 
						|
## Development Tools & Configuration
 | 
						|
 | 
						|
### Code Quality Tools
 | 
						|
- **[Laravel Pint](mdc:pint.json)** - PHP code style fixer
 | 
						|
- **[Rector](mdc:rector.php)** - PHP automated refactoring (989B, 35 lines)
 | 
						|
- **PHPStan** - Static analysis for type safety
 | 
						|
- **ESLint** - JavaScript code quality
 | 
						|
 | 
						|
### Development Configuration Files
 | 
						|
- **[docker-compose.dev.yml](mdc:docker-compose.dev.yml)** - Development Docker setup (3.4KB, 126 lines)
 | 
						|
- **[vite.config.js](mdc:vite.config.js)** - Frontend build configuration (1.0KB, 42 lines)
 | 
						|
- **[.editorconfig](mdc:.editorconfig)** - Code formatting standards (258B, 19 lines)
 | 
						|
 | 
						|
### Git Configuration
 | 
						|
- **[.gitignore](mdc:.gitignore)** - Version control exclusions (522B, 40 lines)
 | 
						|
- **[.gitattributes](mdc:.gitattributes)** - Git file handling (185B, 11 lines)
 | 
						|
 | 
						|
## Development Workflow Process
 | 
						|
 | 
						|
### 1. Feature Development
 | 
						|
```bash
 | 
						|
# Create feature branch
 | 
						|
git checkout -b feature/new-deployment-strategy
 | 
						|
 | 
						|
# Make changes following coding standards
 | 
						|
# Run code quality checks
 | 
						|
./vendor/bin/pint
 | 
						|
./vendor/bin/rector process --dry-run
 | 
						|
./vendor/bin/phpstan analyse
 | 
						|
 | 
						|
# Run tests
 | 
						|
./vendor/bin/pest
 | 
						|
./vendor/bin/pest --coverage
 | 
						|
 | 
						|
# Commit changes
 | 
						|
git add .
 | 
						|
git commit -m "feat: implement blue-green deployment strategy"
 | 
						|
```
 | 
						|
 | 
						|
### 2. Code Review Process
 | 
						|
```bash
 | 
						|
# Push feature branch
 | 
						|
git push origin feature/new-deployment-strategy
 | 
						|
 | 
						|
# Create pull request with:
 | 
						|
# - Clear description of changes
 | 
						|
# - Screenshots for UI changes
 | 
						|
# - Test coverage information
 | 
						|
# - Breaking change documentation
 | 
						|
```
 | 
						|
 | 
						|
### 3. Testing Requirements
 | 
						|
- **Unit tests** for new models and services
 | 
						|
- **Feature tests** for API endpoints
 | 
						|
- **Browser tests** for UI changes
 | 
						|
- **Integration tests** for deployment workflows
 | 
						|
 | 
						|
## Coding Standards & Conventions
 | 
						|
 | 
						|
### PHP Coding Standards
 | 
						|
```php
 | 
						|
// Follow PSR-12 coding standards
 | 
						|
class ApplicationDeploymentService
 | 
						|
{
 | 
						|
    public function __construct(
 | 
						|
        private readonly DockerService $dockerService,
 | 
						|
        private readonly ConfigurationGenerator $configGenerator
 | 
						|
    ) {}
 | 
						|
    
 | 
						|
    public function deploy(Application $application): ApplicationDeploymentQueue
 | 
						|
    {
 | 
						|
        return DB::transaction(function () use ($application) {
 | 
						|
            $deployment = $application->deployments()->create([
 | 
						|
                'status' => 'queued',
 | 
						|
                'commit_sha' => $application->getLatestCommitSha(),
 | 
						|
            ]);
 | 
						|
            
 | 
						|
            DeployApplicationJob::dispatch($deployment);
 | 
						|
            
 | 
						|
            return $deployment;
 | 
						|
        });
 | 
						|
    }
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
### Laravel Best Practices
 | 
						|
```php
 | 
						|
// Use Laravel conventions
 | 
						|
class Application extends Model
 | 
						|
{
 | 
						|
    // Mass assignment protection
 | 
						|
    protected $fillable = [
 | 
						|
        'name', 'git_repository', 'git_branch', 'fqdn'
 | 
						|
    ];
 | 
						|
    
 | 
						|
    // Type casting
 | 
						|
    protected $casts = [
 | 
						|
        'environment_variables' => 'array',
 | 
						|
        'build_pack' => BuildPack::class,
 | 
						|
        'created_at' => 'datetime',
 | 
						|
    ];
 | 
						|
    
 | 
						|
    // Relationships
 | 
						|
    public function server(): BelongsTo
 | 
						|
    {
 | 
						|
        return $this->belongsTo(Server::class);
 | 
						|
    }
 | 
						|
    
 | 
						|
    public function deployments(): HasMany
 | 
						|
    {
 | 
						|
        return $this->hasMany(ApplicationDeploymentQueue::class);
 | 
						|
    }
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
### Frontend Standards
 | 
						|
```javascript
 | 
						|
// Alpine.js component structure
 | 
						|
document.addEventListener('alpine:init', () => {
 | 
						|
    Alpine.data('deploymentMonitor', () => ({
 | 
						|
        status: 'idle',
 | 
						|
        logs: [],
 | 
						|
        
 | 
						|
        init() {
 | 
						|
            this.connectWebSocket();
 | 
						|
        },
 | 
						|
        
 | 
						|
        connectWebSocket() {
 | 
						|
            Echo.private(`application.${this.applicationId}`)
 | 
						|
                .listen('DeploymentStarted', (e) => {
 | 
						|
                    this.status = 'deploying';
 | 
						|
                })
 | 
						|
                .listen('DeploymentCompleted', (e) => {
 | 
						|
                    this.status = 'completed';
 | 
						|
                });
 | 
						|
        }
 | 
						|
    }));
 | 
						|
});
 | 
						|
```
 | 
						|
 | 
						|
### CSS/Tailwind Standards
 | 
						|
```html
 | 
						|
<!-- Use semantic class names and consistent spacing -->
 | 
						|
<div class="bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
 | 
						|
    <div class="p-6">
 | 
						|
        <h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-4">
 | 
						|
            Application Status
 | 
						|
        </h3>
 | 
						|
        <div class="space-y-3">
 | 
						|
            <!-- Content with consistent spacing -->
 | 
						|
        </div>
 | 
						|
    </div>
 | 
						|
</div>
 | 
						|
```
 | 
						|
 | 
						|
## Database Development
 | 
						|
 | 
						|
### Migration Best Practices
 | 
						|
```php
 | 
						|
// Create descriptive migration files
 | 
						|
class CreateApplicationDeploymentQueuesTable extends Migration
 | 
						|
{
 | 
						|
    public function up(): void
 | 
						|
    {
 | 
						|
        Schema::create('application_deployment_queues', function (Blueprint $table) {
 | 
						|
            $table->id();
 | 
						|
            $table->foreignId('application_id')->constrained()->cascadeOnDelete();
 | 
						|
            $table->string('status')->default('queued');
 | 
						|
            $table->string('commit_sha')->nullable();
 | 
						|
            $table->text('build_logs')->nullable();
 | 
						|
            $table->text('deployment_logs')->nullable();
 | 
						|
            $table->timestamp('started_at')->nullable();
 | 
						|
            $table->timestamp('finished_at')->nullable();
 | 
						|
            $table->timestamps();
 | 
						|
            
 | 
						|
            $table->index(['application_id', 'status']);
 | 
						|
            $table->index('created_at');
 | 
						|
        });
 | 
						|
    }
 | 
						|
    
 | 
						|
    public function down(): void
 | 
						|
    {
 | 
						|
        Schema::dropIfExists('application_deployment_queues');
 | 
						|
    }
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
### Model Factory Development
 | 
						|
```php
 | 
						|
// Create comprehensive factories for testing
 | 
						|
class ApplicationFactory extends Factory
 | 
						|
{
 | 
						|
    protected $model = Application::class;
 | 
						|
    
 | 
						|
    public function definition(): array
 | 
						|
    {
 | 
						|
        return [
 | 
						|
            'name' => $this->faker->words(2, true),
 | 
						|
            'fqdn' => $this->faker->domainName,
 | 
						|
            'git_repository' => 'https://github.com/' . $this->faker->userName . '/' . $this->faker->word . '.git',
 | 
						|
            'git_branch' => 'main',
 | 
						|
            'build_pack' => BuildPack::NIXPACKS,
 | 
						|
            'server_id' => Server::factory(),
 | 
						|
            'environment_id' => Environment::factory(),
 | 
						|
        ];
 | 
						|
    }
 | 
						|
    
 | 
						|
    public function withCustomDomain(): static
 | 
						|
    {
 | 
						|
        return $this->state(fn (array $attributes) => [
 | 
						|
            'fqdn' => $this->faker->domainName,
 | 
						|
        ]);
 | 
						|
    }
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
## API Development
 | 
						|
 | 
						|
### Controller Standards
 | 
						|
```php
 | 
						|
class ApplicationController extends Controller
 | 
						|
{
 | 
						|
    public function __construct()
 | 
						|
    {
 | 
						|
        $this->middleware('auth:sanctum');
 | 
						|
        $this->middleware('team.access');
 | 
						|
    }
 | 
						|
    
 | 
						|
    public function index(Request $request): AnonymousResourceCollection
 | 
						|
    {
 | 
						|
        $applications = $request->user()
 | 
						|
            ->currentTeam
 | 
						|
            ->applications()
 | 
						|
            ->with(['server', 'environment', 'latestDeployment'])
 | 
						|
            ->paginate();
 | 
						|
            
 | 
						|
        return ApplicationResource::collection($applications);
 | 
						|
    }
 | 
						|
    
 | 
						|
    public function store(StoreApplicationRequest $request): ApplicationResource
 | 
						|
    {
 | 
						|
        $application = $request->user()
 | 
						|
            ->currentTeam
 | 
						|
            ->applications()
 | 
						|
            ->create($request->validated());
 | 
						|
            
 | 
						|
        return new ApplicationResource($application);
 | 
						|
    }
 | 
						|
    
 | 
						|
    public function deploy(Application $application): JsonResponse
 | 
						|
    {
 | 
						|
        $this->authorize('deploy', $application);
 | 
						|
        
 | 
						|
        $deployment = app(ApplicationDeploymentService::class)
 | 
						|
            ->deploy($application);
 | 
						|
            
 | 
						|
        return response()->json([
 | 
						|
            'message' => 'Deployment started successfully',
 | 
						|
            'deployment_id' => $deployment->id,
 | 
						|
        ]);
 | 
						|
    }
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
### API Resource Development
 | 
						|
```php
 | 
						|
class ApplicationResource extends JsonResource
 | 
						|
{
 | 
						|
    public function toArray($request): array
 | 
						|
    {
 | 
						|
        return [
 | 
						|
            'id' => $this->id,
 | 
						|
            'name' => $this->name,
 | 
						|
            'fqdn' => $this->fqdn,
 | 
						|
            'status' => $this->status,
 | 
						|
            'git_repository' => $this->git_repository,
 | 
						|
            'git_branch' => $this->git_branch,
 | 
						|
            'build_pack' => $this->build_pack,
 | 
						|
            'created_at' => $this->created_at,
 | 
						|
            'updated_at' => $this->updated_at,
 | 
						|
            
 | 
						|
            // Conditional relationships
 | 
						|
            'server' => new ServerResource($this->whenLoaded('server')),
 | 
						|
            'environment' => new EnvironmentResource($this->whenLoaded('environment')),
 | 
						|
            'latest_deployment' => new DeploymentResource($this->whenLoaded('latestDeployment')),
 | 
						|
            
 | 
						|
            // Computed attributes
 | 
						|
            'deployment_url' => $this->getDeploymentUrl(),
 | 
						|
            'can_deploy' => $this->canDeploy(),
 | 
						|
        ];
 | 
						|
    }
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
## Livewire Component Development
 | 
						|
 | 
						|
### Component Structure
 | 
						|
```php
 | 
						|
class ApplicationShow extends Component
 | 
						|
{
 | 
						|
    public Application $application;
 | 
						|
    public bool $showLogs = false;
 | 
						|
    
 | 
						|
    protected $listeners = [
 | 
						|
        'deployment.started' => 'refreshDeploymentStatus',
 | 
						|
        'deployment.completed' => 'refreshDeploymentStatus',
 | 
						|
    ];
 | 
						|
    
 | 
						|
    public function mount(Application $application): void
 | 
						|
    {
 | 
						|
        $this->authorize('view', $application);
 | 
						|
        $this->application = $application;
 | 
						|
    }
 | 
						|
    
 | 
						|
    public function deploy(): void
 | 
						|
    {
 | 
						|
        $this->authorize('deploy', $this->application);
 | 
						|
        
 | 
						|
        try {
 | 
						|
            app(ApplicationDeploymentService::class)->deploy($this->application);
 | 
						|
            
 | 
						|
            $this->dispatch('deployment.started', [
 | 
						|
                'application_id' => $this->application->id
 | 
						|
            ]);
 | 
						|
            
 | 
						|
            session()->flash('success', 'Deployment started successfully');
 | 
						|
        } catch (Exception $e) {
 | 
						|
            session()->flash('error', 'Failed to start deployment: ' . $e->getMessage());
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    public function refreshDeploymentStatus(): void
 | 
						|
    {
 | 
						|
        $this->application->refresh();
 | 
						|
    }
 | 
						|
    
 | 
						|
    public function render(): View
 | 
						|
    {
 | 
						|
        return view('livewire.application.show', [
 | 
						|
            'deployments' => $this->application
 | 
						|
                ->deployments()
 | 
						|
                ->latest()
 | 
						|
                ->limit(10)
 | 
						|
                ->get()
 | 
						|
        ]);
 | 
						|
    }
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
## Queue Job Development
 | 
						|
 | 
						|
### Job Structure
 | 
						|
```php
 | 
						|
class DeployApplicationJob implements ShouldQueue
 | 
						|
{
 | 
						|
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
						|
    
 | 
						|
    public int $tries = 3;
 | 
						|
    public int $maxExceptions = 1;
 | 
						|
    
 | 
						|
    public function __construct(
 | 
						|
        public ApplicationDeploymentQueue $deployment
 | 
						|
    ) {}
 | 
						|
    
 | 
						|
    public function handle(
 | 
						|
        DockerService $dockerService,
 | 
						|
        ConfigurationGenerator $configGenerator
 | 
						|
    ): void {
 | 
						|
        $this->deployment->update(['status' => 'running', 'started_at' => now()]);
 | 
						|
        
 | 
						|
        try {
 | 
						|
            // Generate configuration
 | 
						|
            $config = $configGenerator->generateDockerCompose($this->deployment->application);
 | 
						|
            
 | 
						|
            // Build and deploy
 | 
						|
            $imageTag = $dockerService->buildImage($this->deployment->application);
 | 
						|
            $dockerService->deployContainer($this->deployment->application, $imageTag);
 | 
						|
            
 | 
						|
            $this->deployment->update([
 | 
						|
                'status' => 'success',
 | 
						|
                'finished_at' => now()
 | 
						|
            ]);
 | 
						|
            
 | 
						|
            // Broadcast success
 | 
						|
            broadcast(new DeploymentCompleted($this->deployment));
 | 
						|
            
 | 
						|
        } catch (Exception $e) {
 | 
						|
            $this->deployment->update([
 | 
						|
                'status' => 'failed',
 | 
						|
                'error_message' => $e->getMessage(),
 | 
						|
                'finished_at' => now()
 | 
						|
            ]);
 | 
						|
            
 | 
						|
            broadcast(new DeploymentFailed($this->deployment));
 | 
						|
            
 | 
						|
            throw $e;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    public function backoff(): array
 | 
						|
    {
 | 
						|
        return [1, 5, 10];
 | 
						|
    }
 | 
						|
    
 | 
						|
    public function failed(Throwable $exception): void
 | 
						|
    {
 | 
						|
        $this->deployment->update([
 | 
						|
            'status' => 'failed',
 | 
						|
            'error_message' => $exception->getMessage(),
 | 
						|
            'finished_at' => now()
 | 
						|
        ]);
 | 
						|
    }
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
## Testing Development
 | 
						|
 | 
						|
### Test Structure
 | 
						|
```php
 | 
						|
// Feature test example
 | 
						|
test('user can deploy application via API', function () {
 | 
						|
    $user = User::factory()->create();
 | 
						|
    $application = Application::factory()->create([
 | 
						|
        'team_id' => $user->currentTeam->id
 | 
						|
    ]);
 | 
						|
    
 | 
						|
    // Mock external services
 | 
						|
    $this->mock(DockerService::class, function ($mock) {
 | 
						|
        $mock->shouldReceive('buildImage')->andReturn('app:latest');
 | 
						|
        $mock->shouldReceive('deployContainer')->andReturn(true);
 | 
						|
    });
 | 
						|
    
 | 
						|
    $response = $this->actingAs($user)
 | 
						|
        ->postJson("/api/v1/applications/{$application->id}/deploy");
 | 
						|
    
 | 
						|
    $response->assertStatus(200)
 | 
						|
        ->assertJson([
 | 
						|
            'message' => 'Deployment started successfully'
 | 
						|
        ]);
 | 
						|
    
 | 
						|
    expect($application->deployments()->count())->toBe(1);
 | 
						|
    expect($application->deployments()->first()->status)->toBe('queued');
 | 
						|
});
 | 
						|
```
 | 
						|
 | 
						|
## Documentation Standards
 | 
						|
 | 
						|
### Code Documentation
 | 
						|
```php
 | 
						|
/**
 | 
						|
 * Deploy an application to the specified server.
 | 
						|
 * 
 | 
						|
 * This method creates a new deployment queue entry and dispatches
 | 
						|
 * a background job to handle the actual deployment process.
 | 
						|
 * 
 | 
						|
 * @param Application $application The application to deploy
 | 
						|
 * @param array $options Additional deployment options
 | 
						|
 * @return ApplicationDeploymentQueue The created deployment queue entry
 | 
						|
 * 
 | 
						|
 * @throws DeploymentException When deployment cannot be started
 | 
						|
 * @throws ServerConnectionException When server is unreachable
 | 
						|
 */
 | 
						|
public function deploy(Application $application, array $options = []): ApplicationDeploymentQueue
 | 
						|
{
 | 
						|
    // Implementation
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
### API Documentation
 | 
						|
```php
 | 
						|
/**
 | 
						|
 * @OA\Post(
 | 
						|
 *     path="/api/v1/applications/{application}/deploy",
 | 
						|
 *     summary="Deploy an application",
 | 
						|
 *     description="Triggers a new deployment for the specified application",
 | 
						|
 *     operationId="deployApplication",
 | 
						|
 *     tags={"Applications"},
 | 
						|
 *     security={{"bearerAuth":{}}},
 | 
						|
 *     @OA\Parameter(
 | 
						|
 *         name="application",
 | 
						|
 *         in="path",
 | 
						|
 *         required=true,
 | 
						|
 *         @OA\Schema(type="integer"),
 | 
						|
 *         description="Application ID"
 | 
						|
 *     ),
 | 
						|
 *     @OA\Response(
 | 
						|
 *         response=200,
 | 
						|
 *         description="Deployment started successfully",
 | 
						|
 *         @OA\JsonContent(
 | 
						|
 *             @OA\Property(property="message", type="string"),
 | 
						|
 *             @OA\Property(property="deployment_id", type="integer")
 | 
						|
 *         )
 | 
						|
 *     )
 | 
						|
 * )
 | 
						|
 */
 | 
						|
```
 | 
						|
 | 
						|
## Performance Optimization
 | 
						|
 | 
						|
### Database Optimization
 | 
						|
```php
 | 
						|
// Use eager loading to prevent N+1 queries
 | 
						|
$applications = Application::with([
 | 
						|
    'server:id,name,ip',
 | 
						|
    'environment:id,name',
 | 
						|
    'latestDeployment:id,application_id,status,created_at'
 | 
						|
])->get();
 | 
						|
 | 
						|
// Use database transactions for consistency
 | 
						|
DB::transaction(function () use ($application) {
 | 
						|
    $deployment = $application->deployments()->create(['status' => 'queued']);
 | 
						|
    $application->update(['last_deployment_at' => now()]);
 | 
						|
    DeployApplicationJob::dispatch($deployment);
 | 
						|
});
 | 
						|
```
 | 
						|
 | 
						|
### Caching Strategies
 | 
						|
```php
 | 
						|
// Cache expensive operations
 | 
						|
public function getServerMetrics(Server $server): array
 | 
						|
{
 | 
						|
    return Cache::remember(
 | 
						|
        "server.{$server->id}.metrics",
 | 
						|
        now()->addMinutes(5),
 | 
						|
        fn () => $this->fetchServerMetrics($server)
 | 
						|
    );
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
## Deployment & Release Process
 | 
						|
 | 
						|
### Version Management
 | 
						|
- **[versions.json](mdc:versions.json)** - Version tracking (355B, 19 lines)
 | 
						|
- **[CHANGELOG.md](mdc:CHANGELOG.md)** - Release notes (187KB, 7411 lines)
 | 
						|
- **[cliff.toml](mdc:cliff.toml)** - Changelog generation (3.2KB, 85 lines)
 | 
						|
 | 
						|
### Release Workflow
 | 
						|
```bash
 | 
						|
# Create release branch
 | 
						|
git checkout -b release/v4.1.0
 | 
						|
 | 
						|
# Update version numbers
 | 
						|
# Update CHANGELOG.md
 | 
						|
# Run full test suite
 | 
						|
./vendor/bin/pest
 | 
						|
npm run test
 | 
						|
 | 
						|
# Create release commit
 | 
						|
git commit -m "chore: release v4.1.0"
 | 
						|
 | 
						|
# Create and push tag
 | 
						|
git tag v4.1.0
 | 
						|
git push origin v4.1.0
 | 
						|
 | 
						|
# Merge to main
 | 
						|
git checkout main
 | 
						|
git merge release/v4.1.0
 | 
						|
```
 | 
						|
 | 
						|
## Contributing Guidelines
 | 
						|
 | 
						|
### Pull Request Process
 | 
						|
1. **Fork** the repository
 | 
						|
2. **Create** feature branch from `main`
 | 
						|
3. **Implement** changes with tests
 | 
						|
4. **Run** code quality checks
 | 
						|
5. **Submit** pull request with clear description
 | 
						|
6. **Address** review feedback
 | 
						|
7. **Merge** after approval
 | 
						|
 | 
						|
### Code Review Checklist
 | 
						|
- [ ] Code follows project standards
 | 
						|
- [ ] Tests cover new functionality
 | 
						|
- [ ] Documentation is updated
 | 
						|
- [ ] No breaking changes without migration
 | 
						|
- [ ] Performance impact considered
 | 
						|
- [ ] Security implications reviewed
 | 
						|
 | 
						|
### Issue Reporting
 | 
						|
- Use issue templates
 | 
						|
- Provide reproduction steps
 | 
						|
- Include environment details
 | 
						|
- Add relevant logs/screenshots
 | 
						|
- Label appropriately
 |