PHP Academy · Lekcja

CI/CD z GitHub Actions

Automatycznie testuj i wdrażaj PHP przy każdym wypchnięciu zmian

Lekcja 4 z 413 kroki

CI/CD z GitHub Actions to bezpłatna lekcja PHP Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej PHP Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs PHP Academy zawiera 4 lekcji w sumie.

CI/CD dla PHP

Każdy push powinien być przetestowany, poddany lintowaniu i analizie statycznej, a po pomyślnym przejściu na głównej gałęzi także zbudowany do obrazu i wdrożony. GitHub Actions uruchamia ten pipeline na zarządzanych runnerach w reakcji na zdarzenia repozytorium.

Zbudujemy workflow, który uruchamia PHPUnit na rzeczywistej usłudze MySQL, buforuje Composera, uruchamia PHPStan, buduje obraz Docker i wykonuje wdrożenie.

Budowa workflow

Workflow znajduje się w pliku .github/workflows/*.yml. Zawiera wyzwalacze on:, co najmniej jedno zadanie jobs:, a każde zadanie ma kroki steps:. Zadania działają równolegle na izolowanych runnerach, chyba że połączy się je za pomocą needs:.

name: CI
on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

Akcja setup-php

shivammathur/setup-php to standardowy sposób instalowania na runnerze konkretnej wersji PHP wraz z wybranymi rozszerzeniami i narzędziami, takimi jak Composer czy PHPStan — znacznie szybszy niż budowanie obrazu tylko po to, by uruchomić testy.

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          extensions: pdo_mysql, intl, redis, zip
          coverage: pcov
          tools: composer:v2, phpstan

Buforowanie Composera

Ponowne pobieranie zależności przy każdym uruchomieniu marnuje całe minuty. Należy buforować katalog Composera, używając jako klucza skrótu pliku composer.lock, aby pamięć podręczna była unieważniana tylko wtedy, gdy zmienią się zależności.

      - name: Get Composer cache dir
        id: composer-cache
        run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT

      - uses: actions/cache@v4
        with:
          path: ${{ steps.composer-cache.outputs.dir }}
          key: composer-${{ hashFiles('**/composer.lock') }}
          restore-keys: composer-

      - run: composer install --prefer-dist --no-progress

Kontenery usług

Zadania mogą uruchamiać kontenery usług — rzeczywisty MySQL lub Redis, do którego runner może uzyskać dostęp przez 127.0.0.1. Należy dodać kontrolę zdrowia za pomocą options, aby kroki nie uruchamiały się przed gotowością bazy danych.

  test:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8.4
        env:
          MYSQL_DATABASE: app_test
          MYSQL_ROOT_PASSWORD: root
        ports: ['3306:3306']
        options: >-
          --health-cmd="mysqladmin ping -proot"
          --health-interval=5s --health-retries=10

Uruchamianie testów i pomiar pokrycia

Po zainstalowaniu zależności i uruchomieniu MySQL należy uruchomić PHPUnit. DSN testów należy skierować na 127.0.0.1:3306. Można wygenerować raport pokrycia i opcjonalnie nie zaliczyć budowania, jeśli wynik spadnie poniżej określonego progu.

      - name: Run PHPUnit
        env:
          DATABASE_URL: "mysql://root:root@127.0.0.1:3306/app_test"
        run: vendor/bin/phpunit --coverage-clover=coverage.xml

      - name: Static analysis
        run: phpstan analyse src --level=8 --no-progress

Budowanie w macierzy

Biblioteki powinny przechodzić testy na wielu wersjach PHP. strategy.matrix rozdziela zadanie na równoległe uruchomienia, po jednym dla każdej kombinacji, a ${{ matrix.php }} jest interpolowane w krokach.

  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        php: ['8.2', '8.3', '8.4']
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}

Obliczanie tagu obrazu

Wdrożenia wymagają unikalnego i możliwego do prześledzenia tagu obrazu. Konwencjonalnym wyborem jest SHA commita. Ten fragment pokazuje logikę wyznaczania tagu, którą można wyrazić w workflow — zamianę referencji i SHA na tag rejestru.

<?php
// Mirrors what the workflow computes for the image tag
$ref = 'refs/heads/main';
$sha = '9f41efadc0de1234567890abcdef0000deadbeef';

$branch = str_replace('refs/heads/', '', $ref);
$shortSha = substr($sha, 0, 7);
$tag = sprintf('registry.example.com/app:%s-%s', $branch, $shortSha);

echo $tag . PHP_EOL;          // registry.example.com/app:main-9f41efa
echo 'is_main: ' . ($branch === 'main' ? 'yes' : 'no') . PHP_EOL;
?>

Budowanie i wypychanie obrazu

Na głównej gałęzi należy zbudować obraz Docker za pomocą docker/build-push-action, wykorzystując BuildKit i pamięć podręczną GitHub Actions. Najpierw należy zalogować się do rejestru za pomocą tokenu przechowywanego jako sekret; danych uwierzytelniających nigdy nie wolno wpisywać bezpośrednio w kodzie.

  build:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v6
        with:
          push: true
          target: runtime
          tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Sekrety i OIDC

Dane uwierzytelniające należy przechowywać w sekretach repozytorium lub środowiska i odwoływać się do nich za pomocą ${{ secrets.NAME }} — w logach są maskowane. W przypadku wdrożeń do chmury preferowany jest mechanizm OIDC: runner otrzymuje krótkotrwały token z AWS/GCP przez permissions: id-token: write, dzięki czemu w repozytorium nie trzeba przechowywać długoterminowych kluczy.

  deploy:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      id-token: write     # enables OIDC
      contents: read
    steps:
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/deploy
          aws-region: eu-central-1

Krok wdrażania i środowiska

Wdrożenia na produkcję należy chronić za pomocą środowiska GitHub environment, opcjonalnie z wymaganymi osobami zatwierdzającymi. Następnie krok wdrażania uruchamia proces aktualizacji — aktualizuje wdrożenie Kubernetes, usługę ECS albo łączy się przez SSH, aby pobrać nowy obraz.

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: production       # can require manual approval
      url: https://app.example.com
    steps:
      - name: Roll out
        run: |
          kubectl set image deployment/app \
            app=ghcr.io/${{ github.repository }}:${{ github.sha }}
          kubectl rollout status deployment/app --timeout=120s

Szybkie sprawdzenie

Jaka jest główna zaleta bezpieczeństwa OIDC w porównaniu z przechowywanymi kluczami chmurowymi w Actions?

Podsumowanie

Zbudowano pipeline CI/CD dla PHP w GitHub Actions: wyzwalany przez push i PR, z setup-php oraz rozszerzeniami, buforowanym Composerem kluczowanym na podstawie pliku lockfile, kontenerem usługi MySQL z kontrolą zdrowia, PHPUnit i PHPStan, macierzą wersji, a następnie budowaniem i wypychaniem obrazu tylko z głównej gałęzi z pamięcią podręczną GHA oraz wdrożeniem uwierzytelnianym przez OIDC i chronionym środowiskiem.

Zasady: buforować na podstawie skrótów plików lockfile, kontrolować gotowość usług za pomocą healthchecków, tagować obrazy na podstawie SHA i preferować OIDC zamiast przechowywanych kluczy.

Bezpłatny start

Ucz się PHP dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
49
Lekcje
195

Często zadawane pytania

Czy lekcja „CI/CD z GitHub Actions” jest bezpłatna?

Tak — pełny tekst „CI/CD z GitHub Actions” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu PHP Academy, przejdź na CoddyKit PRO. Kurs PHP Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „CI/CD z GitHub Actions”?

Automatycznie testuj i wdrażaj PHP przy każdym wypchnięciu zmian Ćwiczysz PHP Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć PHP Academy?

Nie wymagamy żadnego doświadczenia. PHP Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „CI/CD z GitHub Actions”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji PHP Academy?

Tak. Każda lekcja PHP Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Konteneryzacja aplikacji PHP
  2. Kompilacje wieloetapowe i optymalizacja
  3. Docker Compose dla lokalnych stosów
  4. CI/CD z GitHub Actions
← Powrót do PHP Academy