Last active
March 20, 2020 00:11
-
-
Save scbedd/eefd6559138f68daf4641303e8e9b58a to your computer and use it in GitHub Desktop.
Powershell Github.io Versioning v1 -> v2 Transition Script
This file contains hidden or 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
# transition old style versioning strategy to new. inclusive of existing versions in both strategies | |
param ( | |
$AzCopy, | |
$SASKey, | |
$Language, | |
$BlobName, | |
$DocLocation, | |
$AccountKey | |
) | |
$AccountName = ($BlobName.Replace("https://", "") -Split "\.")[0] | |
$DocDest = "$($BlobName)/`$web/$($Language)" | |
# specifically ToSemver and SortSemVersions below are shamelessly copy/pasted from an internal script written by coworker weshaggard. | |
# Regex inspired but simplified from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string | |
$SEMVER_REGEX = "^(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)\.(?<patch>0|[1-9]\d*)(?:-?(?<prelabel>[a-zA-Z-]*)(?:\.?(?<prenumber>0|[1-9]\d*))?)?$" | |
function ToSemVer($version){ | |
if ($version -match $SEMVER_REGEX) | |
{ | |
if(-not $matches['prelabel']) { | |
# artifically provide these values for non-prereleases to enable easy sorting of them later than prereleases. | |
$prelabel = "zzz" | |
$prenumber = 999; | |
$isPre = $false; | |
} | |
else { | |
$prelabel = $matches["prelabel"] | |
$prenumber = 0 | |
# some older packages don't have a prenumber, should handle this | |
if($matches["prenumber"]){ | |
$prenumber = [int]$matches["prenumber"] | |
} | |
$isPre = $true; | |
} | |
New-Object PSObject -Property @{ | |
Major = [int]$matches['major'] | |
Minor = [int]$matches['minor'] | |
Patch = [int]$matches['patch'] | |
PrereleaseLabel = $prelabel | |
PrereleaseNumber = $prenumber | |
IsPrerelease = $isPre | |
RawVersion = $version | |
} | |
} | |
else | |
{ | |
if ($ExitOnError) | |
{ | |
throw "Unable to convert $version to valid semver and hard exit on error is enabled. Exiting." | |
} | |
else | |
{ | |
return $null | |
} | |
} | |
} | |
function SortSemVersions($versions) | |
{ | |
return $versions | Sort -Property Major, Minor, Patch, PrereleaseLabel, PrereleaseNumber -Descending | |
} | |
function Sort-Versions | |
{ | |
Param ( | |
[Parameter(Mandatory=$true)] [string[]]$VersionArray | |
) | |
# standard init and sorting existing | |
$versionsObject = New-Object PSObject -Property @{ | |
OriginalVersionArray = $VersionArray | |
SortedVersionArray = @() | |
LatestGAPackage = "" | |
RawVersionsList = "" | |
LatestPreviewPackage = "" | |
} | |
if ($VersionArray.Count -eq 0) | |
{ | |
return $versionsObject | |
} | |
$versionsObject.SortedVersionArray = SortSemVersions -versions ($VersionArray | % { ToSemVer $_}) | |
$versionsObject.RawVersionsList = $versionsObject.SortedVersionArray | % { $_.RawVersion } | |
# handle latest and preview | |
# we only want to hold onto the latest preview if its NEWER than the latest GA. | |
# this means that the latest preview package either A) has to be the latest value in the VersionArray | |
# or B) set to nothing. We'll handle the set to nothing case a bit later. | |
$versionsObject.LatestPreviewPackage = $versionsObject.SortedVersionArray[0].RawVersion | |
$gaVersions = $versionsObject.SortedVersionArray | ? { !$_.IsPrerelease } | |
# we have a GA package | |
if ($gaVersions.Count -ne 0) | |
{ | |
# GA is the newest non-preview package | |
$versionsObject.LatestGAPackage = $gaVersions[0].RawVersion | |
# in the case where latest preview == latestGA (because of our default selection earlier) | |
if ($versionsObject.LatestGAPackage -eq $versionsObject.LatestPreviewPackage) | |
{ | |
# latest is newest, unset latest preview | |
$versionsObject.LatestPreviewPackage = "" | |
} | |
} | |
return $versionsObject | |
} | |
function Get-Existing-Versions | |
{ | |
Param ( | |
[Parameter(Mandatory=$true)] [String]$PkgName | |
) | |
$versionUri = "$($BlobName)/`$web/$($Language)/$($PkgName)/versioning/versions" | |
Write-Host "Heading to $versionUri to retrieve known versions" | |
try { | |
return ((Invoke-RestMethod -Uri $versionUri -MaximumRetryCount 3 -RetryIntervalSec 5) -Split "\n" | % {$_.Trim()} | ? { return $_ }) | |
} | |
catch { | |
# Handle 404. If it's 404, this is the first time we've published this package. | |
if ($_.Exception.Response.StatusCode.value__ -eq 404){ | |
Write-Host "Version file does not exist. This is the first time we have published this package." | |
} | |
else { | |
# If it's not a 404. exit. We don't know what's gone wrong. | |
Write-Host "Exception getting version file. Aborting" | |
Write-Host $_ | |
exit(1) | |
} | |
} | |
} | |
function Update-Existing-Versions | |
{ | |
Param ( | |
[Parameter(Mandatory=$true)] [String]$PkgName, | |
[Parameter(Mandatory=$true)] [String[]]$ExistingVersions | |
) | |
$newStyleVersions = Get-Existing-Versions -PkgName $PkgName | |
Write-Host "Before I update anything, I am seeing ($newStyleVersions) new style versions" | |
Write-Host "And ($ExistingVersions) old style versions." | |
if (!$ExistingVersions) | |
{ | |
$ExistingVersions = @() | |
$ExistingVersions += $newStyleVersions | |
# Write-Host "No existing versions. Adding $PkgVersion." | |
} | |
else | |
{ | |
$ExistingVersions += $newStyleVersions | |
# Write-Host "Already Existing Versions. Adding $PkgVersion." | |
} | |
$combinedVersions = $ExistingVersions | Select-Object -Unique | |
Write-Host $combinedVersions | |
# newest first | |
$sortedVersionObj = (Sort-Versions -VersionArray $combinedVersions) | |
# write to file | |
$sortedVersionObj.RawVersionsList -join "`n" | Out-File -File "$($DocLocation)/versions" -Force -NoNewLine | |
$sortedVersionObj.LatestGAPackage | Out-File -File "$($DocLocation)/latest-ga" -Force -NoNewLine | |
$sortedVersionObj.LatestPreviewPackage | Out-File -File "$($DocLocation)/latest-preview" -Force -NoNewLine | |
& $($AzCopy) cp "$($DocLocation)/versions" "$($DocDest)/$($PkgName)/versioning/versions$($SASKey)" | |
& $($AzCopy) cp "$($DocLocation)/latest-preview" "$($DocDest)/$($PkgName)/versioning/latest-preview$($SASKey)" | |
& $($AzCopy) cp "$($DocLocation)/latest-ga" "$($DocDest)/$($PkgName)/versioning/latest-ga$($SASKey)" | |
} | |
# do a listblobs, listing everything | |
$LIST_EVERYTHING = "$BlobName/`$web/?restype=container&comp=list&prefix=$Language" | |
# find all the packages! | |
# this command pulls down elements that look like | |
# [ | |
# "python/azure-appconfiguration/", | |
# "python/azure-applicationinsights/", | |
# "python/azure-batch/", | |
# "python/azure-cognitiveservices-anomalydetector/", | |
# "python/azure-cognitiveservices-formrecognizer/", | |
# ... | |
# ] | |
if (!(Test-Path "$Language.json")) | |
{ | |
Write-Host "No cached listing" | |
az storage blob list --account-name $AccountName ` | |
--account-key $AccountKey --container-name "`$web" ` | |
--prefix "$Language/" --timeout 60 --num-results * ` | |
--delimiter '/' --query '[].name | [?ends_with(@, `/`)]' ` | |
| Out-File "$Language.json" | |
} | |
# write it to a json, get ready to partay! | |
$data = Get-Content "$Language.json" | ConvertFrom-Json | |
# at this point we have stuff of the form <language>/<packagename>/<other directory levels we don't care bout> | |
# this means that the first element of a split will ALWAYS be the package name | |
$pkgs = $data | % { ($_ -split "/")[1] } | Select-Object -Unique | |
# for each package name | |
foreach ($pkgName in $pkgs) | |
{ | |
$existingVersions = (az storage blob list --account-name $AccountName ` | |
--account-key $AccountKey --container-name "`$web" ` | |
--prefix "$Language/$pkgName/versions" --timeout 60 --num-results * ` | |
--query '[].name' ` | |
| ConvertFrom-Json ` | |
| % { $_.Replace("$Language/$pkgName/versions/", "").Trim() } ) | |
Write-Host "For $pkgName I see the following old-style versions" | |
Write-Host $existingVersions | |
# Update-Existing-Versions -ExistingVersions $existingVersions -PkgName $pkgName | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment