feat: 支持生成发布文件

This commit is contained in:
augushong
2025-03-11 13:14:12 +08:00
parent f96fbd745a
commit 4602952a8a

View File

@@ -51,6 +51,8 @@ class VersionBase extends Command
// 指令配置
$this->setName('admin:version')
->addOption('generate-comment', null, Option::VALUE_NONE, '使用git命令生成说明文件')
->addOption('generate-release', null, Option::VALUE_NONE, '使用git命令生成发布说明文件')
->addOption('release-from-tag', null, Option::VALUE_OPTIONAL, '从指定版本开始生成说明文件')
->addOption('push-tag', null, Option::VALUE_NONE, '使用git命令生成tag并推送')
->setDescription('查看当前ulthon_admin的版本号');
}
@@ -85,6 +87,12 @@ class VersionBase extends Command
if ($is_generate_comment) {
$this->generateComment();
}
$is_generate_release = $input->hasOption('generate-release');
if ($is_generate_release) {
$fromTag = $input->getOption('release-from-tag');
$this->generateRelease($fromTag);
}
}
protected function pushTag()
@@ -202,4 +210,112 @@ class VersionBase extends Command
file_put_contents($tmp_comment_markdown_file, $comment);
$this->output->info('已生成版本更新Markdown' . $tmp_comment_markdown_file);
}
/**
* 生成发布说明文件
* 从指定版本开始生成发布说明.
* @param string|null $fromTag 起始版本号如果为空则使用最近的tag
* @return void
*/
public function generateRelease($fromTag = null)
{
$output = $this->output;
// 如果没有指定起始版本则获取最近的tag
if (empty($fromTag)) {
$fromTag = shell_exec('git describe --tags --abbrev=0');
$fromTag = trim($fromTag);
$output->info('未指定起始版本使用最近的tag: ' . $fromTag);
} else {
$output->info('从指定版本开始生成发布说明: ' . $fromTag);
}
// 获取当前版本
$currentVersion = static::VERSION;
if (!empty(static::PRODUCT_VERSION)) {
$currentVersion = static::PRODUCT_VERSION;
}
// 获取从指定tag到现在的所有提交包含提交哈希和提交日期
$commits = shell_exec("git log {$fromTag}..HEAD --pretty=format:\"%h %ad %s\" --date=short");
if (empty($commits)) {
$output->warning('从 ' . $fromTag . ' 到现在没有任何提交');
return;
}
$commits = explode("\n", $commits);
// 定义提交类型
$types = [
'feat' => '新功能',
'fix' => '修复',
'docs' => '文档',
'style' => '样式',
'refactor' => '重构',
'perf' => '性能优化',
'test' => '测试',
'build' => '构建',
'ci' => '持续集成',
'chore' => '其他',
'revert' => '回退',
];
// 按类型分组提交
$groupedCommits = [];
foreach ($commits as $commit) {
$matched = false;
// 提取提交哈希和日期
preg_match('/^([a-f0-9]+)\s(\d{4}-\d{2}-\d{2})\s(.+)$/', $commit, $matches);
if (count($matches) >= 4) {
$hash = $matches[1];
$date = $matches[2];
$message = $matches[3];
foreach ($types as $type => $desc) {
if (preg_match("/^{$type}:/i", $message)) {
$cleanMessage = preg_replace("/^{$type}:/i", '', $message);
$groupedCommits[$desc][] = [
'message' => trim($cleanMessage),
'hash' => $hash,
'date' => $date
];
$matched = true;
break;
}
}
// 如果没有匹配到任何类型,归类为"其他"
if (!$matched) {
$groupedCommits['其他'][] = [
'message' => trim($message),
'hash' => $hash,
'date' => $date
];
}
}
}
// 生成发布说明
$releaseTitle = "# {$currentVersion} 发布说明\n\n";
$releaseDate = '发布日期: ' . date('Y-m-d') . "\n\n";
$releaseContent = "本次发布包含了从 {$fromTag}{$currentVersion} 的所有更新。\n\n";
foreach ($groupedCommits as $type => $messages) {
$releaseContent .= "## {$type}\n\n";
foreach ($messages as $item) {
$releaseContent .= "- [{$item['date']}] {$item['message']} (#{$item['hash']})\n";
}
$releaseContent .= "\n";
}
$release = $releaseTitle . $releaseDate . $releaseContent;
// 生成发布说明文件
$releaseFile = PathTools::tempBuildPath("release_{$currentVersion}.md");
file_put_contents($releaseFile, $release);
$output->info('已生成发布说明文件: ' . $releaseFile);
}
}