mirror of
https://github.com/actions/versions-package-tools.git
synced 2025-12-10 11:41:23 +00:00
Compare commits
1 Commits
malob/supp
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71775b6820 |
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@@ -1 +0,0 @@
|
||||
* @actions/virtual-environments-owners
|
||||
@@ -1,37 +0,0 @@
|
||||
name: $(date:yyyyMMdd)$(rev:.r)
|
||||
trigger: none
|
||||
pr: none
|
||||
schedules:
|
||||
- cron: "0 8 * * Thu"
|
||||
displayName: Daily build
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
always: true
|
||||
|
||||
variables:
|
||||
PoolName: 'Azure Pipelines'
|
||||
VmImage: 'ubuntu-18.04'
|
||||
|
||||
stages:
|
||||
- stage: Find_New_Versions
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- job: Find_New_Versions
|
||||
pool:
|
||||
name: $(PoolName)
|
||||
vmImage: $(VmImage)
|
||||
steps:
|
||||
- template: /azure-pipelines/templates/get-tool-versions-steps.yml
|
||||
|
||||
- stage: Check_New_Versions
|
||||
dependsOn: Find_New_Versions
|
||||
jobs:
|
||||
- job: Check_New_Versions
|
||||
pool:
|
||||
name: $(PoolName)
|
||||
vmImage: $(VmImage)
|
||||
variables:
|
||||
ToolVersions: $[ stageDependencies.Find_New_Versions.Find_New_Versions.outputs['Get_versions.TOOL_VERSIONS'] ]
|
||||
steps:
|
||||
- template: /azure-pipelines/templates/check-versions.yml
|
||||
@@ -20,38 +20,25 @@ variables:
|
||||
VmImage: 'ubuntu-18.04'
|
||||
|
||||
stages:
|
||||
- stage: Find_New_Versions
|
||||
- stage: Get_New_Versions
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- job: Find_New_Versions
|
||||
- job: Get_Tool_Versions
|
||||
pool:
|
||||
name: $(PoolName)
|
||||
vmImage: $(VmImage)
|
||||
steps:
|
||||
- template: /azure-pipelines/templates/get-tool-versions-steps.yml
|
||||
|
||||
- stage: Check_New_Versions
|
||||
dependsOn: Find_New_Versions
|
||||
jobs:
|
||||
- job: Check_New_Versions
|
||||
pool:
|
||||
name: $(PoolName)
|
||||
vmImage: $(VmImage)
|
||||
variables:
|
||||
ToolVersions: $[ stageDependencies.Find_New_Versions.Find_New_Versions.outputs['Get_versions.TOOL_VERSIONS'] ]
|
||||
steps:
|
||||
- template: /azure-pipelines/templates/check-versions.yml
|
||||
|
||||
- stage: Trigger_Builds
|
||||
dependsOn: [Find_New_Versions, Check_New_Versions]
|
||||
condition: and(succeeded(), ne(variables['WORKFLOW_FILE_NAME'], ''))
|
||||
dependsOn: Get_New_Versions
|
||||
jobs:
|
||||
- deployment: Run_Builds
|
||||
pool:
|
||||
name: $(PoolName)
|
||||
vmImage: $(VmImage)
|
||||
variables:
|
||||
ToolVersions: $[ stageDependencies.Find_New_Versions.Find_New_Versions.outputs['Get_versions.TOOL_VERSIONS'] ]
|
||||
ToolVersions: $[ stageDependencies.Get_New_Versions.Get_Tool_Versions.outputs['Get_versions.TOOL_VERSIONS'] ]
|
||||
timeoutInMinutes: 180
|
||||
environment: 'Get Available Tools Versions - Publishing Approval'
|
||||
strategy:
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
steps:
|
||||
- task: PowerShell@2
|
||||
displayName: Check Versions
|
||||
condition: and(succeeded(), eq(variables.ToolVersions, ''))
|
||||
inputs:
|
||||
TargetType: inline
|
||||
script: |
|
||||
Write-Host "No new versions were found"
|
||||
Import-Module "./azure-devops/azure-devops-api.ps1"
|
||||
|
||||
$azureDevOpsApi = Get-AzureDevOpsApi -TeamFoundationCollectionUri $(System.TeamFoundationCollectionUri) `
|
||||
-ProjectName $(System.TeamProject) `
|
||||
-AccessToken $(System.AccessToken)
|
||||
|
||||
$AzureDevOpsApi.UpdateBuildStatus($(Build.BuildId), 'Cancelling') | Out-Null
|
||||
Start-Sleep -Seconds 60
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Set PIPELINE_URL variable'
|
||||
inputs:
|
||||
TargetType: inline
|
||||
script: |
|
||||
$ToolName = "$(TOOL_NAME)"
|
||||
if ($ToolName -in @("Python", "Xamarin")) {
|
||||
$PipelineUrl = " "
|
||||
} else {
|
||||
$PipelineUrl = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_build/results?buildId=$(Build.BuildId)"
|
||||
}
|
||||
Write-Host "##vso[task.setvariable variable=PIPELINE_URL]$PipelineUrl"
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Change build name'
|
||||
inputs:
|
||||
TargetType: inline
|
||||
script: |
|
||||
$newBuildName = "[FOUND] $(Build.BuildNumber)"
|
||||
Write-Host "##vso[build.updatebuildnumber]$newBuildName"
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Send Slack notification'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: './get-new-tool-versions/send-slack-notification.ps1'
|
||||
arguments: |
|
||||
-Url "$(SLACK_CHANNEL_URL)" `
|
||||
-ToolName "$(TOOL_NAME)" `
|
||||
-ToolVersion "$(ToolVersions)" `
|
||||
-PipelineUrl "$(PIPELINE_URL)" `
|
||||
-ImageUrl "$(IMAGE_URL)"
|
||||
@@ -6,4 +6,42 @@ steps:
|
||||
targetType: filePath
|
||||
filePath: './get-new-tool-versions/get-new-tool-versions.ps1'
|
||||
arguments: |
|
||||
-ToolName "$(TOOL_NAME)"
|
||||
-DistURL "$(DIST_URL)" `
|
||||
-ManifestLink "$(MANIFEST_URL)" `
|
||||
-VersionFilterToInclude $(INCLUDE_FILTER) `
|
||||
-VersionFilterToExclude $(EXCLUDE_FILTER)
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Cancel build'
|
||||
condition: and(succeeded(), eq(variables['Get_versions.TOOL_VERSIONS'], ''))
|
||||
inputs:
|
||||
TargetType: inline
|
||||
script: |
|
||||
Import-Module "./azure-devops/azure-devops-api.ps1"
|
||||
$azureDevOpsApi = Get-AzureDevOpsApi -TeamFoundationCollectionUri $(System.TeamFoundationCollectionUri) `
|
||||
-ProjectName $(System.TeamProject) `
|
||||
-AccessToken $(System.AccessToken)
|
||||
|
||||
$AzureDevOpsApi.UpdateBuildStatus($(Build.BuildId), 'Cancelling') | Out-Null
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Set env variable'
|
||||
condition: and(succeeded(), ne(variables['Get_versions.TOOL_VERSIONS'], ''))
|
||||
inputs:
|
||||
TargetType: inline
|
||||
script: |
|
||||
$PipelineUrl = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_build/results?buildId=$(Build.BuildId)"
|
||||
Write-Output "##vso[task.setvariable variable=PIPELINE_URL]$PipelineUrl"
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Send Slack notification'
|
||||
condition: and(succeeded(), ne(variables['Get_versions.TOOL_VERSIONS'], ''))
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: './get-new-tool-versions/send-slack-notification.ps1'
|
||||
arguments: |
|
||||
-Url "$(SLACK_CHANNEL_URL)" `
|
||||
-ToolName "$(TOOL_NAME)" `
|
||||
-ToolVersion "$(Get_versions.TOOL_VERSIONS)" `
|
||||
-PipelineUrl "$(PIPELINE_URL)" `
|
||||
-ImageUrl "$(IMAGE_URL)"
|
||||
|
||||
@@ -1,15 +1,29 @@
|
||||
steps:
|
||||
- checkout: self
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Get source version'
|
||||
inputs:
|
||||
TargetType: inline
|
||||
script: |
|
||||
$url = "https://api.github.com/repos/$(REPOSITORY)/commits/$(BRANCH)"
|
||||
$commit = Invoke-RestMethod -Uri $url -Method "GET"
|
||||
Write-Output "##vso[task.setvariable variable=COMMIT_SHA]$($commit.sha)"
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: 'Run builds'
|
||||
inputs:
|
||||
targetType: filePath
|
||||
filePath: './github/run-ci-builds.ps1'
|
||||
filePath: './azure-devops/run-ci-builds.ps1'
|
||||
arguments: |
|
||||
-RepositoryFullName $(REPOSITORY_FULL_NAME) `
|
||||
-AccessToken $(GITHUB_TOKEN) `
|
||||
-WorkflowFileName $(WORKFLOW_FILE_NAME) `
|
||||
-WorkflowDispatchRef $(DISPATCH_REF) `
|
||||
-TeamFoundationCollectionUri $(System.TeamFoundationCollectionUri) `
|
||||
-AzureDevOpsProjectName $(System.TeamProject) `
|
||||
-AzureDevOpsAccessToken $(System.AccessToken) `
|
||||
-SourceBranch $(BRANCH) `
|
||||
-DefinitionId $(DEFINITION_ID) `
|
||||
-SourceVersion $(COMMIT_SHA) `
|
||||
-ManifestLink $(MANIFEST_URL) `
|
||||
-WaitForBuilds $(WAIT_FOR_BUILDS) `
|
||||
-ToolVersions "$(ToolVersions)" `
|
||||
-PublishReleases $(PUPLISH_RELEASES)
|
||||
-RetryIntervalSec $(INTERVAL_SEC) `
|
||||
-RetryCount $(RETRY_COUNT)
|
||||
|
||||
@@ -3,11 +3,6 @@ param (
|
||||
)
|
||||
|
||||
$targetPath = $env:AGENT_TOOLSDIRECTORY
|
||||
if ([string]::IsNullOrEmpty($targetPath)) {
|
||||
# GitHub Windows images don't have `AGENT_TOOLSDIRECTORY` variable
|
||||
$targetPath = $env:RUNNER_TOOL_CACHE
|
||||
}
|
||||
|
||||
if ($ToolName) {
|
||||
$targetPath = Join-Path $targetPath $ToolName
|
||||
}
|
||||
|
||||
@@ -83,26 +83,3 @@ function IsNixPlatform {
|
||||
|
||||
return ($Platform -match "macos") -or ($Platform -match "darwin") -or ($Platform -match "ubuntu") -or ($Platform -match "linux")
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Get root directory of selected tool
|
||||
#>
|
||||
function GetToolDirectory {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[String]$ToolName,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[String]$Version,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[String]$Architecture
|
||||
)
|
||||
$targetPath = $env:AGENT_TOOLSDIRECTORY
|
||||
if ([string]::IsNullOrEmpty($targetPath)) {
|
||||
# GitHub Windows images don't have `AGENT_TOOLSDIRECTORY` variable
|
||||
$targetPath = $env:RUNNER_TOOL_CACHE
|
||||
}
|
||||
$ToolcachePath = Join-Path -Path $targetPath -ChildPath $ToolName
|
||||
$ToolcacheVersionPath = Join-Path -Path $ToolcachePath -ChildPath $Version
|
||||
return Join-Path $ToolcacheVersionPath $Architecture
|
||||
}
|
||||
|
||||
93
get-new-tool-versions/get-new-tool-versions.Tests.ps1
Normal file
93
get-new-tool-versions/get-new-tool-versions.Tests.ps1
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -2,34 +2,79 @@
|
||||
.SYNOPSIS
|
||||
Check and return list of new available tool versions
|
||||
|
||||
.PARAMETER ToolName
|
||||
Required parameter. The name of tool for which parser is available (Node, Go, Python, Xamarin)
|
||||
.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] $ToolName
|
||||
[Parameter(Mandatory)] [string] $DistURL,
|
||||
[Parameter(Mandatory)] [string] $ManifestLink,
|
||||
[string[]] $VersionFilterToInclude,
|
||||
[string[]] $VersionFilterToExclude,
|
||||
[UInt32] $RetryIntervalSec = 60,
|
||||
[UInt32] $RetryCount = 3
|
||||
)
|
||||
|
||||
Import-Module "$PSScriptRoot/parsers/parsers-factory.psm1"
|
||||
Import-Module (Join-Path $PSScriptRoot "helpers.psm1")
|
||||
|
||||
$ToolVersionParser = Get-ToolVersionsParser -ToolName $ToolName
|
||||
$VersionsFromDist = $ToolVersionParser.GetAvailableVersions()
|
||||
$VersionsFromManifest = $ToolVersionParser.GetUploadedVersions()
|
||||
function Get-VersionsByUrl {
|
||||
param (
|
||||
[Parameter(Mandatory)] [string] $ToolPackagesUrl,
|
||||
[Parameter(Mandatory)] [UInt32] $RetryIntervalSec,
|
||||
[Parameter(Mandatory)] [UInt32] $RetryCount
|
||||
)
|
||||
|
||||
$joinChars = ", "
|
||||
if ($ToolName -eq "Xamarin") {
|
||||
$VersionsToBuild = $VersionsFromDist | Where-Object { $VersionsFromManifest[$_.name] -notcontains $_.version } | ForEach-Object {[string]::Empty} {
|
||||
'{0,-15} : {1}' -f $_.name, $_.version
|
||||
}
|
||||
$joinChars = "\n\t"
|
||||
} else {
|
||||
$VersionsToBuild = $VersionsFromDist | Where-Object { $VersionsFromManifest -notcontains $_ }
|
||||
$packages = Invoke-RestMethod $ToolPackagesUrl -MaximumRetryCount $RetryCount -RetryIntervalSec $RetryIntervalSec
|
||||
return $packages.version
|
||||
}
|
||||
|
||||
if ($VersionsToBuild) {
|
||||
$availableVersions = $VersionsToBuild -join $joinChars
|
||||
Write-Host "The following versions are available to build:`n${availableVersions}"
|
||||
Write-Host "##vso[task.setvariable variable=TOOL_VERSIONS;isOutput=true]${availableVersions}"
|
||||
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 ","
|
||||
$toolVersions = $availableVersions.Replace(",",", ")
|
||||
Write-Host "The following versions are available to build:`n$toolVersions"
|
||||
Write-Output "##vso[task.setvariable variable=TOOL_VERSIONS;isOutput=true]$toolVersions"
|
||||
} else {
|
||||
Write-Host "There aren't versions to build"
|
||||
}
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
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
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
class BaseVersionsParser {
|
||||
[Int32]$ApiRetryCount = 3
|
||||
[Int32]$ApiRetryIntervalSeconds = 60
|
||||
|
||||
[SemVer[]] GetAvailableVersions() {
|
||||
$allVersionsRaw = $this.ParseAllAvailableVersions()
|
||||
$allVersions = $allVersionsRaw | ForEach-Object { $this.FormatVersion($_) }
|
||||
$filteredVersions = $allVersions | Where-Object { $this.ShouldIncludeVersion($_) }
|
||||
return $filteredVersions
|
||||
}
|
||||
|
||||
[SemVer[]] GetUploadedVersions() {
|
||||
throw "Method is not implemented in base class"
|
||||
}
|
||||
|
||||
hidden [SemVer[]] ParseAllAvailableVersions() {
|
||||
throw "Method is not implemented in base class"
|
||||
}
|
||||
|
||||
hidden [SemVer] FormatVersion([string]$VersionSpec) {
|
||||
throw "Method is not implemented in base class"
|
||||
}
|
||||
|
||||
hidden [bool] ShouldIncludeVersion([SemVer]$Version) {
|
||||
throw "Method is not implemented in base class"
|
||||
}
|
||||
|
||||
hidden [string] BuildGitHubFileUrl($OrganizationName, $RepositoryName, $BranchName, $FilePath) {
|
||||
return "https://raw.githubusercontent.com/${OrganizationName}/${RepositoryName}/${BranchName}/${FilePath}"
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using module "./base-parser.psm1"
|
||||
|
||||
class GoVersionsParser: BaseVersionsParser {
|
||||
[SemVer[]] GetUploadedVersions() {
|
||||
$url = $this.BuildGitHubFileUrl("actions", "go-versions", "main", "versions-manifest.json")
|
||||
$releases = Invoke-RestMethod $url -MaximumRetryCount $this.ApiRetryCount -RetryIntervalSec $this.ApiRetryIntervalSeconds
|
||||
return $releases.version
|
||||
}
|
||||
|
||||
hidden [string[]] ParseAllAvailableVersions() {
|
||||
$url = "https://golang.org/dl/?mode=json&include=all"
|
||||
$releases = Invoke-RestMethod $url -MaximumRetryCount $this.ApiRetryCount -RetryIntervalSec $this.ApiRetryIntervalSeconds
|
||||
return $releases.version
|
||||
}
|
||||
|
||||
hidden [SemVer] FormatVersion([string]$VersionSpec) {
|
||||
$cleanVersion = $VersionSpec -replace "^go", ""
|
||||
$semanticVersion = $cleanVersion -replace '(\d+\.\d+\.?\d*?)((?:alpha|beta|rc))(\d*)', '$1-$2.$3'
|
||||
return [SemVer]$semanticVersion
|
||||
}
|
||||
|
||||
hidden [bool] ShouldIncludeVersion([SemVer]$Version) {
|
||||
if ($Version.PreReleaseLabel) {
|
||||
return $false
|
||||
}
|
||||
|
||||
# For Go, we include all versions greater than 1.12
|
||||
return $Version -gt [SemVer]"1.12.0"
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using module "./base-parser.psm1"
|
||||
|
||||
class NodeVersionsParser: BaseVersionsParser {
|
||||
[SemVer[]] GetUploadedVersions() {
|
||||
$url = $this.BuildGitHubFileUrl("actions", "node-versions", "main", "versions-manifest.json")
|
||||
$releases = Invoke-RestMethod $url -MaximumRetryCount $this.ApiRetryCount -RetryIntervalSec $this.ApiRetryIntervalSeconds
|
||||
return $releases.version
|
||||
}
|
||||
|
||||
hidden [string[]] ParseAllAvailableVersions() {
|
||||
$url = "https://nodejs.org/dist/index.json"
|
||||
$releases = Invoke-RestMethod $url -MaximumRetryCount $this.ApiRetryCount -RetryIntervalSec $this.ApiRetryIntervalSeconds
|
||||
return $releases.version
|
||||
}
|
||||
|
||||
hidden [SemVer] FormatVersion([string]$VersionSpec) {
|
||||
$cleanVersion = $VersionSpec -replace "^v", ""
|
||||
return [SemVer]$cleanVersion
|
||||
}
|
||||
|
||||
hidden [bool] ShouldIncludeVersion([SemVer]$Version) {
|
||||
if ($Version.Major -lt 8) {
|
||||
return $false
|
||||
}
|
||||
|
||||
# For Node.JS, we should include all LTS versions (all even-numbered releases)
|
||||
# https://nodejs.org/en/about/releases/
|
||||
return $Version.Major % 2 -eq 0
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using module "./node-parser.psm1"
|
||||
using module "./go-parser.psm1"
|
||||
using module "./python-parser.psm1"
|
||||
using module "./xamarin-parser.psm1"
|
||||
|
||||
function Get-ToolVersionsParser {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string]$ToolName
|
||||
)
|
||||
|
||||
switch ($ToolName) {
|
||||
"Node" { return [NodeVersionsParser]::New() }
|
||||
"Go" { return [GoVersionsParser]::New() }
|
||||
"Python" { return [PythonVersionsParser]::New() }
|
||||
"Xamarin" { return [XamarinversionsParser]::New() }
|
||||
Default {
|
||||
throw "Unknown tool name"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
using module "./base-parser.psm1"
|
||||
|
||||
class PythonVersionsParser: BaseVersionsParser {
|
||||
[SemVer[]] GetUploadedVersions() {
|
||||
$url = $this.BuildGitHubFileUrl("actions", "python-versions", "main", "versions-manifest.json")
|
||||
$releases = Invoke-RestMethod $url -MaximumRetryCount $this.ApiRetryCount -RetryIntervalSec $this.ApiRetryIntervalSeconds
|
||||
return $releases.version
|
||||
}
|
||||
|
||||
hidden [string[]] ParseAllAvailableVersions() {
|
||||
$stableVersionsUrl = "https://www.python.org/ftp/python"
|
||||
$stableVersionsHtmlRaw = Invoke-WebRequest $stableVersionsUrl -MaximumRetryCount $this.ApiRetryCount -RetryIntervalSec $this.ApiRetryIntervalSeconds
|
||||
$stableVersionsList = $stableVersionsHtmlRaw.Links.href | Where-Object {
|
||||
$parsed = $null
|
||||
return $_.EndsWith("/") -and [SemVer]::TryParse($_.Replace("/", ""), [ref]$parsed)
|
||||
}
|
||||
|
||||
return $stableVersionsList | ForEach-Object {
|
||||
$subVersionsUrl = "${stableVersionsUrl}/${_}"
|
||||
$subVersionsHtmlRaw = Invoke-WebRequest $subVersionsUrl -MaximumRetryCount $this.ApiRetryCount -RetryIntervalSec $this.ApiRetryIntervalSeconds
|
||||
return $subVersionsHtmlRaw.Links.href | ForEach-Object {
|
||||
if ($_ -match "^Python-(\d+\.\d+\.\d+[a-z]{0,2}\d*)\.tgz$") {
|
||||
return $Matches[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hidden [SemVer] FormatVersion([string]$VersionSpec) {
|
||||
$VersionSpec -match "^(\d+)\.(\d+)\.(\d+)([a-z]{1,2})?(\d+)?$"
|
||||
|
||||
if ($Matches.Count -gt 4) {
|
||||
$VersionLabel = "{0}.{1}" -f $this.ConvertPythonLabel($Matches[4]), $Matches[5]
|
||||
return [SemVer]::new($Matches[1], $Matches[2], $Matches[3], $VersionLabel)
|
||||
}
|
||||
|
||||
return [SemVer]::new($Matches[1], $Matches[2], $Matches[3])
|
||||
}
|
||||
|
||||
hidden [string] ConvertPythonLabel([string]$Label) {
|
||||
switch ($Label) {
|
||||
"a" { return "alpha" }
|
||||
"b" { return "beta" }
|
||||
}
|
||||
|
||||
return $Label
|
||||
}
|
||||
|
||||
[bool] ShouldIncludeVersion([SemVer]$Version) {
|
||||
# For Python, we include all versions greater than 3.9.0
|
||||
return $Version -gt [SemVer]"3.9.0"
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using module "./base-parser.psm1"
|
||||
|
||||
class XamarinVersionsParser: BaseVersionsParser {
|
||||
[PSCustomObject] GetAvailableVersions() {
|
||||
$allVersions = $this.ParseAllAvailableVersions()
|
||||
return $allVersions
|
||||
}
|
||||
|
||||
[hashtable] GetUploadedVersions() {
|
||||
$url = $this.BuildGitHubFileUrl("actions", "virtual-environments", "main", "images/macos/toolsets/toolset-11.json")
|
||||
$releases = Invoke-RestMethod $url -MaximumRetryCount $this.ApiRetryCount -RetryIntervalSec $this.ApiRetryIntervalSeconds
|
||||
$xamarin = $releases.xamarin
|
||||
$xamarinReleases = @{
|
||||
'Mono Framework' = $xamarin.'mono-versions'
|
||||
'Xamarin.Android' = $xamarin.'android-versions'
|
||||
'Xamarin.iOS' = $xamarin.'ios-versions'
|
||||
'Xamarin.Mac' = $xamarin.'mac-versions'
|
||||
}
|
||||
return $xamarinReleases
|
||||
}
|
||||
|
||||
hidden [PSCustomObject] ParseAllAvailableVersions() {
|
||||
$url = "http://aka.ms/manifest/stable"
|
||||
$filteredProducts = @('Mono Framework', 'Xamarin.Android', 'Xamarin.iOS', 'Xamarin.Mac')
|
||||
$releases = Invoke-RestMethod $url -MaximumRetryCount $this.ApiRetryCount -RetryIntervalSec $this.ApiRetryIntervalSeconds
|
||||
$items = $releases.items
|
||||
$products = $items | Where-Object {$_.name -in $filteredProducts} | Sort-Object name | Select-Object name, version
|
||||
return $products
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,10 @@ param(
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[System.String]$ToolVersion,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[System.String]$PipelineUrl,
|
||||
|
||||
[System.String]$ImageUrl = 'https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png'
|
||||
)
|
||||
|
||||
@@ -35,14 +38,7 @@ param(
|
||||
Import-Module $PSScriptRoot/helpers.psm1 -DisableNameChecking
|
||||
|
||||
# Create JSON body
|
||||
if ($toolName -eq "Xamarin") {
|
||||
$text = "The following versions of '$toolName' are available, consider adding them to toolset: $toolVersion"
|
||||
} else {
|
||||
$text = "The following versions of '$toolName' are available to upload: $toolVersion"
|
||||
}
|
||||
if (-not ([string]::IsNullOrWhiteSpace($PipelineUrl))) {
|
||||
$text += "\nLink to the pipeline: $pipelineUrl"
|
||||
}
|
||||
$text = "The following versions of '$toolName' are available to upload: $toolVersion\nLink to the pipeline: $pipelineUrl"
|
||||
$jsonBodyMessage = @"
|
||||
{
|
||||
"blocks": [
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
.SYNOPSIS
|
||||
Create commit with all unstaged changes in repository and create pull-request
|
||||
|
||||
.PARAMETER RepositoryFullName
|
||||
Required parameter. The owner and repository name. For example, 'actions/versions-package-tools'
|
||||
.PARAMETER RepositoryOwner
|
||||
Required parameter. The organization which tool repository belongs
|
||||
.PARAMETER RepositoryName
|
||||
Optional parameter. The name of tool repository
|
||||
.PARAMETER AccessToken
|
||||
Required parameter. PAT Token to authorize
|
||||
.PARAMETER BranchName
|
||||
@@ -16,7 +18,8 @@ Required parameter. The title of pull-request
|
||||
Required parameter. The description of pull-request
|
||||
#>
|
||||
param (
|
||||
[Parameter(Mandatory)] [string] $RepositoryFullName,
|
||||
[Parameter(Mandatory)] [string] $RepositoryOwner,
|
||||
[Parameter(Mandatory)] [string] $RepositoryName,
|
||||
[Parameter(Mandatory)] [string] $AccessToken,
|
||||
[Parameter(Mandatory)] [string] $BranchName,
|
||||
[Parameter(Mandatory)] [string] $CommitMessage,
|
||||
@@ -43,11 +46,11 @@ function Update-PullRequest {
|
||||
|
||||
$updatedPullRequest = $GitHubApi.UpdatePullRequest($Title, $Body, $BranchName, $PullRequest.number)
|
||||
|
||||
if (($null -eq $updatedPullRequest) -or ($null -eq $updatedPullRequest.html_url)) {
|
||||
Write-Host "Unexpected error occurs while updating pull request."
|
||||
if (($updatedPullRequest -eq $null) -or ($updatedPullRequest.html_url -eq $null)) {
|
||||
Write-Host "##vso[task.logissue type=error;] Unexpected error occurs while updating pull request."
|
||||
exit 1
|
||||
}
|
||||
Write-host "Pull request updated: $($updatedPullRequest.html_url)"
|
||||
Write-host "##[section] Pull request updated: $($updatedPullRequest.html_url)"
|
||||
}
|
||||
|
||||
function Create-PullRequest {
|
||||
@@ -64,12 +67,12 @@ function Create-PullRequest {
|
||||
|
||||
$createdPullRequest = $GitHubApi.CreateNewPullRequest($Title, $Body, $BranchName)
|
||||
|
||||
if (($null -eq $createdPullRequest) -or ($null -eq $createdPullRequest.html_url)) {
|
||||
Write-Host "Unexpected error occurs while creating pull request."
|
||||
if (($createdPullRequest -eq $null) -or ($createdPullRequest.html_url -eq $null)) {
|
||||
Write-Host "##vso[task.logissue type=error;] Unexpected error occurs while creating pull request."
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-host "Pull request created: $($createdPullRequest.html_url)"
|
||||
Write-host "##[section] Pull request created: $($createdPullRequest.html_url)"
|
||||
}
|
||||
|
||||
Write-Host "Configure local git preferences"
|
||||
@@ -84,8 +87,8 @@ Git-CommitAllChanges -Message $CommitMessage
|
||||
Write-Host "Push branch: $BranchName"
|
||||
Git-PushBranch -Name $BranchName -Force $true
|
||||
|
||||
$gitHubApi = Get-GitHubApi -RepositoryFullName $RepositoryFullName -AccessToken $AccessToken
|
||||
$pullRequest = $gitHubApi.GetPullRequest($BranchName)
|
||||
$gitHubApi = Get-GitHubApi -AccountName $RepositoryOwner -ProjectName $RepositoryName -AccessToken $AccessToken
|
||||
$pullRequest = $gitHubApi.GetPullRequest($BranchName, $RepositoryOwner)
|
||||
|
||||
if ($pullRequest.Count -gt 0) {
|
||||
Write-Host "Update pull request"
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Trigger runs on the workflow_dispatch event to create tool release
|
||||
|
||||
.PARAMETER RepositoryFullName
|
||||
Required parameter. The owner and repository name. For example, 'actions/versions-package-tools'
|
||||
.PARAMETER AccessToken
|
||||
Required parameter. PAT Token to authorize
|
||||
.PARAMETER ToolVersion
|
||||
Required parameter. Version of tool
|
||||
.PARAMETER TagName
|
||||
Required parameter. The name of the release tag
|
||||
.PARAMETER ReleaseBody
|
||||
Required parameter. Text describing the contents of the release
|
||||
.PARAMETER EventType
|
||||
Required parameter. The name of the repository dispatch event
|
||||
#>
|
||||
|
||||
param (
|
||||
[Parameter(Mandatory)] [string] $RepositoryFullName,
|
||||
[Parameter(Mandatory)] [string] $AccessToken,
|
||||
[Parameter(Mandatory)] [string] $ToolVersion,
|
||||
[Parameter(Mandatory)] [string] $TagName,
|
||||
[Parameter(Mandatory)] [string] $ReleaseBody,
|
||||
[Parameter(Mandatory)] [string] $EventType,
|
||||
[UInt32] $RetryIntervalSec = 10,
|
||||
[UInt32] $RetryCount = 5
|
||||
)
|
||||
|
||||
Import-Module (Join-Path $PSScriptRoot "github-api.psm1")
|
||||
|
||||
function Create-Release {
|
||||
param (
|
||||
[Parameter(Mandatory)] [object] $GitHubApi,
|
||||
[Parameter(Mandatory)] [string] $ToolVersion,
|
||||
[Parameter(Mandatory)] [string] $TagName,
|
||||
[Parameter(Mandatory)] [string] $ReleaseBody,
|
||||
[Parameter(Mandatory)] [string] $EventType
|
||||
)
|
||||
|
||||
$eventPayload = @{
|
||||
ToolVersion = $ToolVersion
|
||||
TagName = $TagName
|
||||
ReleaseBody = $ReleaseBody
|
||||
}
|
||||
|
||||
Write-Host "Create '$EventType' repository dispatch event"
|
||||
$GitHubApi.CreateRepositoryDispatch($EventType, $eventPayload)
|
||||
}
|
||||
|
||||
function Validate-ReleaseAvailability {
|
||||
param (
|
||||
[Parameter(Mandatory)] [object] $GitHubApi,
|
||||
[Parameter(Mandatory)] [string] $TagName,
|
||||
[Parameter(Mandatory)] [UInt32] $RetryIntervalSec,
|
||||
[Parameter(Mandatory)] [UInt32] $RetryCount
|
||||
)
|
||||
|
||||
do {
|
||||
$createdRelease = $GitHubApi.GetReleases() | Where-Object { $_.tag_name -eq $TagName }
|
||||
if ($createdRelease) {
|
||||
Write-Host "Release was successfully created: $($createdRelease.html_url)"
|
||||
return
|
||||
}
|
||||
|
||||
$RetryCount--
|
||||
Start-Sleep -Seconds $RetryIntervalSec
|
||||
} while($RetryCount -gt 0)
|
||||
|
||||
Write-Host "Release was not created"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$gitHubApi = Get-GitHubApi -RepositoryFullName $RepositoryFullName -AccessToken $AccessToken
|
||||
|
||||
Create-Release -GitHubApi $gitHubApi `
|
||||
-ToolVersion $ToolVersion `
|
||||
-TagName $TagName `
|
||||
-ReleaseBody $ReleaseBody `
|
||||
-EventType $EventType
|
||||
|
||||
Start-Sleep -s $RetryIntervalSec
|
||||
Validate-ReleaseAvailability -GitHubApi $gitHubApi `
|
||||
-TagName $TagName `
|
||||
-RetryIntervalSec $RetryIntervalSec `
|
||||
-RetryCount $RetryCount
|
||||
@@ -5,8 +5,8 @@ The module that contains a bunch of methods to interact with GitHub API V3
|
||||
class GitHubApi
|
||||
{
|
||||
[string] $BaseUrl
|
||||
[string] $RepoOwner
|
||||
[object] $AuthHeader
|
||||
[string] $RepositoryOwner
|
||||
|
||||
GitHubApi(
|
||||
[string] $AccountName,
|
||||
@@ -15,7 +15,6 @@ class GitHubApi
|
||||
) {
|
||||
$this.BaseUrl = $this.BuildBaseUrl($AccountName, $ProjectName)
|
||||
$this.AuthHeader = $this.BuildAuth($AccessToken)
|
||||
$this.RepositoryOwner = $AccountName
|
||||
}
|
||||
|
||||
[object] hidden BuildAuth([string]$AccessToken) {
|
||||
@@ -44,9 +43,9 @@ class GitHubApi
|
||||
return $this.InvokeRestMethod($url, 'Post', $null, $requestBody)
|
||||
}
|
||||
|
||||
[object] GetPullRequest([string]$BranchName){
|
||||
[object] GetPullRequest([string]$BranchName, [string]$RepositoryOwner){
|
||||
$url = "pulls"
|
||||
return $this.InvokeRestMethod($url, 'GET', "head=$($this.RepositoryOwner):${BranchName}&base=main", $null)
|
||||
return $this.InvokeRestMethod($url, 'GET', "head=${RepositoryOwner}:$BranchName&base=main", $null)
|
||||
}
|
||||
|
||||
[object] UpdatePullRequest([string]$Title, [string]$Body, [string]$BranchName, [string]$PullRequestNumber){
|
||||
@@ -83,39 +82,6 @@ class GitHubApi
|
||||
return $releases
|
||||
}
|
||||
|
||||
[void] CreateRepositoryDispatch([string]$EventType, [object]$EventPayload) {
|
||||
$url = "dispatches"
|
||||
$body = @{
|
||||
event_type = $EventType
|
||||
client_payload = $EventPayload
|
||||
} | ConvertTo-Json
|
||||
|
||||
$this.InvokeRestMethod($url, 'POST', $null, $body)
|
||||
}
|
||||
|
||||
[object] GetWorkflowRuns([string]$WorkflowFileName) {
|
||||
$url = "actions/workflows/$WorkflowFileName/runs"
|
||||
return $this.InvokeRestMethod($url, 'GET', $null, $null)
|
||||
}
|
||||
|
||||
[object] GetWorkflowRunJobs([string]$WorkflowRunId) {
|
||||
$url = "actions/runs/$WorkflowRunId/jobs"
|
||||
return $this.InvokeRestMethod($url, 'GET', $null, $null)
|
||||
}
|
||||
|
||||
[void] CreateWorkflowDispatch([string]$WorkflowFileName, [string]$Ref, [object]$Inputs) {
|
||||
$url = "actions/workflows/${WorkflowFileName}/dispatches"
|
||||
$body = @{ ref = $Ref }
|
||||
|
||||
if ($Inputs) {
|
||||
$body.inputs = $Inputs
|
||||
}
|
||||
|
||||
$jsonBody = $body | ConvertTo-Json
|
||||
|
||||
$this.InvokeRestMethod($url, 'POST', $null, $jsonBody)
|
||||
}
|
||||
|
||||
[string] hidden BuildUrl([string]$Url, [string]$RequestParams) {
|
||||
if ([string]::IsNullOrEmpty($RequestParams)) {
|
||||
return "$($this.BaseUrl)/$($Url)"
|
||||
@@ -151,18 +117,10 @@ class GitHubApi
|
||||
|
||||
function Get-GitHubApi {
|
||||
param (
|
||||
[Parameter(ParameterSetName = 'RepositorySingle')]
|
||||
[string] $RepositoryFullName,
|
||||
[Parameter(ParameterSetName = 'RepositorySplitted')]
|
||||
[string] $RepositoryOwner,
|
||||
[Parameter(ParameterSetName = 'RepositorySplitted')]
|
||||
[string] $RepositoryName,
|
||||
[string] $AccountName,
|
||||
[string] $ProjectName,
|
||||
[string] $AccessToken
|
||||
)
|
||||
|
||||
if ($PSCmdlet.ParameterSetName -eq "RepositorySingle") {
|
||||
$RepositoryOwner, $RepositoryName = $RepositoryFullName.Split('/', 2)
|
||||
}
|
||||
|
||||
return [GitHubApi]::New($RepositoryOwner, $RepositoryName, $AccessToken)
|
||||
return [GitHubApi]::New($AccountName, $ProjectName, $AccessToken)
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Trigger runs on the workflow_dispatch event to build and upload tool packages
|
||||
|
||||
.PARAMETER RepositoryFullName
|
||||
Required parameter. The owner and repository name. For example, 'actions/versions-package-tools'
|
||||
.PARAMETER AccessToken
|
||||
Required parameter. PAT to authorize
|
||||
.PARAMETER WorkflowFileName
|
||||
Required parameter. The name of workflow file that will be triggered
|
||||
.PARAMETER WorkflowDispatchRef
|
||||
Required parameter. The reference of the workflow run. The reference can be a branch, tag, or a commit SHA.
|
||||
.PARAMETER ToolVersions
|
||||
Required parameter. List of tool versions to build and upload
|
||||
.PARAMETER PublishReleases
|
||||
Required parameter. Whether to publish releases, true or false
|
||||
#>
|
||||
|
||||
param (
|
||||
[Parameter(Mandatory)] [string] $RepositoryFullName,
|
||||
[Parameter(Mandatory)] [string] $AccessToken,
|
||||
[Parameter(Mandatory)] [string] $WorkflowFileName,
|
||||
[Parameter(Mandatory)] [string] $WorkflowDispatchRef,
|
||||
[Parameter(Mandatory)] [string] $ToolVersions,
|
||||
[Parameter(Mandatory)] [string] $PublishReleases
|
||||
)
|
||||
|
||||
Import-Module (Join-Path $PSScriptRoot "github-api.psm1")
|
||||
|
||||
function Get-WorkflowRunLink {
|
||||
param(
|
||||
[Parameter(Mandatory)] [object] $GitHubApi,
|
||||
[Parameter(Mandatory)] [string] $WorkflowFileName,
|
||||
[Parameter(Mandatory)] [string] $ToolVersion
|
||||
)
|
||||
|
||||
$listWorkflowRuns = $GitHubApi.GetWorkflowRuns($WorkflowFileName).workflow_runs | Sort-Object -Property 'run_number' -Descending
|
||||
|
||||
foreach ($workflowRun in $listWorkflowRuns) {
|
||||
$workflowRunJob = $gitHubApi.GetWorkflowRunJobs($workflowRun.id).jobs | Select-Object -First 1
|
||||
|
||||
if ($workflowRunJob.name -match $ToolVersion) {
|
||||
return $workflowRun.html_url
|
||||
}
|
||||
}
|
||||
|
||||
return $null
|
||||
}
|
||||
|
||||
function Queue-Builds {
|
||||
param (
|
||||
[Parameter(Mandatory)] [object] $GitHubApi,
|
||||
[Parameter(Mandatory)] [string] $ToolVersions,
|
||||
[Parameter(Mandatory)] [string] $WorkflowFileName,
|
||||
[Parameter(Mandatory)] [string] $WorkflowDispatchRef,
|
||||
[Parameter(Mandatory)] [string] $PublishReleases
|
||||
)
|
||||
|
||||
$inputs = @{
|
||||
PUBLISH_RELEASES = $PublishReleases
|
||||
}
|
||||
|
||||
$ToolVersions.Split(',') | ForEach-Object {
|
||||
$version = $_.Trim()
|
||||
$inputs.VERSION = $version
|
||||
|
||||
Write-Host "Queue build for $version..."
|
||||
$GitHubApi.CreateWorkflowDispatch($WorkflowFileName, $WorkflowDispatchRef, $inputs)
|
||||
|
||||
Start-Sleep -s 10
|
||||
$workflowRunLink = Get-WorkflowRunLink -GitHubApi $GitHubApi `
|
||||
-WorkflowFileName $WorkflowFileName `
|
||||
-ToolVersion $version
|
||||
|
||||
if (-not $workflowRunLink) {
|
||||
Write-Host "Could not find build for $version..."
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "Link to the build: $workflowRunLink"
|
||||
}
|
||||
}
|
||||
|
||||
$gitHubApi = Get-GitHubApi -RepositoryFullName $RepositoryFullName -AccessToken $AccessToken
|
||||
|
||||
Write-Host "Versions to build: $ToolVersions"
|
||||
Queue-Builds -GitHubApi $gitHubApi `
|
||||
-ToolVersions $ToolVersions `
|
||||
-WorkflowFileName $WorkflowFileName `
|
||||
-WorkflowDispatchRef $WorkflowDispatchRef `
|
||||
-PublishReleases $PublishReleases
|
||||
@@ -1,10 +1,13 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Generate versions manifest based on repository releases
|
||||
|
||||
.DESCRIPTION
|
||||
Versions manifest is needed to find the latest assets for particular version of tool
|
||||
.PARAMETER RepositoryFullName
|
||||
Required parameter. The owner and repository name. For example, 'actions/versions-package-tools'
|
||||
.PARAMETER GitHubRepositoryOwner
|
||||
Required parameter. The organization which tool repository belongs
|
||||
.PARAMETER GitHubRepositoryName
|
||||
Required parameter. The name of tool repository
|
||||
.PARAMETER GitHubAccessToken
|
||||
Required parameter. PAT Token to overcome GitHub API Rate limit
|
||||
.PARAMETER OutputFile
|
||||
@@ -14,7 +17,8 @@ Path to the json file with parsing configuration
|
||||
#>
|
||||
|
||||
param (
|
||||
[Parameter(Mandatory)] [string] $RepositoryFullName,
|
||||
[Parameter(Mandatory)] [string] $GitHubRepositoryOwner,
|
||||
[Parameter(Mandatory)] [string] $GitHubRepositoryName,
|
||||
[Parameter(Mandatory)] [string] $GitHubAccessToken,
|
||||
[Parameter(Mandatory)] [string] $OutputFile,
|
||||
[Parameter(Mandatory)] [string] $ConfigurationFile
|
||||
@@ -25,7 +29,7 @@ Import-Module (Join-Path $PSScriptRoot "manifest-utils.psm1") -Force
|
||||
|
||||
$configuration = Read-ConfigurationFile -Filepath $ConfigurationFile
|
||||
|
||||
$gitHubApi = Get-GitHubApi -RepositoryFullName $RepositoryFullName -AccessToken $GitHubAccessToken
|
||||
$gitHubApi = Get-GitHubApi -AccountName $GitHubRepositoryOwner -ProjectName $GitHubRepositoryName -AccessToken $GitHubAccessToken
|
||||
$releases = $gitHubApi.GetReleases()
|
||||
$versionIndex = Build-VersionsManifest -Releases $releases -Configuration $configuration
|
||||
$versionIndex | ConvertTo-Json -Depth 5 | Out-File $OutputFile -Encoding UTF8NoBOM -Force
|
||||
|
||||
@@ -126,7 +126,7 @@ Describe "Build-VersionsManifest" {
|
||||
[PSCustomObject]@{ version = "3.8.3"; stable = $true; release_url = "fake_html_url"; files = $expectedManifestFiles }
|
||||
)
|
||||
[array]$actualManifest = Build-VersionsManifest -Releases $releases -Configuration $configuration
|
||||
Assert-Equivalent -Actual $actualManifest -Expected $expectedManifest
|
||||
Assert-Equivalent -Actual $actualManifest -Expected $expectedManifest
|
||||
}
|
||||
|
||||
It "take latest published release for each version" {
|
||||
@@ -141,74 +141,4 @@ Describe "Build-VersionsManifest" {
|
||||
[array]$actualManifest = Build-VersionsManifest -Releases $releases -Configuration $configuration
|
||||
Assert-Equivalent -Actual $actualManifest -Expected $expectedManifest
|
||||
}
|
||||
|
||||
It "build correct manifest if release includes one asset" {
|
||||
$asset = @(
|
||||
@{ name = "python-3.8.3-linux-16.04-x64.tar.gz"; browser_download_url = "fake_url"; }
|
||||
)
|
||||
$expectedManifestFile = @(
|
||||
[PSCustomObject]@{ filename = "python-3.8.3-linux-16.04-x64.tar.gz"; arch = "x64"; platform = "linux"; platform_version = "16.04"; download_url = "fake_url" }
|
||||
)
|
||||
|
||||
$releases = @(
|
||||
@{ name = "3.8.3"; draft = $false; prerelease = $false; html_url = "fake_html_url"; published_at = "2020-05-06T11:43:38Z"; assets = $asset },
|
||||
@{ name = "3.8.1"; draft = $false; prerelease = $false; html_url = "fake_html_url"; published_at = "2020-05-14T09:54:06Z"; assets = $assets }
|
||||
)
|
||||
$expectedManifest = @(
|
||||
[PSCustomObject]@{ version = "3.8.3"; stable = $true; release_url = "fake_html_url"; files = $expectedManifestFile },
|
||||
[PSCustomObject]@{ version = "3.8.1"; stable = $true; release_url = "fake_html_url"; files = $expectedManifestFiles }
|
||||
)
|
||||
[array]$actualManifest = Build-VersionsManifest -Releases $releases -Configuration $configuration
|
||||
Assert-Equivalent -Actual $actualManifest -Expected $expectedManifest
|
||||
}
|
||||
|
||||
It "set correct lts value for versions" {
|
||||
$releases = @(
|
||||
@{ name = "14.2.1"; draft = false; prerelease = $false; html_url = "fake_html_url"; published_at = "2020-05-14T09:54:06Z"; assets = $assets },
|
||||
@{ name = "12.0.1"; draft = $false; prerelease = false; html_url = "fake_html_url"; published_at = "2020-05-06T11:45:36Z"; assets = $assets },
|
||||
@{ name = "16.2.2"; draft = $false; prerelease = $false; html_url = "fake_html_url"; published_at = "2020-05-06T11:43:38Z"; assets = $assets }
|
||||
)
|
||||
$configuration = @{
|
||||
regex = "python-\d+\.\d+\.\d+-(\w+)-([\w\.]+)?-?(x\d+)";
|
||||
groups = [PSCustomObject]@{ platform = 1; platform_version = 2; arch = "x64"; }
|
||||
lts_rule_expression = "@(@{ Name = '14'; Value = 'Fermium' }, @{ Name = '12'; Value = 'Erbium' })"
|
||||
}
|
||||
$expectedManifest = @(
|
||||
[PSCustomObject]@{ version = "16.2.2"; stable = $true; release_url = "fake_html_url"; files = $expectedManifestFiles },
|
||||
[PSCustomObject]@{ version = "14.2.1"; stable = $true; lts = "Fermium"; release_url = "fake_html_url"; files = $expectedManifestFiles },
|
||||
[PSCustomObject]@{ version = "12.0.1"; stable = $true; lts = "Erbium"; release_url = "fake_html_url"; files = $expectedManifestFiles }
|
||||
)
|
||||
[array]$actualManifest = Build-VersionsManifest -Releases $releases -Configuration $configuration
|
||||
Assert-Equivalent -Actual $actualManifest -Expected $expectedManifest
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Get-VersionLtsStatus" {
|
||||
$ltsRules = @(
|
||||
@{ Name = "14"; Value = "Fermium" },
|
||||
@{ Name = "12"; Value = "Erbium" },
|
||||
@{ Name = "10"; Value = $true },
|
||||
@{ Name = "8.3"; Value = "LTS 8.3" }
|
||||
)
|
||||
|
||||
It "lts label is matched" {
|
||||
Get-VersionLtsStatus -Version "14.2.2" -LtsRules $ltsRules | Should -Be "Fermium"
|
||||
Get-VersionLtsStatus -Version "12.3.1" -LtsRules $ltsRules | Should -Be "Erbium"
|
||||
Get-VersionLtsStatus -Version "10.8.1" -LtsRules $ltsRules | Should -Be $true
|
||||
Get-VersionLtsStatus -Version "8.3.2" -LtsRules $ltsRules | Should -Be "LTS 8.3"
|
||||
Get-VersionLtsStatus -Version "14" -LtsRules $ltsRules | Should -Be "Fermium"
|
||||
}
|
||||
|
||||
It "lts label is not matched" {
|
||||
Get-VersionLtsStatus -Version "9.1" -LtsRules $ltsRules | Should -Be $null
|
||||
Get-VersionLtsStatus -Version "13.8" -LtsRules $ltsRules | Should -Be $null
|
||||
Get-VersionLtsStatus -Version "5" -LtsRules $ltsRules | Should -Be $null
|
||||
Get-VersionLtsStatus -Version "8.4" -LtsRules $ltsRules | Should -Be $null
|
||||
Get-VersionLtsStatus -Version "142.5.1" -LtsRules $ltsRules | Should -Be $null
|
||||
}
|
||||
|
||||
It "no rules" {
|
||||
Get-VersionLtsStatus -Version "14.2.2" | Should -Be $null
|
||||
Get-VersionLtsStatus -Version "12.3.1" -LtsRules $null | Should -Be $null
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,6 @@ function Build-VersionsManifest {
|
||||
)
|
||||
|
||||
$Releases = $Releases | Sort-Object -Property "published_at" -Descending
|
||||
$ltsRules = Get-LtsRules -Configuration $Configuration
|
||||
|
||||
$versionsHash = @{}
|
||||
foreach ($release in $Releases) {
|
||||
@@ -65,49 +64,15 @@ function Build-VersionsManifest {
|
||||
continue
|
||||
}
|
||||
|
||||
$ltsStatus = Get-VersionLtsStatus -Version $versionKey -LtsRules $ltsRules
|
||||
$stable = $version.PreReleaseLabel ? $false : $true
|
||||
[array]$releaseAssets = $release.assets | ForEach-Object { New-AssetItem -ReleaseAsset $_ -Configuration $Configuration }
|
||||
|
||||
$versionHash = [PSCustomObject]@{}
|
||||
$versionHash | Add-Member -Name "version" -Value $versionKey -MemberType NoteProperty
|
||||
$versionHash | Add-Member -Name "stable" -Value $stable -MemberType NoteProperty
|
||||
if ($ltsStatus) {
|
||||
$versionHash | Add-Member -Name "lts" -Value $ltsStatus -MemberType NoteProperty
|
||||
}
|
||||
$versionHash | Add-Member -Name "release_url" -Value $release.html_url -MemberType NoteProperty
|
||||
$versionHash | Add-Member -Name "files" -Value $releaseAssets -MemberType NoteProperty
|
||||
$versionsHash.Add($versionKey, $versionHash)
|
||||
$versionsHash.Add($versionKey, [PSCustomObject]@{
|
||||
version = $versionKey
|
||||
stable = $stable
|
||||
release_url = $release.html_url
|
||||
files = $release.assets | ForEach-Object { New-AssetItem -ReleaseAsset $_ -Configuration $Configuration }
|
||||
})
|
||||
}
|
||||
|
||||
# Sort versions by descending
|
||||
return $versionsHash.Values | Sort-Object -Property @{ Expression = { [Semver]$_.version }; Descending = $true }
|
||||
}
|
||||
|
||||
function Get-LtsRules {
|
||||
param (
|
||||
[Parameter(Mandatory)][object]$Configuration
|
||||
)
|
||||
|
||||
$ruleExpression = $Configuration."lts_rule_expression"
|
||||
if ($ruleExpression) {
|
||||
Invoke-Expression $ruleExpression
|
||||
} else {
|
||||
@()
|
||||
}
|
||||
}
|
||||
|
||||
function Get-VersionLtsStatus {
|
||||
param (
|
||||
[Parameter(Mandatory)][string]$Version,
|
||||
[array]$LtsRules
|
||||
)
|
||||
|
||||
foreach ($ltsRule in $LtsRules) {
|
||||
if (($Version -eq $ltsRule.Name) -or ($Version.StartsWith("$($ltsRule.Name)."))) {
|
||||
return $ltsRule.Value
|
||||
}
|
||||
}
|
||||
|
||||
return $null
|
||||
}
|
||||
}
|
||||
@@ -4,52 +4,30 @@ Pester extension that allows to run command and validate exit code
|
||||
.EXAMPLE
|
||||
"python file.py" | Should -ReturnZeroExitCode
|
||||
#>
|
||||
|
||||
function Get-CommandResult {
|
||||
Param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string] $Command,
|
||||
[switch] $Multiline
|
||||
)
|
||||
# CMD and bash trick to suppress and show error output because some commands write to stderr (for example, "python --version")
|
||||
If ($IsWindows) {
|
||||
$stdout = & $env:comspec /c "$Command 2>&1"
|
||||
} else {
|
||||
$stdout = & bash -c "$Command 2>&1"
|
||||
}
|
||||
$exitCode = $LASTEXITCODE
|
||||
|
||||
return @{
|
||||
Output = If ($Multiline -eq $true) { $stdout } else { [string]$stdout }
|
||||
ExitCode = $exitCode
|
||||
}
|
||||
}
|
||||
|
||||
function ShouldReturnZeroExitCode {
|
||||
Param(
|
||||
[String] $ActualValue,
|
||||
[switch] $Negate,
|
||||
[string] $Because # This parameter is unused by we need it to match Pester asserts signature
|
||||
[Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()]
|
||||
[String]$ActualValue,
|
||||
[switch]$Negate
|
||||
)
|
||||
|
||||
$result = Get-CommandResult $ActualValue
|
||||
Write-Host "Run command '${ActualValue}'"
|
||||
Invoke-Expression -Command $ActualValue | ForEach-Object { Write-Host $_ }
|
||||
$actualExitCode = $LASTEXITCODE
|
||||
|
||||
[bool]$succeeded = $result.ExitCode -eq 0
|
||||
[bool]$succeeded = $actualExitCode -eq 0
|
||||
if ($Negate) { $succeeded = -not $succeeded }
|
||||
|
||||
if (-not $succeeded)
|
||||
{
|
||||
$commandOutputIndent = " " * 4
|
||||
$commandOutput = ($result.Output | ForEach-Object { "${commandOutputIndent}${_}" }) -join "`n"
|
||||
$failureMessage = "Command '${ActualValue}' has finished with exit code ${actualExitCode}`n${commandOutput}"
|
||||
$failureMessage = "Command '${ActualValue}' has finished with exit code ${actualExitCode}"
|
||||
}
|
||||
|
||||
return [PSCustomObject] @{
|
||||
return New-Object PSObject -Property @{
|
||||
Succeeded = $succeeded
|
||||
FailureMessage = $failureMessage
|
||||
}
|
||||
}
|
||||
|
||||
if (Get-Command -Name Add-AssertionOperator -ErrorAction SilentlyContinue) {
|
||||
Add-AssertionOperator -Name ReturnZeroExitCode -InternalName ShouldReturnZeroExitCode -Test ${function:ShouldReturnZeroExitCode}
|
||||
}
|
||||
Add-AssertionOperator -Name ReturnZeroExitCode `
|
||||
-Test $function:ShouldReturnZeroExitCode
|
||||
|
||||
Reference in New Issue
Block a user