CI/CD for PHP Projects: GitHub Actions from A to Z

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why CI/CD is the New Standard for PHP Development

\n

Modern PHP development is unthinkable without automation. Manual deployment, running tests "by eye," and checking code at the last minute is a direct path to bugs in production. CI/CD (Continuous Integration / Continuous Deployment) solves these problems by integrating checks and code deployment directly into your workflow.

\n

GitHub Actions is a powerful and free tool for embedding CI/CD directly into your repository. In this article, we will break down how to set up a complete pipeline for a PHP project on Laravel or Symfony: from installing dependencies to deploying to a server. You will get ready-made configs and an understanding of each stage.

\n\n

1. GitHub Actions Basics: Workflow Structure for PHP

\n

A Workflow in GitHub Actions is an automated process defined in a YAML file in the .github/workflows/ folder. For a PHP project, a typical workflow includes:

\n
    \n
  • Triggers: push to the main branch, pull request.
  • \n
  • Runner: Ubuntu latest (PHP support).
  • \n
  • Steps: Checkout, PHP setup, Composer, tests, linters.
  • \n
\n

Let's look at a minimal ci.yml file:

\n
name: PHP CI\n\non:\n  push:\n    branches: [ main ]\n  pull_request:\n    branches: [ main ]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v3\n\n    - name: Setup PHP\n      uses: shivammathur/setup-php@v2\n      with:\n        php-version: '8.2'\n        extensions: mbstring, pdo_mysql, xml\n        coverage: xdebug\n\n    - name: Install Composer dependencies\n      run: composer install --no-progress --prefer-dist\n\n    - name: Run PHPUnit\n      run: vendor/bin/phpunit --testdox
\n

This workflow runs on every push. It checks that the code builds and tests pass. Note the shivammathur/setup-php action — it is the de facto standard for PHP.

\n\n

2. Advanced Configuration: Static Analysis, Linters, and Caching

\n

CI is not limited to just tests. To maintain code quality, add static analysis (PHPStan, Psalm) and style checking (PHP CS Fixer).

\n

2.1. Adding PHPStan and PHP CS Fixer

\n

Install them as dev dependencies:

\n
composer require --dev phpstan/phpstan friendsofphp/php-cs-fixer
\n

Add the steps to the workflow:

\n
    - name: Run PHPStan\n      run: vendor/bin/phpstan analyse --memory-limit=1G\n\n    - name: Check code style\n      run: vendor/bin/php-cs-fixer fix --dry-run --diff
\n

Tip: use --dry-run to only check files, not modify them. If the style is violated, the CI will fail, and the developer will fix it.

\n

2.2. Caching Composer Dependencies

\n

Each CI run downloads packages from scratch — this is slow. Enable caching:

\n
    - name: Cache Composer packages\n      id: composer-cache\n      uses: actions/cache@v3\n      with:\n        path: vendor\n        key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}\n        restore-keys: |\n          ${{ runner.os }}-php-\n\n    - name: Install dependencies\n      if: steps.composer-cache.outputs.cache-hit != 'true'\n      run: composer install --no-progress --prefer-dist
\n

Now subsequent runs will be 2-3 times faster.

\n\n

3. Testing with a Database and Docker Services

\n

Many PHP applications require MySQL, PostgreSQL, or Redis for tests. GitHub Actions allows you to run Service Containers.

\n

3.1. Example with MySQL and Laravel

\n

Suppose your project uses Laravel with MySQL. Add the service and configure .env:

\n
jobs:\n  test:\n    runs-on: ubuntu-latest\n    services:\n      mysql:\n        image: mysql:8.0\n        env:\n          MYSQL_ROOT_PASSWORD: root\n          MYSQ                

Blogs

Book Recommendations