diff --git a/.env.example b/.env.example index c0660ea..4f4a920 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,6 @@ APP_NAME=Laravel APP_ENV=local -APP_KEY= +APP_KEY=base64:dGhpc2lzYWRlZmF1bHRrZXljaGFuZ2VtZTEyMzQ1 APP_DEBUG=true APP_URL=http://localhost diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..037c653 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,64 @@ +name: Tests + +on: + pull_request: + branches: [main, develop] + push: + branches: [main, develop] + +jobs: + phpunit: + name: PHPUnit Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + extensions: pdo_sqlite, mbstring, zip, gd, bcmath + coverage: none + + - name: Cache Composer packages + uses: actions/cache@v4 + with: + path: vendor + key: composer-${{ hashFiles('composer.lock') }} + restore-keys: composer- + + - name: Install dependencies + run: composer install --no-interaction --no-progress --prefer-dist + + - name: Copy .env + run: cp .env.example .env + + - name: Generate app key + run: php artisan key:generate + + - name: Run PHPUnit tests + run: php artisan test --parallel + env: + DB_CONNECTION: sqlite + DB_DATABASE: ':memory:' + + code-style: + name: Code Style (Pint) + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + + - name: Install dependencies + run: composer install --no-interaction --no-progress --prefer-dist + + - name: Run Pint + run: ./vendor/bin/pint --test diff --git a/README.md b/README.md index 9c5b8ee..00e6572 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Cooperative Bank Management System +[![Tests](https://github.com/vipul26singh/laravel-cooperative-bank/actions/workflows/tests.yml/badge.svg)](https://github.com/vipul26singh/laravel-cooperative-bank/actions/workflows/tests.yml) + A production-ready, open-source **core banking solution** purpose-built for cooperative banks, credit societies, and microfinance institutions. Manages the complete banking lifecycle — from customer onboarding and KYC verification through loan disbursement, EMI collection, fixed deposits, and financial reporting — all from a single web application. Built with **Laravel 13** and deployable in one command via Docker. No banking software license fees. No vendor lock-in. @@ -661,7 +663,7 @@ Planned improvements to make the system production-ready for real bank operation - [ ] **Webhook support** for third-party integrations - [x] **Mobile-responsive testing** — verify all pages work on tablets (common in bank branches) - [x] **Accessibility audit** — ARIA labels, keyboard navigation, screen reader support -- [ ] **CI/CD pipeline** — GitHub Actions for automated testing on every push +- [x] **CI/CD pipeline** — GitHub Actions for automated testing on every push --- diff --git a/app/Http/Controllers/InstallController.php b/app/Http/Controllers/InstallController.php index df33d00..7a5aa57 100644 --- a/app/Http/Controllers/InstallController.php +++ b/app/Http/Controllers/InstallController.php @@ -161,16 +161,38 @@ public function run() $dbPath = database_path('database.sqlite'); if (!file_exists($dbPath)) touch($dbPath); } + // 2. Write .env (uses default key from .env.example so app can boot) File::put(base_path('.env'), $env); $steps[] = ['name' => 'Create .env configuration', 'status' => 'success']; - // 2. Generate app key - Artisan::call('key:generate', ['--force' => true]); - $steps[] = ['name' => 'Generate application encryption key', 'status' => 'success']; + // 3. Try to generate a fresh app key (replaces default key) + try { + Artisan::call('key:generate', ['--force' => true]); + $steps[] = ['name' => 'Generate application encryption key', 'status' => 'success']; + } catch (\Exception $e) { + $steps[] = ['name' => 'Generate application encryption key', 'status' => 'skipped', 'note' => 'Run php artisan key:generate manually']; + } + + // 4. Set DB config at runtime so migrations work without reloading .env + $dbConn = $db['db_connection'] ?? 'sqlite'; + config(["database.default" => $dbConn]); + if ($dbConn === 'sqlite') { + config(["database.connections.sqlite.database" => database_path('database.sqlite')]); + } else { + config([ + "database.connections.{$dbConn}.host" => $db['db_host'] ?? '127.0.0.1', + "database.connections.{$dbConn}.port" => $db['db_port'] ?? '3306', + "database.connections.{$dbConn}.database" => $db['db_database'] ?? 'coopbank', + "database.connections.{$dbConn}.username" => $db['db_username'] ?? 'root', + "database.connections.{$dbConn}.password" => $db['db_password'] ?? '', + ]); + } + DB::purge(); + DB::reconnect(); - // 3. Clear config cache - Artisan::call('config:clear'); - $steps[] = ['name' => 'Clear configuration cache', 'status' => 'success']; + // Clear config cache + try { Artisan::call('config:clear'); } catch (\Exception $e) { /* may fail if no cache exists */ } + $steps[] = ['name' => 'Configure database connection', 'status' => 'success']; // 4. Create storage symlink try { diff --git a/resources/views/install/complete.blade.php b/resources/views/install/complete.blade.php index 4181717..5d10b2b 100644 --- a/resources/views/install/complete.blade.php +++ b/resources/views/install/complete.blade.php @@ -43,6 +43,12 @@ {{-- Post-install Commands --}}
Post-Install (for standalone servers)
+ @if(collect(session('steps', []))->contains(fn($s) => $s['status'] === 'skipped' && str_contains($s['name'], 'encryption'))) + + + + + @endif @@ -52,7 +58,7 @@
Generate App Key
Default key was used. Generate a secure one for production.
php artisan key:generate
Queue Worker
Process background jobs (emails, notifications, audit)
php artisan queue:work
* * * * * cd /path/to/project && php artisan schedule:run >> /dev/null 2>&1
- If using Docker, both are already running automatically via Supervisor. + If using Docker, all of the above are handled automatically.
Go to Login