Back to Blog List
Setting Up CI/CD for Laravel with GitHub Actions
April 10, 2024
Laravel
CI/CD
GitHub Actions
Automation
DevOps

Continuous Integration (CI) and Continuous Deployment (CD) are essential practices for modern software development. Automating your testing and deployment pipelines saves time, reduces errors, and allows for faster releases. GitHub Actions provides a powerful and integrated way to set up CI/CD directly within your GitHub repository.

What is GitHub Actions?

GitHub Actions allows you to automate workflows based on events in your repository, such as pushes, pull requests, or scheduled times. Workflows are defined in YAML files stored in the .github/workflows directory.

Creating a Basic CI Workflow for Laravel

A typical CI workflow for a Laravel application involves:

  • Checking out the code.
  • Setting up PHP and Composer.
  • Installing dependencies.
  • Setting up the environment (.env file).
  • Running tests (e.g., PHPUnit).
  • Optionally, running code style checks (e.g., PHP CS Fixer or Pint).

Here's an example workflow file (.github/workflows/ci.yml):


name: Laravel CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: '8.2' # Adjust to your project's PHP version
        extensions: mbstring, xml, ctype, json, bcmath, pdo, pdo_mysql # Add necessary extensions
        coverage: none # Set to 'xdebug' or 'pcov' if you need coverage reports

    - name: Copy .env
      run: php -r "file_exists('.env') || copy('.env.example', '.env');"

    - name: Install Composer Dependencies
      run: composer install --no-progress --prefer-dist --optimize-autoloader

    - name: Generate key
      run: php artisan key:generate

    # Optional: Setup database (if tests require it)
    # - name: Setup MySQL Database
    #   uses: mirromutth/mysql-action@v1.1
    #   with:
    #     mysql database: 'laravel_test'
    #     mysql root password: 'password'

    # Optional: Run Migrations (if tests require it)
    # env:
    #   DB_CONNECTION: mysql
    #   DB_DATABASE: laravel_test
    #   DB_USERNAME: root
    #   DB_PASSWORD: password
    #   DB_HOST: 127.0.0.1
    #   DB_PORT: 3306 # Default port from mysql-action
    # run: php artisan migrate --seed # Or just migrate

    - name: Execute tests (PHPUnit)
      run: vendor/bin/phpunit
      

Adding Deployment (CD)

Deployment strategies vary greatly depending on your hosting environment (e.g., shared hosting, VPS, serverless, PaaS like Heroku or Vapor). A common approach for VPS deployment involves SSHing into the server and running deployment scripts.

You can add a deployment job that runs only on pushes to the main branch:


# ... (inside ci.yml, add another job)

  deploy:
    needs: test # Ensure tests pass before deploying
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' && github.event_name == 'push' # Only run on push to main

    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    # Add steps for building assets if needed (e.g., npm run build)

    - name: Deploy to server
      uses: appleboy/ssh-action@master
      with:
        host: process.env.SSH_HOST # Use secrets for sensitive data
        username: process.env.SSH_USERNAME
        key: process.env.SSH_PRIVATE_KEY
        port: process.env.SSH_PORT || 22
        script: |
          cd /path/to/your/project
          git pull origin main
          composer install --no-dev --optimize-autoloader
          php artisan migrate --force # Use --force in production
          php artisan config:cache
          php artisan route:cache
          php artisan view:cache
          # Add other deployment commands (e.g., restart queue workers)
      

Important: Store sensitive information like SSH keys, hostnames, and usernames as GitHub Secrets in your repository settings.

Conclusion

GitHub Actions provides a seamless way to integrate CI/CD into your Laravel development workflow. By automating testing and deployment, you ensure code quality, reduce manual errors, and accelerate your release cycle. Start with a basic testing workflow and gradually add deployment steps tailored to your hosting environment.