Files
bhoza-shift-manager/docs/ci-cd.md
2026-03-09 09:18:21 +00:00

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 ci
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