Compare commits

..

20 Commits

Author SHA1 Message Date
Nikita Bykov
742c5dae81 update 2021-08-20 15:17:09 +03:00
Nikita Bykov
f3f0d2026d update 2021-08-20 11:54:21 +03:00
Nikita Bykov
5e6f2c681c update 2021-08-20 11:48:02 +03:00
Nikita Bykov
bb9fd35708 update 2021-08-19 15:17:18 +03:00
Nikita Bykov
9f535cd83f update 2021-08-19 14:36:29 +03:00
Nikita Bykov
750ff93e50 update 2021-08-19 14:31:13 +03:00
Nikita Bykov
a29d98d3f2 update 2021-08-19 12:47:25 +03:00
Nikita Bykov
538be710eb update 2021-08-19 11:50:50 +03:00
Nikita Bykov
8f1a38e755 update 2021-08-19 11:32:59 +03:00
Nikita Bykov
9fc854ce04 update 2021-08-18 18:30:36 +03:00
Nikita Bykov
03ae7d095d add script for slack notification 2021-08-18 17:43:15 +03:00
Nikita Bykov
97e0e3a660 update get-new-tool-version.ps1 2021-08-17 16:57:27 +03:00
Nikita Bykov
b01e7843b6 Update 2021-07-13 18:06:50 +03:00
Nikita Bykov
856cb1ed00 Update 2021-07-13 17:17:45 +03:00
Nikita Bykov
6b744d4218 Add CancelWorkflow method 2021-07-13 17:14:29 +03:00
Nikita Bykov
4b286369c5 Test 2021-07-12 15:42:01 +03:00
Nikita Bykov
65cd85d7fe Test 2021-07-12 15:37:20 +03:00
Nikita Bykov
7654b2e70d Test 2021-07-12 15:12:52 +03:00
Nikita Bykov
7847e40341 Test 2021-07-12 15:10:09 +03:00
Nikita Bykov
d853f172e3 Update get-new-tool-version.ps1 2021-07-12 14:50:19 +03:00
31 changed files with 591 additions and 753 deletions

2
.github/CODEOWNERS vendored
View File

@@ -1 +1 @@
* @actions/setup-actions-team
* @actions/virtual-environments-owners

View File

@@ -1,39 +0,0 @@
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 }}

View File

@@ -1,14 +0,0 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
# Enable version updates for GitHub Actions
- package-ecosystem: 'github-actions'
# Workflow files stored in the default location of `.github/workflows`
# You don't need to specify `/.github/workflows` for `directory`. You can use `directory: "/"`.
directory: '/'
schedule:
interval: 'weekly'

View File

@@ -1,277 +0,0 @@
# This reusable workflow is used by actions/*-versions repositories
# It is designed to
# - build and test new versions of a tool (Go, Node)
# - publish a release with a new tool version
# The GITHUB_TOKEN secret is used to trigger workflow runs and publish releases
name: Generate tool packages
on:
workflow_call:
inputs:
tool-name:
description: "Tool name to build and upload. Supported values are: 'go' and 'node'"
required: true
type: string
tool-version:
description: "Tool version to build and upload"
required: true
type: string
publish-release:
description: "Whether to publish releases"
required: true
type: boolean
defaults:
run:
shell: pwsh
jobs:
build:
name: Build ${{ inputs.tool-name }} ${{ inputs.tool-version }} [${{ matrix.platform }}] [${{ matrix.architecture }}]
runs-on: ubuntu-22.04
env:
ARTIFACT_NAME: ${{ inputs.tool-name }}-${{ inputs.tool-version }}-${{ matrix.platform }}-${{ matrix.architecture }}
excludewinarm: ${{ !(inputs.tool-name == 'node' && inputs['tool-version'] < '20.0.0' && matrix.architecture == 'arm64' && matrix.platform == 'win32') }}
strategy:
fail-fast: false
matrix:
platform: [linux, darwin, win32]
architecture: [x64, arm64]
steps:
- name: checkout
if: env.excludewinarm == 'true'
uses: actions/checkout@v4
with:
submodules: true
- name: Build ${{ inputs.tool-name }} ${{ inputs.tool-version }}
if: env.excludewinarm == 'true'
run: |
./builders/build-${{ inputs.tool-name }}.ps1 -Version ${{ inputs.tool-version }} `
-Platform ${{ matrix.platform }} `
-Architecture ${{ matrix.architecture }}
- name: Publish artifact
if: env.excludewinarm == 'true'
uses: actions/upload-artifact@v4
with:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ runner.temp }}/artifact
test:
name: Test ${{ inputs.tool-name }} ${{ inputs.tool-version }} [${{ matrix.platform }}] [${{ matrix.architecture }}]
needs: build
runs-on: ${{ matrix.os }}
env:
ARTIFACT_NAME: ${{ inputs.tool-name }}-${{ inputs.tool-version }}-${{ matrix.platform }}-${{ matrix.architecture }}
excludewinarm: ${{ !(inputs.tool-name == 'node' && inputs['tool-version'] < '20.0.0' && matrix.architecture == 'arm64' && matrix.platform == 'win32') }}
RUNNER_TYPE: ${{ matrix.runner_type }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
platform: linux
architecture: x64
- os: macos-13
platform: darwin
architecture: x64
- os: windows-latest
platform: win32
architecture: x64
- os: setup-actions-ubuntu-arm64-2-core
platform: linux
architecture: arm64
runner_type: self-hosted
- os: macos-latest
platform: darwin
architecture: arm64
- os: setup-actions-windows-arm64-4-core
platform: win32
architecture: arm64
runner_type: self-hosted
steps:
- name: Setup Environment on Windows ARM64 Runner
if: matrix.os == 'setup-actions-windows-arm64-4-core'
shell: powershell
run: |
# Install Chocolatey
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
echo "C:\ProgramData\Chocolatey\bin" | Out-File -Append -FilePath $env:GITHUB_PATH -Encoding utf8
# Install PowerShell
choco install powershell-core -y
echo "C:\Program Files\PowerShell\7" | Out-File -Append -FilePath $env:GITHUB_PATH -Encoding utf8
# Install Git
choco install git -y
echo "C:\Program Files\Git\cmd" | Out-File -Append -FilePath $env:GITHUB_PATH -Encoding utf8
# Install 7-Zip
choco install 7zip -y
echo "C:\ProgramData\chocolatey\bin" | Out-File -Append -FilePath $env:GITHUB_PATH -Encoding utf8
- name: checkout
if: env.excludewinarm == 'true'
uses: actions/checkout@v4
with:
submodules: true
- name: Fully cleanup the toolcache directory before testing
if: env.excludewinarm == 'true'
run: ./helpers/clean-toolcache.ps1 -ToolName "${{ inputs.tool-name }}"
- name: Download artifact
if: env.excludewinarm == 'true'
uses: actions/download-artifact@v4
with:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ runner.temp }}/${{ env.ARTIFACT_NAME }}
- name: Extract files
if: env.excludewinarm == 'true'
run: |
if ('${{ matrix.platform }}' -eq 'win32') {
if ('${{ inputs.tool-name }}' -eq 'node') {
$artifactName = "${{ env.ARTIFACT_NAME }}.7z"
} elseif ('${{ inputs.tool-name }}' -eq 'go') {
$artifactName = "${{ env.ARTIFACT_NAME }}.zip"
} else {
Write-Host "Unsupported tool - ${{ inputs.tool-name }}"
exit 1
}
7z.exe x "$artifactName" -y | Out-Null
} else {
$artifactName = "${{ env.ARTIFACT_NAME }}.tar.gz"
tar -xzf $artifactName
}
working-directory: ${{ runner.temp }}/${{ env.ARTIFACT_NAME }}
- name: Apply build artifact to the local machine
if: env.excludewinarm == 'true'
run: |
if ('${{ matrix.platform }}' -eq 'win32') { powershell ./setup.ps1 }
else {
sh ./setup.sh
}
working-directory: ${{ runner.temp }}/${{ env.ARTIFACT_NAME }}
- name: Setup Node.js ${{ inputs.tool-version }}
if: env.excludewinarm == 'true' && inputs.tool-name == 'node'
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.tool-version }}
- name: Setup Go ${{ inputs.tool-version }}
if: inputs.tool-name == 'go'
uses: actions/setup-go@v5
with:
go-version: ${{ inputs.tool-version }}
- name: Wait for the logs
if: env.excludewinarm == 'true'
run: |
Write-Host "Fake step that does nothing"
Write-Host "We need it because log from the previous step 'Setup ${{ inputs.tool-name }}' is not available here yet."
Write-Host "In testing step we analyze build log of 'Setup ${{ inputs.tool-name }}' task"
Write-Host "to determine if ${{ inputs.tool-name }} version was consumed from cache or if it was downloaded"
for ($i = 0; $i -lt 200; $i++) { Get-Random }
- name: Run tests
if: env.excludewinarm == 'true'
env:
VERSION: ${{ inputs.tool-version }}
run: |
Install-Module Pester -Force -Scope CurrentUser -SkipPublisherCheck
Import-Module Pester
$toolName = (Get-Culture).TextInfo.ToTitleCase("${{ inputs.tool-name }}")
Invoke-Pester -Script ./$toolName.Tests.ps1 -EnableExit
working-directory: ./tests
publish_release:
name: Publish release
if: inputs.publish-release
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
- name: Generate release body
id: generate-release-body
run: |
if ('${{ inputs.tool-name }}' -eq 'node') {
$releaseBody = 'Node.js ${{ inputs.tool-version }}'
} else {
$releaseBody = 'Go ${{ inputs.tool-version }}'
}
echo "RELEASE_BODY=$releaseBody" >> $env:GITHUB_OUTPUT
- name: Publish Release
id: create_release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
run: |
tag_name="${{ inputs.tool-version }}-${{ github.run_id }}"
gh release create "$tag_name" \
--repo="$GITHUB_REPOSITORY" \
--title="${{ inputs.tool-version }}" \
--notes="${{ steps.generate-release-body.outputs.RELEASE_BODY }}"
release_id=$(gh release view "$tag_name" --repo "$GITHUB_REPOSITORY" --json databaseId --jq '.databaseId')
echo "id=$release_id" >> $GITHUB_OUTPUT
- name: Generate hash for packages
run: |
$childItems = Get-Childitem -Path '.'
$childItems | Foreach-Object {
$packageObj = Get-Childitem -Path $_.FullName | Select-Object -First 1
Write-Host "Package: $($packageObj.Name)"
$actualHash = (Get-FileHash -Path $packageObj.FullName -Algorithm sha256).Hash
$hashString = "$actualHash $($packageObj.Name)"
Write-Host "$hashString"
Add-Content -Path ./hashes.sha256 -Value "$hashString"
}
- name: Upload release assets
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
for (let artifactDir of fs.readdirSync('.')) {
let artifactName = fs.lstatSync(artifactDir).isDirectory() ? fs.readdirSync(`${artifactDir}`)[0] : artifactDir;
console.log(`Upload ${artifactName} asset`);
github.rest.repos.uploadReleaseAsset({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: ${{ steps.create_release.outputs.id }},
name: artifactName,
data: fs.lstatSync(artifactDir).isDirectory() ? fs.readFileSync(`./${artifactDir}/${artifactName}`) : fs.readFileSync(`./${artifactName}`).toString()
});
}
trigger_pr:
name: Trigger "Create Pull Request" workflow
needs: publish_release
runs-on: ubuntu-latest
steps:
- name: Trigger "Create Pull Request" workflow
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'create-pr.yml',
ref: 'main'
});

View File

@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v2
- name: Install Pester
shell: pwsh
@@ -20,4 +20,4 @@ jobs:
run: |
Import-Module Pester
Import-Module Assert
Invoke-Pester -EnableExit
Invoke-Pester -EnableExit

View File

@@ -1,43 +0,0 @@
# This reusable workflow is used by actions/*-versions repositories
# It is designed to create a PR with update of versions-manifest.json when a new release is published
# The GITHUB_TOKEN secret is used to create versions-manifest.json and publish related PR
name: Create Pull Request
on:
workflow_call:
inputs:
tool-name:
description: 'Name of the tool for which PR is created'
required: true
type: string
defaults:
run:
shell: pwsh
jobs:
create_pr:
name: Create Pull Request
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Create versions-manifest.json
run: |
./helpers/packages-generation/manifest-generator.ps1 -RepositoryFullName "$env:GITHUB_REPOSITORY" `
-GitHubAccessToken "${{ secrets.GITHUB_TOKEN }}" `
-OutputFile "./versions-manifest.json" `
-ConfigurationFile "./config/${{ inputs.tool-name }}-manifest-config.json"
- name: Create GitHub PR
run: |
$formattedDate = Get-Date -Format "MM/dd/yyyy"
./helpers/github/create-pull-request.ps1 `
-RepositoryFullName "$env:GITHUB_REPOSITORY" `
-AccessToken "${{ secrets.GITHUB_TOKEN }}" `
-BranchName "update-versions-manifest-file" `
-CommitMessage "Update versions-manifest" `
-PullRequestTitle "[versions-manifest] Update for release from ${formattedDate}" `
-PullRequestBody "Update versions-manifest.json for release from ${formattedDate}"

View File

@@ -1,109 +0,0 @@
# This reusable workflow is used by actions/*-versions repositories
# It is designed to check for new versions of a tool (Python, Node, etc.)
# The 'SLACK_CHANNEL_URL' secret must be added to the repository containing the caller workflow
# in order to publish messages to Slack.
# The 'Get Available Tools Versions - Publishing Approval' environment must be created in the repository containing the caller workflow
# The 'trigger_builds' job requires manual approval
# The GITHUB_TOKEN secret is used to cancel and trigger workflow runs
name: Get new tool versions
on:
workflow_call:
inputs:
tool-name:
description: 'Name of the tool for which versions are searched'
required: true
type: string
image-url:
description: 'Tool image to be attached to Slack posts'
required: true
type: string
defaults:
run:
shell: pwsh
jobs:
find_new_versions:
name: Find new versions
runs-on: ubuntu-latest
outputs:
versions_output: ${{ steps.Get_new_versions.outputs.TOOL_VERSIONS }}
steps:
- uses: actions/checkout@v4
with:
submodules: true
- id: Get_new_versions
name: Get new versions
run: ./helpers/get-new-tool-versions/get-new-tool-versions.ps1 -ToolName ${{ inputs.tool-name }}
check_new_versions:
name: Check new versions
runs-on: ubuntu-latest
needs: find_new_versions
env:
TOOL_VERSIONS: ${{needs.find_new_versions.outputs.versions_output}}
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Check Versions
if: env.TOOL_VERSIONS == ''
run: |
Write-Host "No new versions were found"
Import-Module "./helpers/github/github-api.psm1"
$gitHubApi = Get-GitHubApi -RepositoryFullName "$env:GITHUB_REPOSITORY" `
-AccessToken "${{ secrets.GITHUB_TOKEN }}"
$gitHubApi.CancelWorkflow("$env:GITHUB_RUN_ID")
Start-Sleep -Seconds 60
- name: Send Slack notification
run: |
$pipelineUrl = "$env:GITHUB_SERVER_URL/$env:GITHUB_REPOSITORY/actions/runs/$env:GITHUB_RUN_ID"
$message = "The following versions of '${{ inputs.tool-name }}' are available to upload: ${{ env.TOOL_VERSIONS }}\nLink to the pipeline: $pipelineUrl"
./helpers/get-new-tool-versions/send-slack-notification.ps1 -Url "${{ secrets.SLACK_CHANNEL_URL }}" `
-ToolName "${{ inputs.tool-name }}" `
-ImageUrl "${{ inputs.image-url }}" `
-Text "$message"
trigger_builds:
name: Trigger builds
runs-on: ubuntu-latest
needs: [find_new_versions, check_new_versions]
env:
TOOL_VERSIONS: ${{needs.find_new_versions.outputs.versions_output}}
environment: Get Available Tools Versions - Publishing Approval
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Trigger "Build ${{ inputs.tool-name }} packages" workflow
run: |
$workflowFileName = "build-${{ inputs.tool-name }}-packages.yml".ToLower()
./helpers/github/run-ci-builds.ps1 -RepositoryFullName "$env:GITHUB_REPOSITORY" `
-AccessToken "${{ secrets.GITHUB_TOKEN }}" `
-WorkflowFileName "$workflowFileName" `
-WorkflowDispatchRef "main" `
-ToolVersions "${{ env.TOOL_VERSIONS }}" `
-PublishReleases "true"
check_build:
name: Check build for failures
runs-on: ubuntu-latest
needs: [find_new_versions, check_new_versions, trigger_builds]
if: failure()
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Send Slack notification if build fails
run: |
$pipelineUrl = "$env:GITHUB_SERVER_URL/$env:GITHUB_REPOSITORY/actions/runs/$env:GITHUB_RUN_ID"
$message = "The build of the '${{ inputs.tool-name }}' detection pipeline failed :progress-error:\nLink to the pipeline: $pipelineUrl"
./helpers/get-new-tool-versions/send-slack-notification.ps1 -Url "${{ secrets.SLACK_CHANNEL_URL }}" `
-ToolName "${{ inputs.tool-name }}" `
-Text "$message" `
-ImageUrl "${{ inputs.image-url }}"

View File

@@ -1,89 +0,0 @@
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@v4
- 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 "versions-output=$versionsOutput" >> $env:GITHUB_OUTPUT
- 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_HOOK }}
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@v4
- 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 "failed-jobs=$failedJobs" >> $env:GITHUB_OUTPUT
- uses: ./.github/actions/send-slack-notification
name: Send Slack notification about failure
with:
url: ${{ secrets.SLACK_CHANNEL_HOOK }}
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 }}"

View File

@@ -1,51 +0,0 @@
# This reusable workflow is used by actions/*-versions repositories
# It is designed to validate the versions-manifest.json file
# The 'SLACK_CHANNEL_URL' secret must be added to the repository containing the caller workflow
# in order to publish messages to Slack
name: Validate manifest
on:
workflow_call:
inputs:
tool-name:
description: 'Name of the tool for which manifest is validated'
required: true
type: string
image-url:
description: 'Tool image to be attached to Slack posts'
required: true
type: string
defaults:
run:
shell: pwsh
jobs:
validation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Validate manifest
run: .\helpers\packages-generation\manifest-validator.ps1 -ManifestPath '.\versions-manifest.json'
check_build:
name: Check validation for failures
runs-on: ubuntu-latest
needs: [validation]
if: failure()
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Send Slack notification if validation fails
run: |
$pipelineUrl = "$env:GITHUB_SERVER_URL/$env:GITHUB_REPOSITORY/actions/runs/$env:GITHUB_RUN_ID"
$message = "The validation of ${{ inputs.tool-name }} manifest failed. \nLink to the pipeline: $pipelineUrl"
.\helpers\get-new-tool-versions\send-slack-notification.ps1 -Url "${{ secrets.SLACK_CHANNEL_URL }}" `
-ToolName "${{ inputs.tool-name }}" `
-Text "$message" `
-ImageUrl "${{ inputs.image-url }}"

View File

@@ -1,5 +1,5 @@
# Common tools for generation of packages in the actions/*-versions repositories
This repository contains PowerShell modules that are used to generate packages for Actions. The packages are consumed by the images generated through [actions/runner-images](https://github.com/actions/runner-images) and some of the setup-* Actions
This repository contains PowerShell modules that are used to generate packages for Actions. The packages are consumed by the images generated through [actions/virtual-environments](https://github.com/actions/virtual-environments) and some of the setup-* Actions
## Contribution
Contributions are welcome! See [Contributor's Guide](./CONTRIBUTING.md) for more details about contribution process and code structure

View File

@@ -0,0 +1,108 @@
class AzureDevOpsApi
{
[string] $BaseUrl
[string] $RepoOwner
[object] $AuthHeader
[UInt32] $RetryCount
[UInt32] $RetryIntervalSec
AzureDevOpsApi(
[string] $TeamFoundationCollectionUri,
[string] $ProjectName,
[string] $AccessToken,
[UInt32] $RetryCount,
[UInt32] $RetryIntervalSec
) {
$this.BaseUrl = $this.BuildBaseUrl($TeamFoundationCollectionUri, $ProjectName)
$this.AuthHeader = $this.BuildAuth($AccessToken)
$this.RetryCount = $RetryCount
$this.RetryIntervalSec = $RetryIntervalSec
}
[object] hidden BuildAuth([string]$AccessToken) {
if ([string]::IsNullOrEmpty($AccessToken)) {
return $null
}
return @{
Authorization = "Bearer $AccessToken"
}
}
[string] hidden BuildBaseUrl([string]$TeamFoundationCollectionUri, [string]$ProjectName) {
return "${TeamFoundationCollectionUri}/${ProjectName}/_apis"
}
[object] QueueBuild([string]$ToolVersion, [string]$SourceBranch, [string]$SourceVersion, [UInt32]$DefinitionId){
$url = "build/builds"
# The content of parameters field should be a json string
$buildParameters = @{ VERSION = $ToolVersion } | ConvertTo-Json
$body = @{
definition = @{
id = $DefinitionId
}
sourceBranch = $SourceBranch
sourceVersion = $SourceVersion
parameters = $buildParameters
} | ConvertTo-Json
return $this.InvokeRestMethod($url, 'POST', $body)
}
[object] GetBuildInfo([UInt32]$BuildId){
$url = "build/builds/$BuildId"
return $this.InvokeRestMethod($url, 'GET', $null)
}
[object] UpdateBuildStatus([UInt32]$BuildId, [string]$BuildStatus){
$url = "build/builds/$BuildId"
$body = @{
status = $BuildStatus
} | ConvertTo-Json
return $this.InvokeRestMethod($url, 'PATCH', $body)
}
[string] hidden BuildUrl([string]$Url) {
return "$($this.BaseUrl)/${Url}/?api-version=5.1"
}
[object] hidden InvokeRestMethod(
[string] $Url,
[string] $Method,
[string] $Body
) {
$requestUrl = $this.BuildUrl($Url)
$params = @{
Method = $Method
ContentType = "application/json"
Uri = $requestUrl
Headers = @{}
}
if ($this.AuthHeader) {
$params.Headers += $this.AuthHeader
}
if (![string]::IsNullOrEmpty($body)) {
$params.Body = $Body
}
$params.RetryIntervalSec = $this.RetryIntervalSec
$params.MaximumRetryCount = $this.RetryCount
return Invoke-RestMethod @params
}
}
function Get-AzureDevOpsApi {
param (
[string] $TeamFoundationCollectionUri,
[string] $ProjectName,
[string] $AccessToken,
[UInt32] $RetryCount = 3,
[UInt32] $RetryIntervalSec = 60
)
return [AzureDevOpsApi]::New($TeamFoundationCollectionUri, $ProjectName, $AccessToken, $RetryCount, $RetryIntervalSec)
}

View File

@@ -0,0 +1,44 @@
Import-Module (Join-Path $PSScriptRoot "azure-devops-api.ps1")
class BuildInfo
{
[AzureDevOpsApi] $AzureDevOpsApi
[String] $Name
[UInt32] $Id
[String] $Status
[String] $Result
[String] $Link
BuildInfo([AzureDevOpsApi] $AzureDevOpsApi, [object] $Build)
{
$this.AzureDevOpsApi = $AzureDevOpsApi
$this.Id = $Build.id
$this.Name = $Build.buildNumber
$this.Link = $Build._links.web.href
$this.Status = $Build.status
$this.Result = $Build.result
}
[boolean] IsFinished() {
return ($this.Status -eq "completed") -or ($this.Status -eq "cancelling")
}
[boolean] IsSuccess() {
return $this.Result -eq "succeeded"
}
[void] UpdateBuildInfo() {
$buildInfo = $this.AzureDevOpsApi.GetBuildInfo($this.Id)
$this.Status = $buildInfo.status
$this.Result = $buildInfo.result
}
}
function Get-BuildInfo {
param (
[AzureDevOpsApi] $AzureDevOpsApi,
[object] $Build
)
return [BuildInfo]::New($AzureDevOpsApi, $Build)
}

View File

@@ -0,0 +1,127 @@
param (
[Parameter(Mandatory)] [string] $TeamFoundationCollectionUri,
[Parameter(Mandatory)] [string] $AzureDevOpsProjectName,
[Parameter(Mandatory)] [string] $AzureDevOpsAccessToken,
[Parameter(Mandatory)] [string] $SourceBranch,
[Parameter(Mandatory)] [UInt32] $DefinitionId,
[Parameter(Mandatory)] [string] $SourceVersion,
[Parameter(Mandatory)] [string] $ManifestLink,
[Parameter(Mandatory)] [bool] $WaitForBuilds,
[string] $ToolVersions,
[UInt32] $RetryIntervalSec = 60,
[UInt32] $RetryCount = 3
)
Import-Module (Join-Path $PSScriptRoot "azure-devops-api.ps1")
Import-Module (Join-Path $PSScriptRoot "build-info.ps1")
function Get-ToolVersions {
param (
[Parameter(Mandatory)] [string] $ManifestLink,
[Parameter(Mandatory)] [UInt32] $RetryIntervalSec,
[Parameter(Mandatory)] [UInt32] $Retries,
[string] $ToolVersions
)
[string[]] $versionsList = @()
if ($ToolVersions) {
$versionsList = $ToolVersions.Split(',')
} else {
Write-Host "Get the list of releases from $ManifestLink"
$releases = Invoke-RestMethod $ManifestLink -MaximumRetryCount $Retries -RetryIntervalSec $RetryIntervalSec
$versionsList = $releases.version
}
Write-Host "Versions to build: $versionsList"
return $versionsList
}
function Queue-Builds {
param (
[Parameter(Mandatory)] [AzureDevOpsApi] $AzureDevOpsApi,
[Parameter(Mandatory)] [string[]] $ToolVersions,
[Parameter(Mandatory)] [string] $SourceBranch,
[Parameter(Mandatory)] [string] $SourceVersion,
[Parameter(Mandatory)] [UInt32] $DefinitionId
)
[BuildInfo[]]$queuedBuilds = @()
$ToolVersions | ForEach-Object {
$version = $_.Trim()
Write-Host "Queue build for $version..."
$queuedBuild = $AzureDevOpsApi.QueueBuild($version, $SourceBranch, $SourceVersion, $DefinitionId)
$buildInfo = Get-BuildInfo -AzureDevOpsApi $AzureDevOpsApi -Build $queuedBuild
Write-Host "Queued build: $($buildInfo.Link)"
$queuedBuilds += $buildInfo
}
return $queuedBuilds
}
function Wait-Builds {
param (
[Parameter(Mandatory)] [BuildInfo[]] $Builds,
[Parameter(Mandatory)] [UInt32] $RetryIntervalSec
)
do {
# If build is still running - refresh its status
foreach($build in $builds) {
if (!$build.IsFinished()) {
$build.UpdateBuildInfo()
if ($build.IsFinished()) {
Write-Host "The $($build.Name) build was completed: $($build.Link)"
}
}
}
$runningBuildsCount = ($builds | Where-Object { !$_.IsFinished() }).Length
Start-Sleep -Seconds $RetryIntervalSec
} while($runningBuildsCount -gt 0)
}
function Make-BuildsOutput {
param (
[Parameter(Mandatory)] [BuildInfo[]] $Builds
)
Write-Host "`nBuilds info:"
$builds | Format-Table -AutoSize -Property Name,Id,Status,Result,Link | Out-String -Width 10000
# Return exit code based on status of builds
$failedBuilds = ($builds | Where-Object { !$_.IsSuccess() })
if ($failedBuilds.Length -ne 0) {
Write-Host "##vso[task.logissue type=error;]Builds failed"
$failedBuilds | ForEach-Object -Process { Write-Host "##vso[task.logissue type=error;]Name: $($_.Name); Link: $($_.Link)" }
Write-Host "##vso[task.complete result=Failed]"
} else {
Write-host "##[section]All builds have been passed successfully"
}
}
$azureDevOpsApi = Get-AzureDevOpsApi -TeamFoundationCollectionUri $TeamFoundationCollectionUri `
-ProjectName $AzureDevOpsProjectName `
-AccessToken $AzureDevOpsAccessToken `
-RetryCount $RetryCount `
-RetryIntervalSec $RetryIntervalSec
$toolVersionsList = Get-ToolVersions -ManifestLink $ManifestLink `
-RetryIntervalSec $RetryIntervalSec `
-Retries $RetryCount `
-ToolVersions $ToolVersions
$queuedBuilds = Queue-Builds -AzureDevOpsApi $azureDevOpsApi `
-ToolVersions $toolVersionsList `
-SourceBranch $SourceBranch `
-SourceVersion $SourceVersion `
-DefinitionId $DefinitionId
if ($WaitForBuilds) {
Write-Host "`nWaiting results of builds ..."
Wait-Builds -Builds $queuedBuilds -RetryIntervalSec $RetryIntervalSec
Make-BuildsOutput -Builds $queuedBuilds
}

View File

@@ -0,0 +1,37 @@
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

View File

@@ -0,0 +1,61 @@
name: $(date:yyyyMMdd)$(rev:.r)
trigger: none
pr: none
schedules:
- cron: "0 3 * * *"
displayName: First daily build
branches:
include:
- main
always: true
- cron: "0 15 * * *"
displayName: Second 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
- stage: Trigger_Builds
dependsOn: [Find_New_Versions, Check_New_Versions]
condition: and(succeeded(), ne(variables['WORKFLOW_FILE_NAME'], ''))
jobs:
- deployment: Run_Builds
pool:
name: $(PoolName)
vmImage: $(VmImage)
variables:
ToolVersions: $[ stageDependencies.Find_New_Versions.Find_New_Versions.outputs['Get_versions.TOOL_VERSIONS'] ]
timeoutInMinutes: 180
environment: 'Get Available Tools Versions - Publishing Approval'
strategy:
runOnce:
deploy:
steps:
- template: /azure-pipelines/templates/run-ci-builds-steps.yml

View File

@@ -0,0 +1,49 @@
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)"

View File

@@ -0,0 +1,9 @@
steps:
- task: PowerShell@2
displayName: 'Get new versions'
name: 'Get_versions'
inputs:
targetType: filePath
filePath: './get-new-tool-versions/get-new-tool-versions.ps1'
arguments: |
-ToolName "$(TOOL_NAME)"

View File

@@ -0,0 +1,15 @@
steps:
- checkout: self
- task: PowerShell@2
displayName: 'Run builds'
inputs:
targetType: filePath
filePath: './github/run-ci-builds.ps1'
arguments: |
-RepositoryFullName $(REPOSITORY_FULL_NAME) `
-AccessToken $(GITHUB_TOKEN) `
-WorkflowFileName $(WORKFLOW_FILE_NAME) `
-WorkflowDispatchRef $(DISPATCH_REF) `
-ToolVersions "$(ToolVersions)" `
-PublishReleases $(PUPLISH_RELEASES)

View File

@@ -3,7 +3,7 @@
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)
Required parameter. The name of tool for which parser is available (Node, Go, Python, Xamarin)
#>
param (
@@ -16,12 +16,21 @@ $ToolVersionParser = Get-ToolVersionsParser -ToolName $ToolName
$VersionsFromDist = $ToolVersionParser.GetAvailableVersions()
$VersionsFromManifest = $ToolVersionParser.GetUploadedVersions()
$VersionsToBuild = $VersionsFromDist | Where-Object { $VersionsFromManifest -notcontains $_ }
$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 $_ }
}
if ($VersionsToBuild) {
$availableVersions = $VersionsToBuild -join ", "
$availableVersions = $VersionsToBuild -join $joinChars
Write-Host "The following versions are available to build:`n${availableVersions}"
"TOOL_VERSIONS=${availableVersions}" >> $env:GITHUB_OUTPUT
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"
}

View File

@@ -2,7 +2,7 @@ using module "./base-parser.psm1"
class GoVersionsParser: BaseVersionsParser {
[SemVer[]] GetUploadedVersions() {
$url = $this.BuildGitHubFileUrl("actions", "go-versions", "main", "versions-manifest.json")
$url = $this.BuildGitHubFileUrl("nikita-bykov", "go-versions", "move-get-go-version", "versions-manifest.json")
$releases = Invoke-RestMethod $url -MaximumRetryCount $this.ApiRetryCount -RetryIntervalSec $this.ApiRetryIntervalSeconds
return $releases.version
}

View File

@@ -2,7 +2,7 @@ using module "./base-parser.psm1"
class NodeVersionsParser: BaseVersionsParser {
[SemVer[]] GetUploadedVersions() {
$url = $this.BuildGitHubFileUrl("actions", "node-versions", "main", "versions-manifest.json")
$url = $this.BuildGitHubFileUrl("nikita-bykov", "node-versions", "move-get-node-versions-test", "versions-manifest.json")
$releases = Invoke-RestMethod $url -MaximumRetryCount $this.ApiRetryCount -RetryIntervalSec $this.ApiRetryIntervalSeconds
return $releases.version
}

View File

@@ -1,6 +1,7 @@
using module "./node-parser.psm1"
using module "./go-parser.psm1"
using module "./python-parser.psm1"
using module "./xamarin-parser.psm1"
function Get-ToolVersionsParser {
param(
@@ -12,6 +13,7 @@ function Get-ToolVersionsParser {
"Node" { return [NodeVersionsParser]::New() }
"Go" { return [GoVersionsParser]::New() }
"Python" { return [PythonVersionsParser]::New() }
"Xamarin" { return [XamarinversionsParser]::New() }
Default {
throw "Unknown tool name"
}

View File

@@ -1,27 +0,0 @@
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") {
if ($_.lts) {
$_.$FilterParameter.split(".")[0] + ".0"
}
} else {
$_.$FilterParameter.split(".")[0,1] -join"."
}
} | Select-Object -Unique
$toolsetUrl = "https://raw.githubusercontent.com/actions/runner-images/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
}

View File

@@ -1,19 +0,0 @@
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/runner-images/main/images/macos/toolsets/toolset-12.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
}

View File

@@ -0,0 +1,30 @@
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
}
}

View File

@@ -0,0 +1,60 @@
<#
.SYNOPSIS
Sending messages using Incoming Webhooks
.PARAMETER Url
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
.PARAMETER PipelineUrl
Required parameter. The pipeline URL
.PARAMETER ImageUrl
Optional parameter. The image URL
#>
param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[System.Uri]$Url,
[Parameter(Mandatory)]
[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'
)
# Import helpers module
Import-Module $PSScriptRoot/helpers.psm1 -DisableNameChecking
# Create JSON body
$text = "Some jobs were not successful for the following detection pipelines of '$ToolName'\nLink to the pipeline: '$pipelineUrl'"
$jsonBodyMessage = @"
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "$text"
},
"accessory": {
"type": "image",
"image_url": "$imageUrl",
"alt_text": "$toolName"
}
}
]
}
"@
# Send Slack message
$null = Send-SlackPostMessageIncomingWebHook -Uri $url -Body $jsonBodyMessage

View File

@@ -7,15 +7,11 @@ Required parameter. Incoming Webhook URL to post a message
.PARAMETER ToolName
Required parameter. The name of tool
.PARAMETER ToolVersion
Optional parameter. Specifies the version of tool
Required parameter. Specifies the version of tool
.PARAMETER PipelineUrl
Optional parameter. The pipeline URL
Required 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(
@@ -30,8 +26,7 @@ param(
[System.String]$ToolVersion,
[System.String]$PipelineUrl,
[System.String]$ImageUrl = 'https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png',
[System.String]$Text,
[Switch]$AddToToolsetFlag
[System.String]$Text
)
# Import helpers module
@@ -39,16 +34,15 @@ Import-Module $PSScriptRoot/helpers.psm1 -DisableNameChecking
# Create JSON body
if ([string]::IsNullOrWhiteSpace($Text)) {
if ($AddToToolsetFlag) {
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"
}
}
if (-not ([string]::IsNullOrWhiteSpace($PipelineUrl))) {
$Text += "\nLink to the pipeline: $pipelineUrl"
}
$jsonBodyMessage = @"
{
"blocks": [

View File

@@ -1,38 +0,0 @@
<#
.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-2022"
$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

View File

@@ -77,7 +77,6 @@ Describe "Build-VersionsManifest" {
$assets = @(
@{ name = "python-3.8.3-linux-16.04-x64.tar.gz"; browser_download_url = "fake_url"; }
@{ name = "python-3.8.3-linux-18.04-x64.tar.gz"; browser_download_url = "fake_url"; }
@{ name = "hashes.sha256"; browser_download_url = "fake_url"; }
)
$configuration = @{
regex = "python-\d+\.\d+\.\d+-(\w+)-([\w\.]+)?-?(x\d+)";

View File

@@ -67,7 +67,7 @@ function Build-VersionsManifest {
$ltsStatus = Get-VersionLtsStatus -Version $versionKey -LtsRules $ltsRules
$stable = $version.PreReleaseLabel ? $false : $true
[array]$releaseAssets = $release.assets | Where { $_.Name -ne "hashes.sha256" } | ForEach-Object { New-AssetItem -ReleaseAsset $_ -Configuration $Configuration }
[array]$releaseAssets = $release.assets | ForEach-Object { New-AssetItem -ReleaseAsset $_ -Configuration $Configuration }
$versionHash = [PSCustomObject]@{}
$versionHash | Add-Member -Name "version" -Value $versionKey -MemberType NoteProperty

View File

@@ -1,29 +1,30 @@
param (
[Parameter(Mandatory)][string] $ManifestPath
[Parameter(Mandatory)][string] $ManifestUrl,
[string] $AccessToken
)
$Global:validationFailed = $false
$authorizationHeaderValue = "Basic $AccessToken"
$webRequestHeaders = @{}
if ($AccessToken) {
$webRequestHeaders.Add("Authorization", $authorizationHeaderValue)
}
function Publish-Error {
param(
[string] $ErrorDescription,
[object] $Exception
)
Write-Output "::error ::$ErrorDescription"
if (-not [string]::IsNullOrEmpty($Exception))
{
Write-Output "Exception: $Exception"
}
$Global:validationFailed = $true
Write-Host "##vso[task.logissue type=error]ERROR: $ErrorDescription."
Write-Host "##vso[task.logissue type=error] $Exception"
Write-Host "##vso[task.complete result=Failed;]"
}
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)
@@ -32,16 +33,19 @@ function Test-DownloadUrl {
}
}
if (-not (Test-Path $ManifestPath)) {
Publish-Error "Unable to find manifest json file at '$ManifestPath'"
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'" $_
exit 1
}
Write-Host "Parsing manifest json content from '$ManifestPath'..."
Write-Host "Parsing manifest json content from '$ManifestUrl'..."
try {
$manifestJson = Get-Content $ManifestPath | ConvertFrom-Json
$manifestJson = $manifestResponse.Content | ConvertFrom-Json
} catch {
Publish-Error "Unable to parse manifest json content '$ManifestPath'" $_
Publish-Error "Unable to parse manifest json content '$ManifestUrl'" $_
exit 1
}
@@ -57,7 +61,3 @@ $manifestJson | ForEach-Object {
}
}
}
if ($Global:validationFailed) {
exit 1
}