-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Parameters validation and completer suggestions * Update readme with script * Commit readme changes in script * Update script to avoid adding a new line at the eof * Apply suggestions * Make readme commit message more meaningful * Simplify script and make the base version required and fix regex * Refactor script to start writing tests for it * Add test for tag generation * Support subdirectories inside the provider dir * Support provider subdirectories and use package-YYYY-MM convention for tags * Update tests and test assets * Fix problem in function * Remove unnecessary test files * Use single quotes to avoid scaping the backtick * Improve regex and readability * Refactor tests to avoid depending on input files * Format documents and don't use regex to create DateTime objects * Uncomment lines of code
- Loading branch information
1 parent
08f7f27
commit 15848b6
Showing
3 changed files
with
235 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
function Get-NewTagSection($apiVersion, $resourceProvider, $apiVersionStatus, $specFiles) { | ||
|
||
$tagVersion = $apiVersion -match '(?<date>\d{4}-\d{2})-\d{2}' | ||
$tagVersion = $Matches['date'] | ||
$baseDir = "$resourceProvider/$apiVersionStatus/$apiVersion" | ||
|
||
if ($apiVersionStatus -eq "preview") { | ||
$tagVersion = "preview-" + $tagVersion | ||
} | ||
|
||
$content = @" | ||
### Tag: package-$tagVersion | ||
These settings apply only when ``--tag=package-$tagVersion`` is specified on the command line. | ||
```````yaml `$(tag) == 'package-$tagVersion'` | ||
input-file: | ||
"@ | ||
|
||
foreach ($specFile in $specFiles) { | ||
$content += "`n - $baseDir/$specFile" | ||
} | ||
|
||
$content += "`n" + '```' + "`n" | ||
return $content | ||
} | ||
|
||
function Get-ReadmeWithNewTag($readmeContent, $tagContent) { | ||
return $readmeContent -replace '(?s)(### tag: package.*)', "$tagContent`n`$1" | ||
} | ||
|
||
function Get-ReadmeWithLatestTag($readmeContent, $newApiVersion, $newApiVersionStatus ) { | ||
# Get the current tag date | ||
$currentTag = $readmeContent -match '(?m)^(tag:\s*)(package-)(.*)(?<version>\d{4}-\d{2})(.*)' | ||
$currentTag = $Matches['version'] | ||
$latestVersionDate = [datetime]($currentTag -replace '-preview', '') | ||
|
||
# Convert the new OpenAPI version to a date | ||
$newVersionDate = [datetime]($newApiVersion -replace '-preview', '') | ||
|
||
# Compare two dates | ||
if ($latestVersionDate -gt $newVersionDate) { | ||
Write-Warning "The new version is not newer than the current default version in the readme file." | ||
} | ||
$tagVersion = $newApiVersion -match '\d{4}-\d{2}' | ||
$tagVersion = $Matches[0] | ||
if ($newApiVersionStatus -eq "preview") { | ||
$tagVersion = "preview-" + $tagVersion | ||
} | ||
return $readmeContent -replace '(?m)^(tag:\s*)(package-.*)', "tag: package-$tagVersion" | ||
} | ||
|
||
function New-GitAddAndCommit { | ||
[CmdletBinding(SupportsShouldProcess = $true)] | ||
param( | ||
[Parameter(Mandatory = $true)] | ||
[string]$directory, | ||
[Parameter(Mandatory = $true)] | ||
[string]$message | ||
) | ||
|
||
if ($PSCmdlet.ShouldProcess($directory, "Add and commit")) { | ||
git add $directory | Out-Null | ||
$message | git commit --file=- | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,77 +1,141 @@ | ||
[CmdletBinding()] | ||
[CmdletBinding(SupportsShouldProcess)] | ||
param ( | ||
[Parameter(Mandatory = $true)] | ||
[ValidateScript({ | ||
if (-not (Test-Path "$PSScriptRoot/../../specification/$_")) { | ||
throw "Service directory not found in the specification folder." | ||
} | ||
$true | ||
})] | ||
[ArgumentCompleter({ | ||
Get-ChildItem "$PSScriptRoot/../../specification/" -Directory | Select-Object -ExpandProperty Name | ||
})] | ||
[string] $ServiceDirectory, | ||
|
||
[Parameter()] | ||
[Parameter(Mandatory = $true)] | ||
[ValidateSet('data-plane', 'resource-manager')] | ||
[string] $ServiceType = 'data-plane', | ||
[ArgumentCompleter({ 'data-plane', 'resource-manager' })] | ||
[string] $ServiceType, | ||
|
||
[Parameter(Mandatory = $true)] | ||
[string] $Provider, | ||
|
||
[Parameter()] | ||
[ValidateScript({ | ||
function script:Get-Version([string] $version) { | ||
if ($version -match '^(?<status>stable|preview)/(?<version>(\d{4}-\d{2}-\d{2}|\d+\.\d+)(-preview(\.\d+)?)?)$') { | ||
return $Matches['status'], $Matches['version'] | ||
if (-not (Test-Path "$PSScriptRoot/../../specification/$ServiceDirectory/$ServiceType/$_")) { | ||
$validProviders = (Get-ChildItem "$PSScriptRoot/../../specification/$ServiceDirectory/$ServiceType/" -Directory).Name -join ', ' | ||
throw "Service Provider not found. Valid options are: $validProviders" | ||
} | ||
$true | ||
})] | ||
[ArgumentCompleter({ | ||
param($commandName, | ||
$parameterName, | ||
$wordToComplete, | ||
$commandAst, | ||
$fakeBoundParameters) | ||
Get-ChildItem "$PSScriptRoot/../../specification/$($fakeBoundParameters.ServiceDirectory)/$($fakeBoundParameters.ServiceType)/" -Directory | Select-Object -ExpandProperty Name | ||
})] | ||
[string] $Provider, | ||
|
||
[Parameter(Mandatory = $true)] | ||
[ArgumentCompleter({ "preview/", "stable/" })] | ||
[ValidateScript({ | ||
function script:Get-Version([string] $version) { | ||
if ($version -match '^(?<status>stable|preview)/(?<version>(\d{4}-\d{2}-\d{2}|\d+\.\d+)(-preview(\.\d+)?)?)$') { | ||
return $Matches['status'], $Matches['version'] | ||
} | ||
|
||
throw 'Version must start with "stable/" or "preview/" and end with either a date-based version (recommended) like 2024-01-05 or a major.minor semver, followed by an optional "-preview" for previews APIs.' | ||
} | ||
# Throwing or returning truthy is sufficient. | ||
Get-Version $_ | ||
})] | ||
[string] $FromVersion, | ||
|
||
[Parameter()] | ||
[ValidateScript({Get-Version $_})] | ||
[string] $ToVersion | ||
throw 'Version must start with "stable/" or "preview/" and end with either a date-based version (recommended) like 2024-01-05 or a major.minor semver, followed by an optional "-preview" for previews APIs.' | ||
} | ||
Get-Version $_ })] | ||
[string] $NewVersion, | ||
|
||
[Parameter(Mandatory = $true)] | ||
[ValidateScript({ Get-Version $_ })] | ||
[ArgumentCompleter({ | ||
param($commandName, | ||
$parameterName, | ||
$wordToComplete, | ||
$commandAst, | ||
$fakeBoundParameters) | ||
[string[]] $stableVersions = Get-ChildItem "$PSScriptRoot/../../specification/$($fakeBoundParameters.ServiceDirectory)/$($fakeBoundParameters.ServiceType)/$($fakeBoundParameters.Provider)/stable/" -Directory | Select-Object -ExpandProperty Name | | ||
ForEach-Object { "stable/$_" } | ||
[string[]] $previewVersions = Get-ChildItem "$PSScriptRoot/../../specification/$($fakeBoundParameters.ServiceDirectory)/$($fakeBoundParameters.ServiceType)/$($fakeBoundParameters.Provider)/preview/" -Directory | Select-Object -ExpandProperty Name | | ||
ForEach-Object { "preview/$_" } | ||
return $stableVersions + $previewVersions | ||
})] | ||
[string] $BaseVersion | ||
) | ||
|
||
$ErrorActionPreference = 'Stop' | ||
. "$PSScriptRoot/Copy-ApiVersion-Functions.ps1" | ||
|
||
$oldVersionStatus, $oldVersion = Get-Version $FromVersion | ||
$newVersionStatus, $newVersion = Get-Version $ToVersion | ||
$oldApiVersionStatus, $oldApiVersion = Get-Version $BaseVersion | ||
$newApiVersionStatus, $newApiVersion = Get-Version $NewVersion | ||
|
||
$repoDirectory = Resolve-Path "$PSScriptRoot/../.." | ||
$readmeDirectory = Join-Path $repoDirectory "specification/$ServiceDirectory/$ServiceType" -Resolve | ||
$oldDirectory = Join-Path $repoDirectory "specification/$ServiceDirectory/$ServiceType/$Provider/$oldVersionStatus/$oldVersion" -Resolve | ||
$newDirectory = Join-Path $repoDirectory "specification/$ServiceDirectory/$ServiceType/$Provider/$newVersionStatus/$newVersion" | ||
|
||
$oldDirectory = Join-Path $repoDirectory "specification/$ServiceDirectory/$ServiceType/$Provider/$oldApiVersionStatus/$oldApiVersion" -Resolve | ||
$newDirectory = Join-Path $repoDirectory "specification/$ServiceDirectory/$ServiceType/$Provider/$newApiVersionStatus/$newApiVersion" | ||
|
||
Write-Host "----------------------------------------" | ||
Write-Host "Service Directory: $ServiceDirectory" | ||
Write-Host "Service Type: $ServiceType" | ||
Write-Host "Provider: $Provider" | ||
Write-Host "Base Version: $BaseVersion" | ||
Write-Host "New Version: $NewVersion" | ||
Write-Host "----------------------------------------" | ||
|
||
Write-Verbose "Copying $oldDirectory to $newDirectory" | ||
|
||
# Copy the specs and create and initial commit to make it easier to diff changes to the previous version in a PR. | ||
Copy-Item $oldDirectory $newDirectory -Recurse -Force | ||
|
||
git add $newDirectory | ||
@" | ||
Copy files from $FromVersion | ||
New-GitAddAndCommit $newDirectory @" | ||
Copy files from $BaseVersion | ||
Copied the files in a separate commit. | ||
This allows reviewers to easily diff subsequent changes against the previous spec. | ||
"@ | git commit --file=- | ||
"@ | ||
|
||
# Replace the $oldVersion with the $newVersion within all files in $newDirectory. | ||
# Replace the $oldApiVersion with the $newApiVersion within all files in $newDirectory. | ||
foreach ($file in Get-ChildItem $newDirectory -File -Recurse) { | ||
Write-Verbose "Replacing any API versions in $file" | ||
$content = $file | Get-Content -Raw | ||
$content -replace $oldVersion, $newVersion | Set-Content $file.FullName | ||
$content -replace $oldApiVersion, $newApiVersion | Set-Content $file.FullName | ||
} | ||
|
||
# Commit just the version changes. | ||
git add $newDirectory | ||
@" | ||
Update version to $ToVersion | ||
Updated the API version from $FromVersion to $ToVersion. | ||
"@ | git commit --file=- | ||
|
||
Write-Host '' | ||
Write-Host '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' -ForegroundColor 'Yellow' | ||
Write-Host '!!! IMPORTANT: Action Required !!!' -ForegroundColor 'Yellow' | ||
Write-Host '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' -ForegroundColor 'Yellow' | ||
Write-Host '' | ||
Write-Host "You must manually update the default version and copy $FromVersion sections from any markdown files in $readmeDirectory." | ||
Write-Host 'When complete, commit those changes as shown below, push to the upstream repo, and submit a pull request.' | ||
Write-Host '' | ||
Write-Host ' git commit -am"Updated readme files"' | ||
Write-Host '' | ||
New-GitAddAndCommit $newDirectory @" | ||
Update version to $NewVersion | ||
Updated the API version from $BaseVersion to $NewVersion. | ||
"@ | ||
|
||
# Add new version tag in the readme file | ||
$readmeFile = Get-ChildItem $readmeDirectory -Filter 'readme.md' | ||
if ($readmeFile) { | ||
$jsonFiles = Get-ChildItem $newDirectory -Filter '*.json' | Select-Object -ExpandProperty Name | ||
$newReadmeTagBlock = Get-NewTagSection $newApiVersion $Provider $newApiVersionStatus $jsonFiles | ||
|
||
$readmeContent = $readmeFile | Get-Content -Raw | ||
$readmeContent = Get-ReadmeWithNewTag $readmeContent $newReadmeTagBlock | ||
$readmeContent | Set-Content $readmeFile.FullName -NoNewline | ||
} | ||
else { | ||
Write-Error "No readme file found in $readmeDirectory" | ||
Exit 1 | ||
} | ||
|
||
# Update the latest version tag in the readme file | ||
$val = Get-ReadmeWithLatestTag $readmeContent $newApiVersion $newApiVersionStatus | ||
if ($val -ne "") { | ||
Write-Verbose "Updating the first tag in the first yaml code block in $readmeFile" | ||
$val | Set-Content $readmeFile.FullName -NoNewline | ||
Write-Information "Latest version tag in readme file updated." | ||
} | ||
else { | ||
Write-Warning "The new version is not newer than the current version in the readme file. No changes were made." | ||
} | ||
|
||
New-GitAddAndCommit $readmeDirectory @" | ||
Added tag for $newApiVersion in readme file | ||
"@ |
58 changes: 58 additions & 0 deletions
58
eng/scripts/Tests/Copy-ApiVersion/Copy-ApiVersion.Tests.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
Import-Module Pester | ||
|
||
. "$PSScriptRoot\..\..\Copy-ApiVersion-Functions.ps1" | ||
|
||
Describe "Copy-ApiVersion regex tests" { | ||
Context "Generate new version tag section" { | ||
It "Section tag corresponds to new version" -TestCases @( | ||
@{ | ||
version = "2024-01-01-preview" | ||
provider = "Microsoft.AgFoodPlatform" | ||
versionStatus = "preview" | ||
specsDir = '..\..\..\..\..\specification\agrifood\resource-manager\Microsoft.AgFoodPlatform\preview\2023-06-01-preview' | ||
}, | ||
@{ | ||
version = "2024-01-01" | ||
provider = "Microsoft.Compute\ComputeRP" | ||
versionStatus = "stable" | ||
specsDir = '..\..\..\..\..\specification\compute\resource-manager\Microsoft.Compute\ComputeRP\stable\2023-09-01' | ||
} | ||
) { | ||
param($version, $provider, $versionStatus, $specsDir) | ||
|
||
$jsonFiles = Get-ChildItem $PSScriptRoot+$specsDir -Filter '*.json' | Select-Object -ExpandProperty Name | ||
$newTagSection = Get-NewTagSection $version $provider $versionStatus $jsonFiles | ||
|
||
$version -match '\d{4}-\d{2}' | ||
$tag = $Matches[0] | ||
if ($versionStatus -eq "preview") { | ||
$tag = "preview-" + $tag | ||
} | ||
|
||
$newTagSection | Should match "package-$tag" | ||
} | ||
|
||
It "Default version gets updated" -TestCases @( | ||
@{ | ||
inputReadme = '..\..\..\..\..\specification\agrifood\resource-manager\readme.md' | ||
apiVersion = "2024-01-01-preview" | ||
versionStatus = "preview" | ||
}, | ||
@{ | ||
inputReadme = '..\..\..\..\..\specification\compute\resource-manager\readme.md' | ||
apiVersion = "2024-01-01" | ||
versionStatus = "stable" | ||
} | ||
) { | ||
param($inputReadme, $apiVersion, $versionStatus) | ||
$contents = Get-Content $PSScriptRoot+$inputReadme -Raw | ||
$output = Get-ReadmeWithLatestTag $contents $apiVersion $versionStatus | ||
$tag = $apiVersion -match '\d{4}-\d{2}' | ||
$tag = $Matches[0] | ||
if ($versionStatus -eq "preview") { | ||
$tag = "preview-" + $tag | ||
} | ||
$output | Should match "(?m)^tag:\s*package-$tag" | ||
} | ||
} | ||
} |