GitHub Actions에 PHP 품질 게이트 만들기 — 문법·테스트·의존성 검사를 실패 조건으로 연결

조회수 42

CI를 붙였다는 사실보다 중요한 것은 어떤 오류가 발생하면 병합과 배포를 멈출지 명확히 정하는 일이다. PHP 프로젝트에서는 의존성 정의, 문법, 단위 테스트를 서로 다른 단계로 분리하면 실패 지점을 빠르게 찾을 수 있다.

먼저 정할 품질 게이트

최소 게이트는 composer validate, PHP 문법 검사, 단위 테스트 세 가지로 잡는다. 어느 하나라도 0이 아닌 종료 코드를 반환하면 job이 실패하므로, 뒤에 배포 job을 연결하더라도 성공한 코드만 다음 단계로 넘어간다.

  • 의존성 검사: composer.json과 잠금 파일의 일관성 확인
  • 문법 검사: 저장소의 PHP 파일을 php -l로 확인
  • 회귀 검사: PHPUnit 테스트 실행
  • 버전 검사: 운영 후보인 PHP 8.2와 8.3을 matrix로 각각 실행

PHP 버전별 workflow 작성하기

다음 예시는 읽기 권한만 부여하고, 두 PHP 버전에서 같은 검사를 수행한다. 프로젝트의 PHP 지원 범위와 PHPUnit 실행 경로는 실제 composer.json에 맞게 조정한다.

name: php-quality-gate

on:
  pull_request:
  push:
    branches: [main]

permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        php: ['8.2', '8.3']
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}
          coverage: none
      - run: composer validate --strict
      - run: composer install --no-interaction --prefer-dist
      - name: PHP syntax
        run: find . -type f -name '*.php' -not -path './vendor/*' -print0 | xargs -0 -n1 php -l
      - name: Unit tests
        run: vendor/bin/phpunit

외부 action은 태그보다 커밋 SHA로 고정하면 공급망 변경 위험을 더 줄일 수 있다. 캐시를 추가할 때도 먼저 캐시 없이 성공하는 기준 workflow를 확정한 뒤 최적화하는 편이 문제를 분리하기 쉽다.

성공 후 실패를 주입해 차단 확인하기

  1. 테스트 브랜치에서 workflow를 실행하고 PHP 8.2와 8.3 job이 모두 성공하는지 확인한다.
  2. 성공 화면을 캡처해 images/php-matrix-success.png로 저장한다.
  3. 테스트 브랜치에만 실패하는 assertion을 하나 추가한 뒤 다시 실행한다.
  4. 단위 테스트 단계에서 job이 멈춘 화면을 images/quality-gate-failure.png로 저장한다.
  5. 의도적 실패 코드를 되돌리고 최종 workflow가 다시 성공하는지 확인한다.
PHP 8.2와 8.3 matrix 작업 및 모든 품질 검사가 성공한 GitHub Actions 화면
직접 검증 후 PHP 버전별 성공 결과로 교체할 이미지
의도적으로 실패시킨 테스트 때문에 배포 전 품질 게이트가 중단된 GitHub Actions 화면
직접 실패를 주입해 품질 게이트가 차단되는지 확인할 이미지

CI 결과를 병합 게이트로 연결할 때

로컬에서는 성공하지만 Actions에서 실패한다

PHP 버전, 확장 모듈, 환경 변수와 잠금 파일이 다른지 먼저 비교한다. 테스트가 외부 DB나 시간대에 의존한다면 서비스 컨테이너와 timezone을 workflow에 명시해야 재현성이 높아진다.

한 버전의 실패가 다른 matrix 결과를 가린다

fail-fast: false를 사용하면 한 버전이 실패해도 나머지 버전의 결과를 수집할 수 있다. 호환성 문제인지 공통 코드 문제인지 구분하기 쉬워진다.

검사는 있는데 병합을 막지 못한다

workflow 성공만 확인하지 말고 저장소의 branch protection 또는 ruleset에서 해당 check를 필수 상태 검사로 지정해야 한다.

병합 전 점검 체크리스트

  • 지원하는 모든 PHP matrix job이 실행되는가?
  • 의존성, 문법과 단위 테스트가 각각 실패 조건인가?
  • 의도적인 테스트 실패가 배포 흐름을 중단하는가?
  • 저장소 ruleset에서 해당 check를 필수로 지정했는가?

참고 문서

한 줄 요약

PHP CI는 의존성·문법·테스트를 버전별 필수 검사로 만들고, 실제 실패를 주입해 병합 전에 확실히 차단되는지 확인해야 한다.

댓글 0

  • 첫 번째 댓글을 남겨보세요.