CI/CD for PHP Projects: GitHub Actions – Complete Guide

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

CI/CD for PHP Projects: GitHub Actions



Modern web development is unthinkable without automation. Manually running tests, checking code style, and deploying to a server takes time and is prone to errors. The solution is CI/CD (Continuous Integration / Continuous Deployment). In this article, we will break down how to set up a full pipeline for PHP projects using GitHub Actions. You will learn how to automatically test code, check its quality, and deploy to a production server with every push to the repository.



What is CI/CD and why does a PHP developer need it?

Continuous Integration (CI) is a practice where every commit is automatically checked: unit tests, linters, and security checks are run. Continuous Deployment (CD) is the next step, where code that has successfully passed CI is automatically deployed to a server (staging or production).

This is especially relevant for PHP: the language is dynamic, and typing and syntax errors are often only detected at runtime. GitHub Actions allows you to set up a pipeline that:

  • Runs PHPUnit tests on different PHP versions (7.4, 8.0, 8.1, 8.2).
  • Checks code using PHP_CodeSniffer or PHPStan.
  • Performs deployment to a server via SSH or Docker.


Creating a workflow in GitHub Actions

To start, create a directory .github/workflows in the root of your PHP project. Inside it, create a file, for example ci.yml. This will be your pipeline.

Let's look at a basic example for CI. It will run on every push to the main branch or when a Pull Request is created.



name: PHP CI

on: push: branches: [ "main" ] pull_request: branches: [ "main" ]

jobs: build: runs-on: ubuntu-latest

strategy: matrix: php-versions: ['7.4', '8.0', '8.1', '8.2']

steps: - uses: actions/checkout@v3

- name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-versions }} tools: composer, phpunit

- name: Validate composer.json and composer.lock run: composer validate --strict

- name: Cache Composer packages id: composer-cache uses: actions/cache@v3 with: path: vendor key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} restore-keys: | ${{ runner.os }}-php-

- name: Install dependencies run: composer install --prefer-dist --no-progress

- name: Run PHPUnit tests run: phpunit --configuration phpunit.xml


Breakdown of key points:

  • Matrix strategy — allows running tests on multiple PHP versions simultaneously. This guarantees code compatibility.
  • shivammathur/setup-php — a popular action for setting up the PHP environment. It installs the required version, Composer, and PHPUnit.
  • Caching vendor — speeds up subsequent runs by not downloading dependencies again.
  • composer validate — checks the correctness of composer.json.


Adding static analysis and linting

Tests are good, but you can't do without code quality control. Let's add checks using PHPStan and PHP_CodeSniffer to the same workflow (or create a separate job).



    - name: Run PHPStan      run: vendor/bin/phpstan analyse src tests --level=max

- name: Run PHP_CodeSniffer run: vendor/bin/phpcs --standard=PSR2 src tests


These steps can be added after installing dependencies. PHPStan with the max level will find potential type errors, and PHP_CodeSniffer with the PSR-2 (or PSR-12) standard will ensure a uniform code style. If at least one step fails,

Blogs

Book Recommendations