diff --git a/get-new-tool-versions/get-new-tool-versions.Tests.ps1 b/get-new-tool-versions/get-new-tool-versions.Tests.ps1 new file mode 100644 index 0000000..f16728b --- /dev/null +++ b/get-new-tool-versions/get-new-tool-versions.Tests.ps1 @@ -0,0 +1,93 @@ +#Requires -Modules Pester + +Import-Module (Join-Path $PSScriptRoot "helpers.psm1") -Force + +Describe "Validate-FiltersFormat" { + It "Filter with word" { + { Validate-FiltersFormat -Filters @("1two.2") } | Should -Throw "Invalid filter format" + } + + It "Filter with non-word character" { + { Validate-FiltersFormat -Filters @("1,.2") } | Should -Throw "Invalid filter format" + } + + It "Valid filters" { + { Validate-FiltersFormat -Filters @("*", "1", "1.*", "1.2", "1.2.*") } | Should -Not -Throw "Invalid filter format" + } +} + +Describe "Format-Versions" { + It "Clean versions" { + $actualOutput = Format-Versions -Versions @("14.2.0", "1.14.0") + $expectedOutput = @("14.2.0", "1.14.0") + $actualOutput | Should -Be $expectedOutput + } + + It "Versions with prefixes" { + $actualOutput = Format-Versions -Versions @("v14.2.0", "go1.14.0") + $expectedOutput = @("14.2.0", "1.14.0") + $actualOutput | Should -Be $expectedOutput + } + + It "Skip beta and rc versions" { + $actualOutput = Format-Versions -Versions @("14.2.0-beta", "v1.14.0-rc-1") + $expectedOutput = @() + $actualOutput | Should -Be $expectedOutput + } + + It "Short version" { + $actualOutput = Format-Versions -Versions @("14.2", "v2.0") + $expectedOutput = @("14.2.0", "2.0.0") + $actualOutput | Should -Be $expectedOutput + } + + It "Skip versions with 1 digit" { + $actualOutput = Format-Versions -Versions @("14", "v2") + $expectedOutput = @() + $actualOutput | Should -Be $expectedOutput + } +} + +Describe "Select-VersionsByFilter" { + $inputVersions = @("8.2.1", "9.3.3", "10.0.2", "10.0.3", "10.5.6", "12.4.3", "12.5.1", "14.2.0") + + It "Include filter only" { + $includeFilters = @("8.*", "14.*") + $excludeFilters = @() + $actualOutput = Select-VersionsByFilter -Versions $inputVersions -IncludeFilters $includeFilters -ExcludeFilters $excludeFilters + $expectedOutput = @("8.2.1", "14.2.0") + $actualOutput | Should -Be $expectedOutput + } + + It "Include and exclude filters" { + $includeFilters = @("10.*", "12.*") + $excludeFilters = @("10.0.*", "12.4.3") + $actualOutput = Select-VersionsByFilter -Versions $inputVersions -IncludeFilters $includeFilters -ExcludeFilters $excludeFilters + $expectedOutput = @("10.5.6", "12.5.1") + $actualOutput | Should -Be $expectedOutput + } + + It "Exclude filter only" { + $includeFilters = @() + $excludeFilters = @("10.*", "12.*") + $actualOutput = Select-VersionsByFilter -Versions $inputVersions -IncludeFilters $includeFilters -ExcludeFilters $excludeFilters + $expectedOutput = @("8.2.1", "9.3.3", "14.2.0") + $actualOutput | Should -Be $expectedOutput + } + + It "Include and exclude filters are empty" { + $actualOutput = Select-VersionsByFilter -Versions $inputVersions + $expectedOutput = @("8.2.1", "9.3.3", "10.0.2", "10.0.3", "10.5.6", "12.4.3", "12.5.1", "14.2.0") + $actualOutput | Should -Be $expectedOutput + } +} + +Describe "Skip-ExistingVersions" { + It "Substract versions correctly" { + $distInput = @("14.2.0", "14.3.0", "14.4.0", "14.4.1") + $manifestInput = @("12.0.0", "14.2.0", "14.4.0") + $actualOutput = Skip-ExistingVersions -VersionsFromDist $distInput -VersionsFromManifest $manifestInput + $expectedOutput = @("14.3.0", "14.4.1") + $actualOutput | Should -Be $expectedOutput + } +} \ No newline at end of file diff --git a/get-new-tool-versions/get-new-tool-versions.ps1 b/get-new-tool-versions/get-new-tool-versions.ps1 new file mode 100644 index 0000000..c6f42fe --- /dev/null +++ b/get-new-tool-versions/get-new-tool-versions.ps1 @@ -0,0 +1,79 @@ +<# +.SYNOPSIS +Check and return list of new available tool versions + +.PARAMETER DistURL +Required parameter. Link to the json file included all available tool versions +.PARAMETER ManifestLink +Required parameter. Link to the the version-manifest.json file +.PARAMETER VersionFilterToInclude +Optional parameter. List of filters to include particular versions +.PARAMETER VersionFilterToExclude +Optional parameter. List of filters to exclude particular versions +.PARAMETER RetryIntervalSec +Optional parameter. Retry interval in seconds +.PARAMETER RetryCount +Optional parameter. Retry count +#> + +param ( + [Parameter(Mandatory)] [string] $DistURL, + [Parameter(Mandatory)] [string] $ManifestLink, + [string[]] $VersionFilterToInclude, + [string[]] $VersionFilterToExclude, + [UInt32] $RetryIntervalSec = 60, + [UInt32] $RetryCount = 3 +) + +Import-Module (Join-Path $PSScriptRoot "helpers.psm1") + +function Get-VersionsByUrl { + param ( + [Parameter(Mandatory)] [string] $ToolPackagesUrl, + [Parameter(Mandatory)] [UInt32] $RetryIntervalSec, + [Parameter(Mandatory)] [UInt32] $RetryCount + ) + + $packages = Invoke-RestMethod $ToolPackagesUrl -MaximumRetryCount $RetryCount -RetryIntervalSec $RetryIntervalSec + return $packages.version +} + +if ($VersionFilterToInclude) { + Validate-FiltersFormat -Filters $VersionFilterToInclude +} + +if ($VersionFilterToExclude) { + Validate-FiltersFormat -Filters $VersionFilterToExclude +} + +Write-Host "Get the packages list from $DistURL" +$versionsFromDist = Get-VersionsByUrl -ToolPackagesUrl $DistURL ` + -RetryIntervalSec $RetryIntervalSec ` + -RetryCount $RetryCount + +Write-Host "Get the packages list from $ManifestLink" +[Version[]] $versionsFromManifest = Get-VersionsByUrl -ToolPackagesUrl $ManifestLink ` + -RetryIntervalSec $RetryIntervalSec ` + -RetryCount $RetryCount + +[Version[]] $formattedVersions = Format-Versions -Versions $versionsFromDist + +$formattedVersions = Select-VersionsByFilter -Versions $formattedVersions ` + -IncludeFilters $VersionFilterToInclude ` + -ExcludeFilters $VersionFilterToExclude + +if (-not $formattedVersions) { + Write-Host "Couldn't find available versions with current filters" + exit 1 +} + +$versionsToBuild = Skip-ExistingVersions -VersionsFromManifest $versionsFromManifest ` + -VersionsFromDist $formattedVersions + +if ($versionsToBuild) { + $availableVersions = $versionsToBuild -join "," + Write-Host "The following versions are available to build:`n$availableVersions" + Write-Output "##vso[task.setvariable variable=TOOL_VERSIONS]$availableVersions" +} else { + Write-Host "There aren't versions to build" +} diff --git a/get-new-tool-versions/helpers.psm1 b/get-new-tool-versions/helpers.psm1 new file mode 100644 index 0000000..2f9d582 --- /dev/null +++ b/get-new-tool-versions/helpers.psm1 @@ -0,0 +1,73 @@ +function Validate-FiltersFormat { + param ( + [Parameter(Mandatory)] [string[]] $Filters + ) + + foreach($filter in $Filters) { + $filter.Split('.') | ForEach-Object { + if (($_ -notmatch '^\d+$') -and ($_ -ne '*')) { + throw "Invalid filter format - $filter" + } + } + } +} + +function Format-Versions { + param ( + [Parameter(Mandatory)] [string[]] $Versions + ) + + [Version[]] $formattedVersions = @() + + foreach($version in $Versions) { + # Cut a string from index of first digit because initially it has invalid format (v14.4.0 or go1.14.4) + if (-not ($version -match '(?\d)')) { + Write-Host "Invalid version format - $version" + exit 1 + } + $firstDigitIndex = $version.indexof($Matches.number) + $substredVersion = $version.substring($firstDigitIndex) + + # Filter versions to exclude unstable (for example: "go1.15beta1") + # Valid version format: x.x or x.x.x + if ($substredVersion -notmatch '^\d+\.+\d+\.*\d*$') { + continue + } + + if ($substredVersion.Split(".").Length -lt 3) { + $formattedVersions += "$substredVersion.0" + } else { + $formattedVersions += $substredVersion + } + } + + return $formattedVersions +} + +function Select-VersionsByFilter { + param ( + [Parameter(Mandatory)] [version[]] $Versions, + [string[]] $IncludeFilters, + [string[]] $ExcludeFilters + ) + + if ($IncludeFilters.Length -eq 0) { + $IncludeFilters = @('*') + } + + return $Versions | Where-Object { + $ver = $_ + $matchedIncludeFilters = $IncludeFilters | Where-Object { $ver -like $_ } + $matchedExcludeFilters = $ExcludeFilters | Where-Object { $ver -like $_ } + $matchedIncludeFilters -and (-not $matchedExcludeFilters) + } +} + +function Skip-ExistingVersions { + param ( + [Parameter(Mandatory)] [string[]] $VersionsFromManifest, + [Parameter(Mandatory)] [string[]] $VersionsFromDist + ) + + return $VersionsFromDist | Where-Object { $VersionsFromManifest -notcontains $_ } +} \ No newline at end of file