# CI/CD Pipeline This template includes a GitHub Actions workflow for continuous integration and deployment. ## Overview ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ Push to │────▶│ Run Tests │────▶│ Deploy Staging │ │ develop │ │ + Lint │ │ (automatic) │ └─────────────┘ └─────────────┘ └─────────────────┘ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ Push to │────▶│ Run Tests │────▶│ Deploy Prod │ │ main │ │ + Lint │ │ (with approval)│ └─────────────┘ └─────────────┘ └─────────────────┘ ``` ## Workflow File Located at `.github/workflows/ci.yml` ### Jobs | Job | Trigger | Description | |-----|---------|-------------| | **tests** | All pushes/PRs | Run Pest tests + Pint lint | | **deploy-staging** | Push to `develop` | Auto-deploy to staging | | **deploy-production** | Push to `main` | Deploy with approval | ## Setup ### 1. Create GitHub Secrets Go to: Repository → Settings → Secrets and variables → Actions **For Staging:** ``` STAGING_HOST - Staging server IP/hostname STAGING_USER - SSH username STAGING_SSH_KEY - Private SSH key (full content) ``` **For Production:** ``` PRODUCTION_HOST - Production server IP/hostname PRODUCTION_USER - SSH username PRODUCTION_SSH_KEY - Private SSH key (full content) ``` ### 2. Generate SSH Key ```bash # Generate a new key pair ssh-keygen -t ed25519 -C "github-actions" -f github-actions-key # Add public key to server cat github-actions-key.pub >> ~/.ssh/authorized_keys # Copy private key to GitHub secret cat github-actions-key ``` ### 3. Configure Server On your server, ensure: ```bash # Create deployment directory sudo mkdir -p /var/www/staging sudo mkdir -p /var/www/production sudo chown -R $USER:www-data /var/www/staging /var/www/production # Clone repository cd /var/www/staging git clone git@github.com:your-repo.git . # Install dependencies composer install npm install && npm run build # Configure environment cp .env.example .env php artisan key:generate # Edit .env with production values # Set permissions chmod -R 775 storage bootstrap/cache ``` ### 4. Environment Protection (Optional) For production deployments with approval: 1. Go to Repository → Settings → Environments 2. Create `production` environment 3. Enable "Required reviewers" 4. Add team members who can approve ## Workflow Customization ### Add More Tests ```yaml - name: Run security audit working-directory: ./src run: composer audit - name: Run static analysis working-directory: ./src run: ./vendor/bin/phpstan analyse ``` ### Add Notifications ```yaml - name: Notify Slack uses: 8398a7/action-slack@v3 with: status: ${{ job.status }} fields: repo,commit,author,action env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} if: always() ``` ### Add Database Migrations Check ```yaml - name: Check pending migrations working-directory: ./src run: | PENDING=$(php artisan migrate:status | grep -c "No" || true) if [ "$PENDING" -gt 0 ]; then echo "::warning::There are pending migrations" fi ``` ## Manual Deployment If you prefer manual deployments: ```bash # On your server cd /var/www/production # Enable maintenance mode php artisan down # Pull latest code git pull origin main # Install dependencies composer install --no-dev --optimize-autoloader # Run migrations php artisan migrate --force # Clear and cache php artisan config:cache php artisan route:cache php artisan view:cache # Restart queue workers php artisan queue:restart # Disable maintenance mode php artisan up ``` ## Deployment Script Create `deploy/scripts/deploy.sh` for reusable deployment: ```bash #!/bin/bash set -e echo "🚀 Starting deployment..." # Enter maintenance mode php artisan down # Pull latest changes git pull origin main # Install dependencies composer install --no-dev --optimize-autoloader # Run migrations php artisan migrate --force # Build assets npm install npm run build # Clear caches php artisan config:cache php artisan route:cache php artisan view:cache php artisan event:cache # Restart queue php artisan queue:restart # Exit maintenance mode php artisan up echo "✅ Deployment complete!" ``` ## Rollback If deployment fails: ```bash # Revert to previous commit git reset --hard HEAD~1 # Or specific commit git reset --hard # Re-run caching php artisan config:cache php artisan route:cache # Restart services php artisan queue:restart php artisan up ``` ## Testing Locally Test the CI workflow locally with [act](https://github.com/nektos/act): ```bash # Install act brew install act # macOS # or curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash # Run tests job act -j tests # Run with secrets act -j tests --secret-file .secrets ``` ## Troubleshooting ### SSH Connection Failed - Verify SSH key is correct (no extra newlines) - Check server firewall allows port 22 - Ensure key is added to `~/.ssh/authorized_keys` ### Permission Denied - Check file ownership: `chown -R www-data:www-data /var/www` - Check directory permissions: `chmod -R 775 storage bootstrap/cache` ### Composer/NPM Fails - Ensure sufficient memory on server - Check PHP extensions are installed - Verify Node.js version matches requirements