diff --git a/.github/actions/send-slack-notification/action.yml b/.github/actions/send-slack-notification/action.yml new file mode 100644 index 0000000..42062d3 --- /dev/null +++ b/.github/actions/send-slack-notification/action.yml @@ -0,0 +1,39 @@ +name: 'Send Slack notification' +description: 'SendSlack notification about new versions of a tool' +inputs: + url: + required: true + description: 'Slack channel url' + tool-name: + required: true + description: 'Name of a tool to send notification for. Like Xamarin or Python' + default: 'Xamarin' + tool-version: + required: false + description: 'New versions of a tool' + pipeline-url: + required: false + description: 'Url of a pipeline' + image-url: + required: false + description: 'Image url for message' + default: 'https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png' + text: + required: false + description: 'Message text' + add-to-toolset-flag: + required: false + description: 'Flag to use notification for adding new versions to toolset' +runs: + using: "composite" + steps: + - id: send-slack-notification + name: Send Slack notification + shell: pwsh + run: ./get-new-tool-versions/send-slack-notification.ps1 -Url "${{ inputs.url }}" ` + -ToolName "${{ inputs.tool-name }}" ` + -ToolVersion "${{ inputs.tool-version }}" ` + -PipelineUrl "${{ inputs.pipeline-url }}" ` + -ImageUrl "${{ inputs.image-url }}" ` + -Text "${{ inputs.text }}" ` + ${{ inputs.add-to-toolset-flag }} diff --git a/.github/workflows/azure-webapps-node.yml b/.github/workflows/azure-webapps-node.yml new file mode 100644 index 0000000..723da35 --- /dev/null +++ b/.github/workflows/azure-webapps-node.yml @@ -0,0 +1,74 @@ +# This workflow will build and push a node.js application to an Azure Web App when a commit is pushed to your default branch. +# +# This workflow assumes you have already created the target Azure App Service web app. +# For instructions see https://docs.microsoft.com/en-us/azure/app-service/quickstart-nodejs?tabs=linux&pivots=development-environment-cli +# +# To configure this workflow: +# +# 1. Download the Publish Profile for your Azure Web App. You can download this file from the Overview page of your Web App in the Azure Portal. +# For more information: https://docs.microsoft.com/en-us/azure/app-service/deploy-github-actions?tabs=applevel#generate-deployment-credentials +# +# 2. Create a secret in your repository named AZURE_WEBAPP_PUBLISH_PROFILE, paste the publish profile contents as the value of the secret. +# For instructions on obtaining the publish profile see: https://docs.microsoft.com/azure/app-service/deploy-github-actions#configure-the-github-secret +# +# 3. Change the value for the AZURE_WEBAPP_NAME. Optionally, change the AZURE_WEBAPP_PACKAGE_PATH and NODE_VERSION environment variables below. +# +# For more information on GitHub Actions for Azure: https://github.com/Azure/Actions +# For more information on the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# For more samples to get started with GitHub Action workflows to deploy to Azure: https://github.com/Azure/actions-workflow-samples + +on: + push: + branches: + - main + workflow_dispatch: + +env: + AZURE_WEBAPP_NAME: your-app-name # set this to your application's name + AZURE_WEBAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root + NODE_VERSION: '14.x' # set this to the node version to use + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'npm' + + - name: npm install, build, and test + run: | + npm install + npm run build --if-present + npm run test --if-present + + - name: Upload artifact for deployment job + uses: actions/upload-artifact@v2 + with: + name: node-app + path: . + + deploy: + runs-on: ubuntu-latest + needs: build + environment: + name: 'Development' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} + + steps: + - name: Download artifact from build job + uses: actions/download-artifact@v2 + with: + name: node-app + + - name: 'Deploy to Azure WebApp' + id: deploy-to-webapp + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ env.AZURE_WEBAPP_NAME }} + publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }} + package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }} diff --git a/.github/workflows/blank.yml b/.github/workflows/blank.yml new file mode 100644 index 0000000..30a4bc1 --- /dev/null +++ b/.github/workflows/blank.yml @@ -0,0 +1,36 @@ +# This is a basic workflow to help you get started with Actions + +name: CI + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ main ] + pull_request: + branches: [ main ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + # Runs a single command using the runners shell + - name: Run a one-line script + run: echo Hello, world! + + # Runs a set of commands using the runners shell + - name: Run a multi-line script + run: | + echo Add other actions to build, + echo test, and deploy your project. diff --git a/.github/workflows/get-tools-new-versions.yml b/.github/workflows/get-tools-new-versions.yml new file mode 100644 index 0000000..aeaaf74 --- /dev/null +++ b/.github/workflows/get-tools-new-versions.yml @@ -0,0 +1,89 @@ +name: Get tools new versions +on: + schedule: + - cron: '0 8 * * THU' + workflow_dispatch: + +defaults: + run: + shell: pwsh + +jobs: + find-new-tool-versions: + strategy: + fail-fast: false + matrix: + tool: + - name: 'Xamarin' + image: 'https://avatars.githubusercontent.com/u/790012?s=200&v=4' + releases-url: 'null' + filter-parameter: 'null' + filter-arch: 'null' + - name: 'Python' + image: 'https://avatars.githubusercontent.com/u/1525981?s=200&v=4' + releases-url: 'https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json' + filter-parameter: 'version' + filter-arch: 'x64' + - name: 'PyPy' + image: 'https://avatars.githubusercontent.com/u/318667?s=200&v=4' + releases-url: 'https://downloads.python.org/pypy/versions.json' + filter-parameter: 'python_version' + filter-arch: 'x86' + - name: 'Node' + image: 'https://avatars.githubusercontent.com/u/9950313?s=200&v=4' + releases-url: 'https://raw.githubusercontent.com/actions/node-versions/main/versions-manifest.json' + filter-parameter: 'version' + filter-arch: 'x64' + - name: 'Go' + image: 'https://avatars.githubusercontent.com/u/4314092?s=200&v=4' + releases-url: 'https://raw.githubusercontent.com/actions/go-versions/main/versions-manifest.json' + filter-parameter: 'version' + filter-arch: 'x64' + name: 'Searching for new versions of ${{ matrix.tool.name }}' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - id: get-new-tool-versions + name: Get new tool versions + run: | + $versionsOutput = ./get-new-tool-versions/verify-new-tool-version-added-to-image.ps1 ` + -ToolName ${{ matrix.tool.name }} ` + -ReleasesUrl ${{ matrix.tool.releases-url }} ` + -FilterParameter ${{ matrix.tool.filter-parameter }} ` + -FilterArch ${{ matrix.tool.filter-arch }} + echo "::set-output name=versions-output::$versionsOutput" + - name: Check versions + if: steps.get-new-tool-versions.outputs.versions-output == '' + run: Write-Host "No new versions found" + - uses: ./.github/actions/send-slack-notification + name: Send Slack notification + if: steps.get-new-tool-versions.outputs.versions-output != '' + with: + url: ${{ secrets.SLACK_CHANNEL_URL }} + tool-name: '${{ matrix.tool.name }}' + tool-version: ${{ steps.get-new-tool-versions.outputs.versions-output }} + image-url: '${{ matrix.tool.image }}' + add-to-toolset-flag: '-AddToToolsetFlag' + + check_build: + name: Check build for failures + runs-on: ubuntu-latest + needs: [find-new-tool-versions] + if: failure() + steps: + - uses: actions/checkout@v2 + - id: get-failed-jobs + name: Get failed jobs + run: | + $jobs_url = "$env:GITHUB_API_URL/repos/$env:GITHUB_REPOSITORY/actions/runs/$env:GITHUB_RUN_ID/jobs" + $failedJobs = (Invoke-RestMethod -Uri $jobs_url).jobs | + Where-Object conclusion -eq "failure" | + ForEach-Object {"\n\t" + $_.name.split(" ")[-1] + ": $($_.html_url)"} + echo "::set-output name=failed-jobs::$failedJobs" + - uses: ./.github/actions/send-slack-notification + name: Send Slack notification about failure + with: + url: ${{ secrets.SLACK_CHANNEL_URL }} + tool-name: 'Tool name' + pipeline-url: '$env:GITHUB_SERVER_URL/$env:GITHUB_REPOSITORY/actions/runs/$env:GITHUB_RUN_ID' + text: "Missing toolset tool versions checker pipeline has failed jobs:/n/t${{ steps.get-failed-jobs.outputs.failed-jobs }}" \ No newline at end of file diff --git a/azure-pipelines/templates/check-versions.yml b/azure-pipelines/templates/check-versions.yml index c7ad39f..084c913 100644 --- a/azure-pipelines/templates/check-versions.yml +++ b/azure-pipelines/templates/check-versions.yml @@ -36,7 +36,7 @@ steps: $newBuildName = "[FOUND] $(Build.BuildNumber)" Write-Host "##vso[build.updatebuildnumber]$newBuildName" -- task: PowerShell@2 +- task: PowerShell@2 displayName: 'Send Slack notification' inputs: targetType: filePath diff --git a/get-new-tool-versions/get-new-tool-versions.ps1 b/get-new-tool-versions/get-new-tool-versions.ps1 index e2f0474..e8342ed 100644 --- a/get-new-tool-versions/get-new-tool-versions.ps1 +++ b/get-new-tool-versions/get-new-tool-versions.ps1 @@ -21,6 +21,7 @@ $VersionsToBuild = $VersionsFromDist | Where-Object { $VersionsFromManifest -not if ($VersionsToBuild) { $availableVersions = $VersionsToBuild -join ", " Write-Host "The following versions are available to build:`n${availableVersions}" + Write-Host "::set-output name=TOOL_VERSIONS::${availableVersions}" Write-Host "##vso[task.setvariable variable=TOOL_VERSIONS;isOutput=true]${availableVersions}" } else { Write-Host "There aren't versions to build" diff --git a/get-new-tool-versions/parsers/go-parser.psm1 b/get-new-tool-versions/parsers/go-parser.psm1 index 19f3a21..5b9abb0 100644 --- a/get-new-tool-versions/parsers/go-parser.psm1 +++ b/get-new-tool-versions/parsers/go-parser.psm1 @@ -15,7 +15,7 @@ class GoVersionsParser: BaseVersionsParser { hidden [SemVer] FormatVersion([string]$VersionSpec) { $cleanVersion = $VersionSpec -replace "^go", "" - $semanticVersion = $cleanVersion -replace "(\d+\.\d+\.?\d+?)((?:alpha|beta|rc))(\d*)",'$1-$2.$3' + $semanticVersion = $cleanVersion -replace '(\d+\.\d+\.?\d*?)((?:alpha|beta|rc))(\d*)', '$1-$2.$3' return [SemVer]$semanticVersion } diff --git a/get-new-tool-versions/parsers/verify-added-to-image/verify-common-tool-parser.psm1 b/get-new-tool-versions/parsers/verify-added-to-image/verify-common-tool-parser.psm1 new file mode 100644 index 0000000..3723390 --- /dev/null +++ b/get-new-tool-versions/parsers/verify-added-to-image/verify-common-tool-parser.psm1 @@ -0,0 +1,25 @@ +function Search-ToolsVersionsNotOnImage { + param ( + [string]$ToolName, + [string]$ReleasesUrl, + [string]$FilterParameter, + [string]$FilterArch + ) + + $stableReleases = (Invoke-RestMethod $ReleasesUrl) | Where-Object stable -eq $true + $stableReleaseVersions = $stableReleases | ForEach-Object { + if ($ToolName -eq "Node") { + $_.$FilterParameter.split(".")[0] + ".0" + } else { + $_.$FilterParameter.split(".")[0,1] -join"." + } + } | Select-Object -Unique + $toolsetUrl = "https://raw.githubusercontent.com/actions/virtual-environments/main/images/win/toolsets/toolset-2022.json" + $latestMinorVersion = (Invoke-RestMethod $toolsetUrl).toolcache | + Where-Object {$_.name -eq $ToolName -and $_.arch -eq $FilterArch} | + ForEach-Object {$_.versions.Replace("*","0")} | + Select-Object -Last 1 + $versionsToAdd = $stableReleaseVersions | Where-Object {[version]$_ -gt [version]$latestMinorVersion} + + return $versionsToAdd +} \ No newline at end of file diff --git a/get-new-tool-versions/parsers/verify-added-to-image/verify-xamarin-parser.psm1 b/get-new-tool-versions/parsers/verify-added-to-image/verify-xamarin-parser.psm1 new file mode 100644 index 0000000..4999217 --- /dev/null +++ b/get-new-tool-versions/parsers/verify-added-to-image/verify-xamarin-parser.psm1 @@ -0,0 +1,19 @@ +function Search-XamarinVersionsNotOnImage { + param ( + [string]$ReleasesUrl, + [array]$FilterProducts + ) + + $xamarinReleases = (Invoke-RestMethod $ReleasesUrl).items + $filteredReleases = $xamarinReleases | Where-Object {$_.name -in $FilterProducts.name} | Sort-Object name | Select-Object name, version + $toolsetUrl = "https://raw.githubusercontent.com/actions/virtual-environments/main/images/macos/toolsets/toolset-11.json" + $uploadedReleases = (Invoke-RestMethod $toolsetUrl).xamarin + $releasesOnImage = @() + foreach ($FilterProduct in $FilterProducts) { + $releasesOnImage += @{$FilterProduct.name = $uploadedReleases.($FilterProduct.property)} + } + $versionsToAdd = $filteredReleases | Where-Object {$releasesOnImage.($_.name) -notcontains $_.version} | ForEach-Object {[string]::Empty} { + '{0,-15} : {1}' -f $_.name, $_.version + } + return $versionsToAdd +} \ No newline at end of file diff --git a/get-new-tool-versions/send-slack-notification.ps1 b/get-new-tool-versions/send-slack-notification.ps1 index 050af3e..c609a4b 100644 --- a/get-new-tool-versions/send-slack-notification.ps1 +++ b/get-new-tool-versions/send-slack-notification.ps1 @@ -7,11 +7,15 @@ Required parameter. Incoming Webhook URL to post a message .PARAMETER ToolName Required parameter. The name of tool .PARAMETER ToolVersion -Required parameter. Specifies the version of tool +Optional parameter. Specifies the version of tool .PARAMETER PipelineUrl -Required parameter. The pipeline URL +Optional parameter. The pipeline URL .PARAMETER ImageUrl Optional parameter. The image URL +.PARAMETER Text +Optional parameter. The message to post +.PARAMETER AddToToolsetFlag +Optional parameter. Flag to alternate message text for adding new version of a tool to toolset notification #> param( @@ -23,22 +27,28 @@ param( [ValidateNotNullOrEmpty()] [System.String]$ToolName, - [Parameter(Mandatory)] - [ValidateNotNullOrEmpty()] [System.String]$ToolVersion, - [System.String]$PipelineUrl, - [System.String]$ImageUrl = 'https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png' + [System.String]$ImageUrl = 'https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png', + [System.String]$Text, + [Switch]$AddToToolsetFlag ) # Import helpers module Import-Module $PSScriptRoot/helpers.psm1 -DisableNameChecking # Create JSON body -$text = "The following versions of '$toolName' are available to upload: $toolVersion" +if ([string]::IsNullOrWhiteSpace($Text)) { + if ($AddToToolsetFlag) { + $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 += "\nLink to the pipeline: $pipelineUrl" } + $jsonBodyMessage = @" { "blocks": [ @@ -46,7 +56,7 @@ $jsonBodyMessage = @" "type": "section", "text": { "type": "mrkdwn", - "text": "$text" + "text": "$Text" }, "accessory": { "type": "image", diff --git a/get-new-tool-versions/verify-new-tool-version-added-to-image.ps1 b/get-new-tool-versions/verify-new-tool-version-added-to-image.ps1 new file mode 100644 index 0000000..664729d --- /dev/null +++ b/get-new-tool-versions/verify-new-tool-version-added-to-image.ps1 @@ -0,0 +1,38 @@ +<# +.SYNOPSIS +Check and return list of new available tool versions that not added to toolsets yet + +.PARAMETER ToolName +Required parameter. The name of tool for which parser is available (Python, Xamarin, PyPy, Node, Go) +#> + +param ( + [Parameter(Mandatory)] + [ValidateSet("Python", "Xamarin", "PyPy", "Node", "Go")] + [string] $ToolName, + [string] $ReleasesUrl, + [string] $FilterParameter, + [string] $FilterArch +) + +Get-ChildItem "$PSScriptRoot/parsers/verify-added-to-image/" | ForEach-Object {Import-Module $_.FullName} + +if ($ToolName -in "Python", "PyPy", "Node", "Go") { + $versionsToAdd = Search-ToolsVersionsNotOnImage -ToolName $ToolName -ReleasesUrl $ReleasesUrl -FilterParameter $FilterParameter -FilterArch $FilterArch +} + +if ($ToolName -eq "Xamarin") { + $xamarinReleases = "http://aka.ms/manifest/stable" + $xamarinProducts = @( + [PSCustomObject] @{name = 'Mono Framework'; property = 'mono-versions'} + [PSCustomObject] @{name = 'Xamarin.Android'; property = 'android-versions'} + [PSCustomObject] @{name = 'Xamarin.iOS'; property = 'ios-versions'} + [PSCustomObject] @{name = 'Xamarin.Mac'; property = 'mac-versions'} + ) + $versionsToAdd = Search-XamarinVersionsNotOnImage -ReleasesUrl $xamarinReleases -FilterProducts $xamarinProducts + $joinChars = "\n\t" +} + +$versionsToAdd = $versionsToAdd -join $joinChars + +return $versionsToAdd diff --git a/github/github-api.psm1 b/github/github-api.psm1 index 3103ed0..6ba32c7 100644 --- a/github/github-api.psm1 +++ b/github/github-api.psm1 @@ -124,6 +124,11 @@ class GitHubApi } } + [void] CancelWorkflow([string]$WorkflowId) { + $url = "actions/runs/$WorkflowId/cancel" + $this.InvokeRestMethod($url, 'POST', $null, $null) + } + [object] hidden InvokeRestMethod( [string] $Url, [string] $Method, diff --git a/packages-generation/manifest-utils.Tests.ps1 b/packages-generation/manifest-utils.Tests.ps1 index 0fcaf05..15765d1 100644 --- a/packages-generation/manifest-utils.Tests.ps1 +++ b/packages-generation/manifest-utils.Tests.ps1 @@ -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" { @@ -161,4 +161,54 @@ Describe "Build-VersionsManifest" { [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 + } } \ No newline at end of file diff --git a/packages-generation/manifest-utils.psm1 b/packages-generation/manifest-utils.psm1 index df2a8b2..b0da90b 100644 --- a/packages-generation/manifest-utils.psm1 +++ b/packages-generation/manifest-utils.psm1 @@ -50,6 +50,7 @@ function Build-VersionsManifest { ) $Releases = $Releases | Sort-Object -Property "published_at" -Descending + $ltsRules = Get-LtsRules -Configuration $Configuration $versionsHash = @{} foreach ($release in $Releases) { @@ -64,17 +65,49 @@ 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 } - $versionsHash.Add($versionKey, [PSCustomObject]@{ - version = $versionKey - stable = $stable - release_url = $release.html_url - files = $releaseAssets - }) + $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) } # Sort versions by descending return $versionsHash.Values | Sort-Object -Property @{ Expression = { [Semver]$_.version }; Descending = $true } -} \ No newline at end of file +} + +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 +} diff --git a/packages-generation/manifest-validator.ps1 b/packages-generation/manifest-validator.ps1 index 7266e11..c50bceb 100644 --- a/packages-generation/manifest-validator.ps1 +++ b/packages-generation/manifest-validator.ps1 @@ -1,30 +1,29 @@ param ( - [Parameter(Mandatory)][string] $ManifestUrl, - [string] $AccessToken + [Parameter(Mandatory)][string] $ManifestPath ) -$authorizationHeaderValue = "Basic $AccessToken" -$webRequestHeaders = @{} -if ($AccessToken) { - $webRequestHeaders.Add("Authorization", $authorizationHeaderValue) -} +$Global:validationFailed = $false function Publish-Error { param( [string] $ErrorDescription, [object] $Exception ) - Write-Host "##vso[task.logissue type=error]ERROR: $ErrorDescription." - Write-Host "##vso[task.logissue type=error] $Exception" - Write-Host "##vso[task.complete result=Failed;]" + + Write-Output "::error ::$ErrorDescription" + if (-not [string]::IsNullOrEmpty($Exception)) + { + Write-Output "Exception: $Exception" + } + $Global:validationFailed = $true } function Test-DownloadUrl { - param([string] $DownloadUrl) + param( + [string] $DownloadUrl + ) + $request = [System.Net.WebRequest]::Create($DownloadUrl) - if ($AccessToken) { - $request.Headers.Add("Authorization", $authorizationHeaderValue) - } try { $response = $request.GetResponse() return ([int]$response.StatusCode -eq 200) @@ -33,19 +32,16 @@ function Test-DownloadUrl { } } -Write-Host "Downloading manifest json from '$ManifestUrl'..." -try { - $manifestResponse = Invoke-WebRequest -Method Get -Uri $ManifestUrl -Headers $webRequestHeaders -} catch { - Publish-Error "Unable to download manifest json from '$ManifestUrl'" $_ +if (-not (Test-Path $ManifestPath)) { + Publish-Error "Unable to find manifest json file at '$ManifestPath'" exit 1 } -Write-Host "Parsing manifest json content from '$ManifestUrl'..." +Write-Host "Parsing manifest json content from '$ManifestPath'..." try { - $manifestJson = $manifestResponse.Content | ConvertFrom-Json + $manifestJson = Get-Content $ManifestPath | ConvertFrom-Json } catch { - Publish-Error "Unable to parse manifest json content '$ManifestUrl'" $_ + Publish-Error "Unable to parse manifest json content '$ManifestPath'" $_ exit 1 } @@ -61,3 +57,7 @@ $manifestJson | ForEach-Object { } } } + +if ($Global:validationFailed) { + exit 1 +}