mirror of
https://github.com/actions/versions-package-tools.git
synced 2025-12-10 19:50:24 +00:00
Compare commits
88 Commits
v-malob/fi
...
816a9a3331
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
816a9a3331 | ||
|
|
6c48f687bd | ||
|
|
e60ec8ae98 | ||
|
|
db2ae0a36e | ||
|
|
6fdf7f098f | ||
|
|
4ae553a74d | ||
|
|
13ba3fd9e0 | ||
|
|
552a1a5fda | ||
|
|
1e5d44c7a5 | ||
|
|
817eacd539 | ||
|
|
933aacb90a | ||
|
|
d3c3feee4b | ||
|
|
4028baf988 | ||
|
|
d30950623a | ||
|
|
16b7940fde | ||
|
|
94d413c5d2 | ||
|
|
6d641c49d7 | ||
|
|
447803d00a | ||
|
|
b549ccbeee | ||
|
|
760646fc29 | ||
|
|
a8a2c841ba | ||
|
|
6fbb1f0f20 | ||
|
|
b964a9871b | ||
|
|
d4cf796ec9 | ||
|
|
b8e79c3d16 | ||
|
|
b43c6cc8fd | ||
|
|
5810329d19 | ||
|
|
896369fc7d | ||
|
|
d25937e581 | ||
|
|
c08a90cad6 | ||
|
|
2c15878a9d | ||
|
|
7b3aff2ad5 | ||
|
|
81e64845b7 | ||
|
|
56f47ea626 | ||
|
|
c3143dd446 | ||
|
|
31f01aedc7 | ||
|
|
e6dbb79745 | ||
|
|
fe999f6aa6 | ||
|
|
33b79844a6 | ||
|
|
de5faa4d9c | ||
|
|
a753279554 | ||
|
|
6f1aa3ce73 | ||
|
|
e98e069ca6 | ||
|
|
8e2a68893f | ||
|
|
359c2548cb | ||
|
|
fa49641719 | ||
|
|
b5a05e45d5 | ||
|
|
e71d476320 | ||
|
|
7114ad2b94 | ||
|
|
fb0eac418a | ||
|
|
f07ff8ddf9 | ||
|
|
f72b7a85c7 | ||
|
|
3d09ce1d19 | ||
|
|
a9e00ee513 | ||
|
|
9f82304f9c | ||
|
|
4f7bf4650a | ||
|
|
1eaa091b65 | ||
|
|
5a00becf47 | ||
|
|
9b849b3d5a | ||
|
|
e9ef44e60c | ||
|
|
6b66054ab6 | ||
|
|
8c62a83204 | ||
|
|
ab37396421 | ||
|
|
98826eed53 | ||
|
|
6147177edd | ||
|
|
2a422a2d52 | ||
|
|
46a901fa87 | ||
|
|
f19d5f4b3c | ||
|
|
00039881ba | ||
|
|
878c283d3b | ||
|
|
41a1acf1a4 | ||
|
|
2bd3b2a3c2 | ||
|
|
e81db48281 | ||
|
|
ab218c2436 | ||
|
|
504e746b96 | ||
|
|
4d97edc41a | ||
|
|
80bbe2ac05 | ||
|
|
77b53792b3 | ||
|
|
725c68b777 | ||
|
|
81507e485b | ||
|
|
7ec75e0761 | ||
|
|
590ebcd1ab | ||
|
|
cc2ef5ff7d | ||
|
|
e37209e8d6 | ||
|
|
3d7121daba | ||
|
|
f5bdb61b33 | ||
|
|
96a98e9fb3 | ||
|
|
5f0e0eebc8 |
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* @actions/setup-actions-team
|
||||
39
.github/actions/send-slack-notification/action.yml
vendored
Normal file
39
.github/actions/send-slack-notification/action.yml
vendored
Normal file
@@ -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 }}
|
||||
14
.github/dependabot.yml
vendored
Normal file
14
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# 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'
|
||||
278
.github/workflows/build-tool-packages.yml
vendored
Normal file
278
.github/workflows/build-tool-packages.yml
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
# 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@v5
|
||||
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-15-intel
|
||||
platform: darwin
|
||||
architecture: x64
|
||||
- os: windows-latest
|
||||
platform: win32
|
||||
architecture: x64
|
||||
- os: ubuntu-22.04-arm
|
||||
platform: linux
|
||||
architecture: arm64
|
||||
- os: macos-latest
|
||||
platform: darwin
|
||||
architecture: arm64
|
||||
- os: windows-11-arm
|
||||
platform: win32
|
||||
architecture: arm64
|
||||
|
||||
steps:
|
||||
- name: checkout
|
||||
if: env.excludewinarm == 'true'
|
||||
uses: actions/checkout@v5
|
||||
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@v5
|
||||
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: Ensure Pester Installed
|
||||
run: |
|
||||
$module = Get-Module -ListAvailable -Name Pester
|
||||
if (-not $module -or ($module.Version -lt [Version]"5.0.0")) {
|
||||
Install-Module Pester -Force -Scope CurrentUser -SkipPublisherCheck
|
||||
}
|
||||
|
||||
- name: Run tests
|
||||
if: env.excludewinarm == 'true'
|
||||
env:
|
||||
VERSION: ${{ inputs.tool-version }}
|
||||
run: |
|
||||
Import-Module Pester
|
||||
$toolName = (Get-Culture).TextInfo.ToTitleCase("${{ inputs.tool-name }}")
|
||||
Invoke-Pester -Configuration @{
|
||||
Run = @{ Path = "./$toolName.Tests.ps1" }
|
||||
Should = @{ ErrorAction = 'Continue' }
|
||||
Output = @{ EnableExit = $true }
|
||||
}
|
||||
working-directory: ./tests
|
||||
|
||||
# - 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 -Configuration @{
|
||||
# Run = @{ Path = "./$toolName.Tests.ps1" }
|
||||
# Should = @{ ErrorAction = 'Continue' }
|
||||
# Output = @{ EnableExit = $true }
|
||||
# }
|
||||
# working-directory: ./tests
|
||||
|
||||
publish_release:
|
||||
name: Publish release
|
||||
if: inputs.publish-release
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/download-artifact@v5
|
||||
|
||||
- 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'
|
||||
});
|
||||
2
.github/workflows/common_tests.yml
vendored
2
.github/workflows/common_tests.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Install Pester
|
||||
shell: pwsh
|
||||
|
||||
43
.github/workflows/create-pr-to-update-manifest.yml
vendored
Normal file
43
.github/workflows/create-pr-to-update-manifest.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# 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@v5
|
||||
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}"
|
||||
109
.github/workflows/get-new-tool-versions.yml
vendored
Normal file
109
.github/workflows/get-new-tool-versions.yml
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
# 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@v5
|
||||
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@v5
|
||||
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@v5
|
||||
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@v5
|
||||
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 }}"
|
||||
89
.github/workflows/get-tools-new-versions.yml
vendored
Normal file
89
.github/workflows/get-tools-new-versions.yml
vendored
Normal file
@@ -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@v5
|
||||
- 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@v5
|
||||
- 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 }}"
|
||||
51
.github/workflows/validate-manifest.yml
vendored
Normal file
51
.github/workflows/validate-manifest.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# 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@v5
|
||||
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@v5
|
||||
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 }}"
|
||||
30
README.md
30
README.md
@@ -1,5 +1,29 @@
|
||||
# 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/virtual-environments](https://github.com/actions/virtual-environments) 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/runner-images](https://github.com/actions/runner-images) 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
|
||||
## Recommended permissions
|
||||
|
||||
When using the `versions-package-tools` in your GitHub Actions workflow, it is recommended to set the following permissions to ensure proper functionality:
|
||||
|
||||
```yaml
|
||||
permissions:
|
||||
contents: read # access to read repository's content
|
||||
actions: read # access to reading actions
|
||||
```
|
||||
### Note
|
||||
|
||||
Thank you for your interest in this GitHub action, however, right now we are not taking contributions. Add commentMore actionsAdd commentMore actions
|
||||
|
||||
We continue to focus our resources on strategic areas that help our customers be successful while making developers' lives easier. While GitHub Actions remains a key part of this vision, we are allocating resources towards other areas of Actions and are not taking contributions to this repository at this time. The GitHub public roadmap is the best place to follow along for any updates on features we’re working on and what stage they’re in.
|
||||
|
||||
We are taking the following steps to better direct requests related to GitHub Actions, including:
|
||||
|
||||
1. We will be directing questions and support requests to our [Community Discussions area](https://github.com/orgs/community/discussions/categories/actions)
|
||||
|
||||
2. High Priority bugs can be reported through Community Discussions or you can report these to our support team https://support.github.com/contact/bug-report.
|
||||
|
||||
3. Security Issues should be handled as per our [security.md](security.md)
|
||||
|
||||
We will still provide security updates for this project and fix major breaking changes during this time.
|
||||
|
||||
You are welcome to still raise bugs in this repo.
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
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)
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
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)
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
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
|
||||
@@ -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 -eq "Python") {
|
||||
$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)"
|
||||
@@ -1,9 +0,0 @@
|
||||
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)"
|
||||
@@ -1,15 +0,0 @@
|
||||
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)
|
||||
@@ -21,7 +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 "##vso[task.setvariable variable=TOOL_VERSIONS;isOutput=true]${availableVersions}"
|
||||
"TOOL_VERSIONS=${availableVersions}" >> $env:GITHUB_OUTPUT
|
||||
} else {
|
||||
Write-Host "There aren't versions to build"
|
||||
}
|
||||
|
||||
@@ -15,10 +15,15 @@ class GoVersionsParser: BaseVersionsParser {
|
||||
|
||||
hidden [SemVer] FormatVersion([string]$VersionSpec) {
|
||||
$cleanVersion = $VersionSpec -replace "^go", ""
|
||||
return [SemVer]$cleanVersion
|
||||
$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"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
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
|
||||
}
|
||||
@@ -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/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
|
||||
}
|
||||
@@ -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 (-not ([string]::IsNullOrWhiteSpace($PipelineUrl))) {
|
||||
$text += "\nLink to the pipeline: $pipelineUrl"
|
||||
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"
|
||||
}
|
||||
|
||||
$jsonBodyMessage = @"
|
||||
{
|
||||
"blocks": [
|
||||
@@ -46,7 +56,7 @@ $jsonBodyMessage = @"
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "$text"
|
||||
"text": "$Text"
|
||||
},
|
||||
"accessory": {
|
||||
"type": "image",
|
||||
|
||||
@@ -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-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
|
||||
@@ -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,
|
||||
|
||||
@@ -77,6 +77,7 @@ 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+)";
|
||||
@@ -161,4 +162,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
|
||||
}
|
||||
}
|
||||
@@ -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 }
|
||||
[array]$releaseAssets = $release.assets | Where { $_.Name -ne "hashes.sha256" } | 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 }
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user