From 15d3990f3f42862e54dd05a01106cd4ed27e2ab3 Mon Sep 17 00:00:00 2001 From: Chidozie Ononiwu Date: Tue, 27 Oct 2020 17:09:56 -0700 Subject: [PATCH 1/4] Improve Update-ChangeLog Logic --- eng/common/scripts/ChangeLog-Operations.ps1 | 33 ++++++ eng/common/scripts/Update-ChangeLog.ps1 | 109 ++++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 eng/common/scripts/Update-ChangeLog.ps1 diff --git a/eng/common/scripts/ChangeLog-Operations.ps1 b/eng/common/scripts/ChangeLog-Operations.ps1 index d644d022658aa..405e7acc49e06 100644 --- a/eng/common/scripts/ChangeLog-Operations.ps1 +++ b/eng/common/scripts/ChangeLog-Operations.ps1 @@ -72,6 +72,7 @@ function Get-ChangeLogEntryAsString { return ChangeLogEntryAsString $changeLogEntry } + function ChangeLogEntryAsString($changeLogEntry) { if (!$changeLogEntry) { return "[Missing change log entry]" @@ -121,6 +122,38 @@ function Confirm-ChangeLogEntry { return $true } +function Add-ChangeLogEntry { + param ( + [Parameter(Mandatory = $false)] + $ChangeLogEntries, + [Parameter(Mandatory = $true)] + [String]$NewEntryVersion, + [String]$NewEntryReleaseStatus="(Unreleased)", + [String]$NewEntryContent="" + ) +} + +function Edit-ChangeLogEntry { + param ( + [Parameter(Mandatory = $true)] + $ChangeLogEntries, + [Parameter(Mandatory = $true)] + [string]$VersionToEdit, + [String]$NewEntryReleaseVersion, + [String]$NewEntryReleaseStatus, + [String]$NewEntryReleaseContent + ) +} + +function Set-ChangeLogContent { + param ( + [Parameter(Mandatory = $true)] + [String]$ChangeLogLocation, + [Parameter(Mandatory = $true)] + $ChangeLogEntries + ) +} + function Set-TestChangeLog($TestVersion, $changeLogFile, $ReleaseEntry) { Set-Content -Path $changeLogFile -Value @" # Release History diff --git a/eng/common/scripts/Update-ChangeLog.ps1 b/eng/common/scripts/Update-ChangeLog.ps1 new file mode 100644 index 0000000000000..93ceb387006b6 --- /dev/null +++ b/eng/common/scripts/Update-ChangeLog.ps1 @@ -0,0 +1,109 @@ +# Note: This script will add or replace version title in change log + +# Parameter description +# Version : Version to add or replace in change log +# ChangeLogPath: Path to change log file. If change log path is set to directory then script will probe for change log file in that path +# Unreleased: Default is true. If it is set to false, then today's date will be set in verion title. If it is True then title will show "Unreleased" +# ReplaceVersion: This is useful when replacing current version title with new title.( Helpful to update the title before package release) + +param ( + [Parameter(Mandatory = $true)] + [String]$Version, + [Parameter(Mandatory = $true)] + [String]$ServiceDirectory, + [Parameter(Mandatory = $true)] + [String]$PackageName, + [boolean]$Unreleased=$True, + [boolean]$ReplaceVersion = $False +) + +DynamicParam { + if ($Unreleased -eq $False) { + $releaseStatusAttribute = New-Object System.Management.Automation.ParameterAttribute + $releaseStatusAttribute.Mandatory = $False + $attributeCollection = New-object System.Collections.ObjectModel.Collection[System.Attribute] + $attributeCollection.Add($releaseStatusAttribute) + $releaseStatusParam = New-Object System.Management.Automation.RuntimeDefinedParameter('ReleaseDate', [string], $attributeCollection) + $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary + $paramDictionary.Add('ReleaseDate', $releaseStatusParam) + return $paramDictionary + } +} + +Begin { + . "${PSScriptRoot}\common.ps1" + $UNRELEASED_TAG = "(Unreleased)" + + $dateFormat = "yyyy-MM-dd" + $provider = [System.Globalization.CultureInfo]::InvariantCulture + if ($ReleaseDate) + { + try { + $ReleaseStatus = ([System.DateTime]::ParseExact($ReleaseDate, $dateFormat, $provider)).ToString($dateFormat) + } + catch { + LogError "Invalid Release date. Please use a valid date in the format '$dateFormat'" + } + } + elseif ($Unreleased) { + $ReleaseStatus = "$UNRELEASED_TAG" + } + else { + $ReleaseStatus = "($(Get-Date -Format $dateFormat))" + } +} + +Process { + $PkgProperties = Get-PkgProperties -PackageName $PackageName -ServiceDirectory $ServiceDirectory + $ChangeLogEntries = Get-ChangeLogEntries -ChangeLogLocation $PkgProperties.ChangeLogPath + + if ($ChangeLogEntries.Count -gt 0) + { + if ($ChangeLogEntries.Contains($Version)) + { + if ($ChangeLogEntries[$Version].ReleaseStatus -eq $ReleaseStatus) + { + LogWarning "Version is already present in change log with specificed ReleaseStatus [$ReleaseStatus]" + exit(0) + } + + if ($Unreleased -and ($ChangeLogEntries[$Version].ReleaseStatus -ne $ReleaseStatus)) + { + LogWarning "Version is already present in change log with a release date. Please review [$($PkgProperties.ChangeLogPath)]" + exit(0) + } + + if (!$Unreleased -and ($ChangeLogEntries[$Version].ReleaseStatus -ne $UNRELEASED_TAG)) + { + if ((Get-Date ($ChangeLogEntries[$Version].ReleaseStatus).Trim("()")) -gt (Get-Date $ReleaseStatus.Trim("()"))) + { + LogWarning "New ReleaseDate is older than existing release date in changelog. Please review [$($PkgProperties.ChangeLogPath)]" + exit(0) + } + } + } + + $PresentVersionsSorted = [AzureEngSemanticVersion]::SortVersionStrings($ChangeLogEntries.Keys) + $LatestVersion = $PresentVersionsSorted[0] + + if ($ReplaceVersion) + { + $NewChangeLogEntries = Edit-ChangeLogEntry -ChangeLogEntries $ChangeLogEntries -VersionToEdit $LatestVersion ` + -NewEntryReleaseVersion $Version -NewEntryReleaseStatus $ReleaseStatus + Set-ChangeLogContent -ChangeLogLocation $PkgProperties.ChangeLogPath -ChangeLogEntries $NewChangeLogEntries + } + else + { + $NewChangeLogEntries = Add-ChangeLogEntry -ChangeLogEntries $ChangeLogEntries -NewEntryVersion $Version ` + -NewEntryReleaseStatus $ReleaseStatus + Set-ChangeLogContent -ChangeLogLocation $PkgProperties.ChangeLogPath -ChangeLogEntries $NewChangeLogEntries + } + } + else + { + $NewChangeLogEntries = Add-ChangeLogEntry -NewEntryVersion $Version -NewEntryReleaseStatus $ReleaseStatus + Set-ChangeLogContent -ChangeLogLocation $PkgProperties.ChangeLogPath -ChangeLogEntries $NewChangeLogEntries + } +} + + From 0bf51a229d24c9bad8f2fd8cd4947d8151860b67 Mon Sep 17 00:00:00 2001 From: Chidozie Ononiwu Date: Wed, 28 Oct 2020 16:45:05 -0700 Subject: [PATCH 2/4] Updates to ChangeLog-Operations.ps1, copy-docs-to-blobstorage.ps1, Invoke-GitHubAPI.ps1 and Package-Properties.ps1 --- eng/common/scripts/ChangeLog-Operations.ps1 | 77 +++++++++++++++---- eng/common/scripts/Package-Properties.ps1 | 2 +- .../scripts/copy-docs-to-blobstorage.ps1 | 2 +- 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/eng/common/scripts/ChangeLog-Operations.ps1 b/eng/common/scripts/ChangeLog-Operations.ps1 index 405e7acc49e06..fc5ed4dfbc284 100644 --- a/eng/common/scripts/ChangeLog-Operations.ps1 +++ b/eng/common/scripts/ChangeLog-Operations.ps1 @@ -21,12 +21,8 @@ function Get-ChangeLogEntries { $changeLogEntry = $null foreach ($line in $contents) { if ($line -match $RELEASE_TITLE_REGEX) { - $changeLogEntry = [pscustomobject]@{ - ReleaseVersion = $matches["version"] - ReleaseStatus = $matches["releaseStatus"] - ReleaseTitle = $line - ReleaseContent = @() # Release content without the version title - } + $changeLogEntry = New-ChangeLogEntry -Version $matches["version"] -Status $matches["releaseStatus"] ` + -Title $line -Content @() $changeLogEntries[$changeLogEntry.ReleaseVersion] = $changeLogEntry } else { @@ -122,27 +118,64 @@ function Confirm-ChangeLogEntry { return $true } +function New-ChangeLogEntry { + param ( + [Parameter(Mandatory = $true)] + [String]$Version, + [Parameter(Mandatory = $true)] + [ValidateScript({$_.StartsWith('(') -and $_.EndsWith(')')})] + [String]$Status, + [String]$Title, + [String[]]$Content + ) + + $newChangeLogEntry = [pscustomobject]@{ + ReleaseVersion = $Version + ReleaseStatus = $Status + ReleaseTitle = If ($Title) { $Title } Else { "## $Version $Status"} + ReleaseContent = If ($Content) { $Content } Else { @("") } + } + + return $newChangeLogEntry +} + function Add-ChangeLogEntry { param ( [Parameter(Mandatory = $false)] - $ChangeLogEntries, + [Hashtable]$ChangeLogEntries, [Parameter(Mandatory = $true)] [String]$NewEntryVersion, [String]$NewEntryReleaseStatus="(Unreleased)", [String]$NewEntryContent="" ) + + if ($ChangeLogEntries.Contains($NewEntryVersion)) + { + LogError "This Changelog already contains this entry. Do you mean to edit the entry?" + exit 1 + } + + $newChangeLogEntry = New-ChangeLogEntry -Version $NewEntryVersion -Status $NewEntryReleaseStatus ` + -Content $NewEntryContent + $ChangeLogEntries.Add($NewEntryVersion,$newChangeLogEntry) + return $ChangeLogEntries } function Edit-ChangeLogEntry { param ( [Parameter(Mandatory = $true)] - $ChangeLogEntries, + [Hashtable]$ChangeLogEntries, [Parameter(Mandatory = $true)] [string]$VersionToEdit, [String]$NewEntryReleaseVersion, [String]$NewEntryReleaseStatus, [String]$NewEntryReleaseContent ) + + if ($NewEntryReleaseVersion) { $ChangeLogEntries[$VersionToEdit].ReleaseVersion = $NewEntryReleaseVersion } + if ($NewEntryReleaseStatus) {$ChangeLogEntries[$VersionToEdit].ReleaseStatus = $NewEntryReleaseStatus } + if ($NewEntryReleaseContent) {$ChangeLogEntries[$VersionToEdit].ReleaseContent = $NewEntryReleaseContent } + return $ChangeLogEntries } function Set-ChangeLogContent { @@ -152,12 +185,26 @@ function Set-ChangeLogContent { [Parameter(Mandatory = $true)] $ChangeLogEntries ) -} -function Set-TestChangeLog($TestVersion, $changeLogFile, $ReleaseEntry) { - Set-Content -Path $changeLogFile -Value @" -# Release History -## $TestVersion ($(Get-Date -f "yyyy-MM-dd")) -- $ReleaseEntry -"@ + $changeLogContent = @() + $changeLogContent += "# Release History" + + try { + [AzureEngSemanticVersion] + } + catch { + . "${PSScriptRoot}\SemVer.ps1." + } + + $VersionsSorted = [AzureEngSemanticVersion]::SortVersionStrings($ChangeLogEntries.Keys) + foreach ($version in $VersionsSorted) { + $changeLogEntry = $ChangeLogEntries[$version] + $changeLogContent += $changeLogEntry.ReleaseTitle + foreach ($line in $changeLogEntry.ReleaseContent) { + $changeLogContent += $line + } + $changeLogContent += "" + } + + Set-Content -Path $ChangeLogLocation -Value $changeLogContent } \ No newline at end of file diff --git a/eng/common/scripts/Package-Properties.ps1 b/eng/common/scripts/Package-Properties.ps1 index f17b244f3f220..6e678e55b2b93 100644 --- a/eng/common/scripts/Package-Properties.ps1 +++ b/eng/common/scripts/Package-Properties.ps1 @@ -91,7 +91,7 @@ function Get-PkgProperties { $pkgDirectoryPath = Join-Path $serviceDirectoryPath $directory.Name - if ((Get-ChildItem -Path Function: | ? { $_.Name -eq $GetPackageInfoFromRepoFn }).Count -gt 0) + if (Test-Path Function:GetPackageInfoFromRepoFn) { $pkgProps = &$GetPackageInfoFromRepoFn -pkgPath $pkgDirectoryPath -serviceDirectory $ServiceDirectory -pkgName $PackageName } diff --git a/eng/common/scripts/copy-docs-to-blobstorage.ps1 b/eng/common/scripts/copy-docs-to-blobstorage.ps1 index a81fc485f9538..3d95d58e89675 100644 --- a/eng/common/scripts/copy-docs-to-blobstorage.ps1 +++ b/eng/common/scripts/copy-docs-to-blobstorage.ps1 @@ -231,7 +231,7 @@ function Upload-Blobs } -if ((Get-ChildItem -Path Function: | ? { $_.Name -eq $PublishGithubIODocsFn }).Count -gt 0) +if (Test-Path Function:PublishGithubIODocsFn) { &$PublishGithubIODocsFn -DocLocation $DocLocation -PublicArtifactLocation $PublicArtifactLocation } From 2fd32d4a8e2ecbd3d46a354ae37f455b48c4c76b Mon Sep 17 00:00:00 2001 From: Chidozie Ononiwu Date: Wed, 28 Oct 2020 19:43:10 -0700 Subject: [PATCH 3/4] More changeLog Logic Improvements --- eng/common/scripts/ChangeLog-Operations.ps1 | 91 ++++++++------------- eng/common/scripts/Package-Properties.ps1 | 2 +- eng/common/scripts/SemVer.ps1 | 10 ++- eng/common/scripts/Update-ChangeLog.ps1 | 16 ++-- 4 files changed, 52 insertions(+), 67 deletions(-) diff --git a/eng/common/scripts/ChangeLog-Operations.ps1 b/eng/common/scripts/ChangeLog-Operations.ps1 index fc5ed4dfbc284..57d5fb917126f 100644 --- a/eng/common/scripts/ChangeLog-Operations.ps1 +++ b/eng/common/scripts/ChangeLog-Operations.ps1 @@ -1,6 +1,9 @@ # Common Changelog Operations +. "${PSScriptRoot}\logging.ps1" +. "${PSScriptRoot}\SemVer.ps1" $RELEASE_TITLE_REGEX = "(?^\#+.*(?\b\d+\.\d+\.\d+([^0-9\s][^\s:]+)?)(\s(?\(Unreleased\)|\(\d{4}-\d{2}-\d{2}\)))?)" +$UNRELEASED_TAG = "(Unreleased)" # Returns a Collection of changeLogEntry object containing changelog info for all version present in the gived CHANGELOG function Get-ChangeLogEntries { @@ -22,7 +25,7 @@ function Get-ChangeLogEntries { foreach ($line in $contents) { if ($line -match $RELEASE_TITLE_REGEX) { $changeLogEntry = New-ChangeLogEntry -Version $matches["version"] -Status $matches["releaseStatus"] ` - -Title $line -Content @() + -Title $line $changeLogEntries[$changeLogEntry.ReleaseVersion] = $changeLogEntry } else { @@ -100,12 +103,12 @@ function Confirm-ChangeLogEntry { Write-Host "-----" if ([System.String]::IsNullOrEmpty($changeLogEntry.ReleaseStatus)) { - Write-Error "Entry does not have a correct release status. Please ensure the status is set to a date '(yyyy-MM-dd)' or '(Unreleased)' if not yet released." + Write-Error "Entry does not have a correct release status. Please ensure the status is set to a date '(yyyy-MM-dd)' or '$UNRELEASED_TAG' if not yet released." return $false } if ($ForRelease -eq $True) { - if ($changeLogEntry.ReleaseStatus -eq "(Unreleased)") { + if ($changeLogEntry.ReleaseStatus -eq $UNRELEASED_TAG) { Write-Error "Entry has no release date set. Please ensure to set a release date with format 'yyyy-MM-dd'." return $false } @@ -121,63 +124,40 @@ function Confirm-ChangeLogEntry { function New-ChangeLogEntry { param ( [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] [String]$Version, - [Parameter(Mandatory = $true)] - [ValidateScript({$_.StartsWith('(') -and $_.EndsWith(')')})] - [String]$Status, + [String]$Status=$UNRELEASED_TAG, [String]$Title, [String[]]$Content ) + # Validate relase Status + $Status = $Status.Trim().Trim("()") + if ($Status -ne "Unreleased") { + $dateFormat = "yyyy-MM-dd" + $provider = [System.Globalization.CultureInfo]::InvariantCulture + try { + $Status = ([System.DateTime]::ParseExact($Status, $dateFormat, $provider)).ToString($dateFormat) + } + catch { + LogWarning "Invalid date [ $Status ] passed as status for Version [$Version]. Please use a valid date in the format '$dateFormat' or use '$UNRELEASED_TAG'" + } + } + + $Status = "($Status)" + if (!$Content) { $Content = @() } + if (!$Title) { $Title = "## $Version $Status" } + $newChangeLogEntry = [pscustomobject]@{ ReleaseVersion = $Version ReleaseStatus = $Status - ReleaseTitle = If ($Title) { $Title } Else { "## $Version $Status"} - ReleaseContent = If ($Content) { $Content } Else { @("") } + ReleaseTitle = $Title + ReleaseContent = $Content } return $newChangeLogEntry } -function Add-ChangeLogEntry { - param ( - [Parameter(Mandatory = $false)] - [Hashtable]$ChangeLogEntries, - [Parameter(Mandatory = $true)] - [String]$NewEntryVersion, - [String]$NewEntryReleaseStatus="(Unreleased)", - [String]$NewEntryContent="" - ) - - if ($ChangeLogEntries.Contains($NewEntryVersion)) - { - LogError "This Changelog already contains this entry. Do you mean to edit the entry?" - exit 1 - } - - $newChangeLogEntry = New-ChangeLogEntry -Version $NewEntryVersion -Status $NewEntryReleaseStatus ` - -Content $NewEntryContent - $ChangeLogEntries.Add($NewEntryVersion,$newChangeLogEntry) - return $ChangeLogEntries -} - -function Edit-ChangeLogEntry { - param ( - [Parameter(Mandatory = $true)] - [Hashtable]$ChangeLogEntries, - [Parameter(Mandatory = $true)] - [string]$VersionToEdit, - [String]$NewEntryReleaseVersion, - [String]$NewEntryReleaseStatus, - [String]$NewEntryReleaseContent - ) - - if ($NewEntryReleaseVersion) { $ChangeLogEntries[$VersionToEdit].ReleaseVersion = $NewEntryReleaseVersion } - if ($NewEntryReleaseStatus) {$ChangeLogEntries[$VersionToEdit].ReleaseStatus = $NewEntryReleaseStatus } - if ($NewEntryReleaseContent) {$ChangeLogEntries[$VersionToEdit].ReleaseContent = $NewEntryReleaseContent } - return $ChangeLogEntries -} - function Set-ChangeLogContent { param ( [Parameter(Mandatory = $true)] @@ -188,22 +168,21 @@ function Set-ChangeLogContent { $changeLogContent = @() $changeLogContent += "# Release History" - - try { - [AzureEngSemanticVersion] + $changeLogContent += "" + + try + { + $VersionsSorted = [AzureEngSemanticVersion]::SortVersionStrings($ChangeLogEntries.Keys) } catch { - . "${PSScriptRoot}\SemVer.ps1." + LogError "Problem sorting version in ChangeLogEntries" + return } - $VersionsSorted = [AzureEngSemanticVersion]::SortVersionStrings($ChangeLogEntries.Keys) foreach ($version in $VersionsSorted) { $changeLogEntry = $ChangeLogEntries[$version] $changeLogContent += $changeLogEntry.ReleaseTitle - foreach ($line in $changeLogEntry.ReleaseContent) { - $changeLogContent += $line - } - $changeLogContent += "" + $changeLogContent += $changeLogEntry.ReleaseContent } Set-Content -Path $ChangeLogLocation -Value $changeLogContent diff --git a/eng/common/scripts/Package-Properties.ps1 b/eng/common/scripts/Package-Properties.ps1 index 6e678e55b2b93..f17b244f3f220 100644 --- a/eng/common/scripts/Package-Properties.ps1 +++ b/eng/common/scripts/Package-Properties.ps1 @@ -91,7 +91,7 @@ function Get-PkgProperties { $pkgDirectoryPath = Join-Path $serviceDirectoryPath $directory.Name - if (Test-Path Function:GetPackageInfoFromRepoFn) + if ((Get-ChildItem -Path Function: | ? { $_.Name -eq $GetPackageInfoFromRepoFn }).Count -gt 0) { $pkgProps = &$GetPackageInfoFromRepoFn -pkgPath $pkgDirectoryPath -serviceDirectory $ServiceDirectory -pkgName $PackageName } diff --git a/eng/common/scripts/SemVer.ps1 b/eng/common/scripts/SemVer.ps1 index 0efdfae9cd425..feebbba33b125 100644 --- a/eng/common/scripts/SemVer.ps1 +++ b/eng/common/scripts/SemVer.ps1 @@ -22,6 +22,7 @@ class AzureEngSemanticVersion { [string] $RawVersion [bool] $IsSemVerFormat [string] $DefaultPrereleaseLabel + [string] $ParseLanguage = $Language # Regex inspired but simplified from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string static [string] $SEMVER_REGEX = "(?0|[1-9]\d*)\.(?0|[1-9]\d*)\.(?0|[1-9]\d*)(?:(?-?)(?[a-zA-Z-]*)(?\.?)(?0|[1-9]\d*))?" @@ -143,7 +144,14 @@ class AzureEngSemanticVersion { static [string[]] SortVersionStrings([string[]] $versionStrings) { - $versions = $versionStrings | ForEach-Object { [AzureEngSemanticVersion]::ParseVersionString($_) } + $versions = $versionStrings | ForEach-Object { + if ($ParseLanguage -eq "python") { + [AzureEngSemanticVersion]::ParsePythonVersionString($_) + } + else { + [AzureEngSemanticVersion]::ParseVersionString($_) + } + } $sortedVersions = [AzureEngSemanticVersion]::SortVersions($versions) return ($sortedVersions | ForEach-Object { $_.ToString() }) } diff --git a/eng/common/scripts/Update-ChangeLog.ps1 b/eng/common/scripts/Update-ChangeLog.ps1 index 93ceb387006b6..c1f2989a8beaf 100644 --- a/eng/common/scripts/Update-ChangeLog.ps1 +++ b/eng/common/scripts/Update-ChangeLog.ps1 @@ -39,7 +39,7 @@ Begin { if ($ReleaseDate) { try { - $ReleaseStatus = ([System.DateTime]::ParseExact($ReleaseDate, $dateFormat, $provider)).ToString($dateFormat) + $ReleaseStatus = "({0})" -f ([System.DateTime]::ParseExact($ReleaseDate, $dateFormat, $provider)).ToString($dateFormat) } catch { LogError "Invalid Release date. Please use a valid date in the format '$dateFormat'" @@ -88,22 +88,20 @@ Process { if ($ReplaceVersion) { - $NewChangeLogEntries = Edit-ChangeLogEntry -ChangeLogEntries $ChangeLogEntries -VersionToEdit $LatestVersion ` - -NewEntryReleaseVersion $Version -NewEntryReleaseStatus $ReleaseStatus - Set-ChangeLogContent -ChangeLogLocation $PkgProperties.ChangeLogPath -ChangeLogEntries $NewChangeLogEntries + $ChangeLogEntries.Remove($LatestVersion) + $ChangeLogEntries[$Version] = New-ChangeLogEntry -Version $Version -Status $ReleaseStatus } else { - $NewChangeLogEntries = Add-ChangeLogEntry -ChangeLogEntries $ChangeLogEntries -NewEntryVersion $Version ` - -NewEntryReleaseStatus $ReleaseStatus - Set-ChangeLogContent -ChangeLogLocation $PkgProperties.ChangeLogPath -ChangeLogEntries $NewChangeLogEntries + $ChangeLogEntries[$Version] = New-ChangeLogEntry -Version $Version -Status $ReleaseStatus } } else { - $NewChangeLogEntries = Add-ChangeLogEntry -NewEntryVersion $Version -NewEntryReleaseStatus $ReleaseStatus - Set-ChangeLogContent -ChangeLogLocation $PkgProperties.ChangeLogPath -ChangeLogEntries $NewChangeLogEntries + $ChangeLogEntries[$Version] = New-ChangeLogEntry -Version $Version -Status $ReleaseStatus } + + Set-ChangeLogContent -ChangeLogLocation $PkgProperties.ChangeLogPath -ChangeLogEntries $ChangeLogEntries } From c98ad823aba0149c99ca5bb613c584e9e79afc02 Mon Sep 17 00:00:00 2001 From: Chidozie Ononiwu Date: Wed, 4 Nov 2020 17:04:06 -0800 Subject: [PATCH 4/4] Update date parsing --- eng/common/scripts/ChangeLog-Operations.ps1 | 68 +++++--- eng/common/scripts/Package-Properties.ps1 | 10 +- eng/common/scripts/SemVer.ps1 | 19 +-- eng/common/scripts/Update-ChangeLog.ps1 | 158 ++++++++++-------- .../scripts/copy-docs-to-blobstorage.ps1 | 2 +- 5 files changed, 148 insertions(+), 109 deletions(-) diff --git a/eng/common/scripts/ChangeLog-Operations.ps1 b/eng/common/scripts/ChangeLog-Operations.ps1 index 57d5fb917126f..43dba5d74e6fb 100644 --- a/eng/common/scripts/ChangeLog-Operations.ps1 +++ b/eng/common/scripts/ChangeLog-Operations.ps1 @@ -2,8 +2,9 @@ . "${PSScriptRoot}\logging.ps1" . "${PSScriptRoot}\SemVer.ps1" -$RELEASE_TITLE_REGEX = "(?^\#+.*(?\b\d+\.\d+\.\d+([^0-9\s][^\s:]+)?)(\s(?\(Unreleased\)|\(\d{4}-\d{2}-\d{2}\)))?)" -$UNRELEASED_TAG = "(Unreleased)" +$RELEASE_TITLE_REGEX = "(?^\#+.*(?\b\d+\.\d+\.\d+([^0-9\s][^\s:]+)?)(\s+(?\(Unreleased\)|\(\d{4}-\d{2}-\d{2}\)))?)" +$CHANGELOG_UNRELEASED_STATUS = "(Unreleased)" +$CHANGELOG_DATE_FORMAT = "yyyy-MM-dd" # Returns a Collection of changeLogEntry object containing changelog info for all version present in the gived CHANGELOG function Get-ChangeLogEntries { @@ -14,7 +15,7 @@ function Get-ChangeLogEntries { $changeLogEntries = @{} if (!(Test-Path $ChangeLogLocation)) { - Write-Error "ChangeLog[${ChangeLogLocation}] does not exist" + LogError "ChangeLog[${ChangeLogLocation}] does not exist" return $null } @@ -24,8 +25,12 @@ function Get-ChangeLogEntries { $changeLogEntry = $null foreach ($line in $contents) { if ($line -match $RELEASE_TITLE_REGEX) { - $changeLogEntry = New-ChangeLogEntry -Version $matches["version"] -Status $matches["releaseStatus"] ` - -Title $line + $changeLogEntry = [pscustomobject]@{ + ReleaseVersion = $matches["version"] + ReleaseStatus = $matches["releaseStatus"] + ReleaseTitle = "## {0} {1}" -f $matches["version"], $matches["releaseStatus"] + ReleaseContent = @() + } $changeLogEntries[$changeLogEntry.ReleaseVersion] = $changeLogEntry } else { @@ -93,7 +98,7 @@ function Confirm-ChangeLogEntry { $changeLogEntry = Get-ChangeLogEntry -ChangeLogLocation $ChangeLogLocation -VersionString $VersionString if (!$changeLogEntry) { - Write-Error "ChangeLog[${ChangeLogLocation}] does not have an entry for version ${VersionString}." + LogError "ChangeLog[${ChangeLogLocation}] does not have an entry for version ${VersionString}." return $false } @@ -103,18 +108,28 @@ function Confirm-ChangeLogEntry { Write-Host "-----" if ([System.String]::IsNullOrEmpty($changeLogEntry.ReleaseStatus)) { - Write-Error "Entry does not have a correct release status. Please ensure the status is set to a date '(yyyy-MM-dd)' or '$UNRELEASED_TAG' if not yet released." + LogError "Entry does not have a correct release status. Please ensure the status is set to a date '($CHANGELOG_DATE_FORMAT)' or '$CHANGELOG_UNRELEASED_STATUS' if not yet released." return $false } if ($ForRelease -eq $True) { - if ($changeLogEntry.ReleaseStatus -eq $UNRELEASED_TAG) { - Write-Error "Entry has no release date set. Please ensure to set a release date with format 'yyyy-MM-dd'." + if ($changeLogEntry.ReleaseStatus -eq $CHANGELOG_UNRELEASED_STATUS) { + LogError "Entry has no release date set. Please ensure to set a release date with format '$CHANGELOG_DATE_FORMAT'." return $false } + else { + $status = $changeLogEntry.ReleaseStatus.Trim().Trim("()") + try { + [DateTime]$status + } + catch { + LogError "Invalid date [ $status ] passed as status for Version [$($changeLogEntry.ReleaseVersion)]." + return $false + } + } if ([System.String]::IsNullOrWhiteSpace($changeLogEntry.ReleaseContent)) { - Write-Error "Entry has no content. Please ensure to provide some content of what changed in this version." + LogError "Entry has no content. Please ensure to provide some content of what changed in this version." return $false } } @@ -126,32 +141,38 @@ function New-ChangeLogEntry { [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$Version, - [String]$Status=$UNRELEASED_TAG, - [String]$Title, + [String]$Status=$CHANGELOG_UNRELEASED_STATUS, [String[]]$Content ) - # Validate relase Status + # Validate RelaseStatus $Status = $Status.Trim().Trim("()") if ($Status -ne "Unreleased") { - $dateFormat = "yyyy-MM-dd" - $provider = [System.Globalization.CultureInfo]::InvariantCulture try { - $Status = ([System.DateTime]::ParseExact($Status, $dateFormat, $provider)).ToString($dateFormat) + $Status = ([DateTime]$Status).ToString($CHANGELOG_DATE_FORMAT) } catch { - LogWarning "Invalid date [ $Status ] passed as status for Version [$Version]. Please use a valid date in the format '$dateFormat' or use '$UNRELEASED_TAG'" + LogWarning "Invalid date [ $Status ] passed as status for Version [$Version]. Please use a valid date in the format '$CHANGELOG_DATE_FORMAT' or use '$CHANGELOG_UNRELEASED_STATUS'" + return $null } } - $Status = "($Status)" + + # Validate Version + try { + $Version = ([AzureEngSemanticVersion]::ParseVersionString($Version)).ToString() + } + catch { + LogWarning "Invalid version [ $Version ]." + return $null + } + if (!$Content) { $Content = @() } - if (!$Title) { $Title = "## $Version $Status" } $newChangeLogEntry = [pscustomobject]@{ ReleaseVersion = $Version ReleaseStatus = $Status - ReleaseTitle = $Title + ReleaseTitle = "## $Version $Status" ReleaseContent = $Content } @@ -182,7 +203,12 @@ function Set-ChangeLogContent { foreach ($version in $VersionsSorted) { $changeLogEntry = $ChangeLogEntries[$version] $changeLogContent += $changeLogEntry.ReleaseTitle - $changeLogContent += $changeLogEntry.ReleaseContent + if ($changeLogEntry.ReleaseContent.Count -eq 0) { + $changeLogContent += @("","") + } + else { + $changeLogContent += $changeLogEntry.ReleaseContent + } } Set-Content -Path $ChangeLogLocation -Value $changeLogContent diff --git a/eng/common/scripts/Package-Properties.ps1 b/eng/common/scripts/Package-Properties.ps1 index f17b244f3f220..d75b897f28c63 100644 --- a/eng/common/scripts/Package-Properties.ps1 +++ b/eng/common/scripts/Package-Properties.ps1 @@ -1,4 +1,6 @@ # Helper functions for retireving useful information from azure-sdk-for-* repo +. "${PSScriptRoot}\logging.ps1" + class PackageProps { [string]$Name @@ -81,7 +83,7 @@ function Get-PkgProperties $serviceDirectoryPath = Join-Path $RepoRoot "sdk" $ServiceDirectory if (!(Test-Path $serviceDirectoryPath)) { - Write-Error "Service Directory $ServiceDirectory does not exist" + LogError "Service Directory $ServiceDirectory does not exist" exit 1 } @@ -97,7 +99,7 @@ function Get-PkgProperties } else { - Write-Error "The function '$GetPackageInfoFromRepoFn' was not found." + LogError "The function '$GetPackageInfoFromRepoFn' was not found." } if ($pkgProps -ne $null) @@ -105,7 +107,7 @@ function Get-PkgProperties return $pkgProps } } - Write-Error "Failed to retrive Properties for $PackageName" + LogError "Failed to retrive Properties for $PackageName" } # Takes ServiceName and Repo Root Directory @@ -175,7 +177,7 @@ function Get-PkgListFromYml ($ciYmlPath) } if ($artifactsInCI -eq $null) { - Write-Error "Failed to retrive package names in ci $ciYmlPath" + LogError "Failed to retrive package names in ci $ciYmlPath" } return $artifactsInCI } \ No newline at end of file diff --git a/eng/common/scripts/SemVer.ps1 b/eng/common/scripts/SemVer.ps1 index feebbba33b125..ab4eef38052b5 100644 --- a/eng/common/scripts/SemVer.ps1 +++ b/eng/common/scripts/SemVer.ps1 @@ -22,9 +22,10 @@ class AzureEngSemanticVersion { [string] $RawVersion [bool] $IsSemVerFormat [string] $DefaultPrereleaseLabel - [string] $ParseLanguage = $Language + # Regex inspired but simplified from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string static [string] $SEMVER_REGEX = "(?0|[1-9]\d*)\.(?0|[1-9]\d*)\.(?0|[1-9]\d*)(?:(?-?)(?[a-zA-Z-]*)(?\.?)(?0|[1-9]\d*))?" + static [string] $ParseLanguage = $Language static [AzureEngSemanticVersion] ParseVersionString([string] $versionString) { @@ -58,7 +59,12 @@ class AzureEngSemanticVersion { $this.Minor = [int]$matches.Minor $this.Patch = [int]$matches.Patch - $this.SetupDefaultConventions() + if ([AzureEngSemanticVersion]::ParseLanguage -eq "python") { + $this.SetupPythonConventions() + } + else { + $this.SetupDefaultConventions() + } if ($null -eq $matches['prelabel']) { @@ -144,14 +150,7 @@ class AzureEngSemanticVersion { static [string[]] SortVersionStrings([string[]] $versionStrings) { - $versions = $versionStrings | ForEach-Object { - if ($ParseLanguage -eq "python") { - [AzureEngSemanticVersion]::ParsePythonVersionString($_) - } - else { - [AzureEngSemanticVersion]::ParseVersionString($_) - } - } + $versions = $versionStrings | ForEach-Object { [AzureEngSemanticVersion]::ParseVersionString($_) } $sortedVersions = [AzureEngSemanticVersion]::SortVersions($versions) return ($sortedVersions | ForEach-Object { $_.ToString() }) } diff --git a/eng/common/scripts/Update-ChangeLog.ps1 b/eng/common/scripts/Update-ChangeLog.ps1 index c1f2989a8beaf..eb506076c62bb 100644 --- a/eng/common/scripts/Update-ChangeLog.ps1 +++ b/eng/common/scripts/Update-ChangeLog.ps1 @@ -2,9 +2,8 @@ # Parameter description # Version : Version to add or replace in change log -# ChangeLogPath: Path to change log file. If change log path is set to directory then script will probe for change log file in that path # Unreleased: Default is true. If it is set to false, then today's date will be set in verion title. If it is True then title will show "Unreleased" -# ReplaceVersion: This is useful when replacing current version title with new title.( Helpful to update the title before package release) +# ReplaceLatestEntry: Replaces the latest changelog entry, including its content. param ( [Parameter(Mandatory = $true)] @@ -14,94 +13,107 @@ param ( [Parameter(Mandatory = $true)] [String]$PackageName, [boolean]$Unreleased=$True, - [boolean]$ReplaceVersion = $False + [boolean]$ReplaceLatestEntry = $False, + [String]$ReleaseDate ) -DynamicParam { - if ($Unreleased -eq $False) { - $releaseStatusAttribute = New-Object System.Management.Automation.ParameterAttribute - $releaseStatusAttribute.Mandatory = $False - $attributeCollection = New-object System.Collections.ObjectModel.Collection[System.Attribute] - $attributeCollection.Add($releaseStatusAttribute) - $releaseStatusParam = New-Object System.Management.Automation.RuntimeDefinedParameter('ReleaseDate', [string], $attributeCollection) - $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary - $paramDictionary.Add('ReleaseDate', $releaseStatusParam) - return $paramDictionary - } +if ($ReleaseDate -and ($Unreleased -eq $True)) { + LogError "Do not pass 'ReleaseDate' arguement when 'Unreleased' is true" + exit 1 } -Begin { - . "${PSScriptRoot}\common.ps1" - $UNRELEASED_TAG = "(Unreleased)" +. "${PSScriptRoot}\common.ps1" - $dateFormat = "yyyy-MM-dd" - $provider = [System.Globalization.CultureInfo]::InvariantCulture - if ($ReleaseDate) - { - try { - $ReleaseStatus = "({0})" -f ([System.DateTime]::ParseExact($ReleaseDate, $dateFormat, $provider)).ToString($dateFormat) - } - catch { - LogError "Invalid Release date. Please use a valid date in the format '$dateFormat'" - } +if ($ReleaseDate) +{ + try { + $ReleaseStatus = ([DateTime]$ReleaseDate).ToString($CHANGELOG_DATE_FORMAT) + $ReleaseStatus = "($ReleaseStatus)" } - elseif ($Unreleased) { - $ReleaseStatus = "$UNRELEASED_TAG" - } - else { - $ReleaseStatus = "($(Get-Date -Format $dateFormat))" + catch { + LogError "Invalid 'ReleaseDate'. Please use a valid date in the format '$CHANGELOG_DATE_FORMAT'" + exit 1 } } +elseif ($Unreleased) { + $ReleaseStatus = $CHANGELOG_UNRELEASED_STATUS +} +else { + $ReleaseStatus = "$(Get-Date -Format $CHANGELOG_DATE_FORMAT)" + $ReleaseStatus = "($ReleaseStatus)" +} -Process { - $PkgProperties = Get-PkgProperties -PackageName $PackageName -ServiceDirectory $ServiceDirectory - $ChangeLogEntries = Get-ChangeLogEntries -ChangeLogLocation $PkgProperties.ChangeLogPath +if ($null -eq [AzureEngSemanticVersion]::ParseVersionString($Version)) +{ + LogError "Version [$Version] is invalid. Please use a valid SemVer" + exit(0) +} - if ($ChangeLogEntries.Count -gt 0) +$PkgProperties = Get-PkgProperties -PackageName $PackageName -ServiceDirectory $ServiceDirectory +$ChangeLogEntries = Get-ChangeLogEntries -ChangeLogLocation $PkgProperties.ChangeLogPath + + +if ($ChangeLogEntries.Contains($Version)) +{ + if ($ChangeLogEntries[$Version].ReleaseStatus -eq $ReleaseStatus) { - if ($ChangeLogEntries.Contains($Version)) - { - if ($ChangeLogEntries[$Version].ReleaseStatus -eq $ReleaseStatus) - { - LogWarning "Version is already present in change log with specificed ReleaseStatus [$ReleaseStatus]" - exit(0) - } - - if ($Unreleased -and ($ChangeLogEntries[$Version].ReleaseStatus -ne $ReleaseStatus)) - { - LogWarning "Version is already present in change log with a release date. Please review [$($PkgProperties.ChangeLogPath)]" - exit(0) - } - - if (!$Unreleased -and ($ChangeLogEntries[$Version].ReleaseStatus -ne $UNRELEASED_TAG)) - { - if ((Get-Date ($ChangeLogEntries[$Version].ReleaseStatus).Trim("()")) -gt (Get-Date $ReleaseStatus.Trim("()"))) - { - LogWarning "New ReleaseDate is older than existing release date in changelog. Please review [$($PkgProperties.ChangeLogPath)]" - exit(0) - } - } - } + LogWarning "Version is already present in change log with specificed ReleaseStatus [$ReleaseStatus]" + exit(0) + } - $PresentVersionsSorted = [AzureEngSemanticVersion]::SortVersionStrings($ChangeLogEntries.Keys) - $LatestVersion = $PresentVersionsSorted[0] + if ($Unreleased -and ($ChangeLogEntries[$Version].ReleaseStatus -ne $ReleaseStatus)) + { + LogWarning "Version is already present in change log with a release date. Please review [$($PkgProperties.ChangeLogPath)]" + exit(0) + } - if ($ReplaceVersion) - { - $ChangeLogEntries.Remove($LatestVersion) - $ChangeLogEntries[$Version] = New-ChangeLogEntry -Version $Version -Status $ReleaseStatus - } - else + if (!$Unreleased -and ($ChangeLogEntries[$Version].ReleaseStatus -ne $CHANGELOG_UNRELEASED_STATUS)) + { + if ((Get-Date ($ChangeLogEntries[$Version].ReleaseStatus).Trim("()")) -gt (Get-Date $ReleaseStatus.Trim("()"))) { - $ChangeLogEntries[$Version] = New-ChangeLogEntry -Version $Version -Status $ReleaseStatus + LogWarning "New ReleaseDate for version [$Version] is older than existing release date in changelog. Please review [$($PkgProperties.ChangeLogPath)]" + exit(0) } } - else - { - $ChangeLogEntries[$Version] = New-ChangeLogEntry -Version $Version -Status $ReleaseStatus - } +} - Set-ChangeLogContent -ChangeLogLocation $PkgProperties.ChangeLogPath -ChangeLogEntries $ChangeLogEntries +$PresentVersionsSorted = [AzureEngSemanticVersion]::SortVersionStrings($ChangeLogEntries.Keys) +$LatestVersion = $PresentVersionsSorted[0] + +$LatestsSorted = [AzureEngSemanticVersion]::SortVersionStrings(@($LatestVersion, $Version)) +if ($LatestsSorted[0] -ne $Version) { + LogWarning "Passed Version [$Version] is older than the latestversion [$LatestVersion] in the changelog. Please use a more recent version." + exit(0) } +if ($ReplaceLatestEntry) +{ + $ChangeLogEntries.Remove($LatestVersion) + $newChangeLogEntry = New-ChangeLogEntry -Version $Version -Status $ReleaseStatus + if ($newChangeLogEntry) { + $ChangeLogEntries[$Version] = $newChangeLogEntry + } + else { + LogError "Failed to create new changelog entry" + } +} +elseif ($ChangeLogEntries.Contains($Version)) +{ + $ChangeLogEntries[$Version].ReleaseVersion = $Version + $ChangeLogEntries[$Version].ReleaseStatus = $ReleaseStatus + $ChangeLogEntries[$Version].ReleaseTitle = "## $Version $ReleaseStatus" +} +else +{ + $newChangeLogEntry = New-ChangeLogEntry -Version $Version -Status $ReleaseStatus + if ($newChangeLogEntry) { + $ChangeLogEntries[$Version] = $newChangeLogEntry + } + else { + LogError "Failed to create new changelog entry" + } +} + +Set-ChangeLogContent -ChangeLogLocation $PkgProperties.ChangeLogPath -ChangeLogEntries $ChangeLogEntries + diff --git a/eng/common/scripts/copy-docs-to-blobstorage.ps1 b/eng/common/scripts/copy-docs-to-blobstorage.ps1 index 3d95d58e89675..a81fc485f9538 100644 --- a/eng/common/scripts/copy-docs-to-blobstorage.ps1 +++ b/eng/common/scripts/copy-docs-to-blobstorage.ps1 @@ -231,7 +231,7 @@ function Upload-Blobs } -if (Test-Path Function:PublishGithubIODocsFn) +if ((Get-ChildItem -Path Function: | ? { $_.Name -eq $PublishGithubIODocsFn }).Count -gt 0) { &$PublishGithubIODocsFn -DocLocation $DocLocation -PublicArtifactLocation $PublicArtifactLocation }