Cách Viết 1 Package PHP Thuần Có Tích Hợp Semantic Release

CI/CD cho PHP 8.4 với PHPStan, PHPUnit và Semantic Release trên GitLab


Mục tiêu

Xây dựng một dự án PHP 8.4 thuần (không sử dụng framework) với các thành phần:

  • CI/CD trên GitLab
  • Kiểm tra chất lượng code bằng PHPStan
  • Unit Test bằng PHPUnit
  • Tự động tạo version và release bằng Semantic Release
  • Tự động sinh CHANGELOG.md
  • Tự động tạo GitLab Release và Git Tag

1. Cấu trúc dự án

project/
├── src/
├── tests/
├── composer.json
├── phpstan.neon
├── phpunit.xml
├── .gitlab-ci.yml
├── .releaserc.json
└── package.json

2. Cài đặt Composer

composer.json

{
"name": "yourname/project",
"require": {
"php": "^8.4"
},
"require-dev": {
"phpunit/phpunit": "^11.0",
"phpstan/phpstan": "^1.11"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"test": "phpunit",
"stan": "phpstan analyse"
}
}

Cài đặt dependencies:

composer install

3. Cấu hình PHPStan

phpstan.neon

parameters:
level: 6
paths:
- src
- tests
tmpDir: var/cache/phpstan

Giải thích

Cấu hìnhMô tả
levelMức độ kiểm tra code
pathsCác thư mục cần phân tích
tmpDirThư mục cache

Khuyến nghị: Khi codebase đã ổn định có thể nâng level lên 8 hoặc 9.


4. Cấu hình PHPUnit

phpunit.xml

<?xml version="1.0" encoding="UTF-8"?>

<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.0/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true">

<testsuites>
<testsuite name="Unit">
<directory>tests</directory>
</testsuite>
</testsuites>

<source>
<include>
<directory>src</directory>
</include>
</source>

<coverage>
<report>
<clover outputFile="coverage.xml"/>
</report>
</coverage>

</phpunit>

5. Cấu hình GitLab CI/CD

.gitlab-ci.yml

Pipeline gồm 3 stage:

install
↓
test
↓
release

Cấu hình đầy đủ

stages:
- install
- test
- release

image: php:8.4-cli

variables:
COMPOSER_CACHE_DIR: "$CI_PROJECT_DIR/.composer-cache"

cache:
key: ${CI_COMMIT_REF_SLUG}-composer
paths:
- .composer-cache/
- vendor/

before_script:
- apt-get update -yqq
- apt-get install -yqq git unzip libzip-dev
- docker-php-ext-install zip
- curl -sS https://getcomposer.org/installer | php --
--install-dir=/usr/local/bin --filename=composer

install:
stage: install
script:
- composer install --prefer-dist --no-progress

phpstan:
stage: test
script:
- composer install --prefer-dist --no-progress
- vendor/bin/phpstan analyse --no-progress
--error-format=gitlab > phpstan-report.json || vendor/bin/phpstan analyse --no-progress

artifacts:
reports:
codequality: phpstan-report.json
when: always

phpunit:
stage: test
script:
- composer install --prefer-dist --no-progress
- vendor/bin/phpunit --coverage-text --colors=never

coverage: '/^\s*Lines:\s*\d+.\d+\%/'

artifacts:
reports:
junit: coverage.xml
when: always

semantic-release:
stage: release

image: node:20-alpine

rules:
- if: '$CI_COMMIT_BRANCH == "main"'

script:
- npm install --no-save semantic-release
- npm install --no-save @semantic-release/gitlab
- npm install --no-save @semantic-release/git
- npm install --no-save @semantic-release/changelog
- npm install --no-save @semantic-release/commit-analyzer
- npm install --no-save @semantic-release/release-notes-generator

- npx semantic-release

6. Cấu hình Semantic Release

.releaserc.json

{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",

[
"@semantic-release/changelog",
{
"changelogFile": "CHANGELOG.md"
}
],

[
"@semantic-release/gitlab",
{
"gitlabUrl": "https://gitlab.com"
}
],

[
"@semantic-release/git",
{
"assets": [
"CHANGELOG.md"
],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
]
]
}

Cài thêm plugin:

npm install --no-save @semantic-release/git

7. Cấu hình GitLab Variables

Vào:

Settings
└── CI/CD
└── Variables

Tạo biến:

VariableGiá trịMục đích
GITLAB_TOKENPersonal Access Token hoặc Project Access TokenCho phép Semantic Release tạo tag, release và push commit
CI_REGISTRYCó sẵnSử dụng nếu cần build/push Docker image

Quyền cần cấp cho GITLAB_TOKEN

api
write_repository

8. Quy tắc Commit Message

Semantic Release hoạt động dựa trên chuẩn Conventional Commits.

Patch Release (x.x.1)

fix: sửa lỗi validate email
fix: xử lý null pointer

Minor Release (x.1.0)

feat: thêm API đăng nhập
feat: thêm export excel

Major Release (1.0.0 → 2.0.0)

feat!: thay đổi cấu trúc API

BREAKING CHANGE: endpoint response changed

Không tạo Release

docs: cập nhật tài liệu
test: bổ sung unit test
chore: cập nhật dependencies
style: format code

9. Kiểm tra Local trước khi Push

Cài dependencies

composer install

Chạy PHPStan

vendor/bin/phpstan analyse

Chạy PHPUnit

vendor/bin/phpunit

Kiểm tra Semantic Release

npx semantic-release --dry-run

Lệnh này giúp xem trước version sẽ được tạo mà không thực hiện release thật.


10. Luồng hoạt động sau khi Push Code

Developer Push Code
↓
GitLab Pipeline
↓
Install Dependencies
↓
PHPStan Analysis
↓
PHPUnit Testing
↓
Semantic Release
↓
Create Git Tag
↓
Generate CHANGELOG
↓
Create GitLab Release

11. Các lưu ý quan trọng

1. PHPStan Level

level: 6

Đây là mức kiểm tra trung bình.

Khuyến nghị:

LevelMức độ
6Trung bình
8Nghiêm ngặt
9Rất nghiêm ngặt

2. Release chỉ chạy trên branch main

rules:
- if: '$CI_COMMIT_BRANCH == "main"'

Điều này giúp tránh việc tạo release từ các branch feature hoặc develop.


3. Lỗi Permission Denied

Nếu gặp lỗi:

permission denied
403 forbidden

Hãy kiểm tra:

  • GITLAB_TOKEN tồn tại
  • Token chưa hết hạn
  • Có quyền api
  • Có quyền write_repository

4. Tối ưu Pipeline

Có thể cache thêm:

cache:
paths:
- vendor/
- node_modules/

để giảm thời gian chạy pipeline.


Kết quả đạt được

Sau khi hoàn thành cấu hình:

✅ PHPStan chạy tự động trên GitLab
✅ PHPUnit chạy tự động trên GitLab
✅ Pipeline chặn merge nếu test thất bại
✅ Tự động tăng version theo Conventional Commits
✅ Tự động tạo Git Tag
✅ Tự động sinh CHANGELOG.md
✅ Tự động tạo GitLab Release
✅ Hỗ trợ hoàn toàn cho PHP 8.4 và GitLab CI/CD.

Post a Comment

Previous Post Next Post