🢂Integracja Laravel Artisan z procesami CI/CD

Dowiedz się, jak efektywnie wykorzystać polecenia Artisan w potokach ciągłej integracji i ciągłego wdrażania (CI/CD) dla aplikacji Laravel.

Integracja narzędzia Artisan z procesami CI/CD (Continuous Integration/Continuous Deployment) pozwala na automatyzację i usprawnienie procesu rozwoju, testowania i wdrażania aplikacji Laravel. W tym artykule omówimy, jak efektywnie wykorzystać polecenia Artisan w różnych etapach potoków CI/CD.

Podstawy CI/CD w Laravel

Ciągła integracja (CI) i ciągłe wdrażanie (CD) to praktyki DevOps, które umożliwiają częstsze i bardziej niezawodne wydania oprogramowania. Proces CI/CD zazwyczaj obejmuje:

  1. Pobieranie kodu - pobranie najnowszej wersji kodu z repozytorium
  2. Instalację zależności - instalacja wszystkich wymaganych pakietów
  3. Kompilację zasobów - kompilacja plików CSS, JavaScript itp.
  4. Uruchomienie testów - wykonanie testów automatycznych
  5. Statyczną analizę kodu - sprawdzenie jakości kodu
  6. Wdrożenie - skopiowanie aplikacji na serwer produkcyjny lub testowy

Artisan odgrywa kluczową rolę w wielu z tych etapów, zapewniając narzędzia do automatyzacji złożonych zadań w procesie CI/CD.

Konfiguracja środowiska CI/CD

Przed konfiguracją potoków CI/CD, należy przygotować odpowiednie pliki konfiguracyjne dla różnych środowisk (development, testing, staging, production). Artisan może pomóc w zarządzaniu tymi plikami.

# Generowanie pliku .env dla środowiska testowego
php artisan env:generate --env=testing

# Ustawienie klucza aplikacji dla środowiska CI
php artisan key:generate --env=ci

# Konfiguracja połączenia do bazy danych testowej
php artisan db:configure --database=sqlite --env=testing

W większości przypadków będziesz pracować z plikiem .env.testing lub .env.ci specjalnie dla środowiska CI/CD.

Etap budowania w CI/CD

Na etapie budowania (build) w procesie CI/CD, Artisan pomaga w przygotowaniu aplikacji:

# Instalacja zależności (zazwyczaj przez Composer, nie Artisan)
composer install --no-dev --optimize-autoloader

# Czyszczenie i regeneracja cache aplikacji
php artisan optimize:clear
php artisan optimize

# Kompilacja zasobów frontendu (jeśli używasz np. Mix/Vite)
php artisan mix:compile --production
# lub nowsza wersja
php artisan vite:build

# Publikowanie zasobów pakietów
php artisan vendor:publish --provider="Vendor\Package\ServiceProvider" --tag=public --force

# Linki symboliczne do przechowywania
php artisan storage:link

Uruchamianie testów w CI/CD

Artisan doskonale integruje się z procesem testowania w potokach CI/CD:

# Przygotowanie bazy danych testowej
php artisan migrate:fresh --env=testing --seed

# Uruchomienie wszystkich testów
php artisan test

# Uruchomienie testów równolegle dla szybszego wykonania
php artisan test --parallel

# Uruchomienie określonej grupy testów
php artisan test --testsuite=Feature

# Generowanie raportu pokrycia kodu
XDEBUG_MODE=coverage php artisan test --coverage --min=80

# Uruchamianie testów z generowaniem raportów JUnit (dla integracji z CI)
php artisan test --log-junit junit-report.xml

Statyczna analiza kodu

Laravel Artisan może być używany w połączeniu z narzędziami do statycznej analizy kodu:

# Sprawdzanie standardu kodowania
php artisan pint:test

# Analiza kodu z Laravel Enlightn
php artisan enlightn

# Sprawdzanie bezpieczeństwa aplikacji
php artisan security:check

# Walidacja plików migracji
php artisan migrate:status

Automatyzacja procesu wdrażania

W fazie wdrażania (deployment) w procesie CI/CD, Artisan pomaga w przygotowaniu aplikacji do uruchomienia w środowisku produkcyjnym:

# Przełączenie aplikacji w tryb konserwacji
php artisan down --retry=60

# Uruchomienie migracji bez interakcji
php artisan migrate --force

# Optymalizacja aplikacji dla środowiska produkcyjnego
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache

# Restart workerów kolejki
php artisan queue:restart

# Czyszczenie starych sesji
php artisan session:gc

# Przywrócenie aplikacji do normalnego działania
php artisan up

Przykładowe konfiguracje CI/CD

GitHub Actions

Poniżej znajduje się przykładowy plik konfiguracyjny dla GitHub Actions:

name: Laravel CI/CD

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

jobs:
  laravel-tests:
    runs-on: ubuntu-latest

    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ROOT_PASSWORD: password
          MYSQL_DATABASE: testing
        ports:
          - 3306:3306
        options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

    steps:
    - uses: shivammathur/setup-php@v2
      with:
        php-version: '8.2'
        extensions: mbstring, dom, fileinfo, mysql
        coverage: xdebug

    - uses: actions/checkout@v3

    - name: Copy ENV Laravel Configuration for CI
      run: cp .env.example .env.testing

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

    - name: Generate Application Key
      run: php artisan key:generate --env=testing

    - name: Set Directory Permissions
      run: chmod -R 777 storage bootstrap/cache

    - name: Create Database
      run: php artisan migrate:fresh --seed --env=testing

    - name: Execute Tests
      run: php artisan test --parallel

    - name: Static Analysis
      run: php artisan enlightn --ci

GitLab CI/CD

Poniżej znajduje się przykładowy plik .gitlab-ci.yml:

stages:
  - build
  - test
  - deploy

cache:
  paths:
    - vendor/
    - node_modules/

variables:
  MYSQL_DATABASE: homestead
  MYSQL_ROOT_PASSWORD: secret
  DB_HOST: mysql
  DB_USERNAME: root

build:
  stage: build
  script:
    - cp .env.example .env
    - composer install --prefer-dist --no-ansi --no-interaction --no-progress
    - php artisan key:generate
    - php artisan optimize:clear
    - npm install
    - npm run build
  artifacts:
    expire_in: 1 day
    paths:
      - vendor/
      - .env
      - public/build/

test:
  stage: test
  services:
    - mysql:8.0
  dependencies:
    - build
  script:
    - php artisan migrate:fresh --seed
    - php artisan test --parallel
    - php artisan route:list

deploy_staging:
  stage: deploy
  script:
    - php artisan down --retry=60
    - php artisan migrate --force
    - php artisan config:cache
    - php artisan route:cache
    - php artisan view:cache
    - php artisan queue:restart
    - php artisan up
  environment:
    name: staging
  only:
    - develop

Bitbucket Pipelines

Przykładowy plik bitbucket-pipelines.yml:

image: php:8.2

pipelines:
  default:
    - step:
        name: Build and Test
        caches:
          - composer
        services:
          - mysql
        script:
          - apt-get update && apt-get install -y unzip git libpq-dev libzip-dev
          - docker-php-ext-install pdo pdo_mysql zip
          - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
          - cp .env.example .env.testing
          - composer install --no-interaction --prefer-dist --optimize-autoloader
          - php artisan key:generate --env=testing
          - php artisan migrate:fresh --env=testing
          - php artisan test
        artifacts:
          - vendor/**
          - .env.testing
    - step:
        name: Deploy to Staging
        deployment: staging
        script:
          - php artisan down
          - php artisan migrate --force --env=staging
          - php artisan optimize --env=staging
          - php artisan queue:restart
          - php artisan up

definitions:
  services:
    mysql:
      image: mysql:8.0
      variables:
        MYSQL_DATABASE: 'homestead'
        MYSQL_ROOT_PASSWORD: 'secret'

Artisan i automatyzacja wdrożeń poprzez SSH

W wielu przypadkach wdrożenia są wykonywane przez SSH. Oto przykład skryptu wykorzystującego Artisan w takim scenariuszu:

#!/bin/bash
# deployment-script.sh

# Ustaw zmienne
APP_DIR="/var/www/myapp"
REPO="git@github.com:user/repo.git"
BRANCH="main"

# Zaktualizuj kod
cd $APP_DIR
git pull origin $BRANCH

# Włącz tryb konserwacji
php artisan down --retry=60

# Instalacja zależności
composer install --no-interaction --prefer-dist --optimize-autoloader --no-dev

# Aktualizacja bazy danych
php artisan migrate --force

# Wyczyszczenie i regeneracja cache
php artisan optimize:clear
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache

# Restart kolejek
php artisan queue:restart

# Wyłącz tryb konserwacji
php artisan up

echo "Deployment zakończony pomyślnie!"

Dobre praktyki używania Artisan w CI/CD

  1. Używaj flag --no-interaction i --force - Zapewniają one, że polecenia Artisan nie będą wymagać interakcji użytkownika.

  2. Twórz dedykowane polecenia dla CI/CD - Rozważ utworzenie własnych poleceń Artisan, które będą wykonywać złożone sekwencje zadań specyficzne dla twojego procesu CI/CD.

    php artisan make:command CiDeploy --command=ci:deploy
  3. Zawsze używaj flag środowiskowych - Określaj, w którym środowisku ma działać polecenie, aby uniknąć przypadkowego wykonania na niewłaściwym środowisku.

    php artisan migrate --env=testing
  4. Przechowuj skrypty CI/CD w repozytorium - Trzymaj skrypty wdrożeniowe w folderze, np. .deploy/scripts/, aby wszystkie kroki były udokumentowane i kontrolowane wersją.

  5. Używaj narzędzi do monitorowania - Korzystaj z Artisan do generowania raportów zdrowia, które mogą być monitorowane przez narzędzia CI/CD.

    php artisan health:check --format=json > health-report.json
  6. Automatyzuj testowanie - Wykorzystuj Artisan do automatyzacji testów w procesie CI/CD.

    php artisan test && php artisan dusk
  7. Używaj zmiennych środowiskowych - Przechowuj wrażliwe dane jako zmienne środowiskowe w systemie CI/CD zamiast w plikach konfiguracyjnych.

  8. Cachuj dane tylko wtedy, gdy to konieczne - Pamiętaj, że w środowisku CI/CD czasami lepiej jest nie cachować danych, aby zapewnić świeży stan aplikacji podczas testów.

    # W niektórych przypadkach lepiej nie używać cache podczas testów
    php artisan config:clear
    php artisan route:clear
  9. Twórz krótkie raporty dla statusu CI/CD - Rozważ implementację własnego polecenia Artisan do generowania podsumowań, które mogą być łatwo interpretowane przez systemy CI/CD.

    # Przykład własnego polecenia (wymaga implementacji)
    php artisan app:status --ci-mode
  10. Wdrażaj atomowo - Upewnij się, że proces wdrażania jest atomowy - albo zakończy się sukcesem, albo nie wprowadzi żadnych zmian.

Niestandardowe polecenia Artisan dla CI/CD

Aby jeszcze bardziej usprawnić proces CI/CD, możesz stworzyć dedykowane polecenia Artisan:

// app/Console/Commands/CiDeploy.php
namespace App\Console\Commands;

use Illuminate\Console\Command;

class CiDeploy extends Command
{
    protected $signature = 'ci:deploy {environment} {--skip-tests}';
    protected $description = 'Run deployment steps in CI/CD environment';

    public function handle()
    {
        $environment = $this->argument('environment');
        $skipTests = $this->option('skip-tests');

        $this->info("Deploying to {$environment} environment");

        // Przełącz aplikację w tryb konserwacji
        $this->call('down', [
            '--message' => 'Trwa wdrażanie nowej wersji.',
            '--retry' => 60,
        ]);

        // Pomiń testy, jeśli flaga jest ustawiona
        if (!$skipTests) {
            $this->info('Running tests...');
            $this->call('test');
        }

        // Migracje
        $this->info('Running migrations...');
        $this->call('migrate', [
            '--force' => true,
        ]);

        // Optymalizacja
        $this->info('Optimizing application...');
        $this->call('optimize');

        // Restart kolejek
        $this->info('Restarting queue workers...');
        $this->call('queue:restart');

        // Wyłącz tryb konserwacji
        $this->call('up');

        $this->info('Deployment complete!');

        return Command::SUCCESS;
    }
}

Takie polecenie możesz uruchomić w swoim potoku CI/CD:

php artisan ci:deploy production

Podsumowanie

Integracja Artisan z procesami CI/CD pozwala na znaczną automatyzację i standaryzację procesu rozwoju i wdrażania aplikacji Laravel. Dzięki odpowiedniemu wykorzystaniu poleceń Artisan w potokach CI/CD możesz zapewnić spójność, niezawodność i powtarzalność procesów, co przekłada się na wyższą jakość oprogramowania i szybsze wdrażanie nowych funkcji.