本文目录导读:

我来详细介绍PHP自动化语义发布的实现方法:
语义化版本(SemVer)基础
// 语义化版本格式:MAJOR.MINOR.PATCH // MAJOR: 不兼容的API修改 // MINOR: 向后兼容的功能性新增 // PATCH: 向后兼容的问题修正
自动化版本管理工具
1 使用 semantic-release
// package.json (在PHP项目中使用)
{
"scripts": {
"semantic-release": "semantic-release"
},
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/git"
]
}
2 PHP专用工具:Conventional Commits
{
"require-dev": {
"symplify/monorepo-builder": "^10.0",
"semver/semver": "^3.0"
}
}
实现自动化发布脚本
1 基础发布脚本
<?php
// publish.php
class SemanticPublisher
{
private $versionFile;
private $changelogFile;
public function __construct($versionFile = 'VERSION', $changelogFile = 'CHANGELOG.md')
{
$this->versionFile = $versionFile;
$this->changelogFile = $changelogFile;
}
public function publish()
{
// 获取当前版本
$currentVersion = $this->getCurrentVersion();
// 分析提交信息
$newVersion = $this->analyzeCommits($currentVersion);
// 更新版本号
$this->updateVersion($newVersion);
// 生成变更日志
$this->generateChangelog($newVersion);
// 创建Git标签
$this->createGitTag($newVersion);
echo "Published version: {$newVersion}\n";
}
private function getCurrentVersion()
{
if (file_exists($this->versionFile)) {
return trim(file_get_contents($this->versionFile));
}
return '0.0.0';
}
private function analyzeCommits($currentVersion)
{
// 获取最新提交
$commits = $this->getGitLog();
$major = $minor = $patch = 0;
foreach ($commits as $commit) {
if (preg_match('/^BREAKING CHANGE:/', $commit)) {
$major++;
} elseif (preg_match('/^feat\(/', $commit)) {
$minor++;
} elseif (preg_match('/^fix\(/', $commit)) {
$patch++;
}
}
list($curMajor, $curMinor, $curPatch) = explode('.', $currentVersion);
return ($curMajor + $major) . '.' .
($curMinor + $minor) . '.' .
($curPatch + $patch);
}
private function getGitLog($from = null, $to = 'HEAD')
{
$cmd = "git log --oneline";
if ($from) {
$cmd .= " $from..$to";
}
return explode("\n", shell_exec($cmd));
}
private function updateVersion($newVersion)
{
file_put_contents($this->versionFile, $newVersion);
// 更新composer.json版本
$composer = json_decode(file_get_contents('composer.json'), true);
$composer['version'] = $newVersion;
file_put_contents('composer.json', json_encode($composer, JSON_PRETTY_PRINT));
}
private function generateChangelog($newVersion)
{
$changelog = "# Changelog\n\n";
$changelog .= "## {$newVersion} ({date('Y-m-d')})\n\n";
$commits = $this->getGitLog($this->getLastTag());
foreach ($commits as $commit) {
$changelog .= "- {$commit}\n";
}
file_put_contents($this->changelogFile, $changelog);
}
private function createGitTag($version)
{
$commands = [
"git add {$this->versionFile} {$this->changelogFile} composer.json",
"git commit -m \"chore: release {$version}\"",
"git tag v{$version}",
"git push origin main --tags"
];
foreach ($commands as $cmd) {
shell_exec($cmd);
}
}
private function getLastTag()
{
return trim(shell_exec('git describe --tags --abbrev=0'));
}
}
// 执行发布
$publisher = new SemanticPublisher();
$publisher->publish();
2 使用Composer脚本自动化
// composer.json
{
"scripts": {
"pre-release": "php scripts/pre-release.php",
"post-release": "php scripts/post-release.php",
"release": [
"@pre-release",
"php scripts/publish.php",
"@post-release"
]
}
}
提交信息规范化
1 创建Git提交钩子
<?php
// .git/hooks/commit-msg
class CommitValidator
{
public function validate($message)
{
$patterns = [
'feat' => '/^feat(\(.+\))?: /',
'fix' => '/^fix(\(.+\))?: /',
'docs' => '/^docs(\(.+\))?: /',
'style' => '/^style(\(.+\))?: /',
'refactor' => '/^refactor(\(.+\))?: /',
'test' => '/^test(\(.+\))?: /',
'chore' => '/^chore(\(.+\))?: /',
'BREAKING CHANGE' => '/^BREAKING CHANGE: /'
];
foreach ($patterns as $type => $pattern) {
if (preg_match($pattern, $message)) {
return true;
}
}
return false;
}
}
// 检查提交信息
$message = file_get_contents($argv[1]);
$validator = new CommitValidator();
if (!$validator->validate($message)) {
echo "Error: Commit message must follow conventional format\n";
echo "Example: feat(api): add new endpoint\n";
exit(1);
}
集成GitHub Actions
# .github/workflows/release.yml
name: Release
on:
push:
branches: [ main ]
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.0'
- name: Install dependencies
run: composer install
- name: Run Semantic Release
run: |
composer config version
php scripts/semantic-release.php
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ env.RELEASE_TAG }}
body_path: CHANGELOG.md
自动化发布辅助函数
<?php
// SemanticHelper.php
class SemanticHelper
{
// 分析提交类型
public function analyzeCommitType($commitMessage)
{
if (preg_match('/breaking change/i', $commitMessage)) {
return 'major';
}
if (preg_match('/^feat/i', $commitMessage)) {
return 'minor';
}
if (preg_match('/^fix|^bug|^hotfix/i', $commitMessage)) {
return 'patch';
}
return null;
}
// 生成变更日志
public function generateChangelog($commits, $version, $date)
{
$changelog = "\n## $version ($date)\n\n";
$categories = [
'Features' => 'feat',
'Bug Fixes' => 'fix',
'Documents' => 'docs',
'Refactoring' => 'refactor',
'Tests' => 'test',
'Style' => 'style',
'Chores' => 'chore'
];
foreach ($categories as $title => $prefix) {
$items = array_filter($commits, function($commit) use ($prefix) {
return strpos($commit, $prefix . ':') === 0 ||
strpos($commit, $prefix . '(') === 0;
});
if (!empty($items)) {
$changelog .= "### $title\n";
foreach ($items as $item) {
$changelog .= "- $item\n";
}
$changelog .= "\n";
}
}
return $changelog;
}
// 更新版本配置文件
public function updateVersionConfig($filePath, $newVersion)
{
$config = json_decode(file_get_contents($filePath), true);
$config['version'] = $newVersion;
file_put_contents($filePath, json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
}
// 推送通知
public function sendReleaseNotification($version, $changelog)
{
// 可以集成Slack、Telegram、邮件等通知
$message = "🚀 New Release v$version\n\n" . substr($changelog, 0, 500);
// 发送到Slack
if (getenv('SLACK_WEBHOOK')) {
file_get_contents(getenv('SLACK_WEBHOOK'), false, stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => json_encode(['text' => $message])
]
]));
}
}
}
使用PHP库简化流程
<?php
// 使用semver库
require 'vendor/autoload.php';
use SemVer\SemVer;
class AutomatedReleaser
{
public function determineNextVersion($currentVersion, $commits)
{
$semver = new SemVer($currentVersion);
$type = 'patch'; // 默认patch
foreach ($commits as $commit) {
if (preg_match('/breaking/i', $commit)) {
$type = 'major';
break;
} elseif (preg_match('/^feat/i', $commit)) {
$type = 'minor';
}
}
switch ($type) {
case 'major':
return $semver->major()->value;
case 'minor':
return $semver->minor()->value;
default:
return $semver->patch()->value;
}
}
}
完整示例配置文件
// semantic-release.php
<?php
return [
'project' => 'my-php-app',
'version_file' => 'VERSION',
'changelog_file' => 'CHANGELOG.md',
'git' => [
'branch' => 'main',
'commit_prefix' => 'chore: release'
],
'releases' => [
'auto_version' => true,
'generate_changelog' => true,
'create_git_tag' => true,
'push_to_remote' => true
],
'notifications' => [
'slack_webhook' => env('SLACK_WEBHOOK'),
'telegram_bot' => env('TELEGRAM_BOT'),
'email' => env('RELEASE_EMAIL')
],
'plugins' => [
'post_release' => [
'php scripts/deploy.php',
'composer dump-autoload --optimize'
]
]
];
通过这些工具和方法,你可以实现自动化的语义化发布流程,核心要点包括:规范化的提交信息、自动版本计算、变更日志生成、Git标签和发布管理。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播