A CI folyamat varázsa: automatikus tesztelés és kódellenőrzés egyben
Sziasztok kollégák! Ma arról szeretnék mesélni, hogyan változtathatja meg a mindennapjaitokat egy jól megtervezett CI folyamat. Ha valaha is elgondolkoztatok azon, hogy „biztonságosan” deployolhatnátok anélkül, hogy félnétek attól, hogy minden összeomlik, vagy hogy a kódminőség egyre csúszik lefelé, akkor pontosan erről fogunk beszélni.
Mi is az a CI/CD valójában?
CI a Continuous Integration rövidítése, ami folyamatos integrációt jelent. A lényege, hogy minél gyakrabban integráljuk a kódunkat egy közös tárhelyre (általában git), és minden egyes alkalommal lefuttatunk egy sor automatizált ellenőrzést. A CD pedig vagy Continuous Delivery (folyamatos kézbesítés) vagy Continuous Deployment (folyamatos telepítés) – az első esetben készen áll a deploy-ra, a másodikban pedig automatikusan élesedik.
A legnagyobb tévhit, hogy ez csak nagy projekteknek vagy cégeknek fontos. Valójában akár egy személyes projektben is óriási időt takaríthat meg, és megvéd a kínos buktatóktól.
Miért éri meg beállítani?
Képzeljétek el a következőt: épp siettek, mert holnap délutánra kellene egy új funkció. Összedobtok valamit, átfuttattok pár tesztet manuálisan, és felteszitek a kódot. Másnap reggelre a főnökök panaszokat kapnak, hogy valami eltört a regisztrációban. Kiderül, hogy a pull requestetekben volt egy elírás egy jQuery eseménykezelőben, ami csak bizonyos böngészőkben jelentkezett.
Egy CI folyamat ezt elkapja már a fejlesztés korai szakaszában. Automatikusan futtatja a teszteket, ellenőrzi a kódstílust, és akár alapszintű biztonsági vizsgálatot is végez.
Egy tipikus CI folyamat felépítése
Nézzünk egy konkrét példát egy PHP backenddel és jQuery/Bootstrap frontenddel rendelkező projekthez. A folyamatunk három fő lépésből áll:
1. Kódminőség ellenőrzés (linting, coding standards) 2. Automatikus tesztelés (unit tesztek, integrációs tesztek) 3. Építés és csomagolás (dependencia install, asset-ek buildelése)
Íme egy egyszerűsített .gitlab-ci.yml fájl (hasonló a GitHub Actionshoz is), ami bemutatja a folyamatot:
stages:
- lint
- test
- build
php-linting:
stage: lint
image: php:8.2
script:
- composer install
- vendor/bin/phpcs --standard=PSR12 src/
javascript-quality:
stage: lint
image: node:18
script:
- npm install
- npx eslint assets/js/
- npx stylelint "assets/scss/**/*.scss"
php-tests:
stage: test
image: php:8.2
services:
- mysql:8.0
variables:
MYSQL_ROOT_PASSWORD: password
script:
- composer install
- php vendor/bin/phpunit tests/ --coverage-text
frontend-tests:
stage: test
image: node:18
script:
- npm install
- npm test
build-assets:
stage: build
image: node:18
script:
- npm install
- npm run build
artifacts:
paths:
- public/build/Gyakori buktatók és tanulságok
A tapasztalatom szerint három fő hibát szoktak elkövetni a CI bevezetésekor:
1. Túl korán akarják a tökéletes folyamatot Ne akarjatok egyből 100%-os tesztlefedettséget és mindenféle komplex ellenőrzést. Kezdjetek egyszerűen: egy linting és pár alapvető teszt is óriási előrelépés.
2. Lokális és CI környezet eltérése A klasszikus: „Nálam működik!” Ha a tesztek máshogy futnak lokálisan és a CI szerveren, az általában környezeti változók, adatbázis eltérések vagy cache problémák miatt van. Docker segítheg ezen.
3. Túl lassú folyamat Ha egy CI futtatás 30 percig tart, senki sem fogja szeretni. Párhuzamosítsátok a feladatokat, és csak a szükséges lépéseket végezzétek. Például ne futtassátok újra az asset buildelést, ha csak backend kód változott.
Egy PHP példa a gyakorlatból
Nézzünk egy konkrét esetet, amikor a CI megment minket egy hülye hibától. Tegyük fel, hogy van egy User osztályunk:
<?php
class User {
private $email;
public function setEmail(string $email): void {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Érvénytelen email cím');
}
$this->email = $email;
}
public function getEmail(): string {
return $this->email;
}
}És hozzá egy egyszerű teszt:
<?php
use PHPUnit\Framework\TestCase;
class UserTest extends TestCase {
public function testValidEmailIsAccepted(): void {
$user = new User();
$user->setEmail('teszt@example.com');
$this->assertEquals('teszt@example.com', $user->getEmail());
}
public function testInvalidEmailThrowsException(): void {
$this->expectException(InvalidArgumentException::class);
$user = new User();
$user->setEmail('érvénytelen-email');
}
}Ha valaki megváltoztatja a setEmail metódust úgy, hogy ne ellenőrizze az email címet, a CI azonnal jelezni fogja, hogy a teszt elbukott.
Frontend rész: jQuery és Bootstrap világban
A frontend oldalon is hasonlóan fontosak az ellenőrzések. Például egy jQuery kódrészlet, ami könnyen elfelejtheti a hibakezelést:
// Rossz példa - nincs hibakezelés
$(document).ready(function() {
$('#userForm').submit(function(e) {
e.preventDefault();
$.ajax({
url: '/api/save-user',
method: 'POST',
data: $(this).serialize(),
success: function(response) {
$('#result').html('Sikeres mentés!');
}
// Hiányzik: error callback!
});
});
});
// Javított változat
$(document).ready(function() {
$('#userForm').submit(function(e) {
e.preventDefault();
var $form = $(this);
var $result = $('#result');
$.ajax({
url: '/api/save-user',
method: 'POST',
data: $form.serialize(),
success: function(response) {
$result.removeClass('alert-danger').addClass('alert-success')
.html('Sikeres mentés!').show();
},
error: function(xhr) {
$result.removeClass('alert-success').addClass('alert-danger')
.html('Hiba történt: ' + xhr.responseText).show();
}
});
});
});Egy jó CI folyamat tartalmazhat ESLint konfigurációt, ami figyelmeztet, ha hiányzik az error kezelés, vagy ha nem megfelelő a kódstílus.
React és Python: mikor érdemes bevonni?
React komponensek esetén különösen értékes a CI, mert a típusellenőrzés (TypeScript vagy PropTypes) és a komponens tesztek (Jest + React Testing Library) rengeteg hibát kiszűrhetnek. De ha a projektetek főleg PHP és jQuery/Bootstrap, ne kényszerítsétek be a Reactet csak divatból.
Pythonra általában akkor érdemes váltani a CI folyamatban, ha valamilyen specifikus scriptet írtok hozzá (pl. adatfeldolgozás, ML modell), vagy ha a projektetek backendje Pythonban íródott. PHP projektnél maradjatok a PHP-nél.
Összegzés
A CI folyamat nem varázslat, hanem egy stratégiai befektetés a kódminőségbe és a fejlesztők mentális egészségébe. Az első beállítás pár órát igénybe vehet, de hosszú távon rengeteget takarít meg a debuggingból, a „nálam működik” beszélgetésekből és az éjszakai deploy pánikból.
Ne azzal kezdjétek, hogy minden tökéletes legyen. Kezdjetek egy egyszerű lintinggel és egy-két alapteszttel, majd fokozatosan bővítsétek. Hamarosan észreveszitek, hogy mennyivel magabiztosabban tudtok változtatásokat eszközölni, és mennyivel kevesebb a „jaj, elrontottam valamit” érzés.
Végső soron a legjobb CI folyamat az, amit tényleg használtok, nem az, ami mindent ellenőriz, de annyira lassú, hogy mindenki kikerüli.