#
.SYNOPSIS
风七六平台版本管理工具 - 符合大厂标准的语义化版本自动生成系统
.DESCRIPTION
基于Git提交历史自动计算语义化版本号,支持多环境、多场景版本管理
遵循Conventional Commits规范,自动识别feat/fix/BREAKING CHANGE等提交类型
.NOTES
Author: FZX DevOps Team
Version: 2.0.0
Date: 2026-05-28
Requirements: PowerShell 7+, Git 2.30+
#>
param(
[Parameter(Mandatory=$false)]
[string]$Environment = "development",
[Parameter(Mandatory=$false)]
[string]$Branch = $null,
[Parameter(Mandatory=$false)]
[string]$BuildNumber = $null,
[Parameter(Mandatory=$false)]
[switch]$DryRun,
[Parameter(Mandatory=$false)]
[switch]$Quiet,
[Parameter(Mandatory=$false)]
[switch]$UpdatePom,
[Parameter(Mandatory=$false)]
[switch]$UpdateJson,
[Parameter(Mandatory=$false)]
[switch]$UpdateEnv,
[Parameter(Mandatory=$false)]
[string]$CustomTag = $null
)
# 配置常量
$VERSION_FILE = "VERSION"
$VERSION_JSON_FILE = "version.json"
$ENV_FILE = "env/.env.example"
$BOM_POM_FILE = "services/platform-bom/pom.xml"
$COMMIT_ANALYSIS_DEPTH = 20
$DEFAULT_INITIAL_VERSION = "1.0.0"
# 颜色输出
function Write-ColorOutput {
param(
[string]$Message,
[ConsoleColor]$Color = [ConsoleColor]::White
)
if (-not $Quiet) {
$originalColor = $Host.UI.RawUI.ForegroundColor
$Host.UI.RawUI.ForegroundColor = $Color
Write-Host $Message
$Host.UI.RawUI.ForegroundColor = $originalColor
}
}
# 获取Git信息
function Get-GitInfo {
try {
$currentBranch = git rev-parse --abbrev-ref HEAD 2>&1
if ($LASTEXITCODE -ne 0) {
throw "无法获取当前分支"
}
$commitHash = git rev-parse --short HEAD 2>&1
if ($LASTEXITCODE -ne 0) {
throw "无法获取提交哈希"
}
$commitCount = git rev-list --count HEAD 2>&1
if ($LASTEXITCODE -ne 0) {
throw "无法获取提交数量"
}
$isDirty = git status --porcelain 2>&1
$dirtyFlag = if ($isDirty) { "-dirty" } else { "" }
return @{
Branch = $currentBranch.Trim()
Commit = $commitHash.Trim()
CommitCount = $commitCount.Trim()
IsDirty = $dirtyFlag
}
} catch {
Write-ColorOutput "警告: Git命令执行失败 - $_" -Color Yellow
return @{
Branch = "unknown"
Commit = "unknown"
CommitCount = "0"
IsDirty = ""
}
}
}
# 分析Git提交历史
function Analyze-GitCommits {
param(
[int]$Depth = 20
)
$hasMajor = $false
$hasMinor = $false
$hasPatch = $false
$commits = @()
try {
$logOutput = git log --oneline -$Depth 2>&1
if ($LASTEXITCODE -eq 0) {
foreach ($line in $logOutput) {
if ($line) {
$commits += $line
if ($line -match "BREAKING[\s_-]CHANGE" -or $line -match "!:" ) {
$hasMajor = $true
}
elseif ($line -match "^\w+\s+feat(:|\()") {
$hasMinor = $true
}
elseif ($line -match "^\w+\s+(fix|perf|refactor)(:|\()") {
$hasPatch = $true
}
}
}
}
} catch {
Write-ColorOutput "警告: 无法分析Git提交历史" -Color Yellow
}
return @{
HasMajor = $hasMajor
HasMinor = $hasMinor
HasPatch = $hasPatch
Commits = $commits
}
}
# 解析版本号
function Parse-Version {
param(
[string]$VersionString
)
$cleanVersion = $VersionString -replace "^v", ""
$parts = $cleanVersion -split "\."
if ($parts.Length -ge 3) {
return @{
Major = [int]$parts[0]
Minor = [int]$parts[1]
Patch = [int]$parts[2]
}
}
return @{
Major = 1
Minor = 0
Patch = 0
}
}
# 格式化版本号
function Format-Version {
param(
[int]$Major,
[int]$Minor,
[int]$Patch,
[string]$Branch,
[string]$Commit,
[string]$BuildNumber,
[string]$Environment,
[string]$DirtyFlag
)
$baseVersion = "${Major}.${Minor}.${Patch}"
$qualifiedVersion = "v${baseVersion}"
# 添加环境后缀
if ($Environment -ne "production" -and $Environment -ne "prod") {
$qualifiedVersion += "-${Environment}"
}
# 添加分支信息(非main/master分支)
if ($Branch -and $Branch -notin @("main", "master", "develop")) {
$sanitizedBranch = $Branch -replace "/", "-" -replace "_", "-"
$qualifiedVersion += "-${sanitizedBranch}"
}
# 添加提交哈希
if ($Commit) {
$qualifiedVersion += "-${Commit}"
}
# 添加构建号
if ($BuildNumber) {
$qualifiedVersion += "-${BuildNumber}"
}
# 添加脏标记
if ($DirtyFlag) {
$qualifiedVersion += $DirtyFlag
}
return @{
Base = "v${baseVersion}"
Qualified = $qualifiedVersion
Major = $Major
Minor = $Minor
Patch = $Patch
}
}
# 更新VERSION文件
function Update-VersionFile {
param(
[string]$Version
)
if ($DryRun) {
Write-ColorOutput "[DRY RUN] 将会更新 ${VERSION_FILE}: BASE_VERSION=$Version" -Color Cyan
return
}
"BASE_VERSION=$Version" | Out-File $VERSION_FILE -Encoding utf8
Write-ColorOutput "已更新 ${VERSION_FILE}: BASE_VERSION=$Version" -Color Green
}
# 更新version.json文件
function Update-VersionJson {
param(
[hashtable]$VersionInfo,
[hashtable]$GitInfo
)
$jsonContent = @{
version = $VersionInfo.Qualified
baseVersion = $VersionInfo.Base
commit = $GitInfo.Commit
branch = $GitInfo.Branch
buildNumber = $GitInfo.CommitCount
commitCount = $GitInfo.CommitCount
buildTime = [DateTime]::UtcNow.ToString("o")
generatedAt = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
environment = $Environment
}
if ($DryRun) {
Write-ColorOutput "[DRY RUN] 将会更新 $VERSION_JSON_FILE" -Color Cyan
Write-ColorOutput ($jsonContent | ConvertTo-Json) -Color Gray
return
}
$jsonContent | ConvertTo-Json | Out-File $VERSION_JSON_FILE -Encoding utf8
Write-ColorOutput "已更新 $VERSION_JSON_FILE" -Color Green
}
# 更新BOM pom.xml版本
function Update-BomPom {
param(
[string]$Version
)
if (-not (Test-Path $BOM_POM_FILE)) {
Write-ColorOutput "警告: $BOM_POM_FILE 不存在" -Color Yellow
return
}
$cleanVersion = $Version -replace "^v", ""
$content = Get-Content $BOM_POM_FILE -Raw
if ($content -match '([^<]+)\s*pom') {
$oldVersion = $matches[1]
$newContent = $content -replace "$oldVersion", "$cleanVersion"
if ($DryRun) {
Write-ColorOutput "[DRY RUN] 将会更新 ${BOM_POM_FILE}: $oldVersion -> $cleanVersion" -Color Cyan
return
}
$newContent | Out-File $BOM_POM_FILE -Encoding utf8
Write-ColorOutput "已更新 ${BOM_POM_FILE}: $oldVersion -> $cleanVersion" -Color Green
}
}
# 更新环境变量文件
function Update-EnvFile {
param(
[string]$Version
)
if (-not (Test-Path $ENV_FILE)) {
Write-ColorOutput "警告: $ENV_FILE 不存在" -Color Yellow
return
}
$content = Get-Content $ENV_FILE -Raw
$newContent = $content -replace "APP_VERSION=.*", "APP_VERSION=$Version"
if ($content -eq $newContent) {
$newContent = $content + "`nAPP_VERSION=$Version"
}
if ($DryRun) {
Write-ColorOutput "[DRY RUN] 将会更新 ${ENV_FILE}: APP_VERSION=$Version" -Color Cyan
return
}
$newContent | Out-File $ENV_FILE -Encoding utf8
Write-ColorOutput "已更新 ${ENV_FILE}: APP_VERSION=$Version" -Color Green
}
# 主执行流程
function Main {
Set-Location $PSScriptRoot/..
Write-ColorOutput "========================================" -Color Cyan
Write-ColorOutput " 风七六平台版本管理工具 v2.0.0" -Color Cyan
Write-ColorOutput "========================================" -Color Cyan
# 获取Git信息
Write-ColorOutput "`n[1/4] 获取Git仓库信息..." -Color White
$gitInfo = Get-GitInfo
Write-ColorOutput " 分支: $($gitInfo.Branch)" -Color Gray
Write-ColorOutput " 提交: $($gitInfo.Commit)" -Color Gray
Write-ColorOutput " 提交数: $($gitInfo.CommitCount)" -Color Gray
# 分析提交历史
Write-ColorOutput "`n[2/4] 分析最近 $COMMIT_ANALYSIS_DEPTH 次提交..." -Color White
$commitAnalysis = Analyze-GitCommits -Depth $COMMIT_ANALYSIS_DEPTH
Write-ColorOutput " 包含重大变更: $($commitAnalysis.HasMajor)" -Color Gray
Write-ColorOutput " 包含新功能: $($commitAnalysis.HasMinor)" -Color Gray
Write-ColorOutput " 包含修复: $($commitAnalysis.HasPatch)" -Color Gray
# 读取当前版本
Write-ColorOutput "`n[3/4] 读取当前版本..." -Color White
$currentVersion = $DEFAULT_INITIAL_VERSION
if (Test-Path $VERSION_FILE) {
$content = Get-Content $VERSION_FILE -Raw
if ($content -match "BASE_VERSION=(.+)") {
$currentVersion = $matches[1].Trim()
}
}
Write-ColorOutput " 当前版本: v$currentVersion" -Color Gray
# 解析并计算新版本
$parsedVersion = Parse-Version $currentVersion
$major = $parsedVersion.Major
$minor = $parsedVersion.Minor
$patch = $parsedVersion.Patch
Write-ColorOutput "`n[4/4] 计算新版本..." -Color White
if ($commitAnalysis.HasMajor) {
$major += 1
$minor = 0
$patch = 0
Write-ColorOutput " BREAKING CHANGE 检测到 - 升级 MAJOR 版本" -Color Magenta
}
elseif ($commitAnalysis.HasMinor) {
$minor += 1
$patch = 0
Write-ColorOutput " feat 检测到 - 升级 MINOR 版本" -Color Cyan
}
elseif ($commitAnalysis.HasPatch) {
$patch += 1
Write-ColorOutput " fix/perf/refactor 检测到 - 升级 PATCH 版本" -Color Green
}
else {
Write-ColorOutput " 未检测到版本变更 - 保持当前版本" -Color Gray
}
# 生成版本信息
$branchToUse = if ($Branch) { $Branch } else { $gitInfo.Branch }
$buildNumToUse = if ($BuildNumber) { $BuildNumber } else { $gitInfo.CommitCount }
$versionInfo = Format-Version -Major $major -Minor $minor -Patch $patch `
-Branch $branchToUse -Commit $gitInfo.Commit `
-BuildNumber $buildNumToUse -Environment $Environment `
-DirtyFlag $gitInfo.IsDirty
# 输出版本信息
Write-ColorOutput "`n========================================" -Color Cyan
Write-ColorOutput " 版本计算结果" -Color Cyan
Write-ColorOutput "========================================" -Color Cyan
Write-ColorOutput "`n基础版本: $($versionInfo.Base)" -Color Yellow
Write-ColorOutput "完整版本: $($versionInfo.Qualified)" -Color Green
Write-ColorOutput "环境: $Environment" -Color Gray
Write-ColorOutput "分支: $branchToUse" -Color Gray
Write-ColorOutput "`n========================================" -Color Cyan
# 更新文件
if (-not $DryRun) {
Write-ColorOutput "`n[更新文件]" -Color White
}
# 更新VERSION文件
Update-VersionFile -Version "${major}.${minor}.${patch}"
# 更新version.json
if ($UpdateJson -or (-not $UpdatePom -and -not $UpdateEnv)) {
Update-VersionJson -VersionInfo $versionInfo -GitInfo $gitInfo
}
# 更新pom.xml
if ($UpdatePom) {
Update-BomPom -Version "${major}.${minor}.${patch}"
}
# 更新环境变量
if ($UpdateEnv) {
Update-EnvFile -Version $versionInfo.Qualified
}
# 输出版本号供脚本调用
if (-not $Quiet) {
Write-ColorOutput "`n版本生成完成!" -Color Green
}
# 返回版本号
Write-Output $versionInfo.Qualified
}
Main