-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVersionComponent.ps1
142 lines (124 loc) · 4.07 KB
/
VersionComponent.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
param (
[Parameter(Mandatory = $true)]
[string]$ComponentName,
[Parameter(Mandatory = $false)]
[ValidateSet("major", "minor", "patch")]
[string]$DefaultIncrement = "patch",
[Parameter(Mandatory = $false)]
[bool]$CreateTag = $false,
[Parameter(Mandatory = $false)]
[bool]$VerboseOutput = $false
)
# Function to parse version increment from a commit message
function Get-VersionIncrement {
param ($CommitMessage, $DefaultIncrement)
if ($CommitMessage -match '\+semver:\s*(major|minor|patch)') {
return $matches[1]
}
return $DefaultIncrement
}
# Function to extract and parse version from a tag
function Parse-VersionFromTag {
param ($Tag)
if ($Tag -match "$ComponentName-v(\d+)\.(\d+)\.(\d+)") {
return [version]::new($matches[1], $matches[2], $matches[3])
} else {
Write-Error "Failed to parse version from tag: $Tag"
exit 1
}
}
# Fetch the latest tags
git fetch --tags 2>&1 | Out-Null
# Get the latest tag for the component
$latestTag = git tag --list "$ComponentName-v*" |
ForEach-Object {
if ($_ -match "$ComponentName-v(\d+)\.(\d+)\.(\d+)") {
# Extract the version parts for sorting
[PSCustomObject]@{
Tag = $_
Major = [int]$matches[1]
Minor = [int]$matches[2]
Patch = [int]$matches[3]
}
}
} | Sort-Object -Property Major, Minor, Patch -Descending |
Select-Object -First 1
if (-not $latestTag) {
if ($VerboseOutput) {
Write-Host "No existing tags found for $ComponentName. Starting with version 0.0.0."
}
$version = [version]::new(0, 0, 0)
# Set baseline to the initial commit
$baselineCommit = (git rev-list --max-parents=0 HEAD).Trim()
} else {
$version = Parse-VersionFromTag $latestTag
# Get the commit where the latest tag is pointing
$baselineCommit = (git rev-list -n 1 $latestTag).Trim()
}
# Get commit messages affecting the component's directory since the baseline commit
$logOutput = git log "$baselineCommit..HEAD" -- $ComponentName --pretty=format:"%B" | Out-String
if ($LASTEXITCODE -ne 0) {
Write-Error "Failed to retrieve git log. Ensure the component path and git history are valid."
exit 1
}
$commitMessages = @($logOutput -split "(?=commit\s[0-9a-f]{40})" | Where-Object { $_ -ne "" })
$commitMessages = $commitMessages[-1..-($commitMessages.Count)]
if (-not $commitMessages) {
if ($VerboseOutput) {
Write-Host "No new commits affecting $ComponentName since the last tag."
Write-Host "Current version: $version"
}
Write-Output $version
exit 0
}
# Initialize version components
$newMajor = $version.Major
$newMinor = $version.Minor
$newPatch = $version.Build
# Determine version increments
foreach ($msg in $commitMessages) {
$increment = Get-VersionIncrement $msg $DefaultIncrement
if ($VerboseOutput) {
Write-Host "Processing commit for $($ComponentName): $msg"
Write-Host "Increment parsed: $increment"
}
switch ($increment) {
"major" {
$newMajor++
$newMinor = 0
$newPatch = 0
}
"minor" {
$newMinor++
$newPatch = 0
}
"patch" {
$newPatch++
}
}
}
# Create new version object
$newVersion = [version]::new($newMajor, $newMinor, $newPatch)
# Validate SemVer compliance
if (-not $newVersion) {
Write-Error "Invalid version calculated: $newVersion. Aborting."
exit 1
}
# Conditionally create and push new tag
if ($CreateTag) {
$newTag = "$ComponentName-v$newVersion"
git tag $newTag 2>&1 | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Error "Failed to create tag: $newTag. Ensure you have proper permissions."
exit 1
}
git push origin $newTag 2>&1 | Out-Null
if ($VerboseOutput) {
Write-Host "Tagged $ComponentName with new version: $newTag"
}
} else {
if ($VerboseOutput) {
Write-Host "New version for $($ComponentName): $newVersion (tagging skipped)"
}
}
Write-Output $newVersion