generated from theradcoza/Laravel-Docker-Dev-Template
264 lines
5.7 KiB
Markdown
264 lines
5.7 KiB
Markdown
# 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 <commit-hash>
|
|
|
|
# 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
|