Compare commits

..
623 changed files with 15278 additions and 19167 deletions
-4
View File
@@ -38,13 +38,9 @@ body:
options: options:
- label: Ubuntu 20.04 - label: Ubuntu 20.04
- label: Ubuntu 22.04 - label: Ubuntu 22.04
- label: Ubuntu 24.04
- label: macOS 11 - label: macOS 11
- label: macOS 12 - label: macOS 12
- label: macOS 13 - label: macOS 13
- label: macOS 13 Arm64
- label: macOS 14
- label: macOS 14 Arm64
- label: Windows Server 2019 - label: Windows Server 2019
- label: Windows Server 2022 - label: Windows Server 2022
- type: textarea - type: textarea
-4
View File
@@ -21,13 +21,9 @@ body:
options: options:
- label: Ubuntu 20.04 - label: Ubuntu 20.04
- label: Ubuntu 22.04 - label: Ubuntu 22.04
- label: Ubuntu 24.04
- label: macOS 11 - label: macOS 11
- label: macOS 12 - label: macOS 12
- label: macOS 13 - label: macOS 13
- label: macOS 13 Arm64
- label: macOS 14
- label: macOS 14 Arm64
- label: Windows Server 2019 - label: Windows Server 2019
- label: Windows Server 2022 - label: Windows Server 2022
- type: textarea - type: textarea
-4
View File
@@ -59,13 +59,9 @@ body:
options: options:
- label: Ubuntu 20.04 - label: Ubuntu 20.04
- label: Ubuntu 22.04 - label: Ubuntu 22.04
- label: Ubuntu 24.04
- label: macOS 11 - label: macOS 11
- label: macOS 12 - label: macOS 12
- label: macOS 13 - label: macOS 13
- label: macOS 13 Arm64
- label: macOS 14
- label: macOS 14 Arm64
- label: Windows Server 2019 - label: Windows Server 2019
- label: Windows Server 2022 - label: Windows Server 2022
- type: textarea - type: textarea
+48
View File
@@ -0,0 +1,48 @@
run-name: Cleanup ${{ github.head_ref }}
on:
pull_request_target:
types: labeled
paths:
- 'images/**'
jobs:
clean_ci:
name: Clean CI runs
runs-on: ubuntu-latest
permissions:
actions: write
steps:
- env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: pwsh
run: |
$startDate = Get-Date -UFormat %s
$workflows = @("macos11", "macos12", "ubuntu2004", "ubuntu2204", "windows2019", "windows2022")
while ($true) {
$continue = $false
foreach ($wf in $workflows) {
$skippedCommand = "gh run list --workflow ${wf}.yml --branch ${{ github.event.pull_request.head.ref }} --repo ${{ github.repository }} --status skipped --json databaseId"
$skippedIds = Invoke-Expression -Command $skippedCommand | ConvertFrom-Json | ForEach-Object { $_.databaseId }
$skippedIds | ForEach-Object {
$deleteCommand = "gh run delete --repo ${{ github.repository }} $_"
Invoke-Expression -Command $deleteCommand
}
$pendingCommand = "gh run list --workflow ${wf}.yml --branch ${{ github.event.pull_request.head.ref }} --repo ${{ github.repository }} --status requested --json databaseId --template '{{ . | len }}'"
$pending = Invoke-Expression -Command $pendingCommand
if ($pending -gt 0) {
Write-Host "Pending for ${wf}.yml: $pending run(s)"
$continue = $true
}
}
if ($continue -eq $false) {
Write-Host "All done, exiting"
break
}
$curDate = Get-Date -UFormat %s
if (($curDate - $startDate) -gt 60) {
Write-Host "Reached timeout, exiting"
break
}
Write-Host "Waiting 5 seconds..."
Start-Sleep -Seconds 5
}
+4 -4
View File
@@ -40,11 +40,11 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v3 uses: github/codeql-action/init@v2
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@@ -55,7 +55,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v3 uses: github/codeql-action/autobuild@v2
# ️ Command-line programs to run using the OS shell. # ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl # 📚 https://git.io/JvXDl
@@ -69,4 +69,4 @@ jobs:
# make release # make release
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3 uses: github/codeql-action/analyze@v2
+7 -5
View File
@@ -10,13 +10,15 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Create release for ${{ github.event.client_payload.ReleaseBranchName }} - name: Create release for ${{ github.event.client_payload.ReleaseBranchName }}
uses: ncipollo/release-action@v1.14.0 uses: actions/create-release@v1.1.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
tag: ${{ github.event.client_payload.ReleaseBranchName }} tag_name: ${{ github.event.client_payload.ReleaseBranchName }}
name: ${{ github.event.client_payload.ReleaseTitle }} release_name: ${{ github.event.client_payload.ReleaseTitle }}
body: ${{ github.event.client_payload.ReleaseBody }} body: ${{ github.event.client_payload.ReleaseBody }}
prerelease: ${{ github.event.client_payload.Prerelease }} prerelease: ${{ github.event.client_payload.Prerelease }}
commit: ${{ github.event.client_payload.Commitish }} commitish: ${{ github.event.client_payload.Commitish }}
+5 -5
View File
@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
@@ -22,11 +22,11 @@ jobs:
- name: Create pull request for ${{ github.event.client_payload.ReleaseBranchName }} - name: Create pull request for ${{ github.event.client_payload.ReleaseBranchName }}
id: create-pr id: create-pr
uses: actions/github-script@v7 uses: actions/github-script@v2
with: with:
github-token: ${{secrets.GITHUB_TOKEN}} github-token: ${{secrets.GITHUB_TOKEN}}
script: | script: |
let response = await github.rest.pulls.create({ let response = await github.pulls.create({
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
title: "${{ github.event.client_payload.PullRequestTitle }}", title: "${{ github.event.client_payload.PullRequestTitle }}",
@@ -37,11 +37,11 @@ jobs:
return response.data.number return response.data.number
- name: Request reviewers - name: Request reviewers
uses: actions/github-script@v7 uses: actions/github-script@v2
with: with:
github-token: ${{secrets.PRAPPROVAL_SECRET}} github-token: ${{secrets.PRAPPROVAL_SECRET}}
script: | script: |
github.rest.pulls.requestReviewers({ github.pulls.requestReviewers({
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
pull_number: ${{ steps.create-pr.outputs.result }}, pull_number: ${{ steps.create-pr.outputs.result }},
+13 -34
View File
@@ -1,4 +1,4 @@
name: Create SBOM for the release name: Create and upload a SBOM to release assets
# Inherited variables: # Inherited variables:
# github.event.client_payload.agentSpec - Current YAML Label # github.event.client_payload.agentSpec - Current YAML Label
# github.event.client_payload.ReleaseID - Current release ID # github.event.client_payload.ReleaseID - Current release ID
@@ -14,35 +14,8 @@ defaults:
run: run:
shell: pwsh shell: pwsh
jobs: jobs:
#Checking current release for SBOM #Checking image version on available runner
sbom-check: version-check:
outputs:
check_status: ${{ steps.check.outputs.status }}
runs-on: ubuntu-latest
steps:
- name: Check release for ${{ github.event.client_payload.ReleaseBranchName }}
id: check
shell: pwsh
run: |
$apiUrl = "https://api.github.com/repos/actions/runner-images/releases/${{ github.event.client_payload.ReleaseID }}"
$response = Invoke-RestMethod -Uri $apiUrl -Method Get -SkipHttpErrorCheck
if ($response.message -ilike "Not Found") {
echo "status=release_not_found" >> $env:GITHUB_OUTPUT
Write-Error "Release ${{ github.event.client_payload.ReleaseID }} wasn't found"
exit 1
}
foreach ($asset in $response.assets) {
if ($asset.name -like '*sbom*') {
echo "status=sbom_exists" >> $env:GITHUB_OUTPUT
return "Release ${{ github.event.client_payload.ReleaseID }} already contains a SBOM"
}
}
Write-Host "Release has been found, SBOM is not attached, starting generation."
echo "status=okay" >> $env:GITHUB_OUTPUT
#Generating SBOM
building-sbom:
needs: sbom-check
if: ${{ needs.sbom-check.outputs.check_status == 'okay' }}
runs-on: ${{ github.event.client_payload.agentSpec }} runs-on: ${{ github.event.client_payload.agentSpec }}
steps: steps:
- name: Available image version check for ${{ github.event.client_payload.ReleaseBranchName }} - name: Available image version check for ${{ github.event.client_payload.ReleaseBranchName }}
@@ -53,12 +26,18 @@ jobs:
if ("$imageMajorVersion.$imageMinorVersion" -ne '${{ github.event.client_payload.imageVersion }}') { if ("$imageMajorVersion.$imageMinorVersion" -ne '${{ github.event.client_payload.imageVersion }}') {
throw "Current runner $imageMajorVersion.$imageMinorVersion image version doesn't match ${{ github.event.client_payload.imageVersion }}." throw "Current runner $imageMajorVersion.$imageMinorVersion image version doesn't match ${{ github.event.client_payload.imageVersion }}."
} }
#Install and run SYFT, compress SBOM, upload it to release assets
create-sbom:
needs: version-check
runs-on: ${{ github.event.client_payload.agentSpec }}
steps:
#Installation section
- name: Install SYFT tool on Windows - name: Install SYFT tool on Windows
if: ${{ runner.os == 'Windows' }} if: ${{ runner.os == 'Windows' }}
run: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b D:/syft run: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b D:/syft v0.84.1
- name: Install SYFT tool on Ubuntu or macOS - name: Install SYFT tool on Ubuntu or macOS
if: ${{ runner.os != 'Windows' }} if: ${{ runner.os != 'Windows' }}
run: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin v0.100.0 run: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
#Running section. #Running section.
- name: Run SYFT on Windows - name: Run SYFT on Windows
if: ${{ runner.os == 'Windows' }} if: ${{ runner.os == 'Windows' }}
@@ -74,7 +53,7 @@ jobs:
- name: Compress SBOM file - name: Compress SBOM file
run: Compress-Archive sbom.json sbom.json.zip run: Compress-Archive sbom.json sbom.json.zip
#Upload artifact action #Upload artifact action
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
with: with:
name: sbom-${{ github.event.client_payload.agentSpec }}-${{ github.event.client_payload.imageVersion }} name: sbom-${{ github.event.client_payload.agentSpec }}-${{ github.event.client_payload.imageVersion }}
path: sbom.json.zip path: sbom.json.zip
@@ -89,4 +68,4 @@ jobs:
upload_url: "https://uploads.github.com/repos/actions/runner-images/releases/${{ github.event.client_payload.ReleaseID }}/assets{?name,label}" upload_url: "https://uploads.github.com/repos/actions/runner-images/releases/${{ github.event.client_payload.ReleaseID }}/assets{?name,label}"
asset_path: ./sbom.json.zip asset_path: ./sbom.json.zip
asset_name: sbom.${{ github.event.client_payload.agentSpec }}.json.zip asset_name: sbom.${{ github.event.client_payload.agentSpec }}.json.zip
asset_content_type: application/zip asset_content_type: application/zip
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
steps: steps:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v4 uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
+5 -5
View File
@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
@@ -24,11 +24,11 @@ jobs:
sleep 30 sleep 30
- name: Approve pull request by GitHub-Actions bot - name: Approve pull request by GitHub-Actions bot
uses: actions/github-script@v7 uses: actions/github-script@v2
with: with:
github-token: ${{secrets.PRAPPROVAL_SECRET}} github-token: ${{secrets.PRAPPROVAL_SECRET}}
script: | script: |
github.rest.pulls.createReview({ github.pulls.createReview({
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
pull_number: ${{ github.event.client_payload.PullRequestNumber }}, pull_number: ${{ github.event.client_payload.PullRequestNumber }},
@@ -36,11 +36,11 @@ jobs:
}); });
- name: Merge pull request for ${{ github.event.client_payload.ReleaseBranchName }} - name: Merge pull request for ${{ github.event.client_payload.ReleaseBranchName }}
uses: actions/github-script@v7 uses: actions/github-script@v2
with: with:
github-token: ${{secrets.GITHUB_TOKEN}} github-token: ${{secrets.GITHUB_TOKEN}}
script: | script: |
github.rest.pulls.merge({ github.pulls.merge({
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
pull_number: ${{ github.event.client_payload.PullRequestNumber }}, pull_number: ${{ github.event.client_payload.PullRequestNumber }},
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
steps: steps:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v3
- name: Run Software Report module tests - name: Run Software Report module tests
shell: pwsh shell: pwsh
+1 -1
View File
@@ -5,7 +5,7 @@ on:
pull_request_target: pull_request_target:
types: labeled types: labeled
paths: paths:
- 'images/ubuntu/**' - 'images/linux/**'
defaults: defaults:
run: run:
+1 -1
View File
@@ -5,7 +5,7 @@ on:
pull_request_target: pull_request_target:
types: labeled types: labeled
paths: paths:
- 'images/ubuntu/**' - 'images/linux/**'
defaults: defaults:
run: run:
+4 -4
View File
@@ -10,19 +10,19 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: Update release for ${{ github.event.client_payload.ReleaseBranchName }} - name: Update release for ${{ github.event.client_payload.ReleaseBranchName }}
uses: actions/github-script@v7 uses: actions/github-script@v2
with: with:
github-token: ${{secrets.GITHUB_TOKEN}} github-token: ${{secrets.GITHUB_TOKEN}}
script: | script: |
const response = await github.rest.repos.getReleaseByTag({ const response = await github.repos.getReleaseByTag({
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
tag: "${{ github.event.client_payload.ReleaseBranchName }}" tag: "${{ github.event.client_payload.ReleaseBranchName }}"
}); });
github.rest.repos.updateRelease({ github.repos.updateRelease({
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
release_id: response.data.id, release_id: response.data.id,
+1 -1
View File
@@ -5,7 +5,7 @@ on:
pull_request_target: pull_request_target:
types: labeled types: labeled
paths: paths:
- 'images/windows/**' - 'images/win/**'
defaults: defaults:
run: run:
+1 -1
View File
@@ -5,7 +5,7 @@ on:
pull_request_target: pull_request_target:
types: labeled types: labeled
paths: paths:
- 'images/windows/**' - 'images/win/**'
defaults: defaults:
run: run:
+28 -28
View File
@@ -6,17 +6,17 @@
Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great. Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great.
Contributions to this project are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license) to the public under the [MIT](LICENSE.md) license. Contributions to this project are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license) to the public under the [MIT](LICENSE.md).
Please note that this project is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in this project, you agree to abide by its terms. Please note that this project is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in this project you agree to abide by its terms.
## Submitting a pull request ## Submitting a pull request
1. [Fork][fork] and clone the repository. 1. [Fork][fork] and clone the repository
1. Create a new branch: `git checkout -b my-branch-name`. 1. Create a new branch: `git checkout -b my-branch-name`
1. Make your changes, ensuring that they include steps to install, validate post-install, and update the software report (please see [How to add a new tool](CONTRIBUTING.md#how-to-add-a-new-tool) for details). 1. Make your changes, ensure that they include steps to install, validate post-install and update software report (please see [How to add new tool](CONTRIBUTING.md#how-to-add-new-tool) for details).
1. Test your changes by [creating an image and deploying a VM](docs/create-image-and-azure-resources.md). 1. Test your changes by [creating image and deploying a VM](docs/create-image-and-azure-resources.md).
1. Push to your fork and [submit a pull request][pr]. 1. Push to your fork and [submit a pull request][pr]
Here are a few things you can do that will increase the likelihood of your pull request being accepted: Here are a few things you can do that will increase the likelihood of your pull request being accepted:
@@ -25,40 +25,40 @@ Here are a few things you can do that will increase the likelihood of your pull
- Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests. - Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests.
- Write [good commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). - Write [good commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
- For new tools: - For new tools:
- Make sure that the tool satisfies the [Software Guidelines](README.md#software-guidelines). - Make sure that the tool satisfies [Software Guidelines](README.md#software-guidelines).
- Create an issue and get approval from us to add this tool to the image before creating the pull request. - Create an issue and get an approval from us to add this tool to the image before creating the pull request.
## How to add a new tool ## How to add new tool
### General rules ### General rules
- For every new tool, add validation scripts and update the software report script to ensure that it is included in the documentation. - For every new tool add validation scripts and update software report script to make sure that it is included to documentation
- If the tool is available on multiple platforms (macOS, Windows, Linux), make sure you include it on as many as possible. - If the tool is available in other platforms (macOS, Windows, Linux), make sure you include it in as many as possible.
- If installing multiple versions of the tool, consider putting the list of versions in the corresponding `toolset.json` file. This will help other customers configure their builds flexibly. See [toolset-windows-2019.json](images/windows/toolsets/toolset-2019.json) as an example. - If installing a few versions of the tool, consider putting the list of versions in the corresponding `toolset.json` file. It will help other customers to configure their builds flexibly. See [toolset-windows-2019.json](images/win/toolsets/toolset-2019.json) as example.
- Use consistent naming across all files. - Use consistent naming across all files
- Validation scripts should be simple and shouldn't change the image content. - Validation scripts should be simple and shouldn't change image content
### Windows ### Windows
- Add a script that will install the tool and put the script in the `scripts/build` folder. - Add a script that will install the tool and put the script in the `scripts/Installers` folder.
There are a bunch of helper functions that could simplify your code: `Install-ChocoPackage`, `Install-Binary`, `Install-VSIXFromFile`, `Install-VSIXFromUrl`, `Invoke-DownloadWithRetry`, `Test-IsWin19`, `Test-IsWin22` (find the full list of helpers in [ImageHelpers.psm1](images/windows/scripts/helpers/ImageHelpers.psm1)). There are a bunch of helper functions that could simplify your code: `Choco-Install`, `Install-Binary`, `Install-VsixExtension`, `Start-DownloadWithRetry`, `Test-IsWin19`, `Test-IsWin22` (find the full list of helpers in [ImageHelpers.psm1](images/win/scripts/ImageHelpers/ImageHelpers.psm1)).
- Add a script that will validate the tool installation and put the script in the `scripts/tests` folder. - Add a script that will validate the tool installation and put the script in the `scripts/Tests` folder.
We use [Pester v5](https://github.com/pester/pester) for validation scripts. If the tests for the tool are complex enough, create a separate `*.Tests.ps1`. Otherwise, use `Tools.Tests.ps1` for simple tests. We use [Pester v5](https://github.com/pester/pester) for validation scripts. If the tests for the tool are complex enough, create a separate `*.Tests.ps1`. Otherwise, use `Tools.Tests.ps1` for simple tests.
Add `Invoke-PesterTests -TestFile <testFileName> [-TestName <describeName>]` at the end of the installation script to ensure that your tests will be run. Add `Invoke-PesterTests -TestFile <testFileName> [-TestName <describeName>]` at the end of the installation script to make sure that your tests will be run.
- Add changes to the software report generator `images/windows/scripts/docs-gen/Generate-SoftwareReport.ps1`. The software report generator is used to generate an image's README file, e.g. [Windows2019-Readme.md](images/windows/Windows2019-Readme.md) and uses [MarkdownPS](https://github.com/Sarafian/MarkdownPS). - Add changes to the software report generator `images/win/scripts/SoftwareReport/SoftwareReport.Generator.ps1`. The software report generator is used to generate an image's README file, e.g. [Windows2019-Readme.md](images/win/Windows2019-Readme.md) and uses [MarkdownPS](https://github.com/Sarafian/MarkdownPS).
### Ubuntu ### Ubuntu
- Add a script that will install and validate the tool and put the script in the `scripts/build` folder. - Add script that will install and validate the tool and put the script in the `scripts/installers` folder.
Use existing scripts such as [github-cli.sh](images/ubuntu/scripts/build/github-cli.sh) as a starting point. Use existing scripts such as [github-cli.sh](images/linux/scripts/installers/github-cli.sh) as a starting point.
- Use [helpers](images/ubuntu/scripts/helpers/install.sh) to simplify the installation process. - Use [helpers](images/linux/scripts/helpers/install.sh) to simplify installation process.
- The validation part should `exit 1` if there is any issue with the installation. - Validation part should `exit 1` if any issue with installation.
- Add changes to the software report generator `images/ubuntu/scripts/docs-gen/Generate-SoftwareReport.ps1`. The software report generator is used to generate an image's README file, e.g. [Ubuntu2004-Readme.md](images/ubuntu/Ubuntu2004-README.md) and it uses [MarkdownPS](https://github.com/Sarafian/MarkdownPS). - Add changes to the software report generator `images/linux/scripts/SoftwareReport/SoftwareReport.Generator.ps1`. The software report generator is used to generate an image's README file, e.g. [Ubuntu2004-Readme.md](images/linux/Ubuntu2004-README.md) and it uses [MarkdownPS](https://github.com/Sarafian/MarkdownPS).
### macOS ### macOS
The macOS source lives in this repository and is available for everyone. However, the macOS image-generation CI doesn't support external contributions yet, so we are not able to accept pull requests for now. macOS source lives in this repository and available for everyone. However, macOS image-generation CI doesn't support external contributions yet so we are not able to accept pull-requests for now.
We are in the process of preparing the macOS CI to accept contributions. Until then, we appreciate your patience and ask that you continue to make tool requests by filing issues. We are in the process of preparing macOS CI to accept contributions. Until then, we appreciate your patience and ask you continue to make tool requests by filing issues.
## Resources ## Resources
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2024 GitHub Copyright (c) 2023 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
+202 -214
View File
@@ -1,214 +1,202 @@
# GitHub Actions Runner Images # GitHub Actions Runner Images
**Table of Contents** **Table of Contents**
- [About](#about) - [About](#about)
- [Available Images](#available-images) - [Available Images](#available-images)
- [Announcements](#announcements) - [Announcements](#announcements)
- [Image Definitions](#image-definitions) - [Image Definitions](#image-definitions)
- [Image Releases](#image-releases) - [Image Releases](#image-releases)
- [Software and Image Support](#software-and-image-support) - [Software and Image Support](#software-and-image-support)
- [How to Interact with the Repo](#how-to-interact-with-the-repo) - [How to Interact with the Repo](#how-to-interact-with-the-repo)
- [FAQs](#faqs) - [FAQs](#faqs)
## About ## About
This repository contains the source code used to create the VM images for [GitHub-hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners) used for Actions, as well as for [Microsoft-hosted agents](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops#use-a-microsoft-hosted-agent) used for Azure Pipelines. This repository contains the source code used to create the VM images for [GitHub-hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners) used for Actions, as well as for [Microsoft-hosted agents](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops#use-a-microsoft-hosted-agent) used for Azure Pipelines.
To build a VM machine from this repo's source, see the [instructions](docs/create-image-and-azure-resources.md). To build a VM machine from this repo's source, see the [instructions](docs/create-image-and-azure-resources.md).
## Available Images ## Available Images
| Image | YAML Label | Included Software | Rollout Status of Latest Image Release | | Image | YAML Label | Included Software | Rollout Progress of Latest Image Release |
| --------------------|---------------------|--------------------|--------------------| | --------------------|---------------------|--------------------|---------------------|
| Ubuntu 24.04 <sup>beta</sup> | `ubuntu-24.04` | [ubuntu-24.04] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fmikhailkoliada%2F35b243dd6e217d041fe3dfa5b4e2e2ed%2Fraw%2Fubuntu24.json) | | Ubuntu 22.04 | `ubuntu-latest` or `ubuntu-22.04` | [ubuntu-22.04] | [![status22](https://gh-runnerimagesdeploymentstatus.azurewebsites.net/api/status?imageName=ubuntu22&badge=1)](https://gh-runnerimagesdeploymentstatus.azurewebsites.net/api/status?imageName=ubuntu22&redirect=1)
| Ubuntu 22.04 | `ubuntu-latest` or `ubuntu-22.04` | [ubuntu-22.04] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fmikhailkoliada%2F35b243dd6e217d041fe3dfa5b4e2e2ed%2Fraw%2Fubuntu22.json) | | Ubuntu 20.04 | `ubuntu-20.04` | [ubuntu-20.04] | [![status20](https://gh-runnerimagesdeploymentstatus.azurewebsites.net/api/status?imageName=ubuntu20&badge=1)](https://gh-runnerimagesdeploymentstatus.azurewebsites.net/api/status?imageName=ubuntu20&redirect=1)
| Ubuntu 20.04 | `ubuntu-20.04` | [ubuntu-20.04] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fmikhailkoliada%2F35b243dd6e217d041fe3dfa5b4e2e2ed%2Fraw%2Fubuntu20.json) | | macOS 13 [beta] | `macos-13` or `macos-13-xl`| [macOS-13] | [![statusumac13](https://gh-runnerimagesdeploymentstatus.azurewebsites.net/api/status?imageName=macos-13&badge=1)](https://gh-runnerimagesdeploymentstatus.azurewebsites.net/api/status?imageName=macos-13&redirect=1)
| macOS 14 | `macos-latest-large` or `macos-14-large`| [macOS-14] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fmikhailkoliada%2F35b243dd6e217d041fe3dfa5b4e2e2ed%2Fraw%2Fmacos-14.json) | | macOS 12 | `macos-latest`, `macos-latest-xl`, `macos-12`, or `macos-12-xl`| [macOS-12] | [![statusumac12](https://gh-runnerimagesdeploymentstatus.azurewebsites.net/api/status?imageName=macos-12&badge=1)](https://gh-runnerimagesdeploymentstatus.azurewebsites.net/api/status?imageName=macos-12&redirect=1)
| macOS 14 Arm64 |`macos-latest`, `macos-14`, `macos-latest-xlarge` or `macos-14-xlarge`| [macOS-14-arm64] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fmikhailkoliada%2F35b243dd6e217d041fe3dfa5b4e2e2ed%2Fraw%2Fmacos-14-arm64.json) | | macOS 11 | `macos-11`| [macOS-11] | [![statusmac11](https://gh-runnerimagesdeploymentstatus.azurewebsites.net/api/status?imageName=macos-11&badge=1)](https://gh-runnerimagesdeploymentstatus.azurewebsites.net/api/status?imageName=macos-11&redirect=1)
| macOS 13 | `macos-13` or `macos-13-large` | [macOS-13] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fmikhailkoliada%2F35b243dd6e217d041fe3dfa5b4e2e2ed%2Fraw%2Fmacos-13.json) | | Windows Server 2022 | `windows-latest` or `windows-2022` | [windows-2022] | [![statuswin22](https://gh-runnerimagesdeploymentstatus.azurewebsites.net/api/status?imageName=windows-2022&badge=1)](https://gh-runnerimagesdeploymentstatus.azurewebsites.net/api/status?imageName=windows-2022&redirect=1) |
| macOS 13 Arm64 | `macos-13-xlarge` | [macOS-13-arm64] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fmikhailkoliada%2F35b243dd6e217d041fe3dfa5b4e2e2ed%2Fraw%2Fmacos-13-arm64.json) | | Windows Server 2019 | `windows-2019` | [windows-2019] | [![statuswin19](https://gh-runnerimagesdeploymentstatus.azurewebsites.net/api/status?imageName=windows-2019&badge=1)](https://gh-runnerimagesdeploymentstatus.azurewebsites.net/api/status?imageName=windows-2019&redirect=1)
| macOS 12 | `macos-12` or `macos-12-large`| [macOS-12] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fmikhailkoliada%2F35b243dd6e217d041fe3dfa5b4e2e2ed%2Fraw%2Fmacos-12.json) |
| macOS 11 <sup>deprecated</sup> | `macos-11`| [macOS-11] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fmikhailkoliada%2F35b243dd6e217d041fe3dfa5b4e2e2ed%2Fraw%2FmacOS-11.json) | ### Label scheme
| Windows Server 2022 | `windows-latest` or `windows-2022` | [windows-2022] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fmikhailkoliada%2F35b243dd6e217d041fe3dfa5b4e2e2ed%2Fraw%2Fwin22.json) |
| Windows Server 2019 | `windows-2019` | [windows-2019] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fmikhailkoliada%2F35b243dd6e217d041fe3dfa5b4e2e2ed%2Fraw%2Fwin19.json) | - In general the `-latest` label is used for the latest OS image version that is GA
- Before moving the`-latest` label to a new OS version we will announce the change and give sufficient lead time for users to update their workflows
### Label scheme
[ubuntu-22.04]: https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2204-Readme.md
- In general the `-latest` label is used for the latest OS image version that is GA [ubuntu-20.04]: https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2004-Readme.md
- Before moving the`-latest` label to a new OS version we will announce the change and give sufficient lead time for users to update their workflows [windows-2022]: https://github.com/actions/runner-images/blob/main/images/win/Windows2022-Readme.md
[windows-2019]: https://github.com/actions/runner-images/blob/main/images/win/Windows2019-Readme.md
[ubuntu-24.04]: https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md [macOS-11]: https://github.com/actions/runner-images/blob/main/images/macos/macos-11-Readme.md
[ubuntu-22.04]: https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md [macOS-12]: https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md
[ubuntu-20.04]: https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2004-Readme.md [macOS-13]: https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md
[windows-2022]: https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md [macOS-10.15]: https://github.com/actions/runner-images/blob/main/images/macos/macos-10.15-Readme.md
[windows-2019]: https://github.com/actions/runner-images/blob/main/images/windows/Windows2019-Readme.md [self-hosted runners]: https://help.github.com/en/actions/hosting-your-own-runners
[macOS-11]: https://github.com/actions/runner-images/blob/main/images/macos/macos-11-Readme.md
[macOS-12]: https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md ## Announcements
[macOS-13]: https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md
[macOS-13-arm64]: https://github.com/actions/runner-images/blob/main/images/macos/macos-13-arm64-Readme.md See notable upcoming changes by viewing issues with the [Announcement](https://github.com/actions/runner-images/labels/Announcement) label.
[macOS-14]: https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md
[macOS-14-arm64]: https://github.com/actions/runner-images/blob/main/images/macos/macos-14-arm64-Readme.md ## Image Definitions
[self-hosted runners]: https://help.github.com/en/actions/hosting-your-own-runners
### Beta
## Announcements
The purpose of a Beta is to collect feedback on an image before it is released to GA. The goal of a Beta is to identify and fix any potential issues that exist on that
See notable upcoming changes by viewing issues with the [Announcement](https://github.com/actions/runner-images/labels/Announcement) label. image. Images are updated on a weekly cadence. Any workflows that run on a beta image do not fall under the customer [SLA](https://github.com/customer-terms/github-online-services-sla) in place for Actions.
Customers choosing to use Beta images are encouraged to provide feedback in the runner-images repo by creating an issue. A Beta may take on different availability, i.e. public vs private.
## Image Definitions
### GA
### Beta
A GA (General Availability) image has been through a Beta period and is deemed ready for general use. Images are updated on a weekly cadence. In order to be moved to
The purpose of a Beta is to collect feedback on an image before it is released to GA. The goal of a Beta is to identify and fix any potential issues that exist on that GA the image must meet the following criteria:
image. Images are updated on a weekly cadence. Any workflows that run on a beta image do not fall under the customer [SLA](https://github.com/customer-terms/github-online-services-sla) in place for Actions.
Customers choosing to use Beta images are encouraged to provide feedback in the runner-images repo by creating an issue. A Beta may take on different availability, i.e. public vs private. 1. Has been through a Beta period (public or private)
2. Most major software we install on the image has a compatible
### GA version for the underlying OS and
3. All major bugs reported during the Beta period have been addressed.
A GA (General Availability) image has been through a Beta period and is deemed ready for general use. Images are updated on a weekly cadence. In order to be moved to
GA the image must meet the following criteria: This image type falls under the customer [SLA](https://github.com/customer-terms/github-online-services-sla) for actions. GA images are eventually deprecated according to our guidelines as we only support the
latest 2 versions of an OS.
1. Has been through a Beta period (public or private)
2. Most major software we install on the image has a compatible #### Latest Migration Process
version for the underlying OS and
3. All major bugs reported during the Beta period have been addressed. GitHub Actions and Azure DevOps use the `-latest` YAML label (ex: `ubuntu-latest`, `windows-latest`, and `macos-latest`). These labels point towards the newest stable OS version available.
This image type falls under the customer [SLA](https://github.com/customer-terms/github-online-services-sla) for actions. GA images are eventually deprecated according to our guidelines as we only support the
latest 2 versions of an OS. The `-latest` migration process is gradual and happens over 1-2 months in order to allow customers to adapt their workflows to the newest OS version. During this process, any workflow using the `-latest` label, may see changes in the OS version in their workflows or pipelines. To avoid unwanted migration, users can specify a specific OS version in the yaml file (ex: macos-12, windows-2022, ubuntu-22.04).
#### Latest Migration Process
## Image Releases
GitHub Actions and Azure DevOps use the `-latest` YAML label (ex: `ubuntu-latest`, `windows-latest`, and `macos-latest`). These labels point towards the newest stable OS version available.
*How to best follow along with changes*
The `-latest` migration process is gradual and happens over 1-2 months in order to allow customers to adapt their workflows to the newest OS version. During this process, any workflow using the `-latest` label, may see changes in the OS version in their workflows or pipelines. To avoid unwanted migration, users can specify a specific OS version in the yaml file (ex: macos-12, windows-2022, ubuntu-22.04). 1. Find the latest releases for this repository [here.](https://github.com/actions/runner-images/releases)
2. Subscribe to the releases coming out of this repository, instructions [here.](https://docs.github.com/en/account-and-profile/managing-subscriptions-and-notifications-on-github/setting-up-notifications/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository)
## Image Releases 3. Upcoming changes: A pre-release is created when the deployment of an image has started. As soon as the deployment is finished, the pre-release is converted to a release. If you have subscribed to releases, you will get notified of pre-releases as well.
*How to best follow along with changes* - You can also track upcoming changes using the [awaiting-deployment](https://github.com/actions/runner-images/labels/awaiting-deployment) label.
4. For high impact changes, we will post these in advance to the GitHub Changelog on our [blog](https://github.blog/changelog/) and on [twitter](https://twitter.com/GHchangelog).
1. Find the latest releases for this repository [here.](https://github.com/actions/runner-images/releases) - Ex: breaking changes, GA or deprecation of images
2. Subscribe to the releases coming out of this repository, instructions [here.](https://docs.github.com/en/account-and-profile/managing-subscriptions-and-notifications-on-github/setting-up-notifications/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository)
3. Upcoming changes: A pre-release is created when the deployment of an image has started. As soon as the deployment is finished, the pre-release is converted to a release. If you have subscribed to releases, you will get notified of pre-releases as well. *Cadence*
- You can also track upcoming changes using the [awaiting-deployment](https://github.com/actions/runner-images/labels/awaiting-deployment) label. - We typically deploy weekly updates to the software on the runner images.
4. For high impact changes, we will post these in advance to the GitHub Changelog on our [blog](https://github.blog/changelog/) and on [twitter](https://twitter.com/GHchangelog).
- Ex: breaking changes, GA or deprecation of images ## Software and Image Support
*Cadence* ### Support Policy
- We typically deploy weekly updates to the software on the runner images. - Tools and versions will typically be removed 6 months after they are deprecated or have reached end-of-life
- We support (at maximum) 2 GA images and 1 beta image at a time. We begin the deprecation process of the oldest image label once the newest OS image label has been released to GA.
## Software and Image Support - The images generally contain the latest versions of packages installed except for Ubuntu LTS where we mostly rely on the Canonical-provided repositories.
### Support Policy - Popular tools can have several versions installed side-by-side with the following strategy:
- Tools and versions will typically be removed 6 months after they are deprecated or have reached end-of-life | Tool name | Installation strategy |
- We support (at maximum) 2 GA images and 1 beta image at a time. We begin the deprecation process of the oldest image label once the newest OS image label has been released to GA. |-----------|-----------------------|
- The images generally contain the latest versions of packages installed except for Ubuntu LTS where we mostly rely on the Canonical-provided repositories. | Docker images | not more than 3 latest LTS OS\tool versions. New images or new versions of current images are added using the standard tool request process |
| Java | all LTS versions |
- Popular tools can have several versions installed side-by-side with the following strategy: | Node.js | 3 latest LTS versions |
| Go | 3 latest minor versions |
| Tool name | Installation strategy | | Python <br/> Ruby | 5 most popular `major.minor` versions |
|-----------|-----------------------| | PyPy | 3 most popular `major.minor` versions |
| Docker images | not more than 3 latest LTS OS\tool versions. New images or new versions of current images are added using the standard tool request process | | .NET Core | 2 latest LTS versions and 1 latest version. For each feature version only latest patch is installed |
| Java | all LTS versions | | GCC <br/> GNU Fortran <br/> Clang <br/> GNU C++ | 3 latest major versions |
| Node.js | 3 latest LTS versions | | Android NDK | 1 latest non-LTS, 2 latest LTS versions |
| Go | 3 latest minor versions | | Xcode | - all OS compatible versions side-by-side <br/> - for beta, GM versions - latest beta only <br/> - old patch versions are deprecated in 3 months |
| Python <br/> Ruby | 5 most popular `major.minor` versions |
| PyPy | 3 most popular `major.minor` versions | ### Package managers usage
| .NET Core | 2 latest LTS versions and 1 latest version. For each feature version only latest patch is installed |
| GCC <br/> GNU Fortran <br/> Clang <br/> GNU C++ | 3 latest major versions | We use third-party package managers to install software during the image generation process. The table below lists the package managers and the software installed.
| Android NDK | 1 latest non-LTS, 2 latest LTS versions | > **Note**: third-party repositories are re-evaluated every year to identify if they are still useful and secure.
| Xcode | - all OS compatible versions side-by-side <br/> - for beta, GM versions - latest beta only <br/> - old patch versions are deprecated in 3 months |
| Operating system | Package manager | Third-party repos and packages |
### Package managers usage | :--- | :---: | ---: |
| Ubuntu | [APT](https://wiki.debian.org/Apt) | [Eclipse-Temurin (Adoptium)](https://packages.adoptium.net/artifactory/deb) </br> [Erlang](https://packages.erlang-solutions.com/ubuntu) </br>[Firefox](https://launchpad.net/~mozillateam/+archive/ubuntu/ppa) </br> [gcc, gfortran](https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test) </br> [git](https://launchpad.net/~git-core/+archive/ubuntu/ppa) </br> [HHvm](https://dl.hhvm.com/ubuntu) </br> [PHP](https://launchpad.net/~ondrej/+archive/ubuntu/php) (Ubuntu 20 only) </br> [Mono](https://download.mono-project.com/repo/ubuntu) </br> [PostgreSQL](https://apt.postgresql.org/pub/repos/apt) </br> [R](https://cloud.r-project.org/bin/linux/ubuntu) |
We use third-party package managers to install software during the image generation process. The table below lists the package managers and the software installed. | | [pipx](https://pypa.github.io/pipx) | ansible-core </br>yamllint |
> **Note**: third-party repositories are re-evaluated every year to identify if they are still useful and secure. | Windows | [Chocolatey](https://chocolatey.org) | No third-party repos installed |
| macOS | [Homebrew](https://brew.sh) | [aws-cli v2](https://github.com/aws/homebrew-tap) </br> [azure/bicep](https://github.com/Azure/homebrew-bicep) </br> [mongodb/brew](https://github.com/mongodb/homebrew-brew) |
| Operating system | Package manager | Third-party repos and packages | | | [pipx](https://pypa.github.io/pipx/) | yamllint |
| :--- | :---: | ---: |
| Ubuntu | [APT](https://wiki.debian.org/Apt) | [containers](https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable) (Ubuntu 20 only) <br/> [docker](https://download.docker.com/linux/ubuntu) (Ubuntu20 0nly) <br/> [Eclipse-Temurin (Adoptium)](https://packages.adoptium.net/artifactory/deb/) <br/> [Erlang](https://packages.erlang-solutions.com/ubuntu) <br/> [Firefox](http://ppa.launchpad.net/mozillateam/ppa/ubuntu) <br/> [git-lfs](https://packagecloud.io/install/repositories/github/git-lfs) <br/> [git](https://launchpad.net/~git-core/+archive/ubuntu/ppa) <br/> [Google Cloud CLI](https://packages.cloud.google.com/apt) <br/> [Heroku](https://cli-assets.heroku.com/channels/stable/apt) <br/> [HHvm](https://dl.hhvm.com/ubuntu) <br/> [MongoDB](https://repo.mongodb.org/apt/ubuntu) <br/> [Mono](https://download.mono-project.com/repo/ubuntu) <br/> [MS Edge](https://packages.microsoft.com/repos/edge) <br/> [PostgreSQL](https://apt.postgresql.org/pub/repos/apt/) <br/> [R](https://cloud.r-project.org/bin/linux/ubuntu) | ### Image Deprecation Policy
| | [pipx](https://pypa.github.io/pipx) | ansible-core <br/>yamllint |
| Windows | [Chocolatey](https://chocolatey.org) | No third-party repos installed | - Images begin the deprecation process of the oldest image label once a new GA OS version has been released.
| macOS | [Homebrew](https://brew.sh) | [aws-cli v2](https://github.com/aws/homebrew-tap) </br> [azure/bicep](https://github.com/Azure/homebrew-bicep) </br> [mongodb/brew](https://github.com/mongodb/homebrew-brew) | - Deprecation process begins with an announcement that sets a date for deprecation
| | [pipx](https://pypa.github.io/pipx/) | yamllint | - As it gets closer to the date, GitHub begins doing scheduled brownouts of the image
- During this time there will be an Announcement pinned in the repo to remind users of the deprecation.
### Image Deprecation Policy - Finally GitHub will deprecate the image and it will no longer be available
- Images begin the deprecation process of the oldest image label once a new GA OS version has been released. ### Preinstallation Policy
- Deprecation process begins with an announcement that sets a date for deprecation
- As it gets closer to the date, GitHub begins doing scheduled brownouts of the image In general, these are the guidelines we follow when deciding what to pre-install on our images:
- During this time there will be an Announcement pinned in the repo to remind users of the deprecation.
- Finally GitHub will deprecate the image and it will no longer be available - Popularity: widely-used tools and ecosystems will be given priority.
- Latest Technology: recent versions of tools will be given priority.
### Preinstallation Policy - Deprecation: end-of-life tools and versions will not be added.
- Licensing: MIT, Apache, or GNU licenses are allowed.
In general, these are the guidelines we follow when deciding what to pre-install on our images: - Time & Space on the Image: we will evaluate how much time is saved and how much space is used by having the tool pre-installed.
- Support: If a tool requires the support of more than one version, we will consider the cost of this maintenance.
- Popularity: widely-used tools and ecosystems will be given priority.
- Latest Technology: recent versions of tools will be given priority. ### Default Version Update Policy
- Deprecation: end-of-life tools and versions will not be added.
- Licensing: MIT, Apache, or GNU licenses are allowed. - In general, once a new version is installed on the image, we announce the default version update 2 weeks prior to deploying it.
- Time & Space on the Image: we will evaluate how much time is saved and how much space is used by having the tool pre-installed. - For potentially dangerous updates, we may extend the timeline up to 1 month between the announcement and deployment.
- Support: If a tool requires the support of more than one version, we will consider the cost of this maintenance.
## How to Interact with the Repo
### Default Version Update Policy
- **Issues**: To file a bug report, or request tools to be added/updated, please [open an issue using the appropriate template](https://github.com/actions/runner-images/issues/new/choose)
- In general, once a new version is installed on the image, we announce the default version update 2 weeks prior to deploying it. - **Discussions**: If you want to share your thoughts about image configuration, installed software, or bring a new idea, please create a new topic in a [discussion](https://github.com/actions/runner-images/discussions) for a corresponding category. Before making a new discussion please make sure no similar topics were created earlier.
- For potentially dangerous updates, we may extend the timeline up to 1 month between the announcement and deployment. - For general questions about using the runner images or writing your Actions workflow, please open requests in the [GitHub Actions Community Forum](https://github.community/c/github-actions/41).
## How to Interact with the Repo ## FAQs
- **Issues**: To file a bug report, or request tools to be added/updated, please [open an issue using the appropriate template](https://github.com/actions/runner-images/issues/new/choose) <details>
- **Discussions**: If you want to share your thoughts about image configuration, installed software, or bring a new idea, please create a new topic in a [discussion](https://github.com/actions/runner-images/discussions) for a corresponding category. Before making a new discussion please make sure no similar topics were created earlier. <summary><b><i>What images are available for GitHub Actions and Azure DevOps?</b></i></summary>
- For general questions about using the runner images or writing your Actions workflow, please open requests in the [GitHub Actions Community Forum](https://github.community/c/github-actions/41).
The availability of images for GitHub Actions and Azure DevOps is the same. However, deprecation policies may differ. See documentation for more details:
## FAQs - [GitHub Actions](https://docs.github.com/en/free-pro-team@latest/actions/reference/specifications-for-github-hosted-runners#supported-runners-and-hardware-resources)
- [Azure DevOps](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops&tabs=yaml#software)
<details> </details>
<summary><b><i>What images are available for GitHub Actions and Azure DevOps?</b></i></summary>
<details>
The availability of images for GitHub Actions and Azure DevOps is the same. However, deprecation policies may differ. See documentation for more details: <summary><b><i>What image version is used in my build?</b></i></summary>
- [GitHub Actions](https://docs.github.com/en/free-pro-team@latest/actions/reference/specifications-for-github-hosted-runners#supported-runners-and-hardware-resources)
- [Azure DevOps](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops&tabs=yaml#software) Usually, image deployment takes 2-3 days, and documentation in the `main` branch is only updated when deployment is finished. To find out which image version and what software versions are used in a specific build, see `Set up job` (GitHub Actions) or `Initialize job` (Azure DevOps) step log.
</details> <img width="1440" alt="actions-runner-image" src="https://github.com/actions/runner-images/assets/88318005/922a8bf5-3e4d-4265-9527-b3b51e6bf9c8">
</details>
<details>
<summary><b><i>What image version is used in my build?</b></i></summary> <details>
<summary><b><i>Looking for other Linux distributions?</b></i></summary>
Usually, image deployment takes 2-3 days, and documentation in the `main` branch is only updated when deployment is finished. To find out which image version and what software versions are used in a specific build, see `Set up job` (GitHub Actions) or `Initialize job` (Azure DevOps) step log.
<img width="1440" alt="actions-runner-image" src="https://github.com/actions/runner-images/assets/88318005/922a8bf5-3e4d-4265-9527-b3b51e6bf9c8"> We do not plan to offer other Linux distributions. We recommend using Docker if you'd like to build using other distributions with the hosted runner images. Alternatively, you can leverage [self-hosted runners] and fully customize your VM image to your needs.
</details> </details>
<details> <details>
<summary><b><i>Looking for other Linux distributions?</b></i></summary> <summary><b><i>How do I contribute to the macOS source?</b></i></summary>
We do not plan to offer other Linux distributions. We recommend using Docker if you'd like to build using other distributions with the hosted runner images. Alternatively, you can leverage [self-hosted runners] and fully customize your VM image to your needs. macOS source lives in this repository and is available for everyone. However, macOS image-generation CI doesn't support external contributions yet so we are not able to accept pull-requests for now.
</details>
We are in the process of preparing macOS CI to accept contributions. Until then, we appreciate your patience and ask you to continue to make tool requests by filing issues.
<details> </details>
<summary><b><i>How do I contribute to the macOS source?</b></i></summary>
<details>
macOS source lives in this repository and is available for everyone. However, macOS image-generation CI doesn't support external contributions yet so we are not able to accept pull-requests for now. <summary><b><i>How does GitHub determine what tools are installed on the images?</b></i></summary>
We are in the process of preparing macOS CI to accept contributions. Until then, we appreciate your patience and ask you to continue to make tool requests by filing issues. For some tools, we always install the latest at the time of the deployment; for others, we pin the tool to specific version(s). For more details please see the [Preinstallation Policy](#preinstallation-policy)
</details> </details>
<details> <details>
<summary><b><i>How does GitHub determine what tools are installed on the images?</b></i></summary> <summary><b><i>How do I request that a new tool be pre-installed on the image?</b></i></summary>
Please create an issue and get an approval from us to add this tool to the image before creating the pull request.
For some tools, we always install the latest at the time of the deployment; for others, we pin the tool to specific version(s). For more details please see the [Preinstallation Policy](#preinstallation-policy) </details>
</details>
<details>
<summary><b><i>How do I request that a new tool be pre-installed on the image?</b></i></summary>
Please create an issue and get an approval from us to add this tool to the image before creating the pull request.
</details>
<details>
<summary><b><i>What branch should I use to build custom image?</b></i></summary>
We strongly encourage customers to build their own images using the main branch.
This repository contains multiple branches and releases that serve as document milestones to reflect what software is installed in the images at certain point of time. Current builds are not idempotent and if one tries to build a runner image using the specific tag it is not guaranteed that the build will succeed.
</details>
+117 -118
View File
@@ -2,24 +2,24 @@
The runner-images project uses [Packer](https://www.packer.io/) to generate disk images for Windows 2019/2022 and Ubuntu 20.04/22.04. The runner-images project uses [Packer](https://www.packer.io/) to generate disk images for Windows 2019/2022 and Ubuntu 20.04/22.04.
Each image is configured by a HCL2 Packer template that specifies where to build the image (Azure, in this case), Each image is configured by a JSON or HCL2 Packer template that specifies where to build the image (Azure in this case)
and what steps to run to install software and prepare the disk. and what steps to run to install software and prepare the disk.
The Packer process initializes a connection to the Azure subscription using Azure CLI and creates temporary resources The Packer process initializes a connection to Azure subscription using Azure CLI and creates temporary resources
required for the build process: a resource group, network interfaces and a virtual machine from the "clean" image specified in the template. required for the build process: resource group, network interfaces and virtual machine from the "clean" image specified in the template.
If the VM deployment succeeds, Packer connects to it using SSH or WinRM and begins executing installation steps from the template one-by-one. If the VM deployment succeeds, Packer connects it using ssh or WinRM and begins executing installation steps from the template one-by-one.
If any step fails, image generation is aborted, and the temporary VM is terminated. If any step fails, image generation is aborted and the temporary VM is terminated.
Packer also attempts to clean up all the temporary resources it created (unless otherwise configured). Packer also attempts to cleanup all the temporary resources it created (unless otherwise configured).
After successful completion of all installation steps, Packer creates a managed image from the temporary VM's disk and deletes the VM. After successful completion of all installation steps Packer creates managed image from the temporary VM's disk and deletes the VM.
- [Build Agent Preparation](#build-agent-preparation) - [Build agent preparation](#build-agent-preparation)
- [Manual image generation](#manual-image-generation) - [Manual image generation](#manual-image-generation)
- [Manual Image Generation Customization](#manual-image-generation-customization) - [Manual image generation customization](#manual-image-generation-customization)
- [Network Security](#network-security) - [Network security](#network-security)
- [Azure Subscription Authentication](#azure-subscription-authentication) - [Azure subscription authentication](#azure-subscription-authentication)
- [Generated Machine Deployment](#generated-machine-deployment) - [Generated machine deployment](#generated-machine-deployment)
- [Automated image generation](#automated-image-generation) - [Automated image generation](#automated-image-generation)
- [Required variables](#required-variables) - [Required variables](#required-variables)
- [Optional variables](#optional-variables) - [Optional variables](#optional-variables)
@@ -27,15 +27,15 @@ After successful completion of all installation steps, Packer creates a managed
- [Toolset](#toolset) - [Toolset](#toolset)
- [Post-generation scripts](#post-generation-scripts) - [Post-generation scripts](#post-generation-scripts)
- [Running scripts](#running-scripts) - [Running scripts](#running-scripts)
- [Script Details: Ubuntu](#script-details-ubuntu) - [Script details: Ubuntu](#script-details-ubuntu)
- [Script Details: Windows](#script-details-windows) - [Script details: Windows](#script-details-windows)
## Build Agent Preparation ## Build agent preparation
The build agent is a machine where the Packer process will be started. Build agent is a machine where Packer process will be started.
You can use any physical or virtual machine running Windows or Linux OS. You can use any physical or virtual machine running OS Windows or Linux.
Of course, you may also use an [Azure VM](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/quick-create-cli). Of course you may also use [Azure VM](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/quick-create-cli).
In any case, you will need these software installed: In any case you will need these software installed:
- Packer 1.8.2 or higher. - Packer 1.8.2 or higher.
@@ -60,12 +60,11 @@ In any case, you will need these software installed:
In Windows you already have it. In Windows you already have it.
For Linux follow instructions [here](https://learn.microsoft.com/en-us/windows-server/administration/linux-package-repository-for-microsoft-software) For Linux follow instructions [here](https://learn.microsoft.com/en-us/windows-server/administration/linux-package-repository-for-microsoft-software)
to add Microsoft's Linux Software Repository and then install the `powershell` package. to add Microsoft's Linux Software Repository and then install package `powershell`.
- Azure CLI. - Azure CLI.
Follow the instructions [here](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli). Follow instructions [here](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli).
Or if you use Windows, you may run this command in Powershell instead: Or if you use Windows you may run this command in Powershell instead:
```powershell ```powershell
Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi
@@ -74,72 +73,72 @@ In any case, you will need these software installed:
## Manual image generation ## Manual image generation
This repository includes a script that assists in generating images in Azure. This repo bundles script that helps generating images in Azure.
All you need is an Azure subscription and a build agent configured as described above. All you need are Azure subscription and build agent configured as described above.
We suggest starting with building the UbuntuMinimal image because it includes only basic software and builds in less than 30 minutes. We suggest starting with building UbuntuMinimal image because it includes only basic software and build in less than 30 minutes.
All the commands below should be executed in PowerShell. All the commands below should be executed in Powershell.
First, clone the runner-images repository and set the current directory to it: First clone runner-images repository and set current directory to it:
```powershell ```powershell
git clone https://github.com/actions/runner-images.git git clone https://github.com/actions/runner-images.git
Set-Location runner-images Set-Location runner-images
``` ```
Then, import the [GenerateResourcesAndImage](../helpers/GenerateResourcesAndImage.ps1) script from the `helpers` subdirectory: Then import [GenerateResourcesAndImage](../helpers/GenerateResourcesAndImage.ps1) script from `helpers` subdirectory:
```powershell ```powershell
Import-Module .\helpers\GenerateResourcesAndImage.ps1 Import-Module .\helpers\GenerateResourcesAndImage.ps1
``` ```
Finally, run the `GenerateResourcesAndImage` function, setting the mandatory arguments: image type and where to build and store the resulting managed image: Finally, run `GenerateResourcesAndImage` function setting mandatory arguments: image type and where to create resources:
- `SubscriptionId` - your Azure Subscription ID; - `SubscriptionId` - your Azure Subscription ID
- `ResourceGroupName` - the name of the resource group that will be created within your subscription (e.g., "imagegen-test"); - `ResourceGroupName` - name of the resource group that will be created within your subscription (e.g. "imagegen-test")
- `AzureLocation` - the location where resources will be created (e.g., "East US"); - `AzureLocation` - location where resources will be created (e.g. "East US")
- `ImageType` - the type of image to build (we suggest choosing "UbuntuMinimal" here; other valid options are "Windows2019", "Windows2022", "Ubuntu2004", "Ubuntu2204"). - `ImageType` - what image to build (we suggest choosing "UbuntuMinimal" here, other valid options are "Windows2019", "Windows2022", "Ubuntu2004", "Ubuntu2204")
This function automatically creates all required Azure resources and initiates the Packer image generation for the selected image type. This function automatically creates all required Azure resources and kicks off packer image generation for the selected image type.
When the image is ready, you may proceed to [deployment](#generated-machine-deployment). When image is ready you may proceed to [deployment](#generated-machine-deployment)
## Manual Image Generation Customization ## Manual image generation customization
The `GenerateResourcesAndImage` function accepts a number of arguments that may assist you in generating an image in your specific environment. Function `GenerateResourcesAndImage` accepts a bunch of arguments that may help you generating image in your specific environment.
For example, you may want all the resources involved in the image generation process to be tagged. For example, you may want that all the resources involved in image generation process are tagged.
In this case, pass a HashTable of tags as a value for the `Tags` parameter. In this case pass a HashTable of tags as a value for `Tags` parameter.
If you don't want the function to authenticate interactively, you should create a Service Principal and invoke the function with the parameters `AzureClientId`, `AzureClientSecret` and `AzureTenantId`. If you don't want function to authenticate interactively, you should create Service Principal and invoke the function with parameters `AzureClientId`, `AzureClientSecret` and `AzureTenantId`.
You can find more details in the [corresponding section below](#azure-subscription-authentication). You can find more details [in corresponding section below](#azure-subscription-authentication).
Use `get-help GenerateResourcesAndImage -Detailed` for the complete list of available parameters. Use `get-help GenerateResourcesAndImage -Detailed` for the complete list of parameters available.
### Network Security ### Network security
To connect to a temporary virtual machine, Packer uses WinRM or SSH. To connect to a temporary virtual machine Packer uses WinRM or SSH.
If your build agent is located outside of the Azure subscription where the temporary VM is created, a public network interface and public IP address are used. If your build agent is located outside of the Azure subscription where temporary VM is created, the public network interface and public IP address is used.
Make sure that firewalls are configured properly and that WinRM (TCP port 5986) and SSH (TCP port 22) connections are allowed both outgoing for the build agent and incoming for the temporary VM. Make sure that firewalls are configured properly and WinRM (tcp port 5986) and ssh (tcp port 22) connections are allowed both outgoing for build agent and incoming for temporary VM.
Also, if you don't want the temporary VM to be accessible from everywhere, set the `RestrictToAgentIpAddress` parameter value to `$true` Also if you don't want temporary VM to be accessible from everywhere, set `RestrictToAgentIpAddress` parameter value to `$true`
to set up firewall rules allowing access only from your build agent's public IP address. to setup firewall rules allowing access only from your build agent public IP address.
If your build agent and temporary VM are in the same subscription, you can configure Packer to connect using a private virtual network. If your build agent and temporary VM are in the same subscription you can configure Packer to connect using private virtual network.
To achieve this, set proper values for the environment variables `VNET_RESOURCE_GROUP`, `VNET_NAME` and `VNET_SUBNET`. To achieve that set proper values for environment variables `VNET_RESOURCE_GROUP`, `VNET_NAME` and `VNET_SUBNET`.
### Azure Subscription Authentication ### Azure subscription authentication
Packer uses a Service Principal to authenticate in Azure infrastructure. Packer uses Service Principal to authenticate in Azure infrastructure.
For more information about Service Principals, refer to the For more information about Service Principals refer to
[Azure documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal). [Azure documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal).
The `GenerateResourcesAndImage` function is able to create a Service Principal to be used by Packer. Function `GenerateResourcesAndImage` is able to create Service Principle to be used by Packer.
It uses the Connect-AzAccount cmdlet that invokes an interactive authentication process by default. It uses Connect-AzAccount cmdlet that invokes interactive authentication process by default.
If you don't want to use interactive authentication, you should create a Service Principal with full read-write permissions for the selected Azure subscription on your own If you don't want to use interactive authentication you should create Service Principal with full read-write permissions for selected Azure subscription on your own
and provide proper values for the parameters `AzureClientId`, `AzureClientSecret` and `AzureTenantId`. and provide proper values for parameters `AzureClientId`, `AzureClientSecret` and `AzureTenantId`.
Here is an example of how to create a Service Principal using the Az PowerShell module: Here is an example of how to create Service Principle using Az Powershell module:
```powershell ```powershell
$credentials = [Microsoft.Azure.PowerShell.Cmdlets.Resources.MSGraph.Models.ApiV10.MicrosoftGraphPasswordCredential]@{ $credentials = [Microsoft.Azure.PowerShell.Cmdlets.Resources.MSGraph.Models.ApiV10.MicrosoftGraphPasswordCredential]@{
@@ -161,9 +160,9 @@ Start-Sleep -Seconds 30
} }
``` ```
## Generated Machine Deployment ## Generated machine deployment
After successful image generation, a Virtual Machine can be created from the generated image using the [CreateAzureVMFromPackerTemplate](../helpers/CreateAzureVMFromPackerTemplate.ps1) script. After the successful image generation, Virtual Machine can be created from the generated image using [CreateAzureVMFromPackerTemplate](../helpers/CreateAzureVMFromPackerTemplate.ps1) script.
```powershell ```powershell
Import-Module .\helpers\CreateAzureVMFromPackerTemplate.ps1 Import-Module .\helpers\CreateAzureVMFromPackerTemplate.ps1
@@ -173,29 +172,29 @@ CreateAzureVMFromPackerTemplate -SubscriptionId {YourSubscriptionId} -ResourceGr
Where: Where:
- `SubscriptionId` - the Azure subscription ID where resources will be created; - `SubscriptionId` - The Azure subscription Id where resources will be created.
- `ResourceGroupName` - the Azure resource group name where the Azure virtual machine will be created; - `ResourceGroupName` - The Azure resource group name where the Azure virtual machine will be created.
- `ManagedImageName` - the name of the managed image to be used for the virtual machine creation; - `ManagedImageName` - The name of the managed image to be used for the virtual machine creation.
- `VirtualMachineName` - the name of the virtual machine to be generated; - `VirtualMachineName` - The name of the virtual machine to be generated.
- `AdminUserName` - the administrator username for the virtual machine to be created; - `AdminUserName` - The administrator username for the virtual machine to be created.
- `AdminPassword` - the administrator password for the virtual machine to be created; - `AdminPassword` - The administrator password for the virtual machine to be created.
- `AzureLocation` - the location where the Azure virtual machine will be provisioned (e.g., "eastus"). - `AzureLocation` - The location where the Azure virtual machine will be provisioned. Example: "eastus"
This function creates an Azure VM and generates network resources in Azure to make the VM accessible. The function creates an Azure VM and generates network resources in Azure to make the VM accessible.
## Automated image generation ## Automated image generation
If you want to generate images automatically (e.g., as a part of a CI/CD pipeline), If you want to generate images automatically (e.g. as a part of CI/CD pipeline)
you can use Packer directly. To do this, you will need: you can use Packer directly. To do that you will need:
- a build agent configured as described in the - A build agent configured as described in
[Build agent preparation](#build-agent-preparation) section; [Build agent preparation](#build-agent-preparation) section.
- an Azure subscription and Service Principal configured as described in the - Azure subscription and Service Principal configured as described in
[Azure subscription authentication](#azure-subscription-authentication) section; [Azure subscription authentication](#azure-subscription-authentication) section.
- a resource group created in your Azure subscription where the managed image will be stored; - Resource group created in your Azure subscription where managed image will be stored.
- a string to be used as a password for the user used to install software (Windows only). - String to be used as password for the user used to install software (Windows only).
Then, you can invoke Packer in your CI/CD pipeline using the following command: Then you can invoke Packer in you CI/CD pipeline using the following command:
```powershell ```powershell
packer build -var "subscription_id=$SubscriptionId" ` packer build -var "subscription_id=$SubscriptionId" `
@@ -211,54 +210,54 @@ packer build -var "subscription_id=$SubscriptionId" `
Where: Where:
- `SubscriptionId` - your Azure Subscription ID; - `SubscriptionId` - your Azure Subscription ID
- `ClientId` and `ClientSecret` - Service Principal credentials; - `ClientId` and `ClientSecret` - Service Principal credentials
- `TenantId` - Azure Tenant ID; - `TenantId` - Azure Tenant ID
- `InstallPassword` - password for the user used to install software (Windows only); - `InstallPassword` - password for the user used to install software (Windows only)
- `Location` - location where resources will be created (e.g., "East US"); - `Location` - location where resources will be created (e.g. "East US")
- `ImageName` and `ImageResourceGroupName` - name of the resource group where the managed image will be stored; - `ImageName` and `ImageResourceGroupName` - name of the resource group where managed image will be stored
- `TemplatePath` - path to the Packer template file (e.g., "images/windows/templates/windows-2022.pkr.hcl"). - `TemplatePath` - path to the Packer template file (e.g. "images/win/windows2022.json")
### Required variables ### Required variables
The following variables are required to be passed to the Packer process: The following variables are required to be passed to Packer process:
| Template var | Env var | Description | Template var | Env var | Description
| ------------ | ------- | ----------- | ------------ | ------- | -----------
| `subscription_id` | `ARM_SUBSCRIPTION_ID` | The subscription under which the build will be performed. | `subscription_id` | `ARM_SUBSCRIPTION_ID` | Subscription under which the build will be performed.
| `client_id` | `ARM_CLIENT_ID` | The Active Directory service principal associated with your builder. | `client_id` | `ARM_CLIENT_ID` | The Active Directory service principal associated with your builder.
| `client_secret` | `ARM_CLIENT_SECRET` | The password or secret for your service principal; may be omitted if `client_cert_path` is set. | `client_secret` | `ARM_CLIENT_SECRET` | The password or secret for your service principal; may be omitted if `client_cert_path` is set.
| `client_cert_path` | `ARM_CLIENT_CERT_PATH` | The location of a PEM file containing a certificate and private key for the service principal; may be omitted if `client_secret` is set. | `client_cert_path` | `ARM_CLIENT_CERT_PATH` | The location of a PEM file containing a certificate and private key for service principal; may be omitted if `client_secret` is set.
| `location` | `ARM_RESOURCE_LOCATION` | The Azure datacenter in which your VM will be built. | `location` | `ARM_RESOURCE_LOCATION` | Azure datacenter in which your VM will build.
| `managed_image_resource_group_name` | `ARM_RESOURCE_GROUP` | The resource group under which the final artifact will be stored. | `managed_image_resource_group_name` | `ARM_RESOURCE_GROUP` | Resource group under which the final artifact will be stored.
### Optional variables ### Optional variables
The following variables are optional: The following variables are optional:
- `managed_image_name` - the name of the managed image to create. If not specified, "Runner-Image-{{ImageType}}" will be used; - `managed_image_name` - Name of the managed image to create. If not specified, "Runner-Image-{{ImageType}}" will be used.
- `build_resource_group_name` - specify an existing resource group to run the build in; by default, a temporary resource group will be created and destroyed as part of the build; if you do not have permission to do so, use `build_resource_group_name` to specify an existing resource group to run the build in; - `build_resource_group_name` - Specify an existing resource group to run the build in it. By default, a temporary resource group will be created and destroyed as part of the build. If you do not have permission to do so, use build_resource_group_name to specify an existing resource group to run the build in it.
- `object_id` - the object ID for the AAD SP; will be derived from the oAuth token if empty; - `object_id` - The object ID for the AAD SP. Will be derived from the oAuth token if empty.
- `tenant_id` - the Active Directory tenant identifier with which your `client_id` and `subscription_id` are associated; if not specified, `tenant_id` will be looked up using `subscription_id`; - `tenant_id` - The Active Directory tenant identifier with which your `client_id` and `subscription_id` are associated. If not specified, `tenant_id` will be looked up using `subscription_id`.
- `temp_resource_group_name` - the name assigned to the temporary resource group created during the build; if this value is not set, a random value will be assigned; this resource group is deleted at the end of the build; - `temp_resource_group_name` - Name assigned to the temporary resource group created during the build. If this value is not set, a random value will be assigned. This resource group is deleted at the end of the build.
- `private_virtual_network_with_public_ip` - this value allows you to set a `virtual_network_name` and obtain a public IP; if this value is not set and `virtual_network_name` is defined, Packer is only allowed to be executed from a host on the same subnet / virtual network; - `private_virtual_network_with_public_ip` - This value allows you to set a `virtual_network_name` and obtain a public IP. If this value is not set and `virtual_network_name` is defined Packer is only allowed to be executed from a host on the same subnet / virtual network.
- `virtual_network_name` - use a pre-existing virtual network for the VM; this option enables private communication with the VM, no public IP address is used or provisioned (unless you set `private_virtual_network_with_public_ip`); - `virtual_network_name` - Use a pre-existing virtual network for the VM. This option enables private communication with the VM, no public IP address is used or provisioned (unless you set `private_virtual_network_with_public_ip`).
- `virtual_network_resource_group_name` - if `virtual_network_name` is set, this value may also be set; if `virtual_network_name` is set, and this value is not set, the builder attempts to determine the resource group containing the virtual network; if the resource group cannot be found, or it cannot be disambiguated, this value should be set; - `virtual_network_resource_group_name` - If `virtual_network_name` is set, this value may also be set. If `virtual_network_name` is set, and this value is not set the builder attempts to determine the resource group containing the virtual network. If the resource group cannot be found, or it cannot be disambiguated, this value should be set.
- `virtual_network_subnet_name` - if `virtual_network_name` is set, this value may also be set; if `virtual_network_name` is set, and this value is not set, the builder attempts to determine the subnet to use with the virtual network; if the subnet cannot be found, or it cannot be disambiguated, this value should be set. - `virtual_network_subnet_name` - If `virtual_network_name` is set, this value may also be set. If `virtual_network_name` is set, and this value is not set the builder attempts to determine the subnet to use with the virtual network. If the subnet cannot be found, or it cannot be disambiguated, this value should be set.
## Builder variables ## Builder variables
The `builders` section contains variables for the `azure-arm` builder used in the project. Most of the builder variables are inherited from the `user variables` section, however, the variables can be overwritten to adjust image-generation performance. The `builders` section contains variables for the `azure-arm` builder used in the project. Most of the builder variables are inherited from the `user variables` section, however, the variables can be overwritten to adjust image-generation performance.
- `vm_size` - the size of the VM used for building; this can be changed when you deploy a VM from your image; - `vm_size` - Size of the VM used for building. This can be changed when you deploy a VM from your image.
- `image_os` - the type of OS that will be deployed as a temporary VM; - `image_os` - Type of OS that will be deployed as a temporary VM.
- `image_version` - specify the version of an OS to boot from. - `image_version` - Specify version of an OS to boot from.
**Detailed Azure builders documentation can be found in the [packer documentation](https://www.packer.io/docs/builders/azure).** **Detailed Azure builders documentation can be found in [packer documentation](https://www.packer.io/docs/builders/azure).**
## Toolset ## Toolset
The configuration for some installed software is located in `toolset.json` files. These files define the list of Ruby, Python, Go versions, the list of PowerShell modules and VS components that will be installed on the image. They can be changed if these tools are not required, to reduce image generation time or image size. Configuration for some installed software is located in `toolset.json` files. These files define the list of Ruby, Python, Go versions, the list of PowerShell modules and VS components that will be installed to image. They can be changed if these tools are not required to reduce image generation time or image size.
Generated tool versions and details can be found in related projects: Generated tool versions and details can be found in related projects:
@@ -268,12 +267,12 @@ Generated tool versions and details can be found in related projects:
## Post-generation scripts ## Post-generation scripts
> :warning: These scripts are intended to be run on a VM deployed in Azure > :warning: These scripts are intended to run on a VM deployed in Azure
The user, created during the image generation, does not exist in the resulting image. Hence, some configuration files related to the user's home directory need to be changed, as well as the file permissions for some directories. Scripts for that are located in the `post-gen` folder in the repository: The user, created during the image generation, does not exist in the result image hence some configuration files related to the user's home directory need to be changed as well as the file permissions for some directories. Scripts for that are located in the `post-generation` folder in the repository:
- Windows: <https://github.com/actions/runner-images/tree/main/images/windows/assets/post-gen> - Windows: <https://github.com/actions/runner-images/tree/main/images/win/post-generation>
- Linux: <https://github.com/actions/runner-images/tree/main/images/ubuntu/assets/post-gen> - Linux: <https://github.com/actions/runner-images/tree/main/images/linux/post-generation>
**Note:** The default user for Linux should have `sudo privileges`. **Note:** The default user for Linux should have `sudo privileges`.
@@ -296,16 +295,16 @@ The scripts are copied to the image during the generation process to the followi
Get-ChildItem C:\post-generation -Filter *.ps1 | ForEach-Object { & $_.FullName } Get-ChildItem C:\post-generation -Filter *.ps1 | ForEach-Object { & $_.FullName }
``` ```
### Script Details: Ubuntu ### Script details: Ubuntu
- **cleanup-logs.sh** - removes all build process logs from the machine; - **cleanup-logs.sh** - removes all build process logs from the machine
- **environment-variables.sh** - replaces `$HOME` with the default user's home directory for environment variables related to the default user home directory; - **environment-variables.sh** - replaces `$HOME` with the default user's home directory for environmental variables related to the default user home directory
- **homebrew-permissions.sh** - resets the Homebrew repository directory by running `git reset --hard` to make the working tree clean after changing permissions in /home and changes the repository directory owner to the current user; - **homebrew-permissions.sh** - Resets homebrew repository directory by running `git reset --hard` to make the working tree clean after chmoding /home and changes the repository directory owner to the current user
- **rust-permissions.sh** - fixes permissions for the Rust folder; a detailed issue explanation is provided in [runner-images/issues/572](https://github.com/actions/runner-images/issues/572). - **rust-permissions.sh** - fixes permissions for the Rust folder. Detailed issue explanation is provided in [runner-images/issues/572](https://github.com/actions/runner-images/issues/572).
### Script Details: Windows ### Script details: Windows
- **GenerateIISExpressCertificate.ps1** - generates and imports a certificate to run applications with IIS Express through HTTPS; - **GenerateIISExpressCertificate.ps1** - generates and imports a certificate to run applications with IIS Express through HTTPS
- **InternetExplorerConfiguration.ps1** - turns off the Internet Explorer Enhanced Security feature; - **InternetExplorerConfiguration** - turns off the Internet Explorer Enhanced Security feature
- **Msys2FirstLaunch.ps1** - initializes the bash user profile in MSYS2; - **Msys2FirstLaunch.ps1** - initializes bash user profile in MSYS2
- **VSConfiguration.ps1** - performs initial Visual Studio configuration. - **VSConfiguration.ps1** - performs initial Visual Studio configuration
+27
View File
@@ -0,0 +1,27 @@
# Debugging Failed Packer Builds
## Step 1: Run packer build `-on-error=ask`
When you run the `packer build` command, give it the `-on-error=ask` flag.
By default, `packer build` will delete the resource group as soon as the build fails.
`-on-error=ask` will pause it and wait for your input so you have time to remote in to the VM and diagnose the failure.
When the build fails, you will see this:
![Ask on error screenshot](/docs/resources/askOnError.png "Ask on error screenshot")
## Step 2: Find the resource group name in the build log
At the beginning of the build log (written to console), find the resource group name for the VM:
![Resource group from log screenshot](/docs/resources/resourceGroupName.png "Resource group from log screenshot")
Log into the Azure Portal. Find that resource group under `Resource groups`. You should see the resources for the Packer build:
![Packer resource group in Azure screenshot](/docs/resources/packerResourceGroup.png "Packer resource group in Azure screenshot")
## Step 3: Connect to the VM
Select the VM in the resource group. Click `Connect:`
This will download an RDP file. Open that and enter the credentials found in the JSON file you pass to `packer build`:
![VM credentials screenshot](/docs/resources/vmCredentials.png "VM credentials screenshot")
Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

+1 -1
View File
@@ -28,7 +28,7 @@ Function CreateAzureVMFromPackerTemplate {
The location where the Azure virtual machine will be provisioned. Example: "eastus" The location where the Azure virtual machine will be provisioned. Example: "eastus"
.EXAMPLE .EXAMPLE
CreateAzureVMFromPackerTemplate -SubscriptionId {SubscriptionId} -ResourceGroupName {ResourceGroupName} -VirtualMachineName "testvm1" -ManagedImageName {ManagedImageName} -AdminUsername "shady1" -AdminPassword "SomeSecurePassword1" -AzureLocation "eastus" CreateAzureVMFromPackerTemplate -SubscriptionId {YourSubscriptionId} -ResourceGroupName {ResourceGroupName} -TemplateFile "C:\BuildVmImages\temporaryTemplate.json" -VirtualMachineName "testvm1" -AdminUsername "shady1" -AdminPassword "SomeSecurePassword1" -AzureLocation "eastus"
#> #>
param ( param (
[Parameter(Mandatory = $True)] [Parameter(Mandatory = $True)]
+37 -43
View File
@@ -5,8 +5,7 @@ enum ImageType {
Windows2022 = 2 Windows2022 = 2
Ubuntu2004 = 3 Ubuntu2004 = 3
Ubuntu2204 = 4 Ubuntu2204 = 4
Ubuntu2404 = 5 UbuntuMinimal = 5
UbuntuMinimal = 6
} }
Function Get-PackerTemplatePath { Function Get-PackerTemplatePath {
@@ -18,24 +17,20 @@ Function Get-PackerTemplatePath {
) )
switch ($ImageType) { switch ($ImageType) {
# Note: Double Join-Path is required to support PowerShell 5.1
([ImageType]::Windows2019) { ([ImageType]::Windows2019) {
$relativeTemplatePath = Join-Path (Join-Path "windows" "templates") "windows-2019.pkr.hcl" $relativeTemplatePath = Join-Path "win" "windows2019.json"
} }
([ImageType]::Windows2022) { ([ImageType]::Windows2022) {
$relativeTemplatePath = Join-Path (Join-Path "windows" "templates") "windows-2022.pkr.hcl" $relativeTemplatePath = Join-Path "win" "windows2022.json"
} }
([ImageType]::Ubuntu2004) { ([ImageType]::Ubuntu2004) {
$relativeTemplatePath = Join-Path (Join-Path "ubuntu" "templates") "ubuntu-20.04.pkr.hcl" $relativeTemplatePath = Join-Path "linux" "ubuntu2004.json"
} }
([ImageType]::Ubuntu2204) { ([ImageType]::Ubuntu2204) {
$relativeTemplatePath = Join-Path (Join-Path "ubuntu" "templates") "ubuntu-22.04.pkr.hcl" $relativeTemplatePath = Join-Path "linux" "ubuntu2204.pkr.hcl"
}
([ImageType]::Ubuntu2404) {
$relativeTemplatePath = Join-Path (Join-Path "ubuntu" "templates") "ubuntu-24.04.pkr.hcl"
} }
([ImageType]::UbuntuMinimal) { ([ImageType]::UbuntuMinimal) {
$relativeTemplatePath = Join-Path (Join-Path "ubuntu" "templates") "ubuntu-minimal.pkr.hcl" $relativeTemplatePath = Join-Path "linux" "ubuntuminimal.pkr.hcl"
} }
default { throw "Unknown type of image" } default { throw "Unknown type of image" }
} }
@@ -101,10 +96,8 @@ Function GenerateResourcesAndImage {
This parameter cannot be used in combination with the virtual_network_name packer parameter. This parameter cannot be used in combination with the virtual_network_name packer parameter.
.PARAMETER Force .PARAMETER Force
Delete the resource group if it exists without user confirmation. Delete the resource group if it exists without user confirmation.
This parameter is deprecated and will be removed in a future release.
.PARAMETER ReuseResourceGroup .PARAMETER ReuseResourceGroup
Reuse the resource group if it exists without user confirmation. Reuse the resource group if it exists without user confirmation.
This parameter is deprecated and will be removed in a future release.
.PARAMETER OnError .PARAMETER OnError
Specify how packer handles an error during image creation. Specify how packer handles an error during image creation.
Options: Options:
@@ -152,14 +145,10 @@ Function GenerateResourcesAndImage {
[hashtable] $Tags = @{} [hashtable] $Tags = @{}
) )
if ($Force -or $ReuseResourceGroup) {
Write-Warning "The `ReuseResourceGroup` and `Force` parameters are deprecated and will be removed in a future release. The resource group will be reused when it already exists and an error will be thrown when it doesn't. If you want to delete the resource group, please delete it manually."
}
if ($Force -and $ReuseResourceGroup) { if ($Force -and $ReuseResourceGroup) {
throw "Force and ReuseResourceGroup cannot be used together." throw "Force and ReuseResourceGroup cannot be used together."
} }
Show-LatestCommit -ErrorAction SilentlyContinue Show-LatestCommit -ErrorAction SilentlyContinue
# Validate packer is installed # Validate packer is installed
@@ -180,20 +169,26 @@ Function GenerateResourcesAndImage {
} }
Write-Host "Access to packer generated VM will be restricted to agent IP Address: $AgentIp." Write-Host "Access to packer generated VM will be restricted to agent IP Address: $AgentIp."
if ($PSVersionTable.PSVersion.Major -eq 5) { if ($TemplatePath.Contains("pkr.hcl")) {
Write-Verbose "PowerShell 5 detected. Replacing double quotes with escaped double quotes in allowed inbound IP addresses." if ($PSVersionTable.PSVersion.Major -eq 5) {
$AllowedInboundIpAddresses = '[\"{0}\"]' -f $AgentIp Write-Verbose "PowerShell 5 detected. Replacing double quotes with escaped double quotes in allowed inbound IP addresses."
} $AllowedInboundIpAddresses = '[\"{0}\"]' -f $AgentIp
elseif ($PSVersionTable.PSVersion.Major -eq 7 -and $PSVersionTable.PSVersion.Minor -le 2) { }
Write-Verbose "PowerShell 7.0-7.2 detected. Replacing double quotes with escaped double quotes in allowed inbound IP addresses." else {
$AllowedInboundIpAddresses = '[\"{0}\"]' -f $AgentIp $AllowedInboundIpAddresses = '["{0}"]' -f $AgentIp
}
} }
else { else {
$AllowedInboundIpAddresses = '["{0}"]' -f $AgentIp $AllowedInboundIpAddresses = $AgentIp
} }
} }
else { else {
$AllowedInboundIpAddresses = "[]" if ($TemplatePath.Contains("pkr.hcl")) {
$AllowedInboundIpAddresses = "[]"
}
else {
$AllowedInboundIpAddresses = ""
}
} }
Write-Debug "Allowed inbound IP addresses: $AllowedInboundIpAddresses." Write-Debug "Allowed inbound IP addresses: $AllowedInboundIpAddresses."
@@ -205,21 +200,20 @@ Function GenerateResourcesAndImage {
Write-Verbose "PowerShell 5 detected. Replacing double quotes with escaped double quotes in tags JSON." Write-Verbose "PowerShell 5 detected. Replacing double quotes with escaped double quotes in tags JSON."
$TagsJson = $TagsJson -replace '"', '\"' $TagsJson = $TagsJson -replace '"', '\"'
} }
elseif ($PSVersionTable.PSVersion.Major -eq 7 -and $PSVersionTable.PSVersion.Minor -le 2) {
Write-Verbose "PowerShell 7.0-7.2 detected. Replacing double quotes with escaped double quotes in tags JSON."
$TagsJson = $TagsJson -replace '"', '\"'
}
Write-Debug "Tags JSON: $TagsJson." Write-Debug "Tags JSON: $TagsJson."
if ($TemplatePath.Contains(".json")) {
Write-Verbose "Injecting tags into packer template."
if ($Tags) {
$BuilderScriptPathInjected = $TemplatePath.Replace(".json", "-temp.json")
$PackerTemplateContent = Get-Content -Path $TemplatePath | ConvertFrom-Json
$PackerTemplateContent.builders | Add-Member -Name "azure_tags" -Value $Tags -MemberType NoteProperty
$PackerTemplateContent | ConvertTo-Json -Depth 3 | Out-File -Encoding Ascii $BuilderScriptPathInjected
$TemplatePath = $BuilderScriptPathInjected
}
}
$InstallPassword = $env:UserName + [System.GUID]::NewGuid().ToString().ToUpper() $InstallPassword = $env:UserName + [System.GUID]::NewGuid().ToString().ToUpper()
Write-Host "Downloading packer plugins..."
& $PackerBinary init $TemplatePath
if ($LastExitCode -ne 0) {
throw "Packer plugins download failed."
}
Write-Host "Validating packer template..." Write-Host "Validating packer template..."
& $PackerBinary validate ` & $PackerBinary validate `
"-var=client_id=fake" ` "-var=client_id=fake" `
@@ -233,7 +227,7 @@ Function GenerateResourcesAndImage {
"-var=allowed_inbound_ip_addresses=$($AllowedInboundIpAddresses)" ` "-var=allowed_inbound_ip_addresses=$($AllowedInboundIpAddresses)" `
"-var=azure_tags=$($TagsJson)" ` "-var=azure_tags=$($TagsJson)" `
$TemplatePath $TemplatePath
if ($LastExitCode -ne 0) { if ($LastExitCode -ne 0) {
throw "Packer template validation failed." throw "Packer template validation failed."
} }
@@ -246,7 +240,7 @@ Function GenerateResourcesAndImage {
} }
else { else {
Write-Verbose "AzureClientId was provided, will use service principal login." Write-Verbose "AzureClientId was provided, will use service principal login."
az login --service-principal --username $AzureClientId --password=$AzureClientSecret --tenant $AzureTenantId --output none az login --service-principal --username $AzureClientId --password $AzureClientSecret --tenant $AzureTenantId --output none
} }
az account set --subscription $SubscriptionId az account set --subscription $SubscriptionId
if ($LastExitCode -ne 0) { if ($LastExitCode -ne 0) {
@@ -281,7 +275,7 @@ Function GenerateResourcesAndImage {
# Resource group already exists, ask the user what to do # Resource group already exists, ask the user what to do
$title = "Resource group '$ResourceGroupName' already exists" $title = "Resource group '$ResourceGroupName' already exists"
$message = "Do you want to delete the resource group and all resources in it?" $message = "Do you want to delete the resource group and all resources in it?"
$options = @( $options = @(
[System.Management.Automation.Host.ChoiceDescription]::new("&Yes", "Delete the resource group and all resources in it."), [System.Management.Automation.Host.ChoiceDescription]::new("&Yes", "Delete the resource group and all resources in it."),
[System.Management.Automation.Host.ChoiceDescription]::new("&No", "Keep the resource group and continue."), [System.Management.Automation.Host.ChoiceDescription]::new("&No", "Keep the resource group and continue."),
@@ -337,7 +331,7 @@ Function GenerateResourcesAndImage {
if ($LastExitCode -ne 0) { if ($LastExitCode -ne 0) {
throw "Failed to create service principal '$ServicePrincipalName'." throw "Failed to create service principal '$ServicePrincipalName'."
} }
$ServicePrincipalAppId = $ServicePrincipal.appId $ServicePrincipalAppId = $ServicePrincipal.appId
$ServicePrincipalPassword = $ServicePrincipal.password $ServicePrincipalPassword = $ServicePrincipal.password
$TenantId = $ServicePrincipal.tenant $TenantId = $ServicePrincipal.tenant
@@ -374,7 +368,7 @@ Function GenerateResourcesAndImage {
Write-Error $_ Write-Error $_
} finally { } finally {
Write-Verbose "`nCleaning up..." Write-Verbose "`nCleaning up..."
# Remove ADServicePrincipal and ADApplication # Remove ADServicePrincipal and ADApplication
if ($ADCleanupRequired) { if ($ADCleanupRequired) {
Write-Host "Removing ADServicePrincipal..." Write-Host "Removing ADServicePrincipal..."
@@ -13,15 +13,15 @@ class BaseNode {
} }
[String] ToMarkdown([Int32] $Level) { [String] ToMarkdown([Int32] $Level) {
throw "Abstract method 'ToMarkdown(level)' is not implemented for '$($this.GetType().Name)'" throw "Abtract method 'ToMarkdown(level)' is not implemented for '$($this.GetType().Name)'"
} }
[Boolean] IsSimilarTo([BaseNode] $OtherNode) { [Boolean] IsSimilarTo([BaseNode] $OtherNode) {
throw "Abstract method 'IsSimilarTo' is not implemented for '$($this.GetType().Name)'" throw "Abtract method 'IsSimilarTo' is not implemented for '$($this.GetType().Name)'"
} }
[Boolean] IsIdenticalTo([BaseNode] $OtherNode) { [Boolean] IsIdenticalTo([BaseNode] $OtherNode) {
throw "Abstract method 'IsIdenticalTo' is not implemented for '$($this.GetType().Name)'" throw "Abtract method 'IsIdenticalTo' is not implemented for '$($this.GetType().Name)'"
} }
} }
@@ -39,7 +39,7 @@ class BaseToolNode: BaseNode {
} }
[String] GetValue() { [String] GetValue() {
throw "Abstract method 'GetValue' is not implemented for '$($this.GetType().Name)'" throw "Abtract method 'GetValue' is not implemented for '$($this.GetType().Name)'"
} }
[Boolean] IsSimilarTo([BaseNode] $OtherNode) { [Boolean] IsSimilarTo([BaseNode] $OtherNode) {
@@ -53,4 +53,4 @@ class BaseToolNode: BaseNode {
[Boolean] IsIdenticalTo([BaseNode] $OtherNode) { [Boolean] IsIdenticalTo([BaseNode] $OtherNode) {
return $this.IsSimilarTo($OtherNode) -and ($this.GetValue() -eq $OtherNode.GetValue()) return $this.IsSimilarTo($OtherNode) -and ($this.GetValue() -eq $OtherNode.GetValue())
} }
} }
@@ -12,9 +12,6 @@ parameters:
- name: image_type - name: image_type
type: string type: string
- name: image_template_name
type: string
- name: image_readme_name - name: image_readme_name
type: string type: string
@@ -59,38 +56,37 @@ jobs:
arguments: -RepoUrl $(CUSTOM_REPOSITORY_URL) ` arguments: -RepoUrl $(CUSTOM_REPOSITORY_URL) `
-RepoBranch $(CUSTOM_REPOSITORY_BRANCH) -RepoBranch $(CUSTOM_REPOSITORY_BRANCH)
- task: AzureCLI@2 - task: PowerShell@2
displayName: 'Set variables' displayName: 'Set variables'
inputs: inputs:
azureSubscription: 'spn-hosted-runners' targetType: 'inline'
scriptType: 'pscore' script: |
scriptLocation: 'inlineScript'
inlineScript: |
$ImageType = "${{ parameters.image_type }}" $ImageType = "${{ parameters.image_type }}"
$TemplateDirectoryName = if ($ImageType.StartsWith("ubuntu")) { "ubuntu/templates" } else { "windows/templates" } $TemplateDirectoryName = if ($ImageType.StartsWith("ubuntu")) { "linux" } else { "win" }
$TemplateDirectoryPath = Join-Path "images" $TemplateDirectoryName | Resolve-Path $TemplateDirectoryPath = Join-Path "images" $TemplateDirectoryName | Resolve-Path
$TemplatePath = Join-Path $TemplateDirectoryPath "$ImageType.pkr.hcl"
$TemplateFileName = "${{ parameters.image_template_name }}" if ( -not (Test-Path $TemplatePath) ) {
$TemplatePath = Join-Path $TemplateDirectoryPath $TemplateFileName $TemplatePath = Join-Path $TemplateDirectoryPath "$ImageType.json"
}
Write-Host "##vso[task.setvariable variable=TemplateDirectoryPath;]$TemplateDirectoryPath" Write-Host "##vso[task.setvariable variable=TemplateDirectoryPath;]$TemplateDirectoryPath"
Write-Host "##vso[task.setvariable variable=TemplatePath;]$TemplatePath" Write-Host "##vso[task.setvariable variable=TemplatePath;]$TemplatePath"
$ManagedImageName = "${{ parameters.image_type }}-$(Build.BuildId)" $ManagedImageName = "${{ parameters.image_type }}-$(Build.BuildId)"
Write-Host "##vso[task.setvariable variable=ManagedImageName;]$ManagedImageName" Write-Host "##vso[task.setvariable variable=ManagedImageName;]$ManagedImageName"
$VhdName = "$ManagedImageName.vhd"
Write-Host "##vso[task.setvariable variable=VhdName;]$VhdName"
$TempResourceGroupName = "packer-temp-$ManagedImageName" $TempResourceGroupName = "packer-temp-$ManagedImageName"
Write-Host "##vso[task.setvariable variable=TempResourceGroupName;]$TempResourceGroupName" Write-Host "##vso[task.setvariable variable=TempResourceGroupName;]$TempResourceGroupName"
$clientSecret = $(az keyvault secret show --name "spnhostedrunners" --vault-name "gh-imagegeneration" --query value -o tsv)
Write-Host "##vso[task.setvariable variable=ClientSecret;issecret=true]$clientSecret"
- task: PowerShell@2 - task: PowerShell@2
displayName: 'Build VM' displayName: 'Build VM'
inputs: inputs:
targetType: filePath targetType: filePath
filePath: ./images.CI/linux-and-win/build-image.ps1 filePath: ./images.CI/linux-and-win/build-image.ps1
arguments: -ClientId $(CLIENT_ID) ` arguments: -ClientId $(CLIENT_ID) `
-ClientSecret "$(ClientSecret)" ` -ClientSecret $(CLIENT_SECRET) `
-TemplatePath $(TemplatePath) ` -TemplatePath $(TemplatePath) `
-ImageName "$(ManagedImageName)" ` -ImageName "$(ManagedImageName)" `
-ImageResourceGroupName $(AZURE_RESOURCE_GROUP) ` -ImageResourceGroupName $(AZURE_RESOURCE_GROUP) `
@@ -111,12 +107,8 @@ jobs:
inputs: inputs:
targetType: 'inline' targetType: 'inline'
script: | script: |
$ImageType = "${{ parameters.image_type }}" $readmePath = Join-Path "$(TemplateDirectoryPath)" "${{ parameters.image_readme_name }}"
$rootDirectoryName = if ($ImageType.StartsWith("ubuntu")) { "ubuntu" } else { "windows" } $softwareReportPath = Join-Path "$(TemplateDirectoryPath)" "software-report.json"
$rootDirectoryPath = Join-Path "images" $rootDirectoryName | Resolve-Path
$readmePath = Join-Path $rootDirectoryPath "${{ parameters.image_readme_name }}"
$softwareReportPath = Join-Path $rootDirectoryPath "software-report.json"
Copy-Item -Path $readmePath -Destination "$(Build.ArtifactStagingDirectory)/" Copy-Item -Path $readmePath -Destination "$(Build.ArtifactStagingDirectory)/"
if (Test-Path $softwareReportPath) { if (Test-Path $softwareReportPath) {
@@ -154,6 +146,26 @@ jobs:
-PrefixToPathTrim "$(TemplateDirectoryPath)" ` -PrefixToPathTrim "$(TemplateDirectoryPath)" `
-PrintTopNLongest 25 -PrintTopNLongest 25
- task: PowerShell@2
displayName: 'Convert managed image to VHD'
inputs:
targetType: filePath
filePath: ./images.CI/linux-and-win/convert-to-vhd.ps1
arguments: -SubscriptionId $(AZURE_SUBSCRIPTION) `
-Location $(AZURE_LOCATION) `
-ResourceGroupName $(AZURE_RESOURCE_GROUP) `
-ManagedImageName "$(ManagedImageName)" `
-GalleryName "github_imagegeneration_convert_to_vhd" `
-GalleryImageSku "${{ parameters.image_type }}" `
-GalleryImageVersion "0.0.$(Build.BuildId)" `
-StorageAccountName $(AZURE_STORAGE_ACCOUNT) `
-StorageAccountContainerName "images" `
-VhdName "$(VhdName)" `
-ClientId $(CLIENT_ID) `
-ClientSecret $(CLIENT_SECRET) `
-TenantId $(AZURE_TENANT) `
-RemoveManagedImage
- ${{ if eq(parameters.create_release, true) }}: - ${{ if eq(parameters.create_release, true) }}:
- task: PowerShell@2 - task: PowerShell@2
displayName: 'Create release for VM deployment' displayName: 'Create release for VM deployment'
@@ -164,8 +176,9 @@ jobs:
-Organization $(RELEASE_TARGET_ORGANIZATION) ` -Organization $(RELEASE_TARGET_ORGANIZATION) `
-DefinitionId $(RELEASE_TARGET_DEFINITION_ID) ` -DefinitionId $(RELEASE_TARGET_DEFINITION_ID) `
-Project $(RELEASE_TARGET_PROJECT) ` -Project $(RELEASE_TARGET_PROJECT) `
-ImageType "${{ parameters.image_type }}" ` -ImageName "${{ parameters.image_type }}" `
-ManagedImageName "$(ManagedImageName)" ` -StorageAccountContainerName "images" `
-VhdName "$(VhdName)" `
-AccessToken $(RELEASE_TARGET_TOKEN) -AccessToken $(RELEASE_TARGET_TOKEN)
- task: PowerShell@2 - task: PowerShell@2
@@ -175,7 +188,8 @@ jobs:
targetType: filePath targetType: filePath
filePath: ./images.CI/linux-and-win/cleanup.ps1 filePath: ./images.CI/linux-and-win/cleanup.ps1
arguments: -TempResourceGroupName "$(TempResourceGroupName)" ` arguments: -TempResourceGroupName "$(TempResourceGroupName)" `
-StorageAccount $(AZURE_STORAGE_ACCOUNT) `
-SubscriptionId $(AZURE_SUBSCRIPTION) ` -SubscriptionId $(AZURE_SUBSCRIPTION) `
-ClientId $(CLIENT_ID) ` -ClientId $(CLIENT_ID) `
-ClientSecret "$(ClientSecret)" ` -ClientSecret $(CLIENT_SECRET) `
-TenantId $(AZURE_TENANT) -TenantId $(AZURE_TENANT)
@@ -17,5 +17,4 @@ jobs:
- template: image-generation.yml - template: image-generation.yml
parameters: parameters:
image_type: ubuntu2004 image_type: ubuntu2004
image_readme_name: Ubuntu2004-Readme.md image_readme_name: Ubuntu2004-Readme.md
image_template_name: ubuntu-20.04.pkr.hcl
@@ -17,5 +17,4 @@ jobs:
- template: image-generation.yml - template: image-generation.yml
parameters: parameters:
image_type: ubuntu2204 image_type: ubuntu2204
image_readme_name: Ubuntu2204-Readme.md image_readme_name: Ubuntu2204-Readme.md
image_template_name: ubuntu-22.04.pkr.hcl
@@ -1,21 +0,0 @@
schedules:
- cron: "0 0 * * *"
displayName: Daily
branches:
include:
- main
always: true
trigger: none
pr:
autoCancel: true
branches:
include:
- main
jobs:
- template: image-generation.yml
parameters:
image_type: ubuntu2404
image_readme_name: Ubuntu2404-Readme.md
image_template_name: ubuntu-24.04.pkr.hcl
@@ -17,5 +17,4 @@ jobs:
- template: image-generation.yml - template: image-generation.yml
parameters: parameters:
image_type: windows2019 image_type: windows2019
image_readme_name: Windows2019-Readme.md image_readme_name: Windows2019-Readme.md
image_template_name: windows-2019.pkr.hcl
@@ -17,5 +17,4 @@ jobs:
- template: image-generation.yml - template: image-generation.yml
parameters: parameters:
image_type: windows2022 image_type: windows2022
image_readme_name: Windows2022-Readme.md image_readme_name: Windows2022-Readme.md
image_template_name: windows-2022.pkr.hcl
+3 -6
View File
@@ -22,6 +22,8 @@ if (-not (Test-Path $TemplatePath))
$ImageTemplateName = [io.path]::GetFileName($TemplatePath).Split(".")[0] $ImageTemplateName = [io.path]::GetFileName($TemplatePath).Split(".")[0]
$InstallPassword = [System.GUID]::NewGuid().ToString().ToUpper() $InstallPassword = [System.GUID]::NewGuid().ToString().ToUpper()
packer validate -syntax-only $TemplatePath
$SensitiveData = @( $SensitiveData = @(
'OSType', 'OSType',
'StorageAccountLocation', 'StorageAccountLocation',
@@ -35,12 +37,6 @@ $SensitiveData = @(
Write-Host "Show Packer Version" Write-Host "Show Packer Version"
packer --version packer --version
Write-Host "Download packer plugins"
packer init $TemplatePath
Write-Host "Validate packer template"
packer validate -syntax-only $TemplatePath
Write-Host "Build $ImageTemplateName VM" Write-Host "Build $ImageTemplateName VM"
packer build -var "client_id=$ClientId" ` packer build -var "client_id=$ClientId" `
-var "client_secret=$ClientSecret" ` -var "client_secret=$ClientSecret" `
@@ -54,6 +50,7 @@ packer build -var "client_id=$ClientId" `
-var "virtual_network_name=$VirtualNetworkName" ` -var "virtual_network_name=$VirtualNetworkName" `
-var "virtual_network_resource_group_name=$VirtualNetworkRG" ` -var "virtual_network_resource_group_name=$VirtualNetworkRG" `
-var "virtual_network_subnet_name=$VirtualNetworkSubnet" ` -var "virtual_network_subnet_name=$VirtualNetworkSubnet" `
-var "run_validation_diskspace=$env:RUN_VALIDATION_FLAG" `
-color=false ` -color=false `
$TemplatePath ` $TemplatePath `
| Where-Object { | Where-Object {
+14 -10
View File
@@ -1,19 +1,23 @@
param( param(
[Parameter (Mandatory=$true)] [string] $TempResourceGroupName, [String] [Parameter (Mandatory=$true)] $TempResourceGroupName,
[Parameter (Mandatory=$true)] [string] $SubscriptionId, [String] [Parameter (Mandatory=$true)] $StorageAccount,
[Parameter (Mandatory=$true)] [string] $ClientId, [String] [Parameter (Mandatory=$true)] $SubscriptionId,
[Parameter (Mandatory=$true)] [string] $ClientSecret, [String] [Parameter (Mandatory=$true)] $ClientId,
[Parameter (Mandatory=$true)] [string] $TenantId [String] [Parameter (Mandatory=$true)] $ClientSecret,
[String] [Parameter (Mandatory=$true)] $TenantId
) )
az login --service-principal --username $ClientId --password=$ClientSecret --tenant $TenantId | Out-Null az login --service-principal --username $ClientId --password $ClientSecret --tenant $TenantId | Out-Null
az account set --subscription $SubscriptionId | Out-Null
$groupExist = az group exists --name $TempResourceGroupName $groupExist = az group exists --name $TempResourceGroupName --subscription $SubscriptionId
if ($groupExist -eq "true") { if ($groupExist -eq "true") {
$osDiskName = az deployment group list --resource-group $TempResourceGroupName --query "[].properties.parameters.osDiskName.value" -o tsv
Write-Host "Found a match, deleting temporary files" Write-Host "Found a match, deleting temporary files"
az group delete --name $TempResourceGroupName --yes | Out-Null az group delete --name $TempResourceGroupName --subscription $SubscriptionId --yes | Out-Null
Write-Host "Temporary group was deleted successfully" Write-Host "Temporary group was deleted successfully"
Write-Host "Deleting OS disk"
az storage remove --account-name $StorageAccount -c "images" -n "$osDiskName.vhd" --only-show-errors | Out-Null
Write-Host "OS disk deleted"
} else { } else {
Write-Host "No temporary groups found" Write-Host "No temporary groups found"
} }
+185
View File
@@ -0,0 +1,185 @@
param (
[String] [Parameter (Mandatory = $true)] $SubscriptionId,
[String] [Parameter (Mandatory = $true)] $Location,
[String] [Parameter (Mandatory = $true)] $ResourceGroupName,
[String] [Parameter (Mandatory = $true)] $ManagedImageName,
[String] [Parameter (Mandatory = $true)] $GalleryName,
[String] [Parameter (Mandatory = $true)] $GalleryImageSku,
[String] [Parameter (Mandatory = $true)] $GalleryImageVersion,
[String] [Parameter (Mandatory = $true)] $StorageAccountName,
[String] [Parameter (Mandatory = $true)] $StorageAccountContainerName,
[String] [Parameter (Mandatory = $true)] $VhdName,
[Switch] [Parameter (Mandatory = $false)] $RemoveManagedImage,
[String] [Parameter (Mandatory = $true)] $ClientId,
[String] [Parameter (Mandatory = $true)] $ClientSecret,
[String] [Parameter (Mandatory = $true)] $TenantId
)
$ErrorActionPreference = "Stop"
# Login to Azure
az login --service-principal --username $ClientId --password $ClientSecret --tenant $TenantId | Out-Null
az account set --subscription $SubscriptionId | Out-Null
# Create Compute Image Gallery if it doesn't exist
Write-Host "Creating Compute Image Gallery '$GalleryName'..."
$galleryExists = az sig list --resource-group $ResourceGroupName --query "[?name=='$GalleryName']" -o tsv
if ($null -eq $galleryExists) {
az sig create --resource-group $ResourceGroupName --gallery-name $GalleryName --location $Location
}
# Create Image Definition if it doesn't exist
Write-Host "Creating Image Definition '$ManagedImageName'..."
$imageDefinitionName = "RunnerImage-$GalleryImageSku"
if ($ManagedImageName -like "*windows*") {
$imageOsType = "Windows"
} elseif ($ManagedImageName -like "*ubuntu*") {
$imageOsType = "Linux"
} else {
throw "Unknown OS type for image '$ManagedImageName'"
}
$galleryImageExists = az sig image-definition list --resource-group $ResourceGroupName --gallery-name $GalleryName --query "[?name=='$imageDefinitionName']" -o tsv
if ($null -eq $galleryImageExists) {
az sig image-definition create `
--resource-group $ResourceGroupName `
--gallery-name $GalleryName `
--gallery-image-definition $imageDefinitionName `
--publisher "GuthubImagesGeneration" `
--offer "RunnerImage" `
--sku $GalleryImageSku `
--os-type $imageOsType `
--location $Location
}
# Create Image Version from existing Managed Image
Write-Host "Creating Image Version '$GalleryImageVersion' from Managed Image '$ManagedImageName'..."
az sig image-version create `
--resource-group $ResourceGroupName `
--gallery-name $GalleryName `
--gallery-image-definition $imageDefinitionName `
--gallery-image-version $GalleryImageVersion `
--managed-image "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.Compute/images/$ManagedImageName" `
--target-regions $Location `
--replica-count 1 `
--location $Location
# Create Azure Managed Disk from Shared Image Gallery
Write-Host "Creating Azure Managed Disk '$ManagedImageName' from Shared Image Gallery..."
az disk create `
--resource-group $ResourceGroupName `
--name $ManagedImageName `
--location $Location `
--gallery-image-reference "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.Compute/galleries/$GalleryName/images/$imageDefinitionName/versions/$GalleryImageVersion"
# Generate SAS URL for the Managed Disk
Write-Host "Generating SAS URL for the Managed Disk '$ManagedImageName'..."
$sourceDiskUri = az disk grant-access `
--resource-group $ResourceGroupName `
--name $ManagedImageName `
--duration-in-seconds 86400 `
--access-level Read `
--query [accessSas] -o tsv
Write-Host "Querying key for the storage account '$StorageAccountName'..."
$targetKey = az storage account keys list `
--resource-group $ResourceGroupName `
--account-name $StorageAccountName `
--query "[0].value" -o tsv
Write-Host ("Copying VHD blob from '{0}' to 'https://{1}.blob.core.windows.net/{2}/{3}'..." `
-f $sourceDiskUri.Split('?')[0], $StorageAccountName, $StorageAccountContainerName, $VhdName)
az storage blob copy start `
--source-uri $sourceDiskUri `
--destination-blob $VhdName `
--destination-container $StorageAccountContainerName `
--account-name $StorageAccountName `
--account-key $targetKey `
--only-show-errors
Write-Host "Waiting for the copy to complete..."
while ($true) {
$status = az storage blob show `
--container-name $StorageAccountContainerName `
--name $VhdName `
--account-name $StorageAccountName `
--account-key $targetKey `
--query "properties.copy.status" -o tsv
if ($status -eq "success") {
Write-Host "Copy completed successfully."
break
} elseif ($status -ne "pending") {
Write-Host "Copy failed with status '$status', see blob information below:"
az storage blob show `
--container-name $StorageAccountContainerName `
--name $VhdName `
--account-name $StorageAccountName `
--account-key $targetKey
throw "Copy failed with status '$status'"
}
$progress = az storage blob show `
--container-name $StorageAccountContainerName `
--name $VhdName `
--account-name $StorageAccountName `
--account-key $targetKey `
--query "properties.copy.progress" -o tsv
Write-Host "Progress: $(($progress.Split("/")[0] / $progress.Split("/")[1]).ToString("P"))"
Start-Sleep -Seconds 15
}
Write-Host "Successfully converted '$ManagedImageName' to '$VhdName' in '$StorageAccountName' storage account."
# Remove Managed Image if requested
if ($RemoveManagedImage) {
Write-Host "Removing Managed Image '$ManagedImageName'..."
az image delete `
--resource-group $ResourceGroupName `
--name $ManagedImageName `
--only-show-errors
if ($LastExitCode) {
Write-Host "Warning: Failed to delete the Managed Image '$ManagedImageName'."
}
}
Write-Host "Cleaning up..."
# Revoke SAS URL for the Managed Disk
az disk revoke-access `
--resource-group $ResourceGroupName `
--name $ManagedImageName `
--only-show-errors
if ($LastExitCode) {
Write-Host "Warning: Failed to revoke access to the Managed Disk '$ManagedImageName'."
}
# Delete Azure Managed Disk from Shared Image Gallery
az disk delete `
--resource-group $ResourceGroupName `
--name $ManagedImageName `
--only-show-errors `
--yes
if ($LastExitCode) {
Write-Host "Warning: Failed to delete the Managed Disk '$ManagedImageName'."
}
# Delete Image Version from Shared Image Gallery
az sig image-version delete `
--resource-group $ResourceGroupName `
--gallery-name $GalleryName `
--gallery-image-definition $imageDefinitionName `
--gallery-image-version $GalleryImageVersion `
--only-show-errors
if ($LastExitCode) {
Write-Host "Warning: Failed to delete the Image Version '$GalleryImageVersion'."
}
Write-Host "Done."
+16 -12
View File
@@ -1,11 +1,12 @@
param( param(
[Parameter (Mandatory)] [UInt32] $BuildId, [UInt32] [Parameter (Mandatory)] $BuildId,
[Parameter (Mandatory)] [string] $Organization, [String] [Parameter (Mandatory)] $Organization,
[Parameter (Mandatory)] [string] $Project, [String] [Parameter (Mandatory)] $Project,
[Parameter (Mandatory)] [string] $ImageType, [String] [Parameter (Mandatory)] $ImageName,
[Parameter (Mandatory)] [string] $ManagedImageName, [String] [Parameter (Mandatory)] $StorageAccountContainerName,
[Parameter (Mandatory)] [string] $DefinitionId, [String] [Parameter (Mandatory)] $VhdName,
[Parameter (Mandatory)] [string] $AccessToken [String] [Parameter (Mandatory)] $DefinitionId,
[String] [Parameter (Mandatory)] $AccessToken
) )
$Body = @{ $Body = @{
@@ -14,11 +15,14 @@ $Body = @{
ImageBuildId = @{ ImageBuildId = @{
value = $BuildId value = $BuildId
} }
ImageType = @{ ImageName = @{
value = $ImageType value = $ImageName
} }
ManagedImageName = @{ ImageStorageContainerName = @{
value = $ManagedImageName value = $StorageAccountContainerName
}
ImageBlobPath = @{
value = $VhdName
} }
} }
isDraft = "false" isDraft = "false"
@@ -33,4 +37,4 @@ $headers = @{
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13
$NewRelease = Invoke-RestMethod $URL -Body $Body -Method "POST" -Headers $headers -ContentType "application/json" $NewRelease = Invoke-RestMethod $URL -Body $Body -Method "POST" -Headers $headers -ContentType "application/json"
Write-Host "Created release: $($NewRelease._links.web.href)" Write-Host "Created release: $($NewRelease._links.web.href)"
+1 -1
View File
@@ -13,7 +13,7 @@ function Push-AnkaTemplateToRegistry {
[string] $TemplateName [string] $TemplateName
) )
# if registry uuid doesn't match then delete an image in registry # if registry uuid doesn't match than delete an image in registry
$AnkaCaCrtPath="$HOME/.config/anka/certs/anka-ca-crt.pem" $AnkaCaCrtPath="$HOME/.config/anka/certs/anka-ca-crt.pem"
$images = anka --machine-readable registry --cacert $AnkaCaCrtPath --registry-path $RegistryUrl list | ConvertFrom-Json | ForEach-Object body $images = anka --machine-readable registry --cacert $AnkaCaCrtPath --registry-path $RegistryUrl list | ConvertFrom-Json | ForEach-Object body
$images | Where-Object name -eq $TemplateName | ForEach-Object { $images | Where-Object name -eq $TemplateName | ForEach-Object {
@@ -76,7 +76,7 @@ function Invoke-SoftwareUpdate {
$ipAddress = Get-AnkaVMIPAddress -VMName $TemplateName $ipAddress = Get-AnkaVMIPAddress -VMName $TemplateName
# Unenroll Seed # Unenroll Seed
Write-Host "`t[*] Resetting the seed before requesting stable versions" Write-Host "`t[*] Reseting the seed before requesting stable versions"
Remove-CurrentBetaSeed -HostName $ipAddress | Show-StringWithFormat Remove-CurrentBetaSeed -HostName $ipAddress | Show-StringWithFormat
# Install Software Updates # Install Software Updates
@@ -89,46 +89,42 @@ function Invoke-SoftwareUpdate {
return return
} }
# Define the next macOS version
$command = "sw_vers"
$guestMacosVersion = Invoke-SSHPassCommand -HostName $ipAddress -Command $command
switch -regex ($guestMacosVersion[1]) {
'12.\d' { $nextOSVersion = 'macOS Ventura|macOS Sonoma' }
'13.\d' { $nextOSVersion = 'macOS Sonoma' }
}
Write-Host "`t[*] Fetching Software Updates ready to install on '$TemplateName' VM:" Write-Host "`t[*] Fetching Software Updates ready to install on '$TemplateName' VM:"
Show-StringWithFormat $newUpdates Show-StringWithFormat $newUpdates
$listOfNewUpdates = $($($newUpdates.Split("*")).Split("Title").where({$_ -match "Label:"}).Replace("Label: ", '').where({$_ -notmatch $nextOSVersion})) $listOfNewUpdates = $($($newUpdates.Split("*")).Split("Title") | Where-Object {$_ -match "Label:"}).Replace("Label: ", '')
Write-Host "`t[*] Installing Software Updates on '$TemplateName' VM:" Write-Host "`t[*] Installing Software Updates on '$TemplateName' VM:"
Install-SoftwareUpdate -HostName $ipAddress -listOfUpdates $listOfNewUpdates -Password $Password | Show-StringWithFormat Install-SoftwareUpdate -HostName $ipAddress -listOfUpdates $listOfNewUpdates -Password $Password | Show-StringWithFormat
Write-Host "`t[*] Sleep 60 seconds before the software updates have been installed"
Start-Sleep -Seconds 60
Write-Host "`t[*] Waiting for loginwindow process"
Wait-LoginWindow -HostName $ipAddress | Show-StringWithFormat
# Re-enable AutoLogon after installing a new security software update
Invoke-EnableAutoLogon
# Check if Action: restart
# Make an array of updates
$listOfNewUpdates = $newUpdates.split('*').Trim('')
foreach ($newupdate in $listOfNewUpdates) { foreach ($newupdate in $listOfNewUpdates) {
# Check software updates have been installed # Will be True if the value is not Venture, not empty, and contains "Action: restart" words
$updates = Get-SoftwareUpdate -HostName $ipAddress if ($newupdate.Contains("Action: restart") -and !$newupdate.Contains("macOS Ventura") -and !$newupdate.Contains("macOS Sonoma") -and (-not [String]::IsNullOrEmpty($newupdate))) {
if ($updates.Contains("Action: restart") -and !($updates -match $nextOSVersion)) { Write-Host "`t[*] Sleep 60 seconds before the software updates have been installed"
Write-Host "`t[x] Software updates failed to install: " Start-Sleep -Seconds 60
Show-StringWithFormat $updates
exit 1 Write-Host "`t[*] Waiting for loginwindow process"
Wait-LoginWindow -HostName $ipAddress | Show-StringWithFormat
# Re-enable AutoLogon after installing a new security software update
Invoke-EnableAutoLogon
# Check software updates have been installed
$updates = Get-SoftwareUpdate -HostName $ipAddress
if ($updates.Contains("Action: restart")) {
Write-Host "`t[x] Software updates failed to install: "
Show-StringWithFormat $updates
exit 1
}
} }
} }
Write-Host "`t[*] Show the install history:" Write-Host "`t[*] Show the install history:"
$hUpdates = Get-SoftwareUpdateHistory -HostName $ipAddress $hUpdates = Get-SoftwareUpdateHistory -HostName $ipAddress
Show-StringWithFormat $hUpdates Show-StringWithFormat $hUpdates
Write-Host "`t[*] The current macOS version:"
$command = "sw_vers"
Invoke-SSHPassCommand -HostName $ipAddress -Command $command | Show-StringWithFormat
} }
function Invoke-UpdateSettings { function Invoke-UpdateSettings {
param ( param (
[Parameter(Mandatory)] [Parameter(Mandatory)]
@@ -186,12 +182,6 @@ Write-Host "`n[#2] Create a VM template:"
Write-Host "`t[*] Deleting existed template with name '$TemplateName' before creating a new one" Write-Host "`t[*] Deleting existed template with name '$TemplateName' before creating a new one"
Remove-AnkaVM -VMName $TemplateName Remove-AnkaVM -VMName $TemplateName
# Temporary disable VNC for macOS 14
# It's probably Anka's bug fixed in 3.3.2
if ($shortMacOSVersion -eq "14") {
$env:ANKA_CREATE_VNC = 0
}
Write-Host "`t[*] Creating Anka VM template with name '$TemplateName' and '$TemplateUsername' user" Write-Host "`t[*] Creating Anka VM template with name '$TemplateName' and '$TemplateUsername' user"
Write-Host "`t[*] CPU Count: $CPUCount, RamSize: ${RamSizeGb}G, DiskSizeGb: ${DiskSizeGb}G, InstallerPath: $macOSInstaller, TemplateName: $TemplateName" Write-Host "`t[*] CPU Count: $CPUCount, RamSize: ${RamSizeGb}G, DiskSizeGb: ${DiskSizeGb}G, InstallerPath: $macOSInstaller, TemplateName: $TemplateName"
New-AnkaVMTemplate -InstallerPath "$macOSInstaller" ` New-AnkaVMTemplate -InstallerPath "$macOSInstaller" `
+57 -68
View File
@@ -13,7 +13,7 @@ function Enable-AutoLogon {
[string] $Password [string] $Password
) )
$url = "https://raw.githubusercontent.com/actions/runner-images/main/images/macos/assets/bootstrap-provisioner/setAutoLogin.sh" $url = "https://raw.githubusercontent.com/actions/runner-images/main/images/macos/provision/bootstrap-provisioner/setAutoLogin.sh"
$script = Invoke-RestMethod -Uri $url $script = Invoke-RestMethod -Uri $url
$base64 = [Convert]::ToBase64String($script.ToCharArray()) $base64 = [Convert]::ToBase64String($script.ToCharArray())
$command = "echo $base64 | base64 --decode > ./setAutoLogin.sh;sudo bash ./setAutoLogin.sh '${UserName}' '${Password}';rm ./setAutoLogin.sh" $command = "echo $base64 | base64 --decode > ./setAutoLogin.sh;sudo bash ./setAutoLogin.sh '${UserName}' '${Password}';rm ./setAutoLogin.sh"
@@ -28,31 +28,14 @@ function Invoke-SoftwareUpdateArm64 {
[Parameter(Mandatory)] [Parameter(Mandatory)]
[ValidateNotNullOrEmpty()] [ValidateNotNullOrEmpty()]
[string] $Password, [string] $Password
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[array] $ListOfUpdates
) )
# Define the next macOS version $url = "https://raw.githubusercontent.com/actions/runner-images/main/images/macos/provision/configuration/auto-software-update-arm64.exp"
$command = "sw_vers"
$guestMacosVersion = Invoke-SSHPassCommand -HostName $HostName -Command $command
switch -regex ($guestMacosVersion[1]) {
'13.\d' { $nextOSVersion = 'Sonoma' }
'14.\d' { $nextOSVersion = 'NotYetDefined' }
}
$url = "https://raw.githubusercontent.com/actions/runner-images/main/images/macos/assets/auto-software-update-arm64.exp"
$script = Invoke-RestMethod -Uri $url $script = Invoke-RestMethod -Uri $url
foreach ($update in $listOfUpdates) { $base64 = [Convert]::ToBase64String($script.ToCharArray())
if ($update -notmatch "$nextOSVersion") { $command = "echo $base64 | base64 --decode > ./auto-software-update-arm64.exp;chmod +x ./auto-software-update-arm64.exp; ./auto-software-update-arm64.exp ${Password};rm ./auto-software-update-arm64.exp"
$updatedScript = $script.Replace("MACOSUPDATE", $($($update.trim()).Replace(" ","\ "))) Invoke-SSHPassCommand -HostName $HostName -Command $command
$base64 = [Convert]::ToBase64String($updatedScript.ToCharArray())
$command = "echo $base64 | base64 --decode > ./auto-software-update-arm64.exp;chmod +x ./auto-software-update-arm64.exp; ./auto-software-update-arm64.exp ${Password};rm ./auto-software-update-arm64.exp"
Invoke-SSHPassCommand -HostName $HostName -Command $command
}
}
} }
function Get-AvailableVersions { function Get-AvailableVersions {
@@ -80,24 +63,24 @@ function Get-AvailableIPSWVersions {
) )
if ($IsBeta) { if ($IsBeta) {
$command = { mist list firmware "$MacOSCodeNameOrVersion" --compatible --include-betas --latest --export "/Applications/export.json" } $command = { mist list firmware "$MacOSCodeNameOrVersion" --include-betas --latest --export "/Applications/export.json"}
} elseif ($IsLatest) { } elseif ($IsLatest) {
$command = { mist list firmware "$MacOSCodeNameOrVersion" --compatible --latest --export "/Applications/export.json" } $command = { mist list firmware "$MacOSCodeNameOrVersion" --latest --export "/Applications/export.json" }
} else { } else {
$command = { mist list firmware "$MacOSCodeNameOrVersion" --compatible --export "/Applications/export.json" } $command = { mist list firmware "$MacOSCodeNameOrVersion" --export "/Applications/export.json" }
} }
$condition = { $LASTEXITCODE -eq 0 } $condition = { $LASTEXITCODE -eq 0 }
Invoke-WithRetry -Command $command -BreakCondition $condition | Out-Null Invoke-WithRetry -Command $command -BreakCondition $condition | Out-Null
$softwareList = get-content -Path "/Applications/export.json" $softwareList = get-content -Path "/Applications/export.json"
$availableBuilds = ($softwareList | ConvertFrom-Json).build $turgetVersion = ($softwareList | ConvertFrom-Json).version
if ($null -eq $availableBuilds) { if ($null -eq $turgetVersion) {
Write-Host "Requested macOS '$MacOSCodeNameOrVersion' version not found in the list of available installers." Write-Host "Requested macOS '$MacOSCodeNameOrVersion' version not found in the list of available installers."
$command = { mist list firmware "$($MacOSCodeNameOrVersion.split('.')[0])" } $command = { mist list firmware "$($MacOSCodeNameOrVersion.split('.')[0])" }
Invoke-WithRetry -Command $command -BreakCondition $condition Invoke-WithRetry -Command $command -BreakCondition $condition
exit 1 exit 1
} }
return $availableBuilds return $turgetVersion
} }
function Get-MacOSIPSWInstaller { function Get-MacOSIPSWInstaller {
@@ -113,26 +96,21 @@ function Get-MacOSIPSWInstaller {
$MacOSName = "macOS Monterey" $MacOSName = "macOS Monterey"
} elseif ($MacOSVersion -eq [version] "13.0") { } elseif ($MacOSVersion -eq [version] "13.0") {
$MacOSName = "macOS Ventura" $MacOSName = "macOS Ventura"
} elseif ($MacOSVersion -eq [version] "14.0") {
$MacOSName = "macOS Sonoma"
} else { } else {
$MacOSName = $MacOSVersion.ToString() $MacOSName = $MacOSVersion.ToString()
} }
Write-Host "`t[*] Finding available full installers" Write-Host "`t[*] Finding available full installers"
if ($DownloadLatestVersion -eq $true) { if ($DownloadLatestVersion -eq $true) {
$targetBuild = Get-AvailableIPSWVersions -IsLatest $true -MacOSCodeNameOrVersion $MacOSName $targetVersion = Get-AvailableIPSWVersions -IsLatest $true -MacOSCodeNameOrVersion $MacOSName
Write-Host "`t[*] The 'DownloadLatestVersion' flag is set to true. Latest compatible macOS build of '$MacOSName' is '$targetBuild'" Write-host "`t[*] The 'DownloadLatestVersion' flag is set to true. Latest macOS version is '$MacOSName' - '$targetVersion' now"
} elseif ($BetaSearch -eq $true) { } elseif ($BetaSearch -eq $true) {
$targetBuild = Get-AvailableIPSWVersions -IsBeta $true -MacOSCodeNameOrVersion $MacOSName $targetVersion = Get-AvailableIPSWVersions -IsBeta $true -MacOSCodeNameOrVersion $MacOSName
Write-Host "`t[*] The 'BetaSearch' flag is set to true. Latest compatible beta macOS build of '$MacOSName' is '$targetBuild'" Write-host "`t[*] The 'BetaSearch' flag is set to true. Latestbeta macOS version is '$MacOSName' - '$targetVersion' now"
} else { } else {
$targetBuild = Get-AvailableIPSWVersions -MacOSCodeNameOrVersion $MacOSName -IsLatest $false $targetVersion = Get-AvailableIPSWVersions -MacOSCodeNameOrVersion $MacOSName -IsLatest $false
Write-Host "`t[*] Available compatible macOS builds of '$MacOSName' are: $($targetBuild -join ', ')" Write-host "`t[*] The exact version was specified - '$MacOSName' "
if ($targetBuild.Count -gt 1) {
Write-Error "`t[*] Please specify the exact build number of macOS you want to install"
exit 1
}
} }
$installerPathPattern = "/Applications/Install ${macOSName}*.ipsw" $installerPathPattern = "/Applications/Install ${macOSName}*.ipsw"
@@ -145,12 +123,12 @@ function Get-MacOSIPSWInstaller {
# Download macOS installer # Download macOS installer
$installerDir = "/Applications/" $installerDir = "/Applications/"
$installerName = "Install ${macOSName}.ipsw" $installerName = "Install ${macOSName}.ipsw"
Write-Host "`t[*] Requested macOS '$targetBuild' version installer found, fetching it from mist database" Write-Host "`t[*] Requested macOS '$targetVersion' version installer found, fetching it from mist database"
Invoke-WithRetry { mist download firmware "$targetBuild" --output-directory $installerDir --firmware-name "$installerName" } { $LASTEXITCODE -eq 0 } | Out-Null Invoke-WithRetry { mist download firmware "$targetVersion" --output-directory $installerDir --firmware-name "$installerName" } {$LASTEXITCODE -eq 0} | Out-Null
if (Test-Path "$installerDir$installerName") { if (Test-Path "$installerDir$installerName") {
$result = "$installerDir$installerName" $result = "$installerDir$installerName"
} else { } else {
Write-Error "`t[*] Requested macOS '$targetBuild' version installer failed to download" Write-host "`t[*] Requested macOS '$targetVersion' version installer failed to download"
exit 1 exit 1
} }
return $result return $result
@@ -171,11 +149,11 @@ function Get-MacOSInstaller {
Write-Host "`t[*] Beta Version requested. Enrolling machine to DeveloperSeed" Write-Host "`t[*] Beta Version requested. Enrolling machine to DeveloperSeed"
sudo $seedutil enroll DeveloperSeed | Out-Null sudo $seedutil enroll DeveloperSeed | Out-Null
} else { } else {
Write-Host "`t[*] Resetting the seed before requesting stable versions" Write-Host "`t[*] Reseting the seed before requesting stable versions"
sudo $seedutil unenroll | Out-Null sudo $seedutil unenroll | Out-Null
} }
# Validate there is no software update at the moment # Validate there is no softwareupdate at the moment
Test-SoftwareUpdate Test-SoftwareUpdate
# Validate availability OSVersion # Validate availability OSVersion
@@ -191,7 +169,7 @@ function Get-MacOSInstaller {
exit 1 exit 1
} }
Show-StringWithFormat $filteredVersions Show-StringWithFormat $filteredVersions
$osVersions = $filteredVersions.OSVersion | Sort-Object { [version]$_ } $osVersions = $filteredVersions.OSVersion | Sort-Object {[version]$_}
$MacOSVersion = $osVersions | Select-Object -Last 1 $MacOSVersion = $osVersions | Select-Object -Last 1
Write-Host "`t[*] The 'DownloadLatestVersion' flag is set. Latest macOS version is '$MacOSVersion' now" Write-Host "`t[*] The 'DownloadLatestVersion' flag is set. Latest macOS version is '$MacOSVersion' now"
} }
@@ -266,13 +244,31 @@ function Install-SoftwareUpdate {
[array] $listOfUpdates, [array] $listOfUpdates,
[string] $Password [string] $Password
) )
# If an update is happening on macOS arm64 we will use the additional tool to install updates. # If an update is happening on macOS 12 or 13 we will use the prepared list of updates, otherwise, we will install all updates.
$osArch = $(arch) $command = "sw_vers"
if ($osArch -eq "arm64") { $guestMacosVersion = Invoke-SSHPassCommand -HostName $HostName -Command $command
Invoke-SoftwareUpdateArm64 -HostName $HostName -Password $Password -ListOfUpdates $listOfUpdates if ($guestMacosVersion[1] -match "12") {
foreach ($update in $listOfUpdates){
# Filtering updates that contain "Ventura" word
if ($update -notmatch "Ventura") {
$command = "sudo /usr/sbin/softwareupdate --restart --verbose --install '$($update.trim())'"
Invoke-SSHPassCommand -HostName $HostName -Command $command
}
}
} elseif ($guestMacosVersion[1] -match "13") {
foreach ($update in $listOfUpdates){
# Filtering updates that contain "Sonoma" word
if ($update -notmatch "Sonoma") {
$command = "sudo /usr/sbin/softwareupdate --restart --verbose --install '$($update.trim())'"
Invoke-SSHPassCommand -HostName $HostName -Command $command
}
}
} else { } else {
foreach ($update in $listOfUpdates) { $osArch = $(arch)
$command = "sudo /usr/sbin/softwareupdate --restart --verbose --install '$($update.trim())'" if ($osArch -eq "arm64") {
Invoke-SoftwareUpdateArm64 -HostName $HostName -Password $Password
} else {
$command = "sudo /usr/sbin/softwareupdate --all --install --restart --verbose"
Invoke-SSHPassCommand -HostName $HostName -Command $command Invoke-SSHPassCommand -HostName $HostName -Command $command
} }
} }
@@ -306,11 +302,7 @@ function Invoke-SSHPassCommand {
"${env:SSHUSER}@${HostName}" "${env:SSHUSER}@${HostName}"
) )
$sshPassOptions = $sshArg -join " " $sshPassOptions = $sshArg -join " "
if ($PSVersionTable.PSVersion.Major -eq 7 -and $PSVersionTable.PSVersion.Minor -le 2) { $result = bash -c "$sshPassOptions \""$Command\"" 2>&1"
$result = bash -c "$sshPassOptions \""$Command\"" 2>&1"
} else {
$result = bash -c "$sshPassOptions `"$Command`" 2>&1"
}
if ($LASTEXITCODE -ne 0) { if ($LASTEXITCODE -ne 0) {
Write-Error "There is an error during command execution:`n$result" Write-Error "There is an error during command execution:`n$result"
exit 1 exit 1
@@ -325,17 +317,14 @@ function Invoke-WithRetry {
[int] $RetryCount = 20, [int] $RetryCount = 20,
[int] $Seconds = 60 [int] $Seconds = 60
) )
while ($RetryCount -gt 0) {
try {
if ($Command) {
$result = & $Command
}
if (& $BreakCondition) { while ($RetryCount -gt 0) {
return $result if ($Command) {
} $result = & $Command
} catch { }
Write-Host "`t [!] Error during command execution: $_"
if (& $BreakCondition) {
return $result
} }
$RetryCount-- $RetryCount--
@@ -1,13 +1,11 @@
jobs: jobs:
- job: Image_generation - job: Image_generation
displayName: Image Generation (${{ parameters.image_label }}) displayName: Image Generation (${{ parameters.image_label }})
timeoutInMinutes: 1200 timeoutInMinutes: 720
pool: pool:
name: Mac-Cloud Image Generation name: Mac-Cloud Image Generation
demands:
- PrimaryRackAgent -equals ${{ parameters.primary_agent }}
variables: variables:
- group: ${{ parameters.variable_group_name }} - group: Mac-Cloud Image Generation
steps: steps:
- pwsh: | - pwsh: |
@@ -65,7 +63,6 @@ jobs:
'Using ssh communicator to connect:' 'Using ssh communicator to connect:'
) )
packer init ${{ parameters.template_path }}
packer build -on-error=abort ` packer build -on-error=abort `
-var="vcenter_server=$(vcenter-server-v2)" ` -var="vcenter_server=$(vcenter-server-v2)" `
-var="vcenter_username=$(vcenter-username-v2)" ` -var="vcenter_username=$(vcenter-username-v2)" `
+1 -6
View File
@@ -14,15 +14,10 @@ pr:
include: include:
- main - main
variables:
- group: Mac-Cloud Image Generation
jobs: jobs:
- template: image-generation.yml - template: image-generation.yml
parameters: parameters:
image_label: 'macOS Big Sur' image_label: 'macOS Big Sur'
base_image_name: 'clean-macOS-11-380Gb-runner' base_image_name: 'clean-macOS-11-380Gb-runner'
template_path: 'templates/macOS-11.pkr.hcl' template_path: 'templates/macOS-11.json'
target_datastore: 'ds-image' target_datastore: 'ds-image'
variable_group_name: 'Mac-Cloud Image Generation'
primary_agent: 'true'
+1 -6
View File
@@ -14,15 +14,10 @@ pr:
include: include:
- main - main
variables:
- group: Mac-Cloud Image Generation
jobs: jobs:
- template: image-generation.yml - template: image-generation.yml
parameters: parameters:
image_label: 'macOS Monterey' image_label: 'macOS Monterey'
base_image_name: 'clean-macOS-12-380Gb-runner' base_image_name: 'clean-macOS-12-380Gb-runner'
template_path: 'templates/macOS-12.pkr.hcl' template_path: 'templates/macOS-12.json'
target_datastore: 'ds-image' target_datastore: 'ds-image'
variable_group_name: 'Mac-Cloud Image Generation'
primary_agent: 'true'
@@ -1,23 +0,0 @@
name: macOS-11_$(date:yyyyMMdd)$(rev:.r)_unstable
schedules:
- cron: '45 0 * * 1'
displayName: Weekly
branches:
include:
- main
always: true
trigger: none
variables:
- group: Mac-Cloud Image Generation
jobs:
- template: image-generation.yml
parameters:
image_label: 'macOS Big Sur'
base_image_name: 'clean-macOS-11-380Gb-runner'
template_path: 'templates/macOS-11.pkr.hcl'
target_datastore: 'ds-image'
variable_group_name: 'Mac-Cloud Secondary Image Generation'
primary_agent: 'false'
@@ -1,23 +0,0 @@
name: macOS-12_$(date:yyyyMMdd)$(rev:.r)_unstable
schedules:
- cron: '45 1 * * 1'
displayName: Weekly
branches:
include:
- main
always: true
trigger: none
variables:
- group: Mac-Cloud Image Generation
jobs:
- template: image-generation.yml
parameters:
image_label: 'macOS Monterey'
base_image_name: 'clean-macOS-12-380Gb-runner'
template_path: 'templates/macOS-12.pkr.hcl'
target_datastore: 'ds-image'
variable_group_name: 'Mac-Cloud Secondary Image Generation'
primary_agent: 'false'
+4 -4
View File
@@ -22,8 +22,8 @@ function Validate-Scripts {
return $ScriptWithoutShebangLine return $ScriptWithoutShebangLine
} }
$PathUbuntu = "./images/ubuntu/scripts" $PathUbuntu = "./images/linux/scripts"
$PathMacOS = "./images/macos" $PathMacOS = "./images/macos/provision"
$PatternUbuntu = "#!/bin/bash -e" $PatternUbuntu = "#!/bin/bash -e"
$PatternMacOS = "#!/bin/bash -e -o pipefail" $PatternMacOS = "#!/bin/bash -e -o pipefail"
$ScriptsWithBrokenShebang = @() $ScriptsWithBrokenShebang = @()
@@ -34,10 +34,10 @@ if ($ScriptsWithBrokenShebang.Length -gt 0) {
$ScriptsWithBrokenShebang | ForEach-Object { $ScriptsWithBrokenShebang | ForEach-Object {
Write-Host "##[error] '$_'" Write-Host "##[error] '$_'"
} }
Write-Host "`n`n##[error] Expected shebang for scripts in 'images/ubuntu' folder is '$PatternUbuntu'" Write-Host "`n`n##[error] Expected shebang for scripts in 'images/linux' folder is '$PatternUbuntu'"
Write-Host "##[error] Expected shebang for scripts in 'images/macos' folder is '$PatternMacOS'" Write-Host "##[error] Expected shebang for scripts in 'images/macos' folder is '$PatternMacOS'"
exit 1 exit 1
else { else {
Write-Host "All scripts have correct shebang." Write-Host "All scripts have correct shebang."
} }
} }
@@ -1,13 +1,13 @@
| Announcements | | Announcements |
|-| |-|
| [Ubuntu 24.04 is now available](https://github.com/actions/runner-images/issues/9848) | | [[All OS] Android NDK r23 will be removed from images on October 9](https://github.com/actions/runner-images/issues/8383) |
| [[Ubuntu, Windows] Docker Compose v1 will be removed from images on July, 9](https://github.com/actions/runner-images/issues/9692) | | [[All OS] hub utility will be removed on October 2](https://github.com/actions/runner-images/issues/8362) |
*** ***
# Ubuntu 20.04 # Ubuntu 20.04
- OS Version: 20.04.6 LTS - OS Version: 20.04.6 LTS
- Kernel Version: 5.15.0-1064-azure - Kernel Version: 5.15.0-1047-azure
- Image Version: 20240516.1.0 - Image Version: 20231002.1.0
- Systemd version: 245.4-4ubuntu3.23 - Systemd version: 245.4-4ubuntu3.22
## Installed Software ## Installed Software
@@ -18,32 +18,32 @@
- Clang-tidy: 10.0.0, 11.0.0, 12.0.0 - Clang-tidy: 10.0.0, 11.0.0, 12.0.0
- Dash 0.5.10.2-6 - Dash 0.5.10.2-6
- Erlang 25.3 (Eshell 13.2) - Erlang 25.3 (Eshell 13.2)
- Erlang rebar3 3.23.0 - Erlang rebar3 3.22.1
- GNU C++: 10.5.0 - GNU C++: 9.4.0, 10.5.0
- GNU Fortran: 10.5.0 - GNU Fortran: 9.4.0, 10.5.0
- Julia 1.10.3 - Julia 1.9.3
- Kotlin 1.9.24-release-822 - Kotlin 1.9.10-release-459
- Mono 6.12.0.200 - Mono 6.12.0.200
- MSBuild 16.10.1.31701 (Mono 6.12.0.200) - MSBuild 16.10.1.31701 (Mono 6.12.0.200)
- Node.js 18.20.2 - Node.js 18.18.0
- Perl 5.30.0 - Perl 5.30.0
- Python 3.8.10 - Python 3.8.10
- Ruby 2.7.0p0 - Ruby 2.7.0p0
- Swift 5.10 - Swift 5.9
### Package Management ### Package Management
- cpan 1.64 - cpan 1.64
- Helm 3.14.4 - Helm 3.13.0
- Homebrew 4.3.0 - Homebrew 4.1.13
- Miniconda 24.3.0 - Miniconda 23.5.2
- Npm 10.5.0 - Npm 9.8.1
- NuGet 6.6.1.2 - NuGet 6.6.1.2
- Pip 20.0.2 - Pip 20.0.2
- Pip3 20.0.2 - Pip3 20.0.2
- Pipx 1.5.0 - Pipx 1.2.0
- RubyGems 3.1.2 - RubyGems 3.1.2
- Vcpkg (build from commit 66a252f70) - Vcpkg (build from commit c6d6efed3)
- Yarn 1.22.22 - Yarn 1.22.19
#### Environment variables #### Environment variables
| Name | Value | | Name | Value |
@@ -61,119 +61,118 @@ to accomplish this.
### Project Management ### Project Management
- Ant 1.10.7 - Ant 1.10.7
- Gradle 8.7 - Gradle 8.3
- Lerna 8.1.3 - Lerna 7.3.0
- Maven 3.8.8 - Maven 3.8.8
- Sbt 1.10.0 - Sbt 1.9.6
### Tools ### Tools
- Ansible 2.13.13 - Ansible 2.13.12
- apt-fast 1.10.0 - apt-fast 1.9.12
- AzCopy 10.24.0 - available by `azcopy` and `azcopy10` aliases - AzCopy 10.21.0 - available by `azcopy` and `azcopy10` aliases
- Bazel 7.1.2 - Bazel 6.3.2
- Bazelisk 1.19.0 - Bazelisk 1.18.0
- Bicep 0.27.1 - Bicep 0.21.1
- Buildah 1.22.3 - Buildah 1.22.3
- CMake 3.29.3 - CMake 3.27.6
- CodeQL Action Bundle 2.17.2 - CodeQL Action Bundle 2.14.6
- Docker Amazon ECR Credential Helper 0.8.0 - Docker Amazon ECR Credential Helper 0.7.1
- Docker Compose v1 1.29.2 - Docker Compose v1 1.29.2
- Docker Compose v2 2.23.3 - Docker Compose v2 2.22.0
- Docker-Buildx 0.14.0 - Docker-Buildx 0.11.2
- Docker Client 24.0.9 - Docker Client 24.0.6
- Docker Server 24.0.9 - Docker Server 24.0.6
- Fastlane 2.220.0 - Fastlane 2.216.0
- Git 2.45.1 - Git 2.42.0
- Git LFS 3.5.1 - Git LFS 3.4.0
- Git-ftp 1.6.0 - Git-ftp 1.6.0
- Haveged 1.9.1 - Haveged 1.9.1
- Heroku 8.11.5 - Heroku 8.5.0
- HHVM (HipHop VM) 4.172.1 - HHVM (HipHop VM) 4.172.1
- jq 1.6 - jq 1.6
- Kind 0.23.0 - Kind 0.20.0
- Kubectl 1.30.1 - Kubectl 1.28.2
- Kustomize 5.4.1 - Kustomize 5.1.1
- Leiningen 2.11.2 - Leiningen 2.10.0
- MediaInfo 19.09 - MediaInfo 19.09
- Mercurial 5.3.1 - Mercurial 5.3.1
- Minikube 1.33.1 - Minikube 1.31.2
- n 9.2.3 - n 9.1.0
- Newman 6.1.2 - Newman 6.0.0
- nvm 0.39.7 - nvm 0.39.5
- OpenSSL 1.1.1f-1ubuntu2.22 - OpenSSL 1.1.1f-1ubuntu2.19
- Packer 1.10.3 - Packer 1.9.4
- Parcel 2.12.0 - Parcel 2.9.3
- PhantomJS 2.1.1 2.1.1 - PhantomJS 2.1.1 2.1.1
- Podman 3.4.2 - Podman 3.4.2
- Pulumi 3.116.1 - Pulumi 3.86.0
- R 4.4.0 - R 4.3.1
- Skopeo 1.5.0 - Skopeo 1.5.0
- Sphinx Open Source Search Server 2.2.11 - Sphinx Open Source Search Server 2.2.11
- SVN 1.13.0 - SVN 1.13.0
- Terraform 1.8.3 - Terraform 1.5.7
- yamllint 1.35.1 - yamllint 1.32.0
- yq 4.44.1 - yq 4.35.2
- zstd 1.5.6 - zstd 1.5.5
### CLI Tools ### CLI Tools
- Alibaba Cloud CLI 3.0.174 - Alibaba Cloud CLI 3.0.174
- AWS CLI 2.15.51 - AWS CLI 2.13.22
- AWS CLI Session Manager Plugin 1.2.553.0 - AWS CLI Session Manager Plugin 1.2.497.0
- AWS SAM CLI 1.116.0 - AWS SAM CLI 1.97.0
- Azure CLI 2.60.0 - Azure CLI 2.53.0
- Azure CLI (azure-devops) 1.0.1 - Azure CLI (azure-devops) 0.26.0
- GitHub CLI 2.49.2 - GitHub CLI 2.35.0
- Google Cloud CLI 476.0.0 - Google Cloud CLI 448.0.0
- Netlify CLI 17.23.5 - Netlify CLI 16.4.2
- OpenShift CLI 4.15.13 - OpenShift CLI 4.13.13
- ORAS CLI 1.1.0 - ORAS CLI 1.1.0
- Vercel CLI 34.2.0 - Vercel CLI 32.3.1
### Java ### Java
| Version | Environment Variable | | Version | Environment Variable |
| ------------------- | -------------------- | | ------------------- | -------------------- |
| 8.0.412+8 | JAVA_HOME_8_X64 | | 8.0.382+5 | JAVA_HOME_8_X64 |
| 11.0.23+9 (default) | JAVA_HOME_11_X64 | | 11.0.20+1 (default) | JAVA_HOME_11_X64 |
| 17.0.11+9 | JAVA_HOME_17_X64 | | 17.0.8+1 | JAVA_HOME_17_X64 |
| 21.0.3+9 | JAVA_HOME_21_X64 |
### PHP Tools ### PHP Tools
- PHP: 7.4.33, 8.0.30, 8.1.28, 8.2.19, 8.3.7 - PHP: 7.4.33, 8.0.30, 8.1.23, 8.2.10
- Composer 2.7.6 - Composer 2.6.4
- PHPUnit 8.5.38 - PHPUnit 8.5.34
``` ```
Both Xdebug and PCOV extensions are installed, but only Xdebug is enabled. Both Xdebug and PCOV extensions are installed, but only Xdebug is enabled.
``` ```
### Haskell Tools ### Haskell Tools
- Cabal 3.10.3.0 - Cabal 3.10.1.0
- GHC 9.10.1 - GHC 9.6.3
- GHCup 0.1.22.0 - GHCup 0.1.19.4
- Stack 2.15.7 - Stack 2.13.1
### Rust Tools ### Rust Tools
- Cargo 1.78.0 - Cargo 1.72.1
- Rust 1.78.0 - Rust 1.72.1
- Rustdoc 1.78.0 - Rustdoc 1.72.1
- Rustup 1.27.1 - Rustup 1.26.0
#### Packages #### Packages
- Bindgen 0.69.4 - Bindgen 0.68.1
- Cargo audit 0.20.0 - Cargo audit 0.18.2
- Cargo clippy 0.1.78 - Cargo clippy 0.1.72
- Cargo outdated 0.15.0 - Cargo outdated 0.13.1
- Cbindgen 0.26.0 - Cbindgen 0.26.0
- Rustfmt 1.7.0 - Rustfmt 1.6.0
### Browsers and Drivers ### Browsers and Drivers
- Google Chrome 125.0.6422.60 - Google Chrome 117.0.5938.132
- ChromeDriver 125.0.6422.60 - ChromeDriver 117.0.5938.92
- Chromium 125.0.6422.0 - Chromium 117.0.5938.0
- Microsoft Edge 124.0.2478.105 - Microsoft Edge 117.0.2045.47
- Microsoft Edge WebDriver 124.0.2478.105 - Microsoft Edge WebDriver 117.0.2045.47
- Selenium server 4.21.0 - Selenium server 4.13.0
- Mozilla Firefox 126.0 - Mozilla Firefox 118.0.1
- Geckodriver 0.34.0 - Geckodriver 0.33.0
#### Environment variables #### Environment variables
| Name | Value | | Name | Value |
@@ -184,15 +183,15 @@ Both Xdebug and PCOV extensions are installed, but only Xdebug is enabled.
| SELENIUM_JAR_PATH | /usr/share/java/selenium-server.jar | | SELENIUM_JAR_PATH | /usr/share/java/selenium-server.jar |
### .NET Tools ### .NET Tools
- .NET Core SDK: 6.0.422, 7.0.409, 8.0.300 - .NET Core SDK: 6.0.414, 7.0.111, 7.0.203, 7.0.308, 7.0.401
- nbgv 3.6.133+2d32d93cb1 - nbgv 3.6.133+2d32d93cb1
### Databases ### Databases
- MongoDB 5.0.26 - MongoDB 5.0.21
- sqlite3 3.31.1 - sqlite3 3.31.1
#### PostgreSQL #### PostgreSQL
- PostgreSQL 14.12 - PostgreSQL 14.9
``` ```
User: postgres User: postgres
PostgreSQL service is disabled by default. PostgreSQL service is disabled by default.
@@ -200,7 +199,7 @@ Use the following command as a part of your job to start the service: 'sudo syst
``` ```
#### MySQL #### MySQL
- MySQL 8.0.36-0ubuntu0.20.04.1 - MySQL 8.0.34-0ubuntu0.20.04.1
``` ```
User: root User: root
Password: root Password: root
@@ -210,49 +209,53 @@ Use the following command as a part of your job to start the service: 'sudo syst
#### MS SQL #### MS SQL
- sqlcmd 17.10.0001.1 - sqlcmd 17.10.0001.1
- SqlPackage 162.2.111.2 - SqlPackage 162.0.52.1
### Cached Tools ### Cached Tools
#### Go #### Go
- 1.20.14 - 1.19.13
- 1.21.10 - 1.20.8
- 1.22.3 - 1.21.1
#### Node.js #### Node.js
- 14.21.3
- 16.20.2 - 16.20.2
- 18.20.2 - 18.18.0
- 20.13.1 - 20.8.0
#### Python #### Python
- 3.7.17 - 3.7.17
- 3.8.18 - 3.8.18
- 3.9.19 - 3.9.18
- 3.10.14 - 3.10.13
- 3.11.9 - 3.11.5
- 3.12.3
#### PyPy #### PyPy
- 2.7.18 [PyPy 7.3.16] - 2.7.18 [PyPy 7.3.13]
- 3.6.12 [PyPy 7.3.3] - 3.6.12 [PyPy 7.3.3]
- 3.7.13 [PyPy 7.3.9] - 3.7.13 [PyPy 7.3.9]
- 3.8.16 [PyPy 7.3.11] - 3.8.16 [PyPy 7.3.11]
- 3.9.19 [PyPy 7.3.16] - 3.9.18 [PyPy 7.3.13]
- 3.10.14 [PyPy 7.3.16] - 3.10.13 [PyPy 7.3.13]
#### Ruby #### Ruby
- 3.0.7 - 2.5.9
- 3.1.5 - 2.6.10
- 2.7.8
- 3.0.6
- 3.1.4
### PowerShell Tools ### PowerShell Tools
- PowerShell 7.4.1 - PowerShell 7.2.14
#### PowerShell Modules #### PowerShell Modules
- Az: 11.3.1 - Az: 9.3.0
- Az (Cached): 3.1.0.zip, 4.4.0.zip, 5.9.0.zip, 6.6.0.zip, 7.5.0.zip
- MarkdownPS: 1.9 - MarkdownPS: 1.9
- Microsoft.Graph: 2.19.0 - Microsoft.Graph: 2.6.1
- Pester: 5.5.0 - Pester: 5.5.0
- PSScriptAnalyzer: 1.22.0 - PSScriptAnalyzer: 1.21.0
### Web Servers ### Web Servers
| Name | Version | ConfigFile | ServiceStatus | ListenPort | | Name | Version | ConfigFile | ServiceStatus | ListenPort |
@@ -262,16 +265,20 @@ Use the following command as a part of your job to start the service: 'sudo syst
| nginx | 1.18.0 | /etc/nginx/nginx.conf | inactive | 80 | | nginx | 1.18.0 | /etc/nginx/nginx.conf | inactive | 80 |
### Android ### Android
| Package Name | Version | | Package Name | Version |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Android Command Line Tools | 9.0 | | Android Command Line Tools | 9.0 |
| Android SDK Build-tools | 34.0.0<br>33.0.0 33.0.1 33.0.2 33.0.3<br>32.0.0<br>31.0.0 | | Android Emulator | 32.1.15 |
| Android SDK Platforms | android-34-ext8 (rev 1)<br>android-34-ext11 (rev 1)<br>android-34 (rev 3)<br>android-33-ext5 (rev 1)<br>android-33-ext4 (rev 1)<br>android-33 (rev 3)<br>android-32 (rev 1)<br>android-31 (rev 1) | | Android SDK Build-tools | 34.0.0<br>33.0.0 33.0.1 33.0.2<br>32.0.0<br>31.0.0<br>30.0.0 30.0.1 30.0.2 30.0.3<br>29.0.0 29.0.1 29.0.2 29.0.3<br>28.0.0 28.0.1 28.0.2 28.0.3<br>27.0.0 27.0.1 27.0.2 27.0.3 |
| Android Support Repository | 47.0.0 | | Android SDK Platform-Tools | 34.0.4 |
| CMake | 3.10.2<br>3.18.1<br>3.22.1 | | Android SDK Platforms | android-34 (rev 2)<br>android-33-ext5 (rev 1)<br>android-33-ext4 (rev 1)<br>android-33 (rev 3)<br>android-32 (rev 1)<br>android-31 (rev 1)<br>android-30 (rev 3)<br>android-29 (rev 5)<br>android-28 (rev 6)<br>android-27 (rev 3) |
| Google Play services | 49 | | Android SDK Tools | 26.1.1 |
| Google Repository | 58 | | Android Support Repository | 47.0.0 |
| NDK | 24.0.8215888<br>25.2.9519653 (default)<br>26.3.11579264 | | CMake | 3.10.2<br>3.18.1<br>3.22.1 |
| Google Play services | 49 |
| Google Repository | 58 |
| NDK | 23.2.8568313<br>24.0.8215888<br>25.2.9519653 (default)<br>26.0.10792818 |
| SDK Patch Applier v4 | 1 |
#### Environment variables #### Environment variables
| Name | Value | | Name | Value |
@@ -279,27 +286,34 @@ Use the following command as a part of your job to start the service: 'sudo syst
| ANDROID_HOME | /usr/local/lib/android/sdk | | ANDROID_HOME | /usr/local/lib/android/sdk |
| ANDROID_NDK | /usr/local/lib/android/sdk/ndk/25.2.9519653 | | ANDROID_NDK | /usr/local/lib/android/sdk/ndk/25.2.9519653 |
| ANDROID_NDK_HOME | /usr/local/lib/android/sdk/ndk/25.2.9519653 | | ANDROID_NDK_HOME | /usr/local/lib/android/sdk/ndk/25.2.9519653 |
| ANDROID_NDK_LATEST_HOME | /usr/local/lib/android/sdk/ndk/26.3.11579264 | | ANDROID_NDK_LATEST_HOME | /usr/local/lib/android/sdk/ndk/26.0.10792818 |
| ANDROID_NDK_ROOT | /usr/local/lib/android/sdk/ndk/25.2.9519653 | | ANDROID_NDK_ROOT | /usr/local/lib/android/sdk/ndk/25.2.9519653 |
| ANDROID_SDK_ROOT | /usr/local/lib/android/sdk | | ANDROID_SDK_ROOT | /usr/local/lib/android/sdk |
### Cached Docker images ### Cached Docker images
| Repository:Tag | Digest | Created | | Repository:Tag | Digest | Created |
| -------------------- | ------------------------------------------------------------------------ | ---------- | | ----------------------- | ------------------------------------------------------------------------ | ---------- |
| alpine:3.16 | sha256:452e7292acee0ee16c332324d7de05fa2c99f9994ecc9f0779c602916a672ae4 | 2024-01-27 | | alpine:3.16 | sha256:a8cbb8c69ee71561f4b69c066bad07f7e510caaa523da26fbfc606b10bd7934b | 2023-08-07 |
| alpine:3.17 | sha256:53cf9478b76f4c8fae126acbdfb79bed6e69e628faff572ebe4a029d3d247d98 | 2024-01-27 | | alpine:3.17 | sha256:f71a5f071694a785e064f05fed657bf8277f1b2113a8ed70c90ad486d6ee54dc | 2023-08-07 |
| alpine:3.18 | sha256:11e21d7b981a59554b3f822c49f6e9f57b6068bb74f49c4cd5cc4c663c7e5160 | 2024-01-27 | | alpine:3.18 | sha256:eece025e432126ce23f223450a0326fbebde39cdf496a85d8c016293fc851978 | 2023-09-28 |
| debian:10 | sha256:6e7bd55a5705914837aad8db01b349f4617510c11e47ccae8e87f6f14e489626 | 2024-05-14 | | buildpack-deps:bullseye | sha256:8ee57204a7af0468a61a3e47fbf8412d6ad1d479050bb702d99fd1d3664d7173 | 2023-09-20 |
| debian:11 | sha256:2c7a92a41cb814c00e7d455b2bc0c90ccdb9a4ced2ffdc10e562c7a84a186032 | 2024-05-14 | | buildpack-deps:buster | sha256:0bc568b581ed3e9a13f818fd20258edb623cf67e6d354afadf77fb9095d798a2 | 2023-09-20 |
| debian:9 | sha256:c5c5200ff1e9c73ffbf188b4a67eb1c91531b644856b4aefe86a58d2f0cb05be | 2022-06-23 | | buildpack-deps:stretch | sha256:78e995165a5788c2f55aed6e548d8f6c1534830d4310c870408fccb2da8c5b2e | 2022-06-23 |
| moby/buildkit:latest | sha256:9194b5ec1be368f41c516df7f93f7f540630ea06136056b2ffebb62226ed4ad6 | 2024-04-25 | | debian:10 | sha256:484cc8ab0d73f513e3f9bacd03424eb081bd90f594d7ebde42587843fdc242f3 | 2023-09-20 |
| node:16 | sha256:f77a1aef2da8d83e45ec990f45df50f1a286c5fe8bbfb8c6e4246c6389705c0b | 2023-09-07 | | debian:11 | sha256:54d33aaad0bc936a9a40d856764c7bc35c0afaa9cab51f88bb95f6cd8004438d | 2023-09-20 |
| node:16-alpine | sha256:a1f9d027912b58a7c75be7716c97cfbc6d3099f3a97ed84aa490be9dee20e787 | 2023-08-10 | | debian:9 | sha256:c5c5200ff1e9c73ffbf188b4a67eb1c91531b644856b4aefe86a58d2f0cb05be | 2022-06-23 |
| node:18 | sha256:5bac3a1edff13e76586b8eaef1d411fcd80e4f18cce5bc40ea6993245e0721ec | 2024-05-14 | | moby/buildkit:latest | sha256:890dcae054e3039f6c6b76bf0da80a130fa6e6bb1f3624063ef0210ac2c57b06 | 2023-08-24 |
| node:18-alpine | sha256:4837c2ac8998cf172f5892fb45f229c328e4824c43c8506f8ba9c7996d702430 | 2024-04-23 | | node:14 | sha256:a158d3b9b4e3fa813fa6c8c590b8f0a860e015ad4e59bbce5744d2f6fd8461aa | 2023-04-12 |
| node:20 | sha256:d6925dc84f8c0d1c1f8df4ea6a9a54e57d430241cb734b1b0c45ed6d26e8e9c0 | 2024-05-14 | | node:14-alpine | sha256:434215b487a329c9e867202ff89e704d3a75e554822e07f3e0c0f9e606121b33 | 2023-03-29 |
| node:20-alpine | sha256:291e84d956f1aff38454bbd3da38941461ad569a185c20aa289f71f37ea08e23 | 2024-05-09 | | node:16 | sha256:f77a1aef2da8d83e45ec990f45df50f1a286c5fe8bbfb8c6e4246c6389705c0b | 2023-09-07 |
| ubuntu:20.04 | sha256:874aca52f79ae5f8258faff03e10ce99ae836f6e7d2df6ecd3da5c1cad3a912b | 2024-04-27 | | node:16-alpine | sha256:a1f9d027912b58a7c75be7716c97cfbc6d3099f3a97ed84aa490be9dee20e787 | 2023-08-10 |
| node:18 | sha256:ee0a21d64211d92d4340b225c556e9ef1a8bce1d5b03b49f5f07bf1dbbaa5626 | 2023-09-21 |
| node:18-alpine | sha256:a315556d82ef54561e54fca7d8ee333382de183d4e56841dcefcd05b55310f46 | 2023-09-29 |
| node:20 | sha256:6b3f9aa7eefa8d4c93d43914e78aa2bfea9a12808b0059e5da78854dfa8b8768 | 2023-09-29 |
| node:20-alpine | sha256:37750e51d61bef92165b2e29a77da4277ba0777258446b7a9c99511f119db096 | 2023-09-29 |
| ubuntu:16.04 | sha256:1f1a2d56de1d604801a9671f301190704c25d604a416f59e03c04f5c6ffee0d6 | 2021-08-31 |
| ubuntu:18.04 | sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98 | 2023-05-30 |
| ubuntu:20.04 | sha256:33a5cc25d22c45900796a1aca487ad7a7cb09f09ea00b779e3b2026b4fc2faba | 2023-08-01 |
### Installed apt packages ### Installed apt packages
| Name | Version | | Name | Version |
@@ -308,19 +322,18 @@ Use the following command as a part of your job to start the service: 'sudo syst
| aria2 | 1.35.0-1build1 | | aria2 | 1.35.0-1build1 |
| autoconf | 2.69-11.1 | | autoconf | 2.69-11.1 |
| automake | 1:1.16.1-4ubuntu6 | | automake | 1:1.16.1-4ubuntu6 |
| binutils | 2.34-6ubuntu1.9 | | binutils | 2.34-6ubuntu1.6 |
| bison | 2:3.5.1+dfsg-1 | | bison | 2:3.5.1+dfsg-1 |
| brotli | 1.0.7-6ubuntu0.1 | | brotli | 1.0.7-6ubuntu0.1 |
| bzip2 | 1.0.8-2 | | bzip2 | 1.0.8-2 |
| coreutils | 8.30-3ubuntu2 | | coreutils | 8.30-3ubuntu2 |
| curl | 7.68.0-1ubuntu2.22 | | curl | 7.68.0-1ubuntu2.19 |
| dbus | 1.12.16-2ubuntu2.3 | | dbus | 1.12.16-2ubuntu2.3 |
| dnsutils | 1:9.16.48-0ubuntu0.20.04.1 | | dnsutils | 1:9.16.1-0ubuntu2.16 |
| dpkg | 1.19.7ubuntu3.2 | | dpkg | 1.19.7ubuntu3.2 |
| dpkg-dev | 1.19.7ubuntu3.2 | | dpkg-dev | 1.19.7ubuntu3.2 |
| fakeroot | 1.24-1 | | fakeroot | 1.24-1 |
| file | 1:5.38-4 | | file | 1:5.38-4 |
| findutils | 4.7.0-1ubuntu1 |
| flex | 2.6.4-6.2 | | flex | 2.6.4-6.2 |
| fonts-noto-color-emoji | 0\~20200916-1\~ubuntu20.04.1 | | fonts-noto-color-emoji | 0\~20200916-1\~ubuntu20.04.1 |
| ftp | 0.17-34.1 | | ftp | 0.17-34.1 |
@@ -330,35 +343,35 @@ Use the following command as a part of your job to start the service: 'sudo syst
| haveged | 1.9.1-6ubuntu1 | | haveged | 1.9.1-6ubuntu1 |
| imagemagick | 8:6.9.10.23+dfsg-2.1ubuntu11.9 | | imagemagick | 8:6.9.10.23+dfsg-2.1ubuntu11.9 |
| iproute2 | 5.5.0-1ubuntu1 | | iproute2 | 5.5.0-1ubuntu1 |
| iputils-ping | 3:20190709-3ubuntu1 | | iputils-ping | 3:20190709-3 |
| jq | 1.6-1ubuntu0.20.04.1 | | jq | 1.6-1ubuntu0.20.04.1 |
| lib32z1 | 1:1.2.11.dfsg-2ubuntu1.5 | | lib32z1 | 1:1.2.11.dfsg-2ubuntu1.5 |
| libc++-dev | 1:10.0-50\~exp1 | | libc++-dev | 1:10.0-50\~exp1 |
| libc++abi-dev | 1:10.0-50\~exp1 | | libc++abi-dev | 1:10.0-50\~exp1 |
| libc6-dev | 2.31-0ubuntu9.15 | | libc6-dev | 2.31-0ubuntu9.9 |
| libcurl4 | 7.68.0-1ubuntu2.22 | | libcurl4 | 7.68.0-1ubuntu2.19 |
| libgbm-dev | 21.2.6-0ubuntu0.1\~20.04.2 | | libgbm-dev | 21.2.6-0ubuntu0.1\~20.04.2 |
| libgconf-2-4 | 3.2.6-6ubuntu1 | | libgconf-2-4 | 3.2.6-6ubuntu1 |
| libgsl-dev | 2.5+dfsg-6+deb10u1build0.20.04.1 | | libgsl-dev | 2.5+dfsg-6build1 |
| libgtk-3-0 | 3.24.20-0ubuntu1.1 | | libgtk-3-0 | 3.24.20-0ubuntu1.1 |
| libmagic-dev | 1:5.38-4 | | libmagic-dev | 1:5.38-4 |
| libmagickcore-dev | 8:6.9.10.23+dfsg-2.1ubuntu11.9 | | libmagickcore-dev | 8:6.9.10.23+dfsg-2.1ubuntu11.9 |
| libmagickwand-dev | 8:6.9.10.23+dfsg-2.1ubuntu11.9 | | libmagickwand-dev | 8:6.9.10.23+dfsg-2.1ubuntu11.9 |
| libsecret-1-dev | 0.20.4-0ubuntu1 | | libsecret-1-dev | 0.20.4-0ubuntu1 |
| libsqlite3-dev | 3.31.1-4ubuntu0.6 | | libsqlite3-dev | 3.31.1-4ubuntu0.5 |
| libtool | 2.4.6-14 | | libtool | 2.4.6-14 |
| libunwind8 | 1.2.1-9ubuntu0.1 | | libunwind8 | 1.2.1-9ubuntu0.1 |
| libxkbfile-dev | 1:1.1.0-1 | | libxkbfile-dev | 1:1.1.0-1 |
| libxss1 | 1:1.2.3-1 | | libxss1 | 1:1.2.3-1 |
| libyaml-dev | 0.2.2-1 | | libyaml-dev | 0.2.2-1 |
| locales | 2.31-0ubuntu9.15 | | locales | 2.31-0ubuntu9.9 |
| m4 | 1.4.18-4 | | m4 | 1.4.18-4 |
| make | 4.2.1-1.2 | | make | 4.2.1-1.2 |
| mediainfo | 19.09-1build1 | | mediainfo | 19.09-1build1 |
| mercurial | 5.3.1-1ubuntu1 | | mercurial | 5.3.1-1ubuntu1 |
| net-tools | 1.60+git20180626.aebd88e-1ubuntu1 | | net-tools | 1.60+git20180626.aebd88e-1ubuntu1 |
| netcat | 1.206-1ubuntu1 | | netcat | 1.206-1ubuntu1 |
| openssh-client | 1:8.2p1-4ubuntu0.11 | | openssh-client | 1:8.2p1-4ubuntu0.9 |
| p7zip-full | 16.02+dfsg-7build1 | | p7zip-full | 16.02+dfsg-7build1 |
| p7zip-rar | 16.02-3build1 | | p7zip-rar | 16.02-3build1 |
| parallel | 20161222-1.1 | | parallel | 20161222-1.1 |
@@ -372,23 +385,23 @@ Use the following command as a part of your job to start the service: 'sudo syst
| rsync | 3.1.3-8ubuntu0.7 | | rsync | 3.1.3-8ubuntu0.7 |
| shellcheck | 0.7.0-2build2 | | shellcheck | 0.7.0-2build2 |
| sphinxsearch | 2.2.11-2ubuntu2 | | sphinxsearch | 2.2.11-2ubuntu2 |
| sqlite3 | 3.31.1-4ubuntu0.6 | | sqlite3 | 3.31.1-4ubuntu0.5 |
| ssh | 1:8.2p1-4ubuntu0.11 | | ssh | 1:8.2p1-4ubuntu0.9 |
| sshpass | 1.06-1 | | sshpass | 1.06-1 |
| subversion | 1.13.0-3ubuntu0.2 | | subversion | 1.13.0-3ubuntu0.2 |
| sudo | 1.8.31-1ubuntu1.5 | | sudo | 1.8.31-1ubuntu1.5 |
| swig | 4.0.1-5build1 | | swig | 4.0.1-5build1 |
| tar | 1.30+dfsg-7ubuntu0.20.04.4 | | tar | 1.30+dfsg-7ubuntu0.20.04.3 |
| telnet | 0.17-41.2build1 | | telnet | 0.17-41.2build1 |
| texinfo | 6.7.0.dfsg.2-5 | | texinfo | 6.7.0.dfsg.2-5 |
| time | 1.7-25.1build1 | | time | 1.7-25.1build1 |
| tk | 8.6.9+1 | | tk | 8.6.9+1 |
| tzdata | 2024a-0ubuntu0.20.04 | | tzdata | 2023c-0ubuntu0.20.04.2 |
| unzip | 6.0-25ubuntu1.2 | | unzip | 6.0-25ubuntu1.1 |
| upx | 3.95-2build1 | | upx | 3.95-2build1 |
| wget | 1.20.3-1ubuntu2 | | wget | 1.20.3-1ubuntu2 |
| xorriso | 1.5.2-1 | | xorriso | 1.5.2-1 |
| xvfb | 2:1.20.13-1ubuntu1\~20.04.17 | | xvfb | 2:1.20.13-1ubuntu1\~20.04.8 |
| xz-utils | 5.2.4-1ubuntu1.1 | | xz-utils | 5.2.4-1ubuntu1.1 |
| zip | 3.0-11build1 | | zip | 3.0-11build1 |
| zsync | 0.6.2-3ubuntu1 | | zsync | 0.6.2-3ubuntu1 |
@@ -1,47 +1,47 @@
| Announcements | | Announcements |
|-| |-|
| [Ubuntu 24.04 is now available](https://github.com/actions/runner-images/issues/9848) | | [[All OS] Android NDK r23 will be removed from images on October 9](https://github.com/actions/runner-images/issues/8383) |
| [[Ubuntu, Windows] Docker Compose v1 will be removed from images on July, 9](https://github.com/actions/runner-images/issues/9692) | | [[All OS] hub utility will be removed on October 2](https://github.com/actions/runner-images/issues/8362) |
*** ***
# Ubuntu 22.04 # Ubuntu 22.04
- OS Version: 22.04.4 LTS - OS Version: 22.04.3 LTS
- Kernel Version: 6.5.0-1021-azure - Kernel Version: 6.2.0-1012-azure
- Image Version: 20240516.1.0 - Image Version: 20231001.1.0
- Systemd version: 249.11-0ubuntu3.12 - Systemd version: 249.11-0ubuntu3.10
## Installed Software ## Installed Software
### Language and Runtime ### Language and Runtime
- Bash 5.1.16(1)-release - Bash 5.1.16(1)-release
- Clang: 13.0.1, 14.0.0, 15.0.7 - Clang: 13.0.1, 14.0.0
- Clang-format: 13.0.1, 14.0.0, 15.0.7 - Clang-format: 13.0.1, 14.0.0
- Clang-tidy: 13.0.1, 14.0.0, 15.0.7 - Clang-tidy: 13.0.1, 14.0.0, 15.0.7
- Dash 0.5.11+git20210903+057cd650a4ed-3build1 - Dash 0.5.11+git20210903+057cd650a4ed-3build1
- GNU C++: 10.5.0, 11.4.0, 12.3.0 - GNU C++: 9.5.0, 10.5.0, 11.4.0, 12.3.0
- GNU Fortran: 10.5.0, 11.4.0, 12.3.0 - GNU Fortran: 9.5.0, 10.5.0, 11.4.0, 12.3.0
- Julia 1.10.3 - Julia 1.9.3
- Kotlin 1.9.24-release-822 - Kotlin 1.9.10-release-459
- Mono 6.12.0.200 - Mono 6.12.0.200
- MSBuild 16.10.1.31701 (Mono 6.12.0.200) - MSBuild 16.10.1.31701 (Mono 6.12.0.200)
- Node.js 18.20.2 - Node.js 18.18.0
- Perl 5.34.0 - Perl 5.34.0
- Python 3.10.12 - Python 3.10.12
- Ruby 3.0.2p107 - Ruby 3.0.2p107
- Swift 5.10 - Swift 5.9
### Package Management ### Package Management
- cpan 1.64 - cpan 1.64
- Helm 3.14.4 - Helm 3.13.0
- Homebrew 4.3.0 - Homebrew 4.1.13
- Miniconda 24.3.0 - Miniconda 23.5.2
- Npm 10.5.0 - Npm 9.8.1
- NuGet 6.6.1.2 - NuGet 6.6.1.2
- Pip 22.0.2 - Pip 22.0.2
- Pip3 22.0.2 - Pip3 22.0.2
- Pipx 1.5.0 - Pipx 1.2.0
- RubyGems 3.3.5 - RubyGems 3.3.5
- Vcpkg (build from commit 66a252f70) - Vcpkg (build from commit c6d6efed3)
- Yarn 1.22.22 - Yarn 1.22.19
#### Environment variables #### Environment variables
| Name | Value | | Name | Value |
@@ -58,118 +58,114 @@ to accomplish this.
``` ```
### Project Management ### Project Management
- Ant 1.10.12 - Lerna 7.3.0
- Gradle 8.7
- Lerna 8.1.3
- Maven 3.8.8 - Maven 3.8.8
- Sbt 1.10.0
### Tools ### Tools
- Ansible 2.16.6 - Ansible 2.15.4
- apt-fast 1.10.0 - apt-fast 1.9.12
- AzCopy 10.24.0 - available by `azcopy` and `azcopy10` aliases - AzCopy 10.21.0 - available by `azcopy` and `azcopy10` aliases
- Bazel 7.1.2 - Bazel 6.3.2
- Bazelisk 1.19.0 - Bazelisk 1.18.0
- Bicep 0.27.1 - Bicep 0.21.1
- Buildah 1.23.1 - Buildah 1.23.1
- CMake 3.29.3 - CMake 3.27.6
- CodeQL Action Bundle 2.17.2 - CodeQL Action Bundles 2.14.5 2.14.6
- Docker Amazon ECR Credential Helper 0.8.0 - Docker Amazon ECR Credential Helper 0.7.1
- Docker Compose v1 1.29.2 - Docker Compose v1 1.29.2
- Docker Compose v2 2.23.3 - Docker Compose v2 2.22.0
- Docker-Buildx 0.14.0 - Docker-Buildx 0.11.2
- Docker Client 24.0.9 - Docker Client 24.0.6
- Docker Server 24.0.9 - Docker Server 24.0.6
- Fastlane 2.220.0 - Fastlane 2.216.0
- Git 2.45.1 - Git 2.42.0
- Git LFS 3.5.1 - Git LFS 3.4.0
- Git-ftp 1.6.0 - Git-ftp 1.6.0
- Haveged 1.9.14 - Haveged 1.9.14
- Heroku 8.11.5 - Heroku 8.5.0
- jq 1.6 - jq 1.6
- Kind 0.23.0 - Kind 0.20.0
- Kubectl 1.30.1 - Kubectl 1.28.2
- Kustomize 5.4.1 - Kustomize 5.1.1
- Leiningen 2.11.2 - Leiningen 2.10.0
- MediaInfo 21.09 - MediaInfo 21.09
- Mercurial 6.1.1 - Mercurial 6.1.1
- Minikube 1.33.1 - Minikube 1.31.2
- n 9.2.3 - n 9.1.0
- Newman 6.1.2 - Newman 6.0.0
- nvm 0.39.7 - nvm 0.39.5
- OpenSSL 3.0.2-0ubuntu1.15 - OpenSSL 3.0.2-0ubuntu1.10
- Packer 1.10.3 - Packer 1.9.4
- Parcel 2.12.0 - Parcel 2.9.3
- Podman 3.4.4 - Podman 3.4.4
- Pulumi 3.116.1 - Pulumi 3.86.0
- R 4.4.0 - R 4.3.1
- Skopeo 1.4.1 - Skopeo 1.4.1
- Sphinx Open Source Search Server 2.2.11 - Sphinx Open Source Search Server 2.2.11
- SVN 1.14.1 - SVN 1.14.1
- Terraform 1.8.3 - Terraform 1.5.7
- yamllint 1.35.1 - yamllint 1.32.0
- yq 4.44.1 - yq 4.35.2
- zstd 1.5.6 - zstd 1.5.5
### CLI Tools ### CLI Tools
- Alibaba Cloud CLI 3.0.205 - Alibaba Cloud CLI 3.0.181
- AWS CLI 2.15.51 - AWS CLI 2.13.22
- AWS CLI Session Manager Plugin 1.2.553.0 - AWS CLI Session Manager Plugin 1.2.497.0
- AWS SAM CLI 1.116.0 - AWS SAM CLI 1.97.0
- Azure CLI 2.60.0 - Azure CLI 2.53.0
- Azure CLI (azure-devops) 1.0.1 - Azure CLI (azure-devops) 0.26.0
- GitHub CLI 2.49.2 - GitHub CLI 2.35.0
- Google Cloud CLI 476.0.0 - Google Cloud CLI 448.0.0
- Netlify CLI 17.23.5 - Netlify CLI 16.4.2
- OpenShift CLI 4.15.13 - OpenShift CLI 4.13.13
- ORAS CLI 1.1.0 - ORAS CLI 1.1.0
- Vercel CLI 34.2.0 - Vercel CLI 32.3.1
### Java ### Java
| Version | Environment Variable | | Version | Environment Variable |
| ------------------- | -------------------- | | ------------------- | -------------------- |
| 8.0.412+8 | JAVA_HOME_8_X64 | | 8.0.382+5 | JAVA_HOME_8_X64 |
| 11.0.23+9 (default) | JAVA_HOME_11_X64 | | 11.0.20+1 (default) | JAVA_HOME_11_X64 |
| 17.0.11+9 | JAVA_HOME_17_X64 | | 17.0.8+1 | JAVA_HOME_17_X64 |
| 21.0.3+9 | JAVA_HOME_21_X64 |
### PHP Tools ### PHP Tools
- PHP: 8.1.2 - PHP: 8.1.2
- Composer 2.7.6 - Composer 2.6.4
- PHPUnit 8.5.38 - PHPUnit 8.5.34
``` ```
Both Xdebug and PCOV extensions are installed, but only Xdebug is enabled. Both Xdebug and PCOV extensions are installed, but only Xdebug is enabled.
``` ```
### Haskell Tools ### Haskell Tools
- Cabal 3.10.3.0 - Cabal 3.10.1.0
- GHC 9.10.1 - GHC 9.6.3
- GHCup 0.1.22.0 - GHCup 0.1.19.4
- Stack 2.15.7 - Stack 2.13.1
### Rust Tools ### Rust Tools
- Cargo 1.78.0 - Cargo 1.72.1
- Rust 1.78.0 - Rust 1.72.1
- Rustdoc 1.78.0 - Rustdoc 1.72.1
- Rustup 1.27.1 - Rustup 1.26.0
#### Packages #### Packages
- Bindgen 0.69.4 - Bindgen 0.68.1
- Cargo audit 0.20.0 - Cargo audit 0.18.2
- Cargo clippy 0.1.78 - Cargo clippy 0.1.72
- Cargo outdated 0.15.0 - Cargo outdated 0.13.1
- Cbindgen 0.26.0 - Cbindgen 0.26.0
- Rustfmt 1.7.0 - Rustfmt 1.6.0
### Browsers and Drivers ### Browsers and Drivers
- Google Chrome 125.0.6422.60 - Google Chrome 117.0.5938.132
- ChromeDriver 125.0.6422.60 - ChromeDriver 117.0.5938.92
- Chromium 125.0.6422.0 - Chromium 117.0.5938.0
- Microsoft Edge 124.0.2478.105 - Microsoft Edge 117.0.2045.47
- Microsoft Edge WebDriver 124.0.2478.105 - Microsoft Edge WebDriver 117.0.2045.47
- Selenium server 4.21.0 - Selenium server 4.13.0
- Mozilla Firefox 126.0 - Mozilla Firefox 118.0.1
- Geckodriver 0.34.0 - Geckodriver 0.33.0
#### Environment variables #### Environment variables
| Name | Value | | Name | Value |
@@ -180,14 +176,14 @@ Both Xdebug and PCOV extensions are installed, but only Xdebug is enabled.
| SELENIUM_JAR_PATH | /usr/share/java/selenium-server.jar | | SELENIUM_JAR_PATH | /usr/share/java/selenium-server.jar |
### .NET Tools ### .NET Tools
- .NET Core SDK: 6.0.422, 7.0.409, 8.0.300 - .NET Core SDK: 6.0.414, 7.0.111, 7.0.203, 7.0.308, 7.0.401
- nbgv 3.6.133+2d32d93cb1 - nbgv 3.6.133+2d32d93cb1
### Databases ### Databases
- sqlite3 3.37.2 - sqlite3 3.37.2
#### PostgreSQL #### PostgreSQL
- PostgreSQL 14.12 - PostgreSQL 14.9
``` ```
User: postgres User: postgres
PostgreSQL service is disabled by default. PostgreSQL service is disabled by default.
@@ -195,7 +191,7 @@ Use the following command as a part of your job to start the service: 'sudo syst
``` ```
#### MySQL #### MySQL
- MySQL 8.0.36-0ubuntu0.22.04.1 - MySQL 8.0.34-0ubuntu0.22.04.1
``` ```
User: root User: root
Password: root Password: root
@@ -205,46 +201,46 @@ Use the following command as a part of your job to start the service: 'sudo syst
#### MS SQL #### MS SQL
- sqlcmd 17.10.0001.1 - sqlcmd 17.10.0001.1
- SqlPackage 162.2.111.2 - SqlPackage 162.0.52.1
### Cached Tools ### Cached Tools
#### Go #### Go
- 1.20.14 - 1.19.13
- 1.21.10 - 1.20.8
- 1.22.3 - 1.21.1
#### Node.js #### Node.js
- 14.21.3
- 16.20.2 - 16.20.2
- 18.20.2 - 18.18.0
- 20.13.1 - 20.8.0
#### Python #### Python
- 3.7.17 - 3.7.17
- 3.8.18 - 3.8.18
- 3.9.19 - 3.9.18
- 3.10.14 - 3.10.13
- 3.11.9 - 3.11.5
- 3.12.3
#### PyPy #### PyPy
- 3.7.13 [PyPy 7.3.9] - 3.7.13 [PyPy 7.3.9]
- 3.8.16 [PyPy 7.3.11] - 3.8.16 [PyPy 7.3.11]
- 3.9.19 [PyPy 7.3.16] - 3.9.18 [PyPy 7.3.13]
- 3.10.14 [PyPy 7.3.16] - 3.10.13 [PyPy 7.3.13]
#### Ruby #### Ruby
- 3.1.5 - 3.1.4
### PowerShell Tools ### PowerShell Tools
- PowerShell 7.4.1 - PowerShell 7.2.14
#### PowerShell Modules #### PowerShell Modules
- Az: 11.3.1 - Az: 9.3.0
- MarkdownPS: 1.9 - MarkdownPS: 1.9
- Microsoft.Graph: 2.19.0 - Microsoft.Graph: 2.6.1
- Pester: 5.5.0 - Pester: 5.5.0
- PSScriptAnalyzer: 1.22.0 - PSScriptAnalyzer: 1.21.0
### Web Servers ### Web Servers
| Name | Version | ConfigFile | ServiceStatus | ListenPort | | Name | Version | ConfigFile | ServiceStatus | ListenPort |
@@ -253,16 +249,20 @@ Use the following command as a part of your job to start the service: 'sudo syst
| nginx | 1.18.0 | /etc/nginx/nginx.conf | inactive | 80 | | nginx | 1.18.0 | /etc/nginx/nginx.conf | inactive | 80 |
### Android ### Android
| Package Name | Version | | Package Name | Version |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Android Command Line Tools | 9.0 | | Android Command Line Tools | 9.0 |
| Android SDK Build-tools | 34.0.0<br>33.0.0 33.0.1 33.0.2 33.0.3<br>32.0.0<br>31.0.0 | | Android Emulator | 32.1.15 |
| Android SDK Platforms | android-34-ext8 (rev 1)<br>android-34-ext11 (rev 1)<br>android-34 (rev 3)<br>android-33-ext5 (rev 1)<br>android-33-ext4 (rev 1)<br>android-33 (rev 3)<br>android-32 (rev 1)<br>android-31 (rev 1) | | Android SDK Build-tools | 34.0.0<br>33.0.0 33.0.1 33.0.2<br>32.0.0<br>31.0.0<br>30.0.0 30.0.1 30.0.2 30.0.3<br>29.0.0 29.0.1 29.0.2 29.0.3<br>28.0.0 28.0.1 28.0.2 28.0.3<br>27.0.0 27.0.1 27.0.2 27.0.3 |
| Android Support Repository | 47.0.0 | | Android SDK Platform-Tools | 34.0.4 |
| CMake | 3.10.2<br>3.18.1<br>3.22.1 | | Android SDK Platforms | android-34 (rev 2)<br>android-33-ext5 (rev 1)<br>android-33-ext4 (rev 1)<br>android-33 (rev 3)<br>android-32 (rev 1)<br>android-31 (rev 1)<br>android-30 (rev 3)<br>android-29 (rev 5)<br>android-28 (rev 6)<br>android-27 (rev 3) |
| Google Play services | 49 | | Android SDK Tools | 26.1.1 |
| Google Repository | 58 | | Android Support Repository | 47.0.0 |
| NDK | 24.0.8215888<br>25.2.9519653 (default)<br>26.3.11579264 | | CMake | 3.10.2<br>3.18.1<br>3.22.1 |
| Google Play services | 49 |
| Google Repository | 58 |
| NDK | 23.2.8568313<br>24.0.8215888<br>25.2.9519653 (default)<br>26.0.10792818 |
| SDK Patch Applier v4 | 1 |
#### Environment variables #### Environment variables
| Name | Value | | Name | Value |
@@ -270,27 +270,32 @@ Use the following command as a part of your job to start the service: 'sudo syst
| ANDROID_HOME | /usr/local/lib/android/sdk | | ANDROID_HOME | /usr/local/lib/android/sdk |
| ANDROID_NDK | /usr/local/lib/android/sdk/ndk/25.2.9519653 | | ANDROID_NDK | /usr/local/lib/android/sdk/ndk/25.2.9519653 |
| ANDROID_NDK_HOME | /usr/local/lib/android/sdk/ndk/25.2.9519653 | | ANDROID_NDK_HOME | /usr/local/lib/android/sdk/ndk/25.2.9519653 |
| ANDROID_NDK_LATEST_HOME | /usr/local/lib/android/sdk/ndk/26.3.11579264 | | ANDROID_NDK_LATEST_HOME | /usr/local/lib/android/sdk/ndk/26.0.10792818 |
| ANDROID_NDK_ROOT | /usr/local/lib/android/sdk/ndk/25.2.9519653 | | ANDROID_NDK_ROOT | /usr/local/lib/android/sdk/ndk/25.2.9519653 |
| ANDROID_SDK_ROOT | /usr/local/lib/android/sdk | | ANDROID_SDK_ROOT | /usr/local/lib/android/sdk |
### Cached Docker images ### Cached Docker images
| Repository:Tag | Digest | Created | | Repository:Tag | Digest | Created |
| -------------------- | ------------------------------------------------------------------------ | ---------- | | ----------------------- | ------------------------------------------------------------------------ | ---------- |
| alpine:3.16 | sha256:452e7292acee0ee16c332324d7de05fa2c99f9994ecc9f0779c602916a672ae4 | 2024-01-27 | | alpine:3.16 | sha256:a8cbb8c69ee71561f4b69c066bad07f7e510caaa523da26fbfc606b10bd7934b | 2023-08-07 |
| alpine:3.17 | sha256:53cf9478b76f4c8fae126acbdfb79bed6e69e628faff572ebe4a029d3d247d98 | 2024-01-27 | | alpine:3.17 | sha256:f71a5f071694a785e064f05fed657bf8277f1b2113a8ed70c90ad486d6ee54dc | 2023-08-07 |
| alpine:3.18 | sha256:11e21d7b981a59554b3f822c49f6e9f57b6068bb74f49c4cd5cc4c663c7e5160 | 2024-01-27 | | alpine:3.18 | sha256:eece025e432126ce23f223450a0326fbebde39cdf496a85d8c016293fc851978 | 2023-09-28 |
| debian:10 | sha256:6e7bd55a5705914837aad8db01b349f4617510c11e47ccae8e87f6f14e489626 | 2024-05-14 | | buildpack-deps:bullseye | sha256:8ee57204a7af0468a61a3e47fbf8412d6ad1d479050bb702d99fd1d3664d7173 | 2023-09-20 |
| debian:11 | sha256:2c7a92a41cb814c00e7d455b2bc0c90ccdb9a4ced2ffdc10e562c7a84a186032 | 2024-05-14 | | buildpack-deps:buster | sha256:0bc568b581ed3e9a13f818fd20258edb623cf67e6d354afadf77fb9095d798a2 | 2023-09-20 |
| moby/buildkit:latest | sha256:9194b5ec1be368f41c516df7f93f7f540630ea06136056b2ffebb62226ed4ad6 | 2024-04-25 | | debian:10 | sha256:484cc8ab0d73f513e3f9bacd03424eb081bd90f594d7ebde42587843fdc242f3 | 2023-09-20 |
| node:16 | sha256:f77a1aef2da8d83e45ec990f45df50f1a286c5fe8bbfb8c6e4246c6389705c0b | 2023-09-07 | | debian:11 | sha256:54d33aaad0bc936a9a40d856764c7bc35c0afaa9cab51f88bb95f6cd8004438d | 2023-09-20 |
| node:16-alpine | sha256:a1f9d027912b58a7c75be7716c97cfbc6d3099f3a97ed84aa490be9dee20e787 | 2023-08-10 | | moby/buildkit:latest | sha256:890dcae054e3039f6c6b76bf0da80a130fa6e6bb1f3624063ef0210ac2c57b06 | 2023-08-24 |
| node:18 | sha256:5bac3a1edff13e76586b8eaef1d411fcd80e4f18cce5bc40ea6993245e0721ec | 2024-05-14 | | node:14 | sha256:a158d3b9b4e3fa813fa6c8c590b8f0a860e015ad4e59bbce5744d2f6fd8461aa | 2023-04-12 |
| node:18-alpine | sha256:4837c2ac8998cf172f5892fb45f229c328e4824c43c8506f8ba9c7996d702430 | 2024-04-23 | | node:14-alpine | sha256:434215b487a329c9e867202ff89e704d3a75e554822e07f3e0c0f9e606121b33 | 2023-03-29 |
| node:20 | sha256:d6925dc84f8c0d1c1f8df4ea6a9a54e57d430241cb734b1b0c45ed6d26e8e9c0 | 2024-05-14 | | node:16 | sha256:f77a1aef2da8d83e45ec990f45df50f1a286c5fe8bbfb8c6e4246c6389705c0b | 2023-09-07 |
| node:20-alpine | sha256:291e84d956f1aff38454bbd3da38941461ad569a185c20aa289f71f37ea08e23 | 2024-05-09 | | node:16-alpine | sha256:a1f9d027912b58a7c75be7716c97cfbc6d3099f3a97ed84aa490be9dee20e787 | 2023-08-10 |
| ubuntu:20.04 | sha256:874aca52f79ae5f8258faff03e10ce99ae836f6e7d2df6ecd3da5c1cad3a912b | 2024-04-27 | | node:18 | sha256:ee0a21d64211d92d4340b225c556e9ef1a8bce1d5b03b49f5f07bf1dbbaa5626 | 2023-09-21 |
| ubuntu:22.04 | sha256:a6d2b38300ce017add71440577d5b0a90460d0e57fd7aec21dd0d1b0761bbfb2 | 2024-04-27 | | node:18-alpine | sha256:a315556d82ef54561e54fca7d8ee333382de183d4e56841dcefcd05b55310f46 | 2023-09-29 |
| node:20 | sha256:6b3f9aa7eefa8d4c93d43914e78aa2bfea9a12808b0059e5da78854dfa8b8768 | 2023-09-29 |
| node:20-alpine | sha256:37750e51d61bef92165b2e29a77da4277ba0777258446b7a9c99511f119db096 | 2023-09-29 |
| ubuntu:18.04 | sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98 | 2023-05-30 |
| ubuntu:20.04 | sha256:33a5cc25d22c45900796a1aca487ad7a7cb09f09ea00b779e3b2026b4fc2faba | 2023-08-01 |
| ubuntu:22.04 | sha256:aabed3296a3d45cede1dc866a24476c4d7e093aa806263c27ddaadbdce3c1054 | 2023-08-16 |
### Installed apt packages ### Installed apt packages
| Name | Version | | Name | Version |
@@ -299,21 +304,20 @@ Use the following command as a part of your job to start the service: 'sudo syst
| aria2 | 1.36.0-1 | | aria2 | 1.36.0-1 |
| autoconf | 2.71-2 | | autoconf | 2.71-2 |
| automake | 1:1.16.5-1.3 | | automake | 1:1.16.5-1.3 |
| binutils | 2.38-4ubuntu2.6 | | binutils | 2.38-4ubuntu2.3 |
| bison | 2:3.8.2+dfsg-1build1 | | bison | 2:3.8.2+dfsg-1build1 |
| brotli | 1.0.9-2build6 | | brotli | 1.0.9-2build6 |
| bzip2 | 1.0.8-5build1 | | bzip2 | 1.0.8-5build1 |
| coreutils | 8.32-4.1ubuntu1.2 | | coreutils | 8.32-4.1ubuntu1 |
| curl | 7.81.0-1ubuntu1.16 | | curl | 7.81.0-1ubuntu1.13 |
| dbus | 1.12.20-2ubuntu4.1 | | dbus | 1.12.20-2ubuntu4.1 |
| dnsutils | 1:9.18.18-0ubuntu0.22.04.2 | | dnsutils | 1:9.18.12-0ubuntu0.22.04.3 |
| dpkg | 1.21.1ubuntu2.3 | | dpkg | 1.21.1ubuntu2.2 |
| dpkg-dev | 1.21.1ubuntu2.3 | | dpkg-dev | 1.21.1ubuntu2.2 |
| fakeroot | 1.28-1ubuntu1 | | fakeroot | 1.28-1ubuntu1 |
| file | 1:5.41-3ubuntu0.1 | | file | 1:5.41-3ubuntu0.1 |
| findutils | 4.8.0-1ubuntu3 |
| flex | 2.6.4-8build2 | | flex | 2.6.4-8build2 |
| fonts-noto-color-emoji | 2.042-0ubuntu0.22.04.1 | | fonts-noto-color-emoji | 2.038-0ubuntu1 |
| ftp | 20210827-4build1 | | ftp | 20210827-4build1 |
| g++ | 4:11.2.0-1ubuntu1 | | g++ | 4:11.2.0-1ubuntu1 |
| gcc | 4:11.2.0-1ubuntu1 | | gcc | 4:11.2.0-1ubuntu1 |
@@ -326,24 +330,24 @@ Use the following command as a part of your job to start the service: 'sudo syst
| lib32z1 | 1:1.2.11.dfsg-2ubuntu9.2 | | lib32z1 | 1:1.2.11.dfsg-2ubuntu9.2 |
| libc++-dev | 1:14.0-55\~exp2 | | libc++-dev | 1:14.0-55\~exp2 |
| libc++abi-dev | 1:14.0-55\~exp2 | | libc++abi-dev | 1:14.0-55\~exp2 |
| libc6-dev | 2.35-0ubuntu3.7 | | libc6-dev | 2.35-0ubuntu3.3 |
| libcurl4 | 7.81.0-1ubuntu1.16 | | libcurl4 | 7.81.0-1ubuntu1.13 |
| libgbm-dev | 23.2.1-1ubuntu3.1\~22.04.2 | | libgbm-dev | 23.0.4-0ubuntu1\~22.04.1 |
| libgconf-2-4 | 3.2.6-7ubuntu2 | | libgconf-2-4 | 3.2.6-7ubuntu2 |
| libgsl-dev | 2.7.1+dfsg-3 | | libgsl-dev | 2.7.1+dfsg-3 |
| libgtk-3-0 | 3.24.33-1ubuntu2.1 | | libgtk-3-0 | 3.24.33-1ubuntu2 |
| libmagic-dev | 1:5.41-3ubuntu0.1 | | libmagic-dev | 1:5.41-3ubuntu0.1 |
| libmagickcore-dev | 8:6.9.11.60+dfsg-1.3ubuntu0.22.04.3 | | libmagickcore-dev | 8:6.9.11.60+dfsg-1.3ubuntu0.22.04.3 |
| libmagickwand-dev | 8:6.9.11.60+dfsg-1.3ubuntu0.22.04.3 | | libmagickwand-dev | 8:6.9.11.60+dfsg-1.3ubuntu0.22.04.3 |
| libsecret-1-dev | 0.20.5-2 | | libsecret-1-dev | 0.20.5-2 |
| libsqlite3-dev | 3.37.2-2ubuntu0.3 | | libsqlite3-dev | 3.37.2-2ubuntu0.1 |
| libssl-dev | 3.0.2-0ubuntu1.15 | | libssl-dev | 3.0.2-0ubuntu1.10 |
| libtool | 2.4.6-15build2 | | libtool | 2.4.6-15build2 |
| libunwind8 | 1.3.2-2build2.1 | | libunwind8 | 1.3.2-2build2.1 |
| libxkbfile-dev | 1:1.1.0-1build3 | | libxkbfile-dev | 1:1.1.0-1build3 |
| libxss1 | 1:1.2.3-1build2 | | libxss1 | 1:1.2.3-1build2 |
| libyaml-dev | 0.2.2-1build2 | | libyaml-dev | 0.2.2-1build2 |
| locales | 2.35-0ubuntu3.7 | | locales | 2.35-0ubuntu3.3 |
| lz4 | 1.9.3-2build2 | | lz4 | 1.9.3-2build2 |
| m4 | 1.4.18-5ubuntu2 | | m4 | 1.4.18-5ubuntu2 |
| make | 4.3-4.1build1 | | make | 4.3-4.1build1 |
@@ -351,7 +355,7 @@ Use the following command as a part of your job to start the service: 'sudo syst
| mercurial | 6.1.1-1ubuntu1 | | mercurial | 6.1.1-1ubuntu1 |
| net-tools | 1.60+git20181103.0eebece-1ubuntu5 | | net-tools | 1.60+git20181103.0eebece-1ubuntu5 |
| netcat | 1.218-4ubuntu1 | | netcat | 1.218-4ubuntu1 |
| openssh-client | 1:8.9p1-3ubuntu0.7 | | openssh-client | 1:8.9p1-3ubuntu0.4 |
| p7zip-full | 16.02+dfsg-8 | | p7zip-full | 16.02+dfsg-8 |
| p7zip-rar | 16.02-3build1 | | p7zip-rar | 16.02-3build1 |
| parallel | 20210822+ds-2 | | parallel | 20210822+ds-2 |
@@ -365,23 +369,23 @@ Use the following command as a part of your job to start the service: 'sudo syst
| rsync | 3.2.7-0ubuntu0.22.04.2 | | rsync | 3.2.7-0ubuntu0.22.04.2 |
| shellcheck | 0.8.0-2 | | shellcheck | 0.8.0-2 |
| sphinxsearch | 2.2.11-8 | | sphinxsearch | 2.2.11-8 |
| sqlite3 | 3.37.2-2ubuntu0.3 | | sqlite3 | 3.37.2-2ubuntu0.1 |
| ssh | 1:8.9p1-3ubuntu0.7 | | ssh | 1:8.9p1-3ubuntu0.4 |
| sshpass | 1.09-1 | | sshpass | 1.09-1 |
| subversion | 1.14.1-3ubuntu0.22.04.1 | | subversion | 1.14.1-3ubuntu0.22.04.1 |
| sudo | 1.9.9-1ubuntu2.4 | | sudo | 1.9.9-1ubuntu2.4 |
| swig | 4.0.2-1ubuntu1 | | swig | 4.0.2-1ubuntu1 |
| tar | 1.34+dfsg-1ubuntu0.1.22.04.2 | | tar | 1.34+dfsg-1ubuntu0.1.22.04.1 |
| telnet | 0.17-44build1 | | telnet | 0.17-44build1 |
| texinfo | 6.8-4build1 | | texinfo | 6.8-4build1 |
| time | 1.9-0.1build2 | | time | 1.9-0.1build2 |
| tk | 8.6.11+1build2 | | tk | 8.6.11+1build2 |
| tzdata | 2024a-0ubuntu0.22.04 | | tzdata | 2023c-0ubuntu0.22.04.2 |
| unzip | 6.0-26ubuntu3.2 | | unzip | 6.0-26ubuntu3.1 |
| upx | 3.96-3 | | upx | 3.96-3 |
| wget | 1.21.2-2ubuntu1 | | wget | 1.21.2-2ubuntu1 |
| xorriso | 1.5.4-2 | | xorriso | 1.5.4-2 |
| xvfb | 2:21.1.4-2ubuntu1.7\~22.04.10 | | xvfb | 2:21.1.4-2ubuntu1.7\~22.04.1 |
| xz-utils | 5.2.5-2ubuntu1 | | xz-utils | 5.2.5-2ubuntu1 |
| zip | 3.0-12build2 | | zip | 3.0-12build2 |
| zsync | 0.6.2-3ubuntu1 | | zsync | 0.6.2-3ubuntu1 |
@@ -20,6 +20,7 @@ function Get-AndroidInstalledPackages {
return $androidSDKManagerList return $androidSDKManagerList
} }
function Build-AndroidTable { function Build-AndroidTable {
$packageInfo = Get-AndroidInstalledPackages $packageInfo = Get-AndroidInstalledPackages
return @( return @(
@@ -43,6 +44,10 @@ function Build-AndroidTable {
"Package" = "Android SDK Platforms" "Package" = "Android SDK Platforms"
"Version" = Get-AndroidPlatformVersions -PackageInfo $packageInfo "Version" = Get-AndroidPlatformVersions -PackageInfo $packageInfo
}, },
@{
"Package" = "Android SDK Tools"
"Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Android SDK Tools"
},
@{ @{
"Package" = "Android Support Repository" "Package" = "Android Support Repository"
"Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Android Support Repository" "Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Android Support Repository"
@@ -74,7 +79,7 @@ function Build-AndroidTable {
) | Where-Object { $_.Version } | ForEach-Object { ) | Where-Object { $_.Version } | ForEach-Object {
[PSCustomObject] @{ [PSCustomObject] @{
"Package Name" = $_.Package "Package Name" = $_.Package
"Version" = $_.Version "Version" = $_.Version
} }
} }
} }
@@ -87,7 +92,7 @@ function Get-AndroidPackageVersions {
[object] $MatchedString [object] $MatchedString
) )
$versions = $PackageInfo | Where-Object { $_ -Match $MatchedString } | ForEach-Object { $versions = $packageInfo | Where-Object { $_ -Match $MatchedString } | ForEach-Object {
$packageInfoParts = Split-TableRowByColumns $_ $packageInfoParts = Split-TableRowByColumns $_
return $packageInfoParts[1] return $packageInfoParts[1]
} }
@@ -100,7 +105,7 @@ function Get-AndroidPlatformVersions {
[object] $PackageInfo [object] $PackageInfo
) )
$versions = $PackageInfo | Where-Object { $_ -Match "Android SDK Platform " } | ForEach-Object { $versions = $packageInfo | Where-Object { $_ -Match "Android SDK Platform " } | ForEach-Object {
$packageInfoParts = Split-TableRowByColumns $_ $packageInfoParts = Split-TableRowByColumns $_
$revision = $packageInfoParts[1] $revision = $packageInfoParts[1]
$version = $packageInfoParts[0].split(";")[1] $version = $packageInfoParts[0].split(";")[1]
@@ -123,7 +128,7 @@ function Get-AndroidBuildToolVersions {
[object] $PackageInfo [object] $PackageInfo
) )
$versions = $PackageInfo | Where-Object { $_ -Match "Android SDK Build-Tools" } | ForEach-Object { $versions = $packageInfo | Where-Object { $_ -Match "Android SDK Build-Tools" } | ForEach-Object {
$packageInfoParts = Split-TableRowByColumns $_ $packageInfoParts = Split-TableRowByColumns $_
return $packageInfoParts[1] return $packageInfoParts[1]
} }
@@ -141,7 +146,7 @@ function Get-AndroidGoogleAPIsVersions {
[object] $PackageInfo [object] $PackageInfo
) )
$versions = $PackageInfo | Where-Object { $_ -Match "Google APIs" } | ForEach-Object { $versions = $packageInfo | Where-Object { $_ -Match "Google APIs" } | ForEach-Object {
$packageInfoParts = Split-TableRowByColumns $_ $packageInfoParts = Split-TableRowByColumns $_
return $packageInfoParts[0].split(";")[1] return $packageInfoParts[0].split(";")[1]
} }
@@ -151,7 +156,7 @@ function Get-AndroidGoogleAPIsVersions {
function Get-AndroidNDKVersions { function Get-AndroidNDKVersions {
$ndkFolderPath = Join-Path (Get-AndroidSDKRoot) "ndk" $ndkFolderPath = Join-Path (Get-AndroidSDKRoot) "ndk"
$versions = Get-ChildItem -Path $ndkFolderPath -Name $versions = Get-ChildItem -Path $ndkFolderPath -Name
$ndkDefaultVersion = (Get-ToolsetContent).android.ndk.default $ndkDefaultVersion = Get-ToolsetValue "android.ndk.default"
$ndkDefaultFullVersion = Get-ChildItem "$env:ANDROID_HOME/ndk/$ndkDefaultVersion.*" -Name | Select-Object -Last 1 $ndkDefaultFullVersion = Get-ChildItem "$env:ANDROID_HOME/ndk/$ndkDefaultVersion.*" -Name | Select-Object -Last 1
return ($versions | ForEach-Object { return ($versions | ForEach-Object {
@@ -166,7 +171,7 @@ function Build-AndroidEnvironmentTable {
$shouldResolveLink = 'ANDROID_NDK', 'ANDROID_NDK_HOME', 'ANDROID_NDK_ROOT', 'ANDROID_NDK_LATEST_HOME' $shouldResolveLink = 'ANDROID_NDK', 'ANDROID_NDK_HOME', 'ANDROID_NDK_ROOT', 'ANDROID_NDK_LATEST_HOME'
return $androidVersions | Sort-Object -Property Name | ForEach-Object { return $androidVersions | Sort-Object -Property Name | ForEach-Object {
[PSCustomObject] @{ [PSCustomObject] @{
"Name" = $_.Name "Name" = $_.Name
"Value" = if ($shouldResolveLink.Contains($_.Name )) { Get-PathWithLink($_.Value) } else {$_.Value} "Value" = if ($shouldResolveLink.Contains($_.Name )) { Get-PathWithLink($_.Value) } else {$_.Value}
} }
} }
@@ -1,59 +1,60 @@
function Get-ChromeVersion { function Get-ChromeVersion {
$googleChromeVersion = google-chrome --version | Get-StringPart -Part 2 $googleChromeVersion = google-chrome --version | Take-OutputPart -Part 2
return $googleChromeVersion return $googleChromeVersion
} }
function Get-ChromeDriverVersion { function Get-ChromeDriverVersion {
$chromeDriverVersion = chromedriver --version | Get-StringPart -Part 1 $chromeDriverVersion = chromedriver --version | Take-OutputPart -Part 1
return $chromeDriverVersion return $chromeDriverVersion
} }
function Get-FirefoxVersion { function Get-FirefoxVersion {
$firefoxVersion = $(firefox --version) | Get-StringPart -Part 2 $firefoxVersion = $(firefox --version) | Take-OutputPart -Part 2
return $firefoxVersion return $firefoxVersion
} }
function Get-GeckodriverVersion { function Get-GeckodriverVersion {
$geckodriverVersion = geckodriver --version | Select-Object -First 1 | Get-StringPart -Part 1 $geckodriverVersion = geckodriver --version | Select-Object -First 1 | Take-OutputPart -Part 1
return $geckodriverVersion return $geckodriverVersion
} }
function Get-ChromiumVersion { function Get-ChromiumVersion {
$chromiumVersion = chromium-browser --version | Get-StringPart -Part 1 $chromiumVersion = chromium-browser --version | Take-OutputPart -Part 1
return $chromiumVersion return $chromiumVersion
} }
function Get-EdgeVersion { function Get-EdgeVersion {
$edgeVersion = (microsoft-edge --version).Trim() | Get-StringPart -Part 2 $edgeVersion = (microsoft-edge --version).Trim() | Take-OutputPart -Part 2
return $edgeVersion return $edgeVersion
} }
function Get-EdgeDriverVersion { function Get-EdgeDriverVersion {
$edgeDriverVersion = msedgedriver --version | Get-StringPart -Part 3 $edgeDriverVersion = msedgedriver --version | Take-OutputPart -Part 3
return $edgeDriverVersion return $edgeDriverVersion
} }
function Get-SeleniumVersion { function Get-SeleniumVersion {
$fullSeleniumVersion = (Get-ChildItem "/usr/share/java/selenium-server-*").Name -replace "selenium-server-" $seleniumBinaryName = Get-ToolsetValue "selenium.binary_name"
$fullSeleniumVersion = (Get-ChildItem "/usr/share/java/${seleniumBinaryName}-*").Name -replace "${seleniumBinaryName}-"
return $fullSeleniumVersion return $fullSeleniumVersion
} }
function Build-BrowserWebdriversEnvironmentTable { function Build-BrowserWebdriversEnvironmentTable {
return @( return @(
[PSCustomObject] @{ [PSCustomObject] @{
"Name" = "CHROMEWEBDRIVER" "Name" = "CHROMEWEBDRIVER"
"Value" = $env:CHROMEWEBDRIVER "Value" = $env:CHROMEWEBDRIVER
}, },
[PSCustomObject] @{ [PSCustomObject] @{
"Name" = "EDGEWEBDRIVER" "Name" = "EDGEWEBDRIVER"
"Value" = $env:EDGEWEBDRIVER "Value" = $env:EDGEWEBDRIVER
}, },
[PSCustomObject] @{ [PSCustomObject] @{
"Name" = "GECKOWEBDRIVER" "Name" = "GECKOWEBDRIVER"
"Value" = $env:GECKOWEBDRIVER "Value" = $env:GECKOWEBDRIVER
}, },
[PSCustomObject] @{ [PSCustomObject] @{
"Name" = "SELENIUM_JAR_PATH" "Name" = "SELENIUM_JAR_PATH"
"Value" = $env:SELENIUM_JAR_PATH "Value" = $env:SELENIUM_JAR_PATH
} }
) )
@@ -1,18 +1,18 @@
function Get-ToolcacheRubyVersions { function Get-ToolcacheRubyVersions {
$toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "Ruby" $toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "Ruby"
return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version] $_ } return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version]$_ }
} }
function Get-ToolcachePythonVersions { function Get-ToolcachePythonVersions {
$toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "Python" $toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "Python"
return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version] $_ } return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version]$_ }
} }
function Get-ToolcachePyPyVersions { function Get-ToolcachePyPyVersions {
$toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "PyPy" $toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "PyPy"
Get-ChildItem -Path $toolcachePath -Name | Sort-Object { [Version] $_ } | ForEach-Object { Get-ChildItem -Path $toolcachePath -Name | Sort-Object { [Version] $_ } | ForEach-Object {
$pypyRootPath = Join-Path $toolcachePath $_ "x64" $pypyRootPath = Join-Path $toolcachePath $_ "x64"
[string] $pypyVersionOutput = & "$pypyRootPath/bin/python" -c "import sys;print(sys.version)" [string]$pypyVersionOutput = & "$pypyRootPath/bin/python" -c "import sys;print(sys.version)"
$pypyVersionOutput -match "^([\d\.]+) \(.+\) \[PyPy ([\d\.]+\S*) .+]$" | Out-Null $pypyVersionOutput -match "^([\d\.]+) \(.+\) \[PyPy ([\d\.]+\S*) .+]$" | Out-Null
return "{0} [PyPy {1}]" -f $Matches[1], $Matches[2] return "{0} [PyPy {1}]" -f $Matches[1], $Matches[2]
} }
@@ -20,10 +20,10 @@ function Get-ToolcachePyPyVersions {
function Get-ToolcacheNodeVersions { function Get-ToolcacheNodeVersions {
$toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "node" $toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "node"
return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version] $_ } return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version]$_ }
} }
function Get-ToolcacheGoVersions { function Get-ToolcacheGoVersions {
$toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "go" $toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "go"
return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version] $_ } return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version]$_ }
} }
@@ -10,17 +10,18 @@ function Get-DashVersion {
function Get-CPPVersions { function Get-CPPVersions {
$result = Get-CommandResult "apt list --installed" -Multiline $result = Get-CommandResult "apt list --installed" -Multiline
$cppVersions = $result.Output | Where-Object { $_ -match "g\+\+-\d\d\/" } | ForEach-Object { $cppVersions = $result.Output | Where-Object { $_ -match "g\+\+-\d+"} | ForEach-Object {
& $_.Split("/")[0] --version | Select-Object -First 1 | Get-StringPart -Part 3 & $_.Split("/")[0] --version | Select-Object -First 1 | Take-OutputPart -Part 3
} | Sort-Object {[Version] $_} } | Sort-Object {[Version]$_}
return $cppVersions return $cppVersions
} }
function Get-FortranVersions { function Get-FortranVersions {
$result = Get-CommandResult "apt list --installed" -Multiline $result = Get-CommandResult "apt list --installed" -Multiline
$fortranVersions = $result.Output | Where-Object { $_ -match "^gfortran-\d\d\/" } | ForEach-Object { $fortranVersions = $result.Output | Where-Object { $_ -match "^gfortran-\d+"} | ForEach-Object {
& $_.Split("/")[0] --version | Select-Object -First 1 | Get-StringPart -Part 4 $_ -match "now (?<version>\d+\.\d+\.\d+)-" | Out-Null
} | Sort-Object {[Version] $_} $Matches.version
} | Sort-Object {[Version]$_}
return $fortranVersions return $fortranVersions
} }
@@ -29,25 +30,24 @@ function Get-ClangToolVersions {
[Parameter(Mandatory = $true)] [Parameter(Mandatory = $true)]
[string] $ToolName, [string] $ToolName,
[string] $VersionLineMatcher = "${ToolName} version", [string] $VersionLineMatcher = "${ToolName} version",
[string] $VersionPattern = "\d+\.\d+\.\d+)" [string] $VersionPattern = "\d+\.\d+\.\d+)-"
) )
$result = Get-CommandResult "apt list --installed" -Multiline $result = Get-CommandResult "apt list --installed" -Multiline
$toolVersions = $result.Output | Where-Object { $_ -match "^${ToolName}-\d+" } | ForEach-Object { $toolVersions = $result.Output | Where-Object { $_ -match "^${ToolName}-\d+"} | ForEach-Object {
$clangCommand = ($_ -Split "/")[0] $clangCommand = ($_ -Split "/")[0]
Invoke-Expression "$clangCommand --version" | Where-Object { $_ -match "${VersionLineMatcher}" } | ForEach-Object { Invoke-Expression "$clangCommand --version" | Where-Object { $_ -match "${VersionLineMatcher}" } | ForEach-Object {
$_ -match "${VersionLineMatcher} (?<version>${VersionPattern}" | Out-Null $_ -match "${VersionLineMatcher} (?<version>${VersionPattern}" | Out-Null
$Matches.version $Matches.version
} }
} | Sort-Object {[Version] $_} } | Sort-Object {[Version]$_}
return $toolVersions return $toolVersions
} }
function Get-ClangTidyVersions { function Get-ClangTidyVersions {
$clangVersions = Get-ClangToolVersions -ToolName "clang-tidy" -VersionLineMatcher "LLVM version" -VersionPattern "\d+\.\d+\.\d+)" return Get-ClangToolVersions -ToolName "clang-tidy" -VersionLineMatcher "LLVM version" -VersionPattern "\d+\.\d+\.\d+)"
return $clangVersions
} }
@@ -64,7 +64,7 @@ function Get-ErlangRebar3Version {
} }
function Get-MonoVersion { function Get-MonoVersion {
$monoVersion = mono --version | Out-String | Get-StringPart -Part 4 $monoVersion = mono --version | Out-String | Take-OutputPart -Part 4
return $monoVersion return $monoVersion
} }
@@ -75,7 +75,7 @@ function Get-MsbuildVersion {
} }
function Get-NuGetVersion { function Get-NuGetVersion {
$nugetVersion = nuget help | Select-Object -First 1 | Get-StringPart -Part 2 $nugetVersion = nuget help | Select-Object -First 1 | Take-OutputPart -Part 2
return $nugetVersion return $nugetVersion
} }
@@ -85,8 +85,7 @@ function Get-NodeVersion {
} }
function Get-OpensslVersion { function Get-OpensslVersion {
$opensslVersion = $(dpkg-query -W -f '${Version}' openssl) return $(dpkg-query -W -f '${Version}' openssl)
return $opensslVersion
} }
function Get-PerlVersion { function Get-PerlVersion {
@@ -96,32 +95,31 @@ function Get-PerlVersion {
function Get-PythonVersion { function Get-PythonVersion {
$result = Get-CommandResult "python --version" $result = Get-CommandResult "python --version"
$version = $result.Output | Get-StringPart -Part 1 $version = $result.Output | Take-OutputPart -Part 1
return $version return $version
} }
function Get-PowershellVersion { function Get-PowershellVersion {
$pwshVersion = $(pwsh --version) | Get-StringPart -Part 1 return $(pwsh --version) | Take-OutputPart -Part 1
return $pwshVersion
} }
function Get-RubyVersion { function Get-RubyVersion {
$rubyVersion = ruby --version | Out-String | Get-StringPart -Part 1 $rubyVersion = ruby --version | Out-String | Take-OutputPart -Part 1
return $rubyVersion return $rubyVersion
} }
function Get-SwiftVersion { function Get-SwiftVersion {
$swiftVersion = swift --version | Out-String | Get-StringPart -Part 2 $swiftVersion = swift --version | Out-String | Take-OutputPart -Part 2
return $swiftVersion return $swiftVersion
} }
function Get-KotlinVersion { function Get-KotlinVersion {
$kotlinVersion = kotlin -version | Out-String | Get-StringPart -Part 2 $kotlinVersion = kotlin -version | Out-String | Take-OutputPart -Part 2
return $kotlinVersion return $kotlinVersion
} }
function Get-JuliaVersion { function Get-JuliaVersion {
$juliaVersion = julia --version | Get-StringPart -Part 2 $juliaVersion = julia --version | Take-OutputPart -Part 2
return $juliaVersion return $juliaVersion
} }
@@ -137,7 +135,7 @@ function Get-HomebrewVersion {
} }
function Get-CpanVersion { function Get-CpanVersion {
$result = Get-CommandResult "cpan --version" -ExpectedExitCode @(25, 255) $result = Get-CommandResult "cpan --version" -ExpectExitCode @(25, 255)
$result.Output -match "version (?<version>\d+\.\d+) " | Out-Null $result.Output -match "version (?<version>\d+\.\d+) " | Out-Null
return $Matches.version return $Matches.version
} }
@@ -149,7 +147,7 @@ function Get-GemVersion {
} }
function Get-MinicondaVersion { function Get-MinicondaVersion {
$condaVersion = conda --version | Get-StringPart -Part 1 $condaVersion = conda --version | Take-OutputPart -Part 1
return $condaVersion return $condaVersion
} }
@@ -174,13 +172,15 @@ function Get-ParcelVersion {
} }
function Get-PipVersion { function Get-PipVersion {
$pipVersion = pip --version | Get-StringPart -Part 1 $result = Get-CommandResult "pip --version"
return $pipVersion $result.Output -match "pip (?<version>\d+\.\d+\.\d+)" | Out-Null
return $Matches.version
} }
function Get-Pip3Version { function Get-Pip3Version {
$pip3Version = pip3 --version | Get-StringPart -Part 1 $result = Get-CommandResult "pip3 --version"
return $pip3Version $result.Output -match "pip (?<version>\d+\.\d+\.\d+)" | Out-Null
return $Matches.version
} }
function Get-VcpkgVersion { function Get-VcpkgVersion {
@@ -195,7 +195,7 @@ function Get-AntVersion {
} }
function Get-GradleVersion { function Get-GradleVersion {
$gradleVersion = (gradle -v) -match "^Gradle \d" | Get-StringPart -Part 1 $gradleVersion = (gradle -v) -match "^Gradle \d" | Take-OutputPart -Part 1
return $gradleVersion return $gradleVersion
} }
@@ -213,14 +213,14 @@ function Get-SbtVersion {
function Get-PHPVersions { function Get-PHPVersions {
$result = Get-CommandResult "apt list --installed" -Multiline $result = Get-CommandResult "apt list --installed" -Multiline
return $result.Output | Where-Object { $_ -match "^php\d+\.\d+/" } | ForEach-Object { return $result.Output | Where-Object { $_ -match "^php\d+\.\d+/"} | ForEach-Object {
$_ -match "now (\d+:)?(?<version>\d+\.\d+\.\d+)" | Out-Null $_ -match "now (\d+:)?(?<version>\d+\.\d+\.\d+)" | Out-Null
$Matches.version $Matches.version
} }
} }
function Get-ComposerVersion { function Get-ComposerVersion {
$composerVersion = (composer --version) -replace " version" | Get-StringPart -Part 1 $composerVersion = (composer --version) -replace " version" | Take-OutputPart -Part 1
return $composerVersion return $composerVersion
} }
@@ -281,7 +281,7 @@ function Get-PowerShellModules {
} }
function Get-DotNetCoreSdkVersions { function Get-DotNetCoreSdkVersions {
$dotNetCoreSdkVersion = dotnet --list-sdks list | ForEach-Object { $_ | Get-StringPart -Part 0 } $dotNetCoreSdkVersion = dotnet --list-sdks list | ForEach-Object { $_ | Take-OutputPart -Part 0 }
return $dotNetCoreSdkVersion return $dotNetCoreSdkVersion
} }
@@ -307,8 +307,8 @@ function Get-CachedDockerImagesTableData {
$parts = $_.Split("|") $parts = $_.Split("|")
[PSCustomObject] @{ [PSCustomObject] @{
"Repository:Tag" = $parts[0] "Repository:Tag" = $parts[0]
"Digest" = $parts[1] "Digest" = $parts[1]
"Created" = $parts[2].split(' ')[0] "Created" = $parts[2].split(' ')[0]
} }
} | Sort-Object -Property "Repository:Tag" } | Sort-Object -Property "Repository:Tag"
} }
@@ -318,10 +318,10 @@ function Get-AptPackages {
$output = @() $output = @()
ForEach ($pkg in ($apt.vital_packages + $apt.common_packages + $apt.cmd_packages)) { ForEach ($pkg in ($apt.vital_packages + $apt.common_packages + $apt.cmd_packages)) {
$version = $(dpkg-query -W -f '${Version}' $pkg) $version = $(dpkg-query -W -f '${Version}' $pkg)
if ($null -eq $version) { if ($Null -eq $version) {
$version = $(dpkg-query -W -f '${Version}' "$pkg*") $version = $(dpkg-query -W -f '${Version}' "$pkg*")
} }
$version = $version -replace '~','\~' $version = $version -replace '~','\~'
$output += [PSCustomObject] @{ $output += [PSCustomObject] @{
@@ -341,18 +341,18 @@ function Get-PipxVersion {
function Build-PackageManagementEnvironmentTable { function Build-PackageManagementEnvironmentTable {
return @( return @(
[PSCustomObject] @{ [PSCustomObject] @{
"Name" = "CONDA" "Name" = "CONDA"
"Value" = $env:CONDA "Value" = $env:CONDA
}, },
[PSCustomObject] @{ [PSCustomObject] @{
"Name" = "VCPKG_INSTALLATION_ROOT" "Name" = "VCPKG_INSTALLATION_ROOT"
"Value" = $env:VCPKG_INSTALLATION_ROOT "Value" = $env:VCPKG_INSTALLATION_ROOT
} }
) )
} }
function Get-SystemdVersion { function Get-SystemdVersion {
$matchCollection = [regex]::Matches((systemctl --version | head -n 1), "\((.*?)\)") $matches = [regex]::Matches((systemctl --version | head -n 1), "\((.*?)\)")
$result = foreach ($match in $matchCollection) {$match.Groups[1].Value} $result = foreach ($match in $matches) {$match.Groups[1].Value}
return $result return $result
} }
@@ -1,25 +1,25 @@
function Get-PostgreSqlVersion { function Get-PostgreSqlVersion {
$postgreSQLVersion = psql --version | Get-StringPart -Part 2 $postgreSQLVersion = psql --version | Take-OutputPart -Part 2
return $postgreSQLVersion return $postgreSQLVersion
} }
function Get-MongoDbVersion { function Get-MongoDbVersion {
$mongoDBVersion = mongod --version | Select-Object -First 1 | Get-StringPart -Part 2 -Delimiter "v" $mongoDBVersion = mongod --version | Select-Object -First 1 | Take-OutputPart -Part 2 -Delimiter "v"
return $mongoDBVersion return $mongoDBVersion
} }
function Get-SqliteVersion { function Get-SqliteVersion {
$sqliteVersion = sqlite3 --version | Get-StringPart -Part 0 $sqliteVersion = sqlite3 --version | Take-OutputPart -Part 0
return $sqliteVersion return $sqliteVersion
} }
function Get-MySQLVersion { function Get-MySQLVersion {
$mySQLVersion = mysqld --version | Get-StringPart -Part 2 $mySQLVersion = mysqld --version | Take-OutputPart -Part 2
return $mySQLVersion return $mySQLVersion
} }
function Get-SQLCmdVersion { function Get-SQLCmdVersion {
$sqlcmdVersion = sqlcmd -? | Select-String -Pattern "Version" | Get-StringPart -Part 1 $sqlcmdVersion = sqlcmd -? | Select-String -Pattern "Version" | Take-OutputPart -Part 1
return $sqlcmdVersion return $sqlcmdVersion
} }
@@ -2,8 +2,8 @@ using module ./software-report-base/SoftwareReport.psm1
using module ./software-report-base/SoftwareReport.Nodes.psm1 using module ./software-report-base/SoftwareReport.Nodes.psm1
param ( param (
[Parameter(Mandatory)] [Parameter(Mandatory)][string]
[string] $OutputDirectory $OutputDirectory
) )
$global:ErrorActionPreference = "Stop" $global:ErrorActionPreference = "Stop"
@@ -15,7 +15,7 @@ Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Browsers.psm1") -DisableN
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.CachedTools.psm1") -DisableNameChecking Import-Module (Join-Path $PSScriptRoot "SoftwareReport.CachedTools.psm1") -DisableNameChecking
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Common.psm1") -DisableNameChecking Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Common.psm1") -DisableNameChecking
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Databases.psm1") -DisableNameChecking Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Databases.psm1") -DisableNameChecking
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Helpers.psm1") -DisableNameChecking Import-Module "$PSScriptRoot/../helpers/SoftwareReport.Helpers.psm1" -DisableNameChecking
Import-Module "$PSScriptRoot/../helpers/Common.Helpers.psm1" -DisableNameChecking Import-Module "$PSScriptRoot/../helpers/Common.Helpers.psm1" -DisableNameChecking
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Java.psm1") -DisableNameChecking Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Java.psm1") -DisableNameChecking
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Rust.psm1") -DisableNameChecking Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Rust.psm1") -DisableNameChecking
@@ -23,7 +23,7 @@ Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Tools.psm1") -DisableName
Import-Module (Join-Path $PSScriptRoot "SoftwareReport.WebServers.psm1") -DisableNameChecking Import-Module (Join-Path $PSScriptRoot "SoftwareReport.WebServers.psm1") -DisableNameChecking
# Restore file owner in user profile # Restore file owner in user profile
sudo chown -R ${env:USER}: $env:HOME Restore-UserOwner
# Software report # Software report
$softwareReport = [SoftwareReport]::new("Ubuntu $(Get-OSVersionShort)") $softwareReport = [SoftwareReport]::new("Ubuntu $(Get-OSVersionShort)")
@@ -48,20 +48,14 @@ if (Test-IsUbuntu20) {
$languageAndRuntime.AddToolVersionsListInline("GNU C++", $(Get-CPPVersions), "^\d+") $languageAndRuntime.AddToolVersionsListInline("GNU C++", $(Get-CPPVersions), "^\d+")
$languageAndRuntime.AddToolVersionsListInline("GNU Fortran", $(Get-FortranVersions), "^\d+") $languageAndRuntime.AddToolVersionsListInline("GNU Fortran", $(Get-FortranVersions), "^\d+")
$languageAndRuntime.AddToolVersion("Julia", $(Get-JuliaVersion)) $languageAndRuntime.AddToolVersion("Julia", $(Get-JuliaVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { $languageAndRuntime.AddToolVersion("Kotlin", $(Get-KotlinVersion))
$languageAndRuntime.AddToolVersion("Kotlin", $(Get-KotlinVersion)) $languageAndRuntime.AddToolVersion("Mono", $(Get-MonoVersion))
} $languageAndRuntime.AddToolVersion("MSBuild", $(Get-MsbuildVersion))
if (-not $(Test-IsUbuntu24)) {
$languageAndRuntime.AddToolVersion("Mono", $(Get-MonoVersion))
$languageAndRuntime.AddToolVersion("MSBuild", $(Get-MsbuildVersion))
}
$languageAndRuntime.AddToolVersion("Node.js", $(Get-NodeVersion)) $languageAndRuntime.AddToolVersion("Node.js", $(Get-NodeVersion))
$languageAndRuntime.AddToolVersion("Perl", $(Get-PerlVersion)) $languageAndRuntime.AddToolVersion("Perl", $(Get-PerlVersion))
$languageAndRuntime.AddToolVersion("Python", $(Get-PythonVersion)) $languageAndRuntime.AddToolVersion("Python", $(Get-PythonVersion))
$languageAndRuntime.AddToolVersion("Ruby", $(Get-RubyVersion)) $languageAndRuntime.AddToolVersion("Ruby", $(Get-RubyVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { $languageAndRuntime.AddToolVersion("Swift", $(Get-SwiftVersion))
$languageAndRuntime.AddToolVersion("Swift", $(Get-SwiftVersion))
}
# Package Management # Package Management
$packageManagement = $installedSoftware.AddHeader("Package Management") $packageManagement = $installedSoftware.AddHeader("Package Management")
@@ -70,9 +64,7 @@ $packageManagement.AddToolVersion("Helm", $(Get-HelmVersion))
$packageManagement.AddToolVersion("Homebrew", $(Get-HomebrewVersion)) $packageManagement.AddToolVersion("Homebrew", $(Get-HomebrewVersion))
$packageManagement.AddToolVersion("Miniconda", $(Get-MinicondaVersion)) $packageManagement.AddToolVersion("Miniconda", $(Get-MinicondaVersion))
$packageManagement.AddToolVersion("Npm", $(Get-NpmVersion)) $packageManagement.AddToolVersion("Npm", $(Get-NpmVersion))
if (-not $(Test-IsUbuntu24)) { $packageManagement.AddToolVersion("NuGet", $(Get-NuGetVersion))
$packageManagement.AddToolVersion("NuGet", $(Get-NuGetVersion))
}
$packageManagement.AddToolVersion("Pip", $(Get-PipVersion)) $packageManagement.AddToolVersion("Pip", $(Get-PipVersion))
$packageManagement.AddToolVersion("Pip3", $(Get-Pip3Version)) $packageManagement.AddToolVersion("Pip3", $(Get-Pip3Version))
$packageManagement.AddToolVersion("Pipx", $(Get-PipxVersion)) $packageManagement.AddToolVersion("Pipx", $(Get-PipxVersion))
@@ -89,11 +81,15 @@ to accomplish this.
# Project Management # Project Management
$projectManagement = $installedSoftware.AddHeader("Project Management") $projectManagement = $installedSoftware.AddHeader("Project Management")
$projectManagement.AddToolVersion("Ant", $(Get-AntVersion)) if (Test-IsUbuntu20) {
$projectManagement.AddToolVersion("Gradle", $(Get-GradleVersion)) $projectManagement.AddToolVersion("Ant", $(Get-AntVersion))
$projectManagement.AddToolVersion("Lerna", $(Get-LernaVersion)) $projectManagement.AddToolVersion("Gradle", $(Get-GradleVersion))
$projectManagement.AddToolVersion("Maven", $(Get-MavenVersion)) }
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) {
$projectManagement.AddToolVersion("Lerna", $(Get-LernaVersion))
}
$projectManagement.AddToolVersion("Maven", $(Get-MavenVersion))
if (Test-IsUbuntu20) {
$projectManagement.AddToolVersion("Sbt", $(Get-SbtVersion)) $projectManagement.AddToolVersion("Sbt", $(Get-SbtVersion))
} }
@@ -109,21 +105,19 @@ $tools.AddToolVersion("Buildah", $(Get-BuildahVersion))
$tools.AddToolVersion("CMake", $(Get-CMakeVersion)) $tools.AddToolVersion("CMake", $(Get-CMakeVersion))
$tools.AddToolVersion("CodeQL Action Bundle", $(Get-CodeQLBundleVersion)) $tools.AddToolVersion("CodeQL Action Bundle", $(Get-CodeQLBundleVersion))
$tools.AddToolVersion("Docker Amazon ECR Credential Helper", $(Get-DockerAmazonECRCredHelperVersion)) $tools.AddToolVersion("Docker Amazon ECR Credential Helper", $(Get-DockerAmazonECRCredHelperVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { $tools.AddToolVersion("Docker Compose v1", $(Get-DockerComposeV1Version))
$tools.AddToolVersion("Docker Compose v1", $(Get-DockerComposeV1Version))
}
$tools.AddToolVersion("Docker Compose v2", $(Get-DockerComposeV2Version)) $tools.AddToolVersion("Docker Compose v2", $(Get-DockerComposeV2Version))
$tools.AddToolVersion("Docker-Buildx", $(Get-DockerBuildxVersion)) $tools.AddToolVersion("Docker-Buildx", $(Get-DockerBuildxVersion))
$tools.AddToolVersion("Docker Client", $(Get-DockerClientVersion)) $tools.AddToolVersion("Docker Client", $(Get-DockerClientVersion))
$tools.AddToolVersion("Docker Server", $(Get-DockerServerVersion)) $tools.AddToolVersion("Docker Server", $(Get-DockerServerVersion))
$tools.AddToolVersion("Fastlane", $(Get-FastlaneVersion)) if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) {
$tools.AddToolVersion("Fastlane", $(Get-FastlaneVersion))
}
$tools.AddToolVersion("Git", $(Get-GitVersion)) $tools.AddToolVersion("Git", $(Get-GitVersion))
$tools.AddToolVersion("Git LFS", $(Get-GitLFSVersion)) $tools.AddToolVersion("Git LFS", $(Get-GitLFSVersion))
$tools.AddToolVersion("Git-ftp", $(Get-GitFTPVersion)) $tools.AddToolVersion("Git-ftp", $(Get-GitFTPVersion))
$tools.AddToolVersion("Haveged", $(Get-HavegedVersion)) $tools.AddToolVersion("Haveged", $(Get-HavegedVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { $tools.AddToolVersion("Heroku", $(Get-HerokuVersion))
$tools.AddToolVersion("Heroku", $(Get-HerokuVersion))
}
if (Test-IsUbuntu20) { if (Test-IsUbuntu20) {
$tools.AddToolVersion("HHVM (HipHop VM)", $(Get-HHVMVersion)) $tools.AddToolVersion("HHVM (HipHop VM)", $(Get-HHVMVersion))
} }
@@ -131,119 +125,89 @@ $tools.AddToolVersion("jq", $(Get-JqVersion))
$tools.AddToolVersion("Kind", $(Get-KindVersion)) $tools.AddToolVersion("Kind", $(Get-KindVersion))
$tools.AddToolVersion("Kubectl", $(Get-KubectlVersion)) $tools.AddToolVersion("Kubectl", $(Get-KubectlVersion))
$tools.AddToolVersion("Kustomize", $(Get-KustomizeVersion)) $tools.AddToolVersion("Kustomize", $(Get-KustomizeVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { $tools.AddToolVersion("Leiningen", $(Get-LeiningenVersion))
$tools.AddToolVersion("Leiningen", $(Get-LeiningenVersion))
}
$tools.AddToolVersion("MediaInfo", $(Get-MediainfoVersion)) $tools.AddToolVersion("MediaInfo", $(Get-MediainfoVersion))
$tools.AddToolVersion("Mercurial", $(Get-HGVersion)) $tools.AddToolVersion("Mercurial", $(Get-HGVersion))
$tools.AddToolVersion("Minikube", $(Get-MinikubeVersion)) $tools.AddToolVersion("Minikube", $(Get-MinikubeVersion))
$tools.AddToolVersion("n", $(Get-NVersion)) $tools.AddToolVersion("n", $(Get-NVersion))
$tools.AddToolVersion("Newman", $(Get-NewmanVersion)) $tools.AddToolVersion("Newman", $(Get-NewmanVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { $tools.AddToolVersion("nvm", $(Get-NvmVersion))
$tools.AddToolVersion("nvm", $(Get-NvmVersion))
}
$tools.AddToolVersion("OpenSSL", $(Get-OpensslVersion)) $tools.AddToolVersion("OpenSSL", $(Get-OpensslVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { $tools.AddToolVersion("Packer", $(Get-PackerVersion))
$tools.AddToolVersion("Packer", $(Get-PackerVersion))
}
$tools.AddToolVersion("Parcel", $(Get-ParcelVersion)) $tools.AddToolVersion("Parcel", $(Get-ParcelVersion))
if (Test-IsUbuntu20) { if (Test-IsUbuntu20) {
$tools.AddToolVersion("PhantomJS", $(Get-PhantomJSVersion)) $tools.AddToolVersion("PhantomJS", $(Get-PhantomJSVersion))
} }
$tools.AddToolVersion("Podman", $(Get-PodManVersion)) $tools.AddToolVersion("Podman", $(Get-PodManVersion))
$tools.AddToolVersion("Pulumi", $(Get-PulumiVersion)) $tools.AddToolVersion("Pulumi", $(Get-PulumiVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { $tools.AddToolVersion("R", $(Get-RVersion))
$tools.AddToolVersion("R", $(Get-RVersion))
}
$tools.AddToolVersion("Skopeo", $(Get-SkopeoVersion)) $tools.AddToolVersion("Skopeo", $(Get-SkopeoVersion))
$tools.AddToolVersion("Sphinx Open Source Search Server", $(Get-SphinxVersion)) $tools.AddToolVersion("Sphinx Open Source Search Server", $(Get-SphinxVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { $tools.AddToolVersion("SVN", $(Get-SVNVersion))
$tools.AddToolVersion("SVN", $(Get-SVNVersion)) $tools.AddToolVersion("Terraform", $(Get-TerraformVersion))
$tools.AddToolVersion("Terraform", $(Get-TerraformVersion))
}
$tools.AddToolVersion("yamllint", $(Get-YamllintVersion)) $tools.AddToolVersion("yamllint", $(Get-YamllintVersion))
$tools.AddToolVersion("yq", $(Get-YqVersion)) $tools.AddToolVersion("yq", $(Get-YqVersion))
$tools.AddToolVersion("zstd", $(Get-ZstdVersion)) $tools.AddToolVersion("zstd", $(Get-ZstdVersion))
# CLI Tools # CLI Tools
$cliTools = $installedSoftware.AddHeader("CLI Tools") $cliTools = $installedSoftware.AddHeader("CLI Tools")
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { $cliTools.AddToolVersion("Alibaba Cloud CLI", $(Get-AlibabaCloudCliVersion))
$cliTools.AddToolVersion("Alibaba Cloud CLI", $(Get-AlibabaCloudCliVersion))
}
$cliTools.AddToolVersion("AWS CLI", $(Get-AWSCliVersion)) $cliTools.AddToolVersion("AWS CLI", $(Get-AWSCliVersion))
$cliTools.AddToolVersion("AWS CLI Session Manager Plugin", $(Get-AWSCliSessionManagerPluginVersion)) $cliTools.AddToolVersion("AWS CLI Session Manager Plugin", $(Get-AWSCliSessionManagerPluginVersion))
$cliTools.AddToolVersion("AWS SAM CLI", $(Get-AWSSAMVersion)) $cliTools.AddToolVersion("AWS SAM CLI", $(Get-AWSSAMVersion))
$cliTools.AddToolVersion("Azure CLI", $(Get-AzureCliVersion)) $cliTools.AddToolVersion("Azure CLI", $(Get-AzureCliVersion))
$cliTools.AddToolVersion("Azure CLI (azure-devops)", $(Get-AzureDevopsVersion)) $cliTools.AddToolVersion("Azure CLI (azure-devops)", $(Get-AzureDevopsVersion))
$cliTools.AddToolVersion("GitHub CLI", $(Get-GitHubCliVersion)) $cliTools.AddToolVersion("GitHub CLI", $(Get-GitHubCliVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { $cliTools.AddToolVersion("Google Cloud CLI", $(Get-GoogleCloudCLIVersion))
$cliTools.AddToolVersion("Google Cloud CLI", $(Get-GoogleCloudCLIVersion)) $cliTools.AddToolVersion("Netlify CLI", $(Get-NetlifyCliVersion))
$cliTools.AddToolVersion("Netlify CLI", $(Get-NetlifyCliVersion)) $cliTools.AddToolVersion("OpenShift CLI", $(Get-OCCliVersion))
$cliTools.AddToolVersion("OpenShift CLI", $(Get-OCCliVersion)) $cliTools.AddToolVersion("ORAS CLI", $(Get-ORASCliVersion))
$cliTools.AddToolVersion("ORAS CLI", $(Get-ORASCliVersion)) $cliTools.AddToolVersion("Vercel CLI", $(Get-VerselCliversion))
$cliTools.AddToolVersion("Vercel CLI", $(Get-VerselCliversion))
}
# Java
$installedSoftware.AddHeader("Java").AddTable($(Get-JavaVersionsTable)) $installedSoftware.AddHeader("Java").AddTable($(Get-JavaVersionsTable))
# PHP Tools
$phpTools = $installedSoftware.AddHeader("PHP Tools") $phpTools = $installedSoftware.AddHeader("PHP Tools")
$phpTools.AddToolVersionsListInline("PHP", $(Get-PHPVersions), "^\d+\.\d+") $phpTools.AddToolVersionsListInline("PHP", $(Get-PHPVersions), "^\d+\.\d+")
$phpTools.AddToolVersion("Composer", $(Get-ComposerVersion)) $phpTools.AddToolVersion("Composer", $(Get-ComposerVersion))
$phpTools.AddToolVersion("PHPUnit", $(Get-PHPUnitVersion)) $phpTools.AddToolVersion("PHPUnit", $(Get-PHPUnitVersion))
$phpTools.AddNote("Both Xdebug and PCOV extensions are installed, but only Xdebug is enabled.") $phpTools.AddNote("Both Xdebug and PCOV extensions are installed, but only Xdebug is enabled.")
# Haskell Tools
$haskellTools = $installedSoftware.AddHeader("Haskell Tools") $haskellTools = $installedSoftware.AddHeader("Haskell Tools")
$haskellTools.AddToolVersion("Cabal", $(Get-CabalVersion)) $haskellTools.AddToolVersion("Cabal", $(Get-CabalVersion))
$haskellTools.AddToolVersion("GHC", $(Get-GHCVersion)) $haskellTools.AddToolVersion("GHC", $(Get-GHCVersion))
$haskellTools.AddToolVersion("GHCup", $(Get-GHCupVersion)) $haskellTools.AddToolVersion("GHCup", $(Get-GHCupVersion))
$haskellTools.AddToolVersion("Stack", $(Get-StackVersion)) $haskellTools.AddToolVersion("Stack", $(Get-StackVersion))
# Rust Tools
Initialize-RustEnvironment Initialize-RustEnvironment
$rustTools = $installedSoftware.AddHeader("Rust Tools") $rustTools = $installedSoftware.AddHeader("Rust Tools")
$rustTools.AddToolVersion("Cargo", $(Get-CargoVersion)) $rustTools.AddToolVersion("Cargo", $(Get-CargoVersion))
$rustTools.AddToolVersion("Rust", $(Get-RustVersion)) $rustTools.AddToolVersion("Rust", $(Get-RustVersion))
$rustTools.AddToolVersion("Rustdoc", $(Get-RustdocVersion)) $rustTools.AddToolVersion("Rustdoc", $(Get-RustdocVersion))
$rustTools.AddToolVersion("Rustup", $(Get-RustupVersion)) $rustTools.AddToolVersion("Rustup", $(Get-RustupVersion))
# Packages
$rustToolsPackages = $rustTools.AddHeader("Packages") $rustToolsPackages = $rustTools.AddHeader("Packages")
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { $rustToolsPackages.AddToolVersion("Bindgen", $(Get-BindgenVersion))
$rustToolsPackages.AddToolVersion("Bindgen", $(Get-BindgenVersion)) $rustToolsPackages.AddToolVersion("Cargo audit", $(Get-CargoAuditVersion))
$rustToolsPackages.AddToolVersion("Cargo audit", $(Get-CargoAuditVersion)) $rustToolsPackages.AddToolVersion("Cargo clippy", $(Get-CargoClippyVersion))
$rustToolsPackages.AddToolVersion("Cargo clippy", $(Get-CargoClippyVersion)) $rustToolsPackages.AddToolVersion("Cargo outdated", $(Get-CargoOutdatedVersion))
$rustToolsPackages.AddToolVersion("Cargo outdated", $(Get-CargoOutdatedVersion)) $rustToolsPackages.AddToolVersion("Cbindgen", $(Get-CbindgenVersion))
$rustToolsPackages.AddToolVersion("Cbindgen", $(Get-CbindgenVersion))
}
$rustToolsPackages.AddToolVersion("Rustfmt", $(Get-RustfmtVersion)) $rustToolsPackages.AddToolVersion("Rustfmt", $(Get-RustfmtVersion))
# Browsers and Drivers
$browsersTools = $installedSoftware.AddHeader("Browsers and Drivers") $browsersTools = $installedSoftware.AddHeader("Browsers and Drivers")
$browsersTools.AddToolVersion("Google Chrome", $(Get-ChromeVersion)) $browsersTools.AddToolVersion("Google Chrome", $(Get-ChromeVersion))
$browsersTools.AddToolVersion("ChromeDriver", $(Get-ChromeDriverVersion)) $browsersTools.AddToolVersion("ChromeDriver", $(Get-ChromeDriverVersion))
$browsersTools.AddToolVersion("Chromium", $(Get-ChromiumVersion)) $browsersTools.AddToolVersion("Chromium", $(Get-ChromiumVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { $browsersTools.AddToolVersion("Microsoft Edge", $(Get-EdgeVersion))
$browsersTools.AddToolVersion("Microsoft Edge", $(Get-EdgeVersion)) $browsersTools.AddToolVersion("Microsoft Edge WebDriver", $(Get-EdgeDriverVersion))
$browsersTools.AddToolVersion("Microsoft Edge WebDriver", $(Get-EdgeDriverVersion))
}
$browsersTools.AddToolVersion("Selenium server", $(Get-SeleniumVersion)) $browsersTools.AddToolVersion("Selenium server", $(Get-SeleniumVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) { $browsersTools.AddToolVersion("Mozilla Firefox", $(Get-FirefoxVersion))
$browsersTools.AddToolVersion("Mozilla Firefox", $(Get-FirefoxVersion)) $browsersTools.AddToolVersion("Geckodriver", $(Get-GeckodriverVersion))
$browsersTools.AddToolVersion("Geckodriver", $(Get-GeckodriverVersion))
}
# Environment variables
$browsersTools.AddHeader("Environment variables").AddTable($(Build-BrowserWebdriversEnvironmentTable)) $browsersTools.AddHeader("Environment variables").AddTable($(Build-BrowserWebdriversEnvironmentTable))
# .NET Tools
$netCoreTools = $installedSoftware.AddHeader(".NET Tools") $netCoreTools = $installedSoftware.AddHeader(".NET Tools")
$netCoreTools.AddToolVersionsListInline(".NET Core SDK", $(Get-DotNetCoreSdkVersions), "^\d+\.\d+\.\d") $netCoreTools.AddToolVersionsListInline(".NET Core SDK", $(Get-DotNetCoreSdkVersions), "^\d+\.\d+\.\d")
$netCoreTools.AddNodes($(Get-DotnetTools)) $netCoreTools.AddNodes($(Get-DotnetTools))
# Databases
$databasesTools = $installedSoftware.AddHeader("Databases") $databasesTools = $installedSoftware.AddHeader("Databases")
if (Test-IsUbuntu20) { if (Test-IsUbuntu20) {
$databasesTools.AddToolVersion("MongoDB", $(Get-MongoDbVersion)) $databasesTools.AddToolVersion("MongoDB", $(Get-MongoDbVersion))
@@ -251,21 +215,15 @@ if (Test-IsUbuntu20) {
$databasesTools.AddToolVersion("sqlite3", $(Get-SqliteVersion)) $databasesTools.AddToolVersion("sqlite3", $(Get-SqliteVersion))
$databasesTools.AddNode($(Build-PostgreSqlSection)) $databasesTools.AddNode($(Build-PostgreSqlSection))
$databasesTools.AddNode($(Build-MySQLSection)) $databasesTools.AddNode($(Build-MySQLSection))
if (-not $(Test-IsUbuntu24)) { $databasesTools.AddNode($(Build-MSSQLToolsSection))
$databasesTools.AddNode($(Build-MSSQLToolsSection))
}
# Cached Tools
$cachedTools = $installedSoftware.AddHeader("Cached Tools") $cachedTools = $installedSoftware.AddHeader("Cached Tools")
$cachedTools.AddToolVersionsList("Go", $(Get-ToolcacheGoVersions), "^\d+\.\d+") $cachedTools.AddToolVersionsList("Go", $(Get-ToolcacheGoVersions), "^\d+\.\d+")
$cachedTools.AddToolVersionsList("Node.js", $(Get-ToolcacheNodeVersions), "^\d+") $cachedTools.AddToolVersionsList("Node.js", $(Get-ToolcacheNodeVersions), "^\d+")
$cachedTools.AddToolVersionsList("Python", $(Get-ToolcachePythonVersions), "^\d+\.\d+") $cachedTools.AddToolVersionsList("Python", $(Get-ToolcachePythonVersions), "^\d+\.\d+")
$cachedTools.AddToolVersionsList("PyPy", $(Get-ToolcachePyPyVersions), "^\d+\.\d+") $cachedTools.AddToolVersionsList("PyPy", $(Get-ToolcachePyPyVersions), "^\d+\.\d+")
if (-not $(Test-IsUbuntu24)) { $cachedTools.AddToolVersionsList("Ruby", $(Get-ToolcacheRubyVersions), "^\d+\.\d+")
$cachedTools.AddToolVersionsList("Ruby", $(Get-ToolcacheRubyVersions), "^\d+\.\d+")
}
# PowerShell Tools
$powerShellTools = $installedSoftware.AddHeader("PowerShell Tools") $powerShellTools = $installedSoftware.AddHeader("PowerShell Tools")
$powerShellTools.AddToolVersion("PowerShell", $(Get-PowershellVersion)) $powerShellTools.AddToolVersion("PowerShell", $(Get-PowershellVersion))
$powerShellTools.AddHeader("PowerShell Modules").AddNodes($(Get-PowerShellModules)) $powerShellTools.AddHeader("PowerShell Modules").AddNodes($(Get-PowerShellModules))
@@ -274,12 +232,9 @@ $installedSoftware.AddHeader("Web Servers").AddTable($(Build-WebServersTable))
$androidTools = $installedSoftware.AddHeader("Android") $androidTools = $installedSoftware.AddHeader("Android")
$androidTools.AddTable($(Build-AndroidTable)) $androidTools.AddTable($(Build-AndroidTable))
$androidTools.AddHeader("Environment variables").AddTable($(Build-AndroidEnvironmentTable)) $androidTools.AddHeader("Environment variables").AddTable($(Build-AndroidEnvironmentTable))
if (-not $(Test-IsUbuntu24)) { $installedSoftware.AddHeader("Cached Docker images").AddTable($(Get-CachedDockerImagesTableData))
$installedSoftware.AddHeader("Cached Docker images").AddTable($(Get-CachedDockerImagesTableData))
}
$installedSoftware.AddHeader("Installed apt packages").AddTable($(Get-AptPackages)) $installedSoftware.AddHeader("Installed apt packages").AddTable($(Get-AptPackages))
$softwareReport.ToJson() | Out-File -FilePath "${OutputDirectory}/software-report.json" -Encoding UTF8NoBOM $softwareReport.ToJson() | Out-File -FilePath "${OutputDirectory}/software-report.json" -Encoding UTF8NoBOM
@@ -1,5 +1,5 @@
function Get-JavaVersionsTable { function Get-JavaVersionsTable {
$javaToolcacheVersions = Get-ChildItem $env:AGENT_TOOLSDIRECTORY/Java*/* -Directory | Sort-Object { [int] $_.Name.Split(".")[0] } $javaToolcacheVersions = Get-ChildItem $env:AGENT_TOOLSDIRECTORY/Java*/* -Directory | Sort-Object { [int]$_.Name.Split(".")[0] }
return $javaToolcacheVersions | ForEach-Object { return $javaToolcacheVersions | ForEach-Object {
$majorVersion = $_.Name.split(".")[0] $majorVersion = $_.Name.split(".")[0]
@@ -5,51 +5,51 @@ function Initialize-RustEnvironment {
} }
function Get-RustVersion { function Get-RustVersion {
$rustVersion = $(rustc --version) | Get-StringPart -Part 1 $rustVersion = $(rustc --version) | Take-OutputPart -Part 1
return $rustVersion return $rustVersion
} }
function Get-BindgenVersion { function Get-BindgenVersion {
$bindgenVersion = $(bindgen --version) | Get-StringPart -Part 1 $bindgenVersion = $(bindgen --version) | Take-OutputPart -Part 1
return $bindgenVersion return $bindgenVersion
} }
function Get-CargoVersion { function Get-CargoVersion {
$cargoVersion = $(cargo --version) | Get-StringPart -Part 1 $cargoVersion = $(cargo --version) | Take-OutputPart -Part 1
return $cargoVersion return $cargoVersion
} }
function Get-CargoAuditVersion { function Get-CargoAuditVersion {
$cargoAuditVersion = $(cargo-audit --version) | Get-StringPart -Part 1 $cargoAuditVersion = $(cargo-audit --version) | Take-OutputPart -Part 1
return $cargoAuditVersion return $cargoAuditVersion
} }
function Get-CargoOutdatedVersion { function Get-CargoOutdatedVersion {
$cargoOutdatedVersion = cargo outdated --version | Get-StringPart -Part 1 $cargoOutdatedVersion = cargo outdated --version | Take-OutputPart -Part 1
return $cargoOutdatedVersion return $cargoOutdatedVersion
} }
function Get-CargoClippyVersion { function Get-CargoClippyVersion {
$cargoClippyVersion = $(cargo-clippy --version) | Get-StringPart -Part 1 $cargoClippyVersion = $(cargo-clippy --version) | Take-OutputPart -Part 1
return $cargoClippyVersion return $cargoClippyVersion
} }
function Get-CbindgenVersion { function Get-CbindgenVersion {
$cbindgenVersion = $(cbindgen --version) | Get-StringPart -Part 1 $cbindgenVersion = $(cbindgen --version) | Take-OutputPart -Part 1
return $cbindgenVersion return $cbindgenVersion
} }
function Get-RustupVersion { function Get-RustupVersion {
$rustupVersion = $(rustup --version) | Get-StringPart -Part 1 $rustupVersion = $(rustup --version) | Take-OutputPart -Part 1
return $rustupVersion return $rustupVersion
} }
function Get-RustdocVersion { function Get-RustdocVersion {
$rustdocVersion = $(rustdoc --version) | Get-StringPart -Part 1 $rustdocVersion = $(rustdoc --version) | Take-OutputPart -Part 1
return $rustdocVersion return $rustdocVersion
} }
function Get-RustfmtVersion { function Get-RustfmtVersion {
$rustfmtVersion = $(rustfmt --version) | Get-StringPart -Part 1 | Get-StringPart -Part 0 -Delimiter "-" $rustfmtVersion = $(rustfmt --version) | Take-OutputPart -Part 1 | Take-OutputPart -Part 0 -Delimiter "-"
return $rustfmtVersion return $rustfmtVersion
} }
@@ -10,18 +10,18 @@ function Get-AptFastVersion {
} }
function Get-AzCopyVersion { function Get-AzCopyVersion {
$azcopyVersion = [string]$(azcopy --version) | Get-StringPart -Part 2 $azcopyVersion = azcopy --version | Take-OutputPart -Part 2
return "$azcopyVersion - available by ``azcopy`` and ``azcopy10`` aliases" return "$azcopyVersion - available by ``azcopy`` and ``azcopy10`` aliases"
} }
function Get-BazelVersion { function Get-BazelVersion {
$bazelVersion = bazel --version | Select-String "bazel" | Get-StringPart -Part 1 $bazelVersion = bazel --version | Select-String "bazel" | Take-OutputPart -Part 1
return $bazelVersion return $bazelVersion
} }
function Get-BazeliskVersion { function Get-BazeliskVersion {
$result = Get-CommandResult "bazelisk version" -Multiline $result = Get-CommandResult "bazelisk version" -Multiline
$bazeliskVersion = $result.Output | Select-String "Bazelisk version:" | Get-StringPart -Part 2 | Get-StringPart -Part 0 -Delimiter "v" $bazeliskVersion = $result.Output | Select-String "Bazelisk version:" | Take-OutputPart -Part 2 | Take-OutputPart -Part 0 -Delimiter "v"
return $bazeliskVersion return $bazeliskVersion
} }
@@ -39,32 +39,32 @@ function Get-CodeQLBundleVersion {
} }
function Get-PodManVersion { function Get-PodManVersion {
$podmanVersion = podman --version | Get-StringPart -Part 2 $podmanVersion = podman --version | Take-OutputPart -Part 2
return $podmanVersion return $podmanVersion
} }
function Get-BuildahVersion { function Get-BuildahVersion {
$buildahVersion = buildah --version | Get-StringPart -Part 2 $buildahVersion = buildah --version | Take-OutputPart -Part 2
return $buildahVersion return $buildahVersion
} }
function Get-SkopeoVersion { function Get-SkopeoVersion {
$skopeoVersion = skopeo --version | Get-StringPart -Part 2 $skopeoVersion = skopeo --version | Take-OutputPart -Part 2
return $skopeoVersion return $skopeoVersion
} }
function Get-CMakeVersion { function Get-CMakeVersion {
$cmakeVersion = cmake --version | Select-Object -First 1 | Get-StringPart -Part 2 $cmakeVersion = cmake --version | Select-Object -First 1 | Take-OutputPart -Part 2
return $cmakeVersion return $cmakeVersion
} }
function Get-DockerComposeV1Version { function Get-DockerComposeV1Version {
$composeVersion = docker-compose -v | Get-StringPart -Part 2 | Get-StringPart -Part 0 -Delimiter "," $composeVersion = docker-compose -v | Take-OutputPart -Part 2 | Take-OutputPart -Part 0 -Delimiter ","
return $composeVersion return $composeVersion
} }
function Get-DockerComposeV2Version { function Get-DockerComposeV2Version {
$composeVersion = docker compose version | Get-StringPart -Part 3 | Get-StringPart -Part 0 -Delimiter "v" $composeVersion = docker compose version | Take-OutputPart -Part 3 | Take-OutputPart -Part 0 -Delimiter "v"
return $composeVersion return $composeVersion
} }
@@ -79,62 +79,62 @@ function Get-DockerServerVersion {
} }
function Get-DockerBuildxVersion { function Get-DockerBuildxVersion {
$buildxVersion = docker buildx version | Get-StringPart -Part 1 | Get-StringPart -Part 0 -Delimiter "v" $buildxVersion = docker buildx version | Take-OutputPart -Part 1 | Take-OutputPart -Part 0 -Delimiter "v"
return $buildxVersion return $buildxVersion
} }
function Get-DockerAmazonECRCredHelperVersion { function Get-DockerAmazonECRCredHelperVersion {
$ecrVersion = docker-credential-ecr-login -v | Select-String "Version:" | Get-StringPart -Part 1 $ecrVersion = docker-credential-ecr-login -v | Select-String "Version:" | Take-OutputPart -Part 1
return $ecrVersion return $ecrVersion
} }
function Get-GitVersion { function Get-GitVersion {
$gitVersion = git --version | Get-StringPart -Part -1 $gitVersion = git --version | Take-OutputPart -Part -1
return $gitVersion return $gitVersion
} }
function Get-GitLFSVersion { function Get-GitLFSVersion {
$result = Get-CommandResult "git-lfs --version" $result = Get-CommandResult "git-lfs --version"
$gitlfsversion = $result.Output | Get-StringPart -Part 0 | Get-StringPart -Part 1 -Delimiter "/" $gitlfsversion = $result.Output | Take-OutputPart -Part 0 | Take-OutputPart -Part 1 -Delimiter "/"
return $gitlfsversion return $gitlfsversion
} }
function Get-GitFTPVersion { function Get-GitFTPVersion {
$gitftpVersion = git-ftp --version | Get-StringPart -Part 2 $gitftpVersion = git-ftp --version | Take-OutputPart -Part 2
return $gitftpVersion return $gitftpVersion
} }
function Get-GoogleCloudCLIVersion { function Get-GoogleCloudCLIVersion {
return (gcloud --version | Select-Object -First 1) | Get-StringPart -Part 3 return (gcloud --version | Select-Object -First 1) | Take-OutputPart -Part 3
} }
function Get-HavegedVersion { function Get-HavegedVersion {
$havegedVersion = dpkg-query --showformat='${Version}' --show haveged | Get-StringPart -Part 0 -Delimiter "-" $havegedVersion = dpkg-query --showformat='${Version}' --show haveged | Take-OutputPart -Part 0 -Delimiter "-"
return $havegedVersion return $havegedVersion
} }
function Get-HerokuVersion { function Get-HerokuVersion {
$herokuVersion = heroku version | Get-StringPart -Part 0 | Get-StringPart -Part 1 -Delimiter "/" $herokuVersion = heroku version | Take-OutputPart -Part 0 | Take-OutputPart -Part 1 -Delimiter "/"
return $herokuVersion return $herokuVersion
} }
function Get-HHVMVersion { function Get-HHVMVersion {
$hhvmVersion = hhvm --version | Select-Object -First 1 | Get-StringPart -Part 2 $hhvmVersion = hhvm --version | Select-Object -First 1 | Take-OutputPart -Part 2
return $hhvmVersion return $hhvmVersion
} }
function Get-SVNVersion { function Get-SVNVersion {
$svnVersion = svn --version | Select-Object -First 1 | Get-StringPart -Part 2 $svnVersion = svn --version | Select-Object -First 1 | Take-OutputPart -Part 2
return $svnVersion return $svnVersion
} }
function Get-KustomizeVersion { function Get-KustomizeVersion {
$kustomizeVersion = kustomize version --short | Get-StringPart -Part 0 | Get-StringPart -Part 1 -Delimiter "v" $kustomizeVersion = kustomize version --short | Take-OutputPart -Part 0 | Take-OutputPart -Part 1 -Delimiter "v"
return $kustomizeVersion return $kustomizeVersion
} }
function Get-KindVersion { function Get-KindVersion {
$kindVersion = kind version | Get-StringPart -Part 1 | Get-StringPart -Part 0 -Delimiter "v" $kindVersion = kind version | Take-OutputPart -Part 1 | Take-OutputPart -Part 0 -Delimiter "v"
return $kindVersion return $kindVersion
} }
@@ -144,21 +144,21 @@ function Get-KubectlVersion {
} }
function Get-MinikubeVersion { function Get-MinikubeVersion {
$minikubeVersion = minikube version --short | Get-StringPart -Part 0 -Delimiter "v" $minikubeVersion = minikube version --short | Take-OutputPart -Part 0 -Delimiter "v"
return $minikubeVersion return $minikubeVersion
} }
function Get-HGVersion { function Get-HGVersion {
$hgVersion = hg --version | Select-Object -First 1 | Get-StringPart -Part -1 | Get-StringPart -Part 0 -Delimiter ")" $hgVersion = hg --version | Select-Object -First 1 | Take-OutputPart -Part -1 | Take-OutputPart -Part 0 -Delimiter ")"
return $hgVersion return $hgVersion
} }
function Get-LeiningenVersion { function Get-LeiningenVersion {
return "$(lein -v | Get-StringPart -Part 1)" return "$(lein -v | Take-OutputPart -Part 1)"
} }
function Get-MediainfoVersion { function Get-MediainfoVersion {
$mediainfoVersion = (mediainfo --version | Select-Object -Index 1 | Get-StringPart -Part 2).Replace('v', '') $mediainfoVersion = (mediainfo --version | Select-Object -Index 1 | Take-OutputPart -Part 2).Replace('v', '')
return $mediainfoVersion return $mediainfoVersion
} }
@@ -177,7 +177,7 @@ function Get-NvmVersion {
} }
function Get-PackerVersion { function Get-PackerVersion {
$packerVersion = (packer --version | Select-String "^Packer").Line.Replace('v','') | Get-StringPart -Part 1 $packerVersion = packer --version
return $packerVersion return $packerVersion
} }
@@ -187,11 +187,11 @@ function Get-PhantomJSVersion {
} }
function Get-TerraformVersion { function Get-TerraformVersion {
return (terraform version | Select-String "^Terraform").Line.Replace('v','') | Get-StringPart -Part 1 return (terraform version | Select-String "^Terraform").Line.Replace('v','') | Take-OutputPart -Part 1
} }
function Get-JqVersion { function Get-JqVersion {
$jqVersion = jq --version | Get-StringPart -Part 1 -Delimiter "-" $jqVersion = jq --version | Take-OutputPart -Part 1 -Delimiter "-"
return $jqVersion return $jqVersion
} }
@@ -211,7 +211,7 @@ function Get-AlibabaCloudCliVersion {
function Get-AWSCliVersion { function Get-AWSCliVersion {
$result = Get-CommandResult "aws --version" $result = Get-CommandResult "aws --version"
$awsVersion = $result.Output | Get-StringPart -Part 0 | Get-StringPart -Part 1 -Delimiter "/" $awsVersion = $result.Output | Take-OutputPart -Part 0 | Take-OutputPart -Part 1 -Delimiter "/"
return $awsVersion return $awsVersion
} }
@@ -221,21 +221,21 @@ function Get-AWSCliSessionManagerPluginVersion {
} }
function Get-AWSSAMVersion { function Get-AWSSAMVersion {
return $(sam --version | Get-StringPart -Part -1) return $(sam --version | Take-OutputPart -Part -1)
} }
function Get-FastlaneVersion { function Get-FastlaneVersion {
$fastlaneVersion = fastlane --version | Select-String "^fastlane [0-9]" | Get-StringPart -Part 1 $fastlaneVersion = fastlane --version | Select-String "^fastlane [0-9]" | Take-OutputPart -Part 1
return $fastlaneVersion return $fastlaneVersion
} }
function Get-GitHubCliVersion { function Get-GitHubCliVersion {
$ghVersion = gh --version | Select-String "gh version" | Get-StringPart -Part 2 $ghVersion = gh --version | Select-String "gh version" | Take-OutputPart -Part 2
return $ghVersion return $ghVersion
} }
function Get-NetlifyCliVersion { function Get-NetlifyCliVersion {
$netlifyVersion = netlify --version | Get-StringPart -Part 0 | Get-StringPart -Part 1 -Delimiter "/" $netlifyVersion = netlify --version | Take-OutputPart -Part 0 | Take-OutputPart -Part 1 -Delimiter "/"
return $netlifyVersion return $netlifyVersion
} }
@@ -245,7 +245,7 @@ function Get-OCCliVersion {
} }
function Get-ORASCliVersion { function Get-ORASCliVersion {
$orasVersion = oras version | Select-String "^Version:" | Get-StringPart -Part 1 $orasVersion = oras version | Select-String "^Version:" | Take-OutputPart -Part 1
return $orasVersion return $orasVersion
} }
@@ -255,30 +255,30 @@ function Get-VerselCliversion {
} }
function Get-PulumiVersion { function Get-PulumiVersion {
$pulumiVersion = pulumi version | Get-StringPart -Part 0 -Delimiter "v" $pulumiVersion = pulumi version | Take-OutputPart -Part 0 -Delimiter "v"
return $pulumiVersion return $pulumiVersion
} }
function Get-RVersion { function Get-RVersion {
$rVersion = (Get-CommandResult "R --version | grep 'R version'").Output | Get-StringPart -Part 2 $rVersion = (Get-CommandResult "R --version | grep 'R version'").Output | Take-OutputPart -Part 2
return $rVersion return $rVersion
} }
function Get-SphinxVersion { function Get-SphinxVersion {
$sphinxVersion = searchd -h | Select-Object -First 1 | Get-StringPart -Part 1 | Get-StringPart -Part 0 -Delimiter "-" $sphinxVersion = searchd -h | Select-Object -First 1 | Take-OutputPart -Part 1 | Take-OutputPart -Part 0 -Delimiter "-"
return $sphinxVersion return $sphinxVersion
} }
function Get-YamllintVersion { function Get-YamllintVersion {
return $(yamllint --version) | Get-StringPart -Part 1 return $(yamllint --version) | Take-OutputPart -Part 1
} }
function Get-ZstdVersion { function Get-ZstdVersion {
$zstdVersion = zstd --version | Get-StringPart -Part 1 -Delimiter "v" | Get-StringPart -Part 0 -Delimiter "," $zstdVersion = zstd --version | Take-OutputPart -Part 1 -Delimiter "v" | Take-OutputPart -Part 0 -Delimiter ","
return "$zstdVersion" return "$zstdVersion"
} }
function Get-YqVersion { function Get-YqVersion {
$yqVersion = $(yq -V) | Get-StringPart -Part 3 $yqVersion = $(yq -V) | Take-OutputPart -Part 3
return $yqVersion.TrimStart("v").Trim() return $yqVersion.TrimStart("v").Trim()
} }
@@ -1,15 +1,15 @@
function Get-ApacheVersion { function Get-ApacheVersion {
$name = "apache2" $name = "apache2"
$port = 80 $port = 80
$version = bash -c "apache2 -v | grep -Po 'Apache/(\d+.){2}\d+'" | Get-StringPart -Part 1 -Delimiter "/" $version = bash -c "apache2 -v | grep -Po 'Apache/(\d+.){2}\d+'" | Take-OutputPart -Part 1 -Delimiter "/"
$serviceStatus = systemctl status apache2 | grep "Active:" | Get-StringPart -Part 1 $serviceStatus = systemctl status apache2 | grep "Active:" | Take-OutputPart -Part 1
$configFile = "/etc/apache2/apache2.conf" $configFile = "/etc/apache2/apache2.conf"
return [PsCustomObject]@{ return [PsCustomObject]@{
"Name" = $name "Name" = $name
"Version" = $version "Version" = $version
"ConfigFile" = $configFile "ConfigFile" = $configFile
"ServiceStatus" = $serviceStatus "ServiceStatus" = $serviceStatus
"ListenPort" = $port "ListenPort" = $port
} }
} }
@@ -17,14 +17,14 @@ function Get-NginxVersion {
$name = "nginx" $name = "nginx"
$port = 80 $port = 80
$version = (dpkg-query --showformat='${Version}' --show nginx).Split('-')[0] $version = (dpkg-query --showformat='${Version}' --show nginx).Split('-')[0]
$serviceStatus = systemctl status nginx | grep "Active:" | Get-StringPart -Part 1 $serviceStatus = systemctl status nginx | grep "Active:" | Take-OutputPart -Part 1
$configFile = "/etc/nginx/nginx.conf" $configFile = "/etc/nginx/nginx.conf"
return [PsCustomObject]@{ return [PsCustomObject]@{
"Name" = $name "Name" = $name
"Version" = $version "Version" = $version
"ConfigFile" = $configFile "ConfigFile" = $configFile
"ServiceStatus" = $serviceStatus "ServiceStatus" = $serviceStatus
"ListenPort" = $port "ListenPort" = $port
} }
} }
@@ -35,11 +35,11 @@ function Get-Xsp4Version {
$serviceStatus = systemctl show -p ActiveState --value mono-xsp4 $serviceStatus = systemctl show -p ActiveState --value mono-xsp4
$configFile = "/etc/default/mono-xsp4" $configFile = "/etc/default/mono-xsp4"
return [PsCustomObject]@{ return [PsCustomObject]@{
"Name" = $name "Name" = $name
"Version" = $version "Version" = $version
"ConfigFile" = $configFile "ConfigFile" = $configFile
"ServiceStatus" = $serviceStatus "ServiceStatus" = $serviceStatus
"ListenPort" = $port "ListenPort" = $port
} }
} }
@@ -0,0 +1,7 @@
#!/bin/bash -e
prefix=/usr/local/bin
for tool in apt apt-get apt-fast apt-key;do
sudo rm -f $prefix/$tool
done
@@ -1,15 +1,12 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################
## File: configure-apt-mock.sh # A temporary workaround for https://github.com/Azure/azure-linux-extensions/issues/1238
## Desc: A temporary workaround for https://github.com/Azure/azure-linux-extensions/issues/1238.
## Cleaned up during cleanup.sh.
################################################################################
prefix=/usr/local/bin prefix=/usr/local/bin
for real_tool in /usr/bin/apt /usr/bin/apt-get /usr/bin/apt-key; do for real_tool in /usr/bin/apt /usr/bin/apt-get /usr/bin/apt-fast /usr/bin/apt-key;do
tool=$(basename $real_tool) tool=`basename $real_tool`
cat >$prefix/$tool <<EOT cat >$prefix/$tool <<EOT
#!/bin/sh #!/bin/sh
i=1 i=1
@@ -50,5 +47,5 @@ while [ \$i -le 30 ];do
i=\$((i + 1)) i=\$((i + 1))
done done
EOT EOT
chmod +x $prefix/$tool chmod +x $prefix/$tool
done done
@@ -1,7 +1,7 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################ ################################################################################
## File: configure-apt-sources.sh ## File: apt-ubuntu-archive.sh
## Desc: Configure apt sources with failover from Azure to Ubuntu archives. ## Desc: Script for configuring apt sources. https://manpages.ubuntu.com/manpages/jammy/en/man1/apt-transport-mirror.1.html
################################################################################ ################################################################################
touch /etc/apt/apt-mirrors.txt touch /etc/apt/apt-mirrors.txt
@@ -12,5 +12,4 @@ printf "http://security.ubuntu.com/ubuntu/\tpriority:3\n" | tee -a /etc/apt/apt-
sed -i 's/http:\/\/azure.archive.ubuntu.com\/ubuntu\//mirror+file:\/etc\/apt\/apt-mirrors.txt/' /etc/apt/sources.list sed -i 's/http:\/\/azure.archive.ubuntu.com\/ubuntu\//mirror+file:\/etc\/apt\/apt-mirrors.txt/' /etc/apt/sources.list
# Apt changes to survive Cloud Init cp -f /etc/apt/sources.list /etc/cloud/templates/sources.list.ubuntu.tmpl
cp -f /etc/apt/sources.list /etc/cloud/templates/sources.list.ubuntu.tmpl
@@ -1,8 +1,4 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################
## File: configure-apt.sh
## Desc: Configure apt, install jq and apt-fast packages.
################################################################################
# Stop and disable apt-daily upgrade services; # Stop and disable apt-daily upgrade services;
systemctl stop apt-daily.timer systemctl stop apt-daily.timer
@@ -42,8 +38,6 @@ apt-get update
# Install jq # Install jq
apt-get install jq apt-get install jq
if ! is_ubuntu24; then # Install apt-fast using quick-install.sh
# Install apt-fast using quick-install.sh # https://github.com/ilikenwf/apt-fast
# https://github.com/ilikenwf/apt-fast bash -c "$(curl -fsSL https://raw.githubusercontent.com/ilikenwf/apt-fast/master/quick-install.sh)"
bash -c "$(curl -fsSL https://raw.githubusercontent.com/ilikenwf/apt-fast/master/quick-install.sh)"
fi
@@ -1,8 +1,4 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################
## File: configure-limits.sh
## Desc: Configure limits
################################################################################
echo 'session required pam_limits.so' >> /etc/pam.d/common-session echo 'session required pam_limits.so' >> /etc/pam.d/common-session
echo 'session required pam_limits.so' >> /etc/pam.d/common-session-noninteractive echo 'session required pam_limits.so' >> /etc/pam.d/common-session-noninteractive
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash -e
################################################################################
## File: reboot.sh
## Desc: Reboot VM
################################################################################
echo "Reboot VM"
sudo reboot
@@ -1,13 +1,13 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################ ################################################################################
## File: install-ms-repos.sh ## File: repos.sh
## Desc: Install official Microsoft package repos for the distribution ## Desc: Installs official Microsoft package repos for the distribution
################################################################################ ################################################################################
os_label=$(lsb_release -rs) LSB_RELEASE=$(lsb_release -rs)
# Install Microsoft repository # Install Microsoft repository
wget https://packages.microsoft.com/config/ubuntu/$os_label/packages-microsoft-prod.deb wget https://packages.microsoft.com/config/ubuntu/$LSB_RELEASE/packages-microsoft-prod.deb
dpkg -i packages-microsoft-prod.deb dpkg -i packages-microsoft-prod.deb
# update # update
@@ -1,16 +1,4 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################
## File: configure-snap.sh
## Desc: Configure snap
################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/etc-environment.sh
# Update /etc/environment to include /snap/bin in PATH
# because /etc/profile.d is ignored by `--norc` shell launch option
prepend_etc_environment_path "/snap/bin"
# Put snapd auto refresh on hold # Put snapd auto refresh on hold
# as it may generate too much traffic on Canonical's snap server # as it may generate too much traffic on Canonical's snap server
@@ -0,0 +1,93 @@
function Get-CommandResult {
param (
[Parameter(Mandatory=$true)]
[string] $Command,
[int[]] $ExpectExitCode = 0,
[switch] $Multiline,
[bool] $ValidateExitCode = $true
)
# Bash trick to suppress and show error output because some commands write to stderr (for example, "python --version")
$stdout = & bash -c "$Command 2>&1"
$exitCode = $LASTEXITCODE
if ($ValidateExitCode) {
if ($ExpectExitCode -notcontains $exitCode) {
try {
throw "StdOut: '$stdout' ExitCode: '$exitCode'"
} catch {
Write-Host $_.Exception.Message
Write-Host $_.ScriptStackTrace
exit $LASTEXITCODE
}
}
}
return @{
Output = If ($Multiline -eq $true) { $stdout } else { [string]$stdout }
ExitCode = $exitCode
}
}
function Get-OSVersionShort {
$(Get-OSVersionFull) | Take-OutputPart -Delimiter '.' -Part 0,1
}
function Get-OSVersionFull {
lsb_release -ds | Take-OutputPart -Part 1, 2
}
function Get-KernelVersion {
$kernelVersion = uname -r
return $kernelVersion
}
function Test-IsUbuntu20 {
return (lsb_release -rs) -eq "20.04"
}
function Test-IsUbuntu22 {
return (lsb_release -rs) -eq "22.04"
}
function Get-ToolsetContent {
$toolset = Join-Path $env:INSTALLER_SCRIPT_FOLDER "toolset.json"
Get-Content $toolset -Raw | ConvertFrom-Json
}
function Get-ToolsetValue {
param (
[Parameter(Mandatory = $true)]
[string] $KeyPath
)
$jsonNode = Get-ToolsetContent
$pathParts = $KeyPath.Split(".")
# try to walk through all arguments consequentially to resolve specific json node
$pathParts | ForEach-Object {
$jsonNode = $jsonNode.$_
}
return $jsonNode
}
function Get-AndroidPackages {
$packagesListFile = "/usr/local/lib/android/sdk/packages-list.txt"
if (-Not (Test-Path -Path $packagesListFile -PathType Leaf)) {
(/usr/local/lib/android/sdk/cmdline-tools/latest/bin/sdkmanager --list --verbose 2>&1) |
Where-Object { $_ -Match "^[^\s]" } |
Where-Object { $_ -NotMatch "^(Loading |Info: Parsing |---|\[=+|Installed |Available )" } |
Where-Object { $_ -NotMatch "^[^;]*$" } |
Out-File -FilePath $packagesListFile
Write-Host Android packages list:
Get-Content $packagesListFile
}
return Get-Content $packagesListFile
}
function Get-EnvironmentVariable($variable) {
return [System.Environment]::GetEnvironmentVariable($variable)
}
@@ -0,0 +1,41 @@
function Take-OutputPart {
param (
[Parameter(ValueFromPipeline)]
[string] $toolOutput,
[string] $Delimiter = " ",
[int[]] $Part
)
$parts = $toolOutput.Split($Delimiter, [System.StringSplitOptions]::RemoveEmptyEntries)
$selectedParts = $parts[$Part]
return [string]::Join($Delimiter, $selectedParts)
}
function Restore-UserOwner {
sudo chown -R ${env:USER}: $env:HOME
}
function Get-LinkTarget {
param (
[string] $inputPath
)
$link = Get-Item $inputPath | Select-Object -ExpandProperty Target
if ($link) {
return " -> $link"
}
return ""
}
function Get-PathWithLink {
param (
[string] $inputPath
)
$link = Get-LinkTarget($inputPath)
return "${inputPath}${link}"
}
function Get-AptSourceRepository {
param([String] $PackageName)
$sourceUrl = Get-Content "$PSScriptRoot/../helpers/apt-sources.txt" | Select-String -Pattern $PackageName | Take-OutputPart -Part (1..3)
return $sourceUrl
}
@@ -1,32 +1,13 @@
Import-Module "$PSScriptRoot/../helpers/Common.Helpers.psm1" -DisableNameChecking Import-Module "$PSScriptRoot/../helpers/Common.Helpers.psm1" -DisableNameChecking
# Validates that tool is installed and in PATH
function Validate-ToolExist($tool) {
Get-Command $tool -ErrorAction SilentlyContinue | Should -BeTrue
}
function Invoke-PesterTests { function Invoke-PesterTests {
<#
.SYNOPSIS
Runs Pester tests based on the provided test file and test name.
.DESCRIPTION
The Invoke-PesterTests function runs Pester tests based on the provided test file and test name.
.PARAMETER TestFile
The name of the test file to run. This should be the base name of the test file without the extension.
Using "*" will run all tests from all test files.
.PARAMETER TestName
The name of the specific test to run. If provided, only the test with the matching name will be executed.
.EXAMPLE
Invoke-PesterTests -TestFile "MyTests" -TestName "Test1"
Runs the test named "Test1" from the test file "MyTests.Tests.ps1".
.EXAMPLE
Invoke-PesterTests -TestFile "*"
Runs all tests from all test files
#>
Param( Param(
[Parameter(Mandatory = $true)] [Parameter(Mandatory)][string] $TestFile,
[string] $TestFile,
[string] $TestName [string] $TestName
) )
@@ -36,12 +17,12 @@ function Invoke-PesterTests {
} }
# Check that Pester module is imported # Check that Pester module is imported
if (-not (Get-Module "Pester")) { if (!(Get-Module "Pester")) {
Import-Module Pester Import-Module Pester
} }
$configuration = [PesterConfiguration] @{ $configuration = [PesterConfiguration] @{
Run = @{ Path = $testPath; PassThru = $true } Run = @{ Path = $testPath; PassThru = $true }
Output = @{ Verbosity = "Detailed"; RenderMode = "Plaintext" } Output = @{ Verbosity = "Detailed"; RenderMode = "Plaintext" }
} }
if ($TestName) { if ($TestName) {
@@ -62,29 +43,6 @@ function Invoke-PesterTests {
} }
function ShouldReturnZeroExitCode { function ShouldReturnZeroExitCode {
<#
.SYNOPSIS
Implements a custom Should-operator for the Pester framework.
.DESCRIPTION
This function is used to check if a command has returned a zero exit code.
It can be used by registering it using the Add-ShouldOperator function in Pester.
.PARAMETER ActualValue
The actual value to be checked.
.PARAMETER Negate
A switch parameter that, when specified, negates the result of the check.
.PARAMETER Because
An optional string that provides additional context or explanation for the check.
.NOTES
This function is designed to be used with the Pester framework.
.LINK
https://pester.dev/docs/assertions/custom-assertions
#>
Param( Param(
[string] $ActualValue, [string] $ActualValue,
[switch] $Negate, [switch] $Negate,
@@ -93,10 +51,11 @@ function ShouldReturnZeroExitCode {
$result = Get-CommandResult $ActualValue -ValidateExitCode $false $result = Get-CommandResult $ActualValue -ValidateExitCode $false
[bool] $succeeded = $result.ExitCode -eq 0 [bool]$succeeded = $result.ExitCode -eq 0
if ($Negate) { $succeeded = -not $succeeded } if ($Negate) { $succeeded = -not $succeeded }
if (-not $succeeded) { if (-not $succeeded)
{
$commandOutputIndent = " " * 4 $commandOutputIndent = " " * 4
$commandOutput = ($result.Output | ForEach-Object { "${commandOutputIndent}${_}" }) -join "`n" $commandOutput = ($result.Output | ForEach-Object { "${commandOutputIndent}${_}" }) -join "`n"
$failureMessage = "Command '${ActualValue}' has finished with exit code`n${commandOutput}" $failureMessage = "Command '${ActualValue}' has finished with exit code`n${commandOutput}"
@@ -108,30 +67,7 @@ function ShouldReturnZeroExitCode {
} }
} }
function ShouldOutputTextMatchingRegex { function ShouldMatchCommandOutput {
<#
.SYNOPSIS
Implements a custom Should-operator for the Pester framework.
.DESCRIPTION
This function is used to check if a command outputs text that matches a regular expression.
It can be used by registering it using the Add-ShouldOperator function in Pester.
.PARAMETER ActualValue
The actual value to be checked.
.PARAMETER RegularExpression
The regular expression to be used for the check.
.PARAMETER Negate
A switch parameter that, when specified, negates the result of the check.
.NOTES
This function is designed to be used with the Pester framework.
.LINK
https://pester.dev/docs/assertions/custom-assertions
#>
Param( Param(
[string] $ActualValue, [string] $ActualValue,
[string] $RegularExpression, [string] $RegularExpression,
@@ -141,14 +77,17 @@ function ShouldOutputTextMatchingRegex {
$output = (Get-CommandResult $ActualValue -ValidateExitCode $false).Output | Out-String $output = (Get-CommandResult $ActualValue -ValidateExitCode $false).Output | Out-String
[bool] $succeeded = $output -cmatch $RegularExpression [bool] $succeeded = $output -cmatch $RegularExpression
if ($Negate) { $succeeded = -not $succeeded } if ($Negate) {
$succeeded = -not $succeeded
}
$failureMessage = '' $failureMessage = ''
if (-not $succeeded) { if (-not $succeeded) {
if ($Negate) { if ($Negate) {
$failureMessage = "Expected regular expression '$RegularExpression' for '$ActualValue' command to not match '$output', but it did match." $failureMessage = "Expected regular expression '$RegularExpression' for '$ActualValue' command to not match '$output', but it did match."
} else { }
else {
$failureMessage = "Expected regular expression '$RegularExpression' for '$ActualValue' command to match '$output', but it did not match." $failureMessage = "Expected regular expression '$RegularExpression' for '$ActualValue' command to match '$output', but it did not match."
} }
} }
@@ -161,5 +100,5 @@ function ShouldOutputTextMatchingRegex {
If (Get-Command -Name Add-ShouldOperator -ErrorAction SilentlyContinue) { If (Get-Command -Name Add-ShouldOperator -ErrorAction SilentlyContinue) {
Add-ShouldOperator -Name ReturnZeroExitCode -InternalName ShouldReturnZeroExitCode -Test ${function:ShouldReturnZeroExitCode} Add-ShouldOperator -Name ReturnZeroExitCode -InternalName ShouldReturnZeroExitCode -Test ${function:ShouldReturnZeroExitCode}
Add-ShouldOperator -Name OutputTextMatchingRegex -InternalName ShouldOutputTextMatchingRegex -Test ${function:ShouldOutputTextMatchingRegex} Add-ShouldOperator -Name MatchCommandOutput -InternalName ShouldMatchCommandOutput -Test ${function:ShouldMatchCommandOutput}
} }
@@ -8,67 +8,62 @@
# values containg slashes (i.e. directory path) # values containg slashes (i.e. directory path)
# The values containing '%' will break the functions # The values containing '%' will break the functions
get_etc_environment_variable() { function getEtcEnvironmentVariable {
local variable_name=$1 variable_name="$1"
# remove `variable_name=` and possible quotes from the line # remove `variable_name=` and possible quotes from the line
grep "^${variable_name}=" /etc/environment | sed -E "s%^${variable_name}=\"?([^\"]+)\"?.*$%\1%" grep "^${variable_name}=" /etc/environment |sed -E "s%^${variable_name}=\"?([^\"]+)\"?.*$%\1%"
} }
add_etc_environment_variable() { function addEtcEnvironmentVariable {
local variable_name=$1 variable_name="$1"
local variable_value=$2 variable_value="$2"
echo "${variable_name}=${variable_value}" | sudo tee -a /etc/environment echo "$variable_name=$variable_value" | sudo tee -a /etc/environment
} }
replace_etc_environment_variable() { function replaceEtcEnvironmentVariable {
local variable_name=$1 variable_name="$1"
local variable_value=$2 variable_value="$2"
# modify /etc/environemnt in place by replacing a string that begins with variable_name # modify /etc/environemnt in place by replacing a string that begins with variable_name
sudo sed -i -e "s%^${variable_name}=.*$%${variable_name}=${variable_value}%" /etc/environment sudo sed -i -e "s%^${variable_name}=.*$%${variable_name}=\"${variable_value}\"%" /etc/environment
} }
set_etc_environment_variable() { function setEtcEnvironmentVariable {
local variable_name=$1 variable_name="$1"
local variable_value=$2 variable_value="$2"
if grep "^${variable_name}=" /etc/environment > /dev/null; then if grep "$variable_name" /etc/environment > /dev/null; then
replace_etc_environment_variable $variable_name $variable_value replaceEtcEnvironmentVariable $variable_name $variable_value
else else
add_etc_environment_variable $variable_name $variable_value addEtcEnvironmentVariable $variable_name $variable_value
fi fi
} }
prepend_etc_environment_variable() { function prependEtcEnvironmentVariable {
local variable_name=$1 variable_name="$1"
local element=$2 element="$2"
# TODO: handle the case if the variable does not exist # TODO: handle the case if the variable does not exist
existing_value=$(get_etc_environment_variable "${variable_name}") existing_value=$(getEtcEnvironmentVariable "${variable_name}")
set_etc_environment_variable "${variable_name}" "${element}:${existing_value}" setEtcEnvironmentVariable "${variable_name}" "${element}:${existing_value}"
} }
append_etc_environment_variable() { function appendEtcEnvironmentVariable {
local variable_name=$1 variable_name="$1"
local element=$2 element="$2"
# TODO: handle the case if the variable does not exist # TODO: handle the case if the variable does not exist
existing_value=$(get_etc_environment_variable "${variable_name}") existing_value=$(getEtcEnvironmentVariable "${variable_name}")
set_etc_environment_variable "${variable_name}" "${existing_value}:${element}" setEtcEnvironmentVariable "${variable_name}" "${existing_value}:${element}"
} }
prepend_etc_environment_path() { function prependEtcEnvironmentPath {
local element=$1 element="$1"
prependEtcEnvironmentVariable PATH "${element}"
prepend_etc_environment_variable PATH "${element}"
} }
append_etc_environment_path() { function appendEtcEnvironmentPath {
local element=$1 element="$1"
appendEtcEnvironmentVariable PATH "${element}"
append_etc_environment_variable PATH "${element}"
} }
# Process /etc/environment as if it were shell script with `export VAR=...` expressions # Process /etc/environment as if it were shell script with `export VAR=...` expressions
@@ -80,10 +75,11 @@ append_etc_environment_path() {
# TODO: there might be the others variables to be processed in the same way as "PATH" variable # TODO: there might be the others variables to be processed in the same way as "PATH" variable
# ie MANPATH, INFOPATH, LD_*, etc. In the current implementation the values from /etc/evironments # ie MANPATH, INFOPATH, LD_*, etc. In the current implementation the values from /etc/evironments
# replace the values of the current environment # replace the values of the current environment
reload_etc_environment() { function reloadEtcEnvironment {
# add `export ` to every variable of /etc/environemnt except PATH and eval the result shell script # add `export ` to every variable of /etc/environemnt except PATH and eval the result shell script
eval $(grep -v '^PATH=' /etc/environment | sed -e 's%^%export %') eval $(grep -v '^PATH=' /etc/environment | sed -e 's%^%export %')
# handle PATH specially # handle PATH specially
etc_path=$(get_etc_environment_variable PATH) etc_path=$(getEtcEnvironmentVariable PATH)
export PATH="$PATH:$etc_path" export PATH="$PATH:$etc_path"
} }
+175
View File
@@ -0,0 +1,175 @@
#!/bin/bash -e
################################################################################
## File: install.sh
## Desc: Helper functions for installing tools
################################################################################
download_with_retries() {
# Due to restrictions of bash functions, positional arguments are used here.
# In case if you using latest argument NAME, you should also set value to all previous parameters.
# Example: download_with_retries $ANDROID_SDK_URL "." "android_sdk.zip"
local URL="$1"
local DEST="${2:-.}"
local NAME="${3:-${URL##*/}}"
local COMPRESSED="$4"
if [[ $COMPRESSED == "compressed" ]]; then
local COMMAND="curl $URL -4 -sL --compressed -o '$DEST/$NAME' -w '%{http_code}'"
else
local COMMAND="curl $URL -4 -sL -o '$DEST/$NAME' -w '%{http_code}'"
fi
# Save current errexit state and disable it to prevent unexpected exit on error
if echo $SHELLOPTS | grep '\(^\|:\)errexit\(:\|$\)' > /dev/null;
then
local ERR_EXIT_ENABLED=true
else
local ERR_EXIT_ENABLED=false
fi
set +e
echo "Downloading '$URL' to '${DEST}/${NAME}'..."
retries=20
interval=30
while [ $retries -gt 0 ]; do
((retries--))
test "$ERR_EXIT_ENABLED" = true && set +e
http_code=$(eval $COMMAND)
exit_code=$?
test "$ERR_EXIT_ENABLED" = true && set -e
if [ $http_code -eq 200 ] && [ $exit_code -eq 0 ]; then
echo "Download completed"
return 0
else
echo "Error — Either HTTP response code for '$URL' is wrong - '$http_code' or exit code is not 0 - '$exit_code'. Waiting $interval seconds before the next attempt, $retries attempts left"
sleep $interval
fi
done
echo "Could not download $URL"
return 1
}
## Use dpkg to figure out if a package has already been installed
## Example use:
## if ! IsPackageInstalled packageName; then
## echo "packageName is not installed!"
## fi
IsPackageInstalled() {
dpkg -S $1 &> /dev/null
}
verlte() {
sortedVersion=$(echo -e "$1\n$2" | sort -V | head -n1)
[ "$1" = "$sortedVersion" ]
}
get_toolset_path() {
echo "/imagegeneration/installers/toolset.json"
}
get_toolset_value() {
local toolset_path=$(get_toolset_path)
local query=$1
echo "$(jq -r "$query" $toolset_path)"
}
get_github_package_download_url() {
local REPO_ORG=$1
local FILTER=$2
local VERSION=$3
local SEARCH_IN_COUNT="100"
json=$(curl -fsSL "https://api.github.com/repos/${REPO_ORG}/releases?per_page=${SEARCH_IN_COUNT}")
if [ -n "$VERSION" ]; then
tagName=$(echo $json | jq -r '.[] | select(.prerelease==false).tag_name' | sort --unique --version-sort | egrep -v ".*-[a-z]|beta" | egrep "\w*${VERSION}" | tail -1)
else
tagName=$(echo $json | jq -r '.[] | select((.prerelease==false) and (.assets | length > 0)).tag_name' | sort --unique --version-sort | egrep -v ".*-[a-z]|beta" | tail -1)
fi
downloadUrl=$(echo $json | jq -r ".[] | select(.tag_name==\"${tagName}\").assets[].browser_download_url | select(${FILTER})" | head -n 1)
if [ -z "$downloadUrl" ]; then
echo "Failed to parse a download url for the '${tagName}' tag using '${FILTER}' filter"
exit 1
fi
echo $downloadUrl
}
get_github_package_hash() {
local repo_owner=$1
local repo_name=$2
local file_name=$3
local url=$4
local version=${5:-"latest"}
local prerelease=${6:-false}
local delimiter=${7:-'|'}
local word_number=${8:-2}
if [[ -z "$file_name" ]]; then
echo "File name is not specified."
exit 1
fi
if [[ -n "$url" ]]; then
release_url="$url"
else
if [ "$version" == "latest" ]; then
release_url="https://api.github.com/repos/${repo_owner}/${repo_name}/releases/latest"
else
json=$(curl -fsSL "https://api.github.com/repos/${repo_owner}/${repo_name}/releases?per_page=100")
tags=$(echo "$json" | jq -r --arg prerelease "$prerelease" '.[] | select(.prerelease == ($prerelease | test("true"; "i"))) | .tag_name')
tag=$(echo "$tags" | grep -o "$version")
if [[ "$(echo "$tag" | wc -l)" -gt 1 ]]; then
echo "Multiple tags found matching the version $version. Please specify a more specific version."
exit 1
fi
if [[ -z "$tag" ]]; then
echo "Failed to get a tag name for version $version."
exit 1
fi
release_url="https://api.github.com/repos/${repo_owner}/${repo_name}/releases/tags/$tag"
fi
fi
body=$(curl -fsSL "$release_url" | jq -r '.body' | tr -d '`')
matching_line=$(echo "$body" | grep "$file_name")
if [[ "$(echo "$matching_line" | wc -l)" -gt 1 ]]; then
echo "Multiple lines found included the file $file_name. Please specify a more specific file name."
exit 1
fi
if [[ -z "$matching_line" ]]; then
echo "File name '$file_name' not found in release body."
exit 1
fi
result=$(echo "$matching_line" | cut -d "$delimiter" -f "$word_number" | tr -d -c '[:alnum:]')
if [[ -z "$result" ]]; then
echo "Empty result. Check parameters delimiter and/or word_number for the matching line."
exit 1
fi
echo "$result"
}
use_checksum_comparison() {
local file_path=$1
local checksum=$2
local sha_type=${3:-"256"}
echo "Performing checksum verification"
if [[ ! -f "$file_path" ]]; then
echo "File not found: $file_path"
exit 1
fi
local_file_hash=$(shasum --algorithm "$sha_type" "$file_path" | awk '{print $1}')
if [[ "$local_file_hash" != "$checksum" ]]; then
echo "Checksum verification failed. Expected hash: $checksum; Actual hash: $local_file_hash."
exit 1
else
echo "Checksum verification passed"
fi
}
@@ -4,5 +4,5 @@
## Desc: Helper function for invoking tests ## Desc: Helper function for invoking tests
################################################################################ ################################################################################
pwsh -Command "Import-Module '$HELPER_SCRIPTS/../tests/Helpers.psm1' -DisableNameChecking pwsh -Command "Import-Module '$HELPER_SCRIPTS/Tests.Helpers.psm1' -DisableNameChecking
Invoke-PesterTests -TestFile \"$1\" -TestName \"$2\"" Invoke-PesterTests -TestFile \"$1\" -TestName \"$2\""
+20
View File
@@ -0,0 +1,20 @@
#!/bin/bash -e
################################################################################
## File: install-helpers.sh
## Desc: Helper functions for installing tools
################################################################################
function isUbuntu20
{
lsb_release -d | grep -q 'Ubuntu 20'
}
function isUbuntu22
{
lsb_release -d | grep -q 'Ubuntu 22'
}
function getOSVersionLabel
{
lsb_release -cs
}
@@ -0,0 +1,95 @@
################################################################################
## File: Configure-Toolset.ps1
## Team: CI-Build
## Desc: Configure toolset
################################################################################
Import-Module "$env:HELPER_SCRIPTS/Tests.Helpers.psm1" -DisableNameChecking
function Get-ToolsetToolFullPath
{
param
(
[Parameter(Mandatory)] [string] $ToolName,
[Parameter(Mandatory)] [string] $ToolVersion,
[Parameter(Mandatory)] [string] $ToolArchitecture
)
$toolPath = Join-Path -Path $env:AGENT_TOOLSDIRECTORY -ChildPath $toolName
$toolPathVersion = Join-Path -Path $toolPath -ChildPath $toolVersion
$foundVersion = Get-Item $toolPathVersion | Sort-Object -Property {[version]$_.name} -Descending | Select-Object -First 1
$installationDir = Join-Path -Path $foundVersion -ChildPath $toolArchitecture
return $installationDir
}
function Add-EnvironmentVariable
{
param
(
[Parameter(Mandatory)] [string] $Name,
[Parameter(Mandatory)] [string] $Value,
[string] $FilePath = "/etc/environment"
)
$envVar = "{0}={1}" -f $name, $value
Tee-Object -InputObject $envVar -FilePath $filePath -Append
}
$ErrorActionPreference = "Stop"
Write-Host "Configure toolset tools environment..."
$toolsEnvironment = @{
go = @{
command = "ln -s {0}/bin/* /usr/bin/"
variableTemplate = "GOROOT_{0}_{1}_X64"
}
}
$toolset = Get-Content -Path "$env:INSTALLER_SCRIPT_FOLDER/toolset.json" -Raw | ConvertFrom-Json
foreach ($tool in $toolset.toolcache)
{
$toolName = $tool.name
$toolArch = $tool.arch
$toolEnvironment = $toolsEnvironment[$toolName]
if (-not $toolEnvironment)
{
continue
}
foreach ($toolVersion in $tool.versions)
{
Write-Host "Set $toolName $toolVersion environment variable..."
$toolPath = Get-ToolsetToolFullPath -ToolName $toolName -ToolVersion $toolVersion -ToolArchitecture $toolArch
$envName = $toolEnvironment.variableTemplate -f $toolVersion.split(".")
# Add environment variable name=value
Add-EnvironmentVariable -Name $envName -Value $toolPath
}
# Invoke command and add env variable for the default tool version
$toolDefVersion = $tool.default
if (-not $toolDefVersion)
{
continue
}
$envDefName = $toolEnvironment.defaultVariable
$toolPath = Get-ToolsetToolFullPath -ToolName $toolName -ToolVersion $toolDefVersion -ToolArchitecture $toolArch
if ($envDefName)
{
Write-Host "Set default $envDefName for $toolName $toolDefVersion environment variable..."
Add-EnvironmentVariable -Name $envDefName -Value $toolPath
}
if ($toolEnvironment.command)
{
$command = $toolEnvironment.command -f $toolPath
Write-Host "Invoke $command command for default $toolName $toolDefVersion..."
Invoke-Expression -Command $command
}
}
Invoke-PesterTests -TestFile "Toolset" -TestName "Toolset"
@@ -0,0 +1,40 @@
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
Import-Module "$env:HELPER_SCRIPTS/Tests.Helpers.psm1" -DisableNameChecking
# Get modules content from toolset
$modules = (Get-ToolsetContent).azureModules
$installPSModulePath = "/usr/share"
foreach ($module in $modules)
{
$moduleName = $module.name
Write-Host "Installing ${moduleName} to the ${installPSModulePath} path..."
foreach ($version in $module.versions)
{
$modulePath = Join-Path -Path $installPSModulePath -ChildPath "${moduleName}_${version}"
Write-Host " - $version [$modulePath]"
Save-Module -Path $modulePath -Name $moduleName -RequiredVersion $version -Force
}
$assets = Invoke-RestMethod $module.url
# Get github release asset for each version
foreach ($toolVersion in $module.zip_versions) {
$asset = $assets | Where-Object version -eq $toolVersion `
| Select-Object -ExpandProperty files `
| Select-Object -First 1
Write-Host "Installing $($module.name) $toolVersion ..."
if ($null -ne $asset) {
Write-Host "Download $($asset.filename)"
wget $asset.download_url -nv --retry-connrefused --tries=10 -P $installPSModulePath
} else {
Write-Host "Asset was not found in versions manifest"
exit 1
}
}
}
Invoke-PesterTests -TestFile "PowerShellModules" -TestName "AzureModules"
@@ -1,35 +1,34 @@
################################################################################ $ErrorActionPreference = "Stop"
## File: Install-PowerShellModules.ps1 $ProgressPreference = "SilentlyContinue"
## Desc: Install modules for PowerShell
################################################################################ Import-Module "$env:HELPER_SCRIPTS/Tests.Helpers.psm1" -DisableNameChecking
$ErrorActionPreference = "Stop" # Specifies the installation policy
$ProgressPreference = "SilentlyContinue" Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
Import-Module "$env:HELPER_SCRIPTS/../tests/Helpers.psm1" # Try to update PowerShellGet before the actual installation
Install-Module -Name PowerShellGet -Force
# Specifies the installation policy Update-Module -Name PowerShellGet -Force
Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
# Install PowerShell modules
# Try to update PowerShellGet before the actual installation $modules = (Get-ToolsetContent).powershellModules
Install-Module -Name PowerShellGet -Force
Update-Module -Name PowerShellGet -Force foreach($module in $modules)
{
# Install PowerShell modules $moduleName = $module.name
$modules = (Get-ToolsetContent).powershellModules Write-Host "Installing ${moduleName} module"
foreach($module in $modules) { if ($module.versions)
$moduleName = $module.name {
foreach ($version in $module.versions)
Write-Host "Installing ${moduleName} module" {
if ($module.versions) { Write-Host " - $version"
foreach ($version in $module.versions) { Install-Module -Name $moduleName -RequiredVersion $version -Scope AllUsers -SkipPublisherCheck -Force
Write-Host " - $version" }
Install-Module -Name $moduleName -RequiredVersion $version -Scope AllUsers -SkipPublisherCheck -Force continue
} }
} else {
Install-Module -Name $moduleName -Scope AllUsers -SkipPublisherCheck -Force Install-Module -Name $moduleName -Scope AllUsers -SkipPublisherCheck -Force
} }
}
Invoke-PesterTests -TestFile "PowerShellModules" -TestName "PowerShellModules"
Invoke-PesterTests -TestFile "PowerShellModules" -TestName "PowerShellModules"
@@ -4,21 +4,19 @@
## Desc: Install toolset ## Desc: Install toolset
################################################################################ ################################################################################
Import-Module "$env:HELPER_SCRIPTS/../tests/Helpers.psm1" Function Install-Asset {
function Install-Asset {
param( param(
[Parameter(Mandatory = $true)] [Parameter(Mandatory = $true)]
[object] $ReleaseAsset [object] $ReleaseAsset
) )
Write-Host "Download $($ReleaseAsset.filename)" Write-Host "Download $($ReleaseAsset.filename)"
$assetArchivePath = Invoke-DownloadWithRetry $ReleaseAsset.download_url wget $ReleaseAsset.download_url -nv --retry-connrefused --tries=10
Write-Host "Extract $($ReleaseAsset.filename) content..." Write-Host "Extract $($ReleaseAsset.filename) content..."
$assetFolderPath = Join-Path "/tmp" "$($ReleaseAsset.filename)-temp-dir" $assetFolderPath = Join-Path "/tmp" $($ReleaseAsset.filename)
New-Item -ItemType Directory -Path $assetFolderPath | Out-Null New-Item -ItemType Directory -Path $assetFolderPath
tar -xzf $assetArchivePath -C $assetFolderPath tar -xzf $ReleaseAsset.filename -C $assetFolderPath
Write-Host "Invoke installation script..." Write-Host "Invoke installation script..."
Push-Location -Path $assetFolderPath Push-Location -Path $assetFolderPath
@@ -28,8 +26,10 @@ function Install-Asset {
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
# Get toolcache content from toolset # Get toolset content
$tools = (Get-ToolsetContent).toolcache | Where-Object { $_.url -ne $null } $toolset = Get-Content -Path "$env:INSTALLER_SCRIPT_FOLDER/toolset.json" -Raw
$tools = ConvertFrom-Json -InputObject $toolset | Select-Object -ExpandProperty toolcache | Where-Object {$_.url -ne $null }
foreach ($tool in $tools) { foreach ($tool in $tools) {
# Get versions manifest for current tool # Get versions manifest for current tool
@@ -38,18 +38,17 @@ foreach ($tool in $tools) {
# Get github release asset for each version # Get github release asset for each version
foreach ($toolVersion in $tool.versions) { foreach ($toolVersion in $tool.versions) {
$asset = $assets | Where-Object version -like $toolVersion ` $asset = $assets | Where-Object version -like $toolVersion `
| Select-Object -ExpandProperty files ` | Select-Object -ExpandProperty files `
| Where-Object { ($_.platform -eq $tool.platform) -and ($_.arch -eq $tool.arch) -and ($_.platform_version -eq $tool.platform_version)} ` | Where-Object { ($_.platform -eq $tool.platform) -and ($_.platform_version -eq $tool.platform_version)} `
| Select-Object -First 1 | Select-Object -First 1
if (-not $asset) {
Write-Host "Asset for $($tool.name) $toolVersion $($tool.arch) not found in versions manifest"
exit 1
}
Write-Host "Installing $($tool.name) $toolVersion $($tool.arch)..." Write-Host "Installing $($tool.name) $toolVersion $($tool.arch)..."
Install-Asset -ReleaseAsset $asset if ($null -ne $asset) {
Install-Asset -ReleaseAsset $asset
} else {
Write-Host "Asset was not found in versions manifest"
exit 1
}
} }
chown -R "$($env:SUDO_USER):$($env:SUDO_USER)" "/opt/hostedtoolcache/$($tool.name)" chown -R "$($env:SUDO_USER):$($env:SUDO_USER)" "/opt/hostedtoolcache/$($tool.name)"
} }
@@ -1,7 +1,8 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################ ################################################################################
## File: install-actions-cache.sh ## File: action-archive-cache.sh
## Desc: Download latest release from https://github.com/actions/action-versions ## Desc: Download latest release from https://github.com/actions/action-verions
## and un-tar to /opt/actionarchivecache
## Maintainer: #actions-runtime and @TingluoHuang ## Maintainer: #actions-runtime and @TingluoHuang
################################################################################ ################################################################################
@@ -14,11 +15,12 @@ ACTION_ARCHIVE_CACHE_DIR=/opt/actionarchivecache
mkdir -p $ACTION_ARCHIVE_CACHE_DIR mkdir -p $ACTION_ARCHIVE_CACHE_DIR
chmod -R 777 $ACTION_ARCHIVE_CACHE_DIR chmod -R 777 $ACTION_ARCHIVE_CACHE_DIR
echo "Setting up ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE variable to ${ACTION_ARCHIVE_CACHE_DIR}" echo "Setting up ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE variable to ${ACTION_ARCHIVE_CACHE_DIR}"
set_etc_environment_variable "ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE" "${ACTION_ARCHIVE_CACHE_DIR}" addEtcEnvironmentVariable ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE ${ACTION_ARCHIVE_CACHE_DIR}
# Download latest release from github.com/actions/action-versions and untar to /opt/actionarchivecache # Download latest release from github.com/actions/action-versions and untar to /opt/actionarchivecache
download_url=$(resolve_github_release_asset_url "actions/action-versions" "endswith(\"action-versions.tar.gz\")" "latest") downloadUrl=$(get_github_package_download_url "actions/action-versions" "contains(\"action-versions.tar.gz\")")
archive_path=$(download_with_retry "$download_url") echo "Downloading action-versions $downloadUrl"
tar -xzf "$archive_path" -C $ACTION_ARCHIVE_CACHE_DIR download_with_retries "$downloadUrl" "/tmp" action-versions.tar.gz
tar -xzf /tmp/action-versions.tar.gz -C $ACTION_ARCHIVE_CACHE_DIR
invoke_tests "ActionArchiveCache" invoke_tests "ActionArchiveCache"
@@ -0,0 +1,24 @@
#!/bin/bash -e
################################################################################
## File: aliyun-cli.sh
## Desc: Installs Alibaba Cloud CLI
################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/os.sh
source $HELPER_SCRIPTS/install.sh
# Install Alibaba Cloud CLI
# Pin tool version on ubuntu20 due to issues with GLIBC_2.32 not available
if isUbuntu20; then
toolsetVersion=$(get_toolset_value '.aliyunCli.version')
downloadUrl="https://github.com/aliyun/aliyun-cli/releases/download/v$toolsetVersion/aliyun-cli-linux-$toolsetVersion-amd64.tgz"
else
downloadUrl="https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz"
fi
download_with_retries $downloadUrl "/tmp"
tar xzf /tmp/aliyun-cli-linux-*-amd64.tgz
mv aliyun /usr/local/bin
invoke_tests "CLI.Tools" "Aliyun CLI"
+126
View File
@@ -0,0 +1,126 @@
#!/bin/bash -e
################################################################################
## File: android.sh
## Desc: Installs Android SDK
################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/os.sh
source $HELPER_SCRIPTS/install.sh
source $HELPER_SCRIPTS/etc-environment.sh
function filter_components_by_version {
minimumVersion=$1
shift
toolsArr=("$@")
for item in ${toolsArr[@]}
do
# take the last argument after spliting string by ';'' and '-''
version=$(echo "${item##*[-;]}")
if verlte $minimumVersion $version
then
components+=($item)
fi
done
}
function get_full_ndk_version {
majorVersion=$1
ndkFullVersion=$($SDKMANAGER --list | grep "ndk;${majorVersion}.*" | awk '{gsub("ndk;", ""); print $1}' | sort -V | tail -n1)
echo "$ndkFullVersion"
}
# Set env variable for SDK Root (https://developer.android.com/studio/command-line/variables)
ANDROID_ROOT=/usr/local/lib/android
ANDROID_SDK_ROOT=${ANDROID_ROOT}/sdk
SDKMANAGER=${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager
echo "ANDROID_SDK_ROOT=${ANDROID_SDK_ROOT}" | tee -a /etc/environment
# ANDROID_HOME is deprecated, but older versions of Gradle rely on it
echo "ANDROID_HOME=${ANDROID_SDK_ROOT}" | tee -a /etc/environment
# Create android sdk directory
mkdir -p ${ANDROID_SDK_ROOT}
cmdlineTools="android-cmdline-tools.zip"
# Download the latest command line tools so that we can accept all of the licenses.
# See https://developer.android.com/studio/#command-tools
cmdlineToolsVersion=$(get_toolset_value '.android."cmdline-tools"')
if [[ $cmdlineToolsVersion == "latest" ]]; then
repositoryXmlUrl="https://dl.google.com/android/repository/repository2-1.xml"
download_with_retries $repositoryXmlUrl "/tmp" "repository2-1.xml"
cmdlineToolsVersion=$(
yq -p=xml \
'.sdk-repository.remotePackage[] | select(."+@path" == "cmdline-tools;latest" and .channelRef."+@ref" == "channel-0").archives.archive[].complete.url | select(contains("commandlinetools-linux"))' \
/tmp/repository2-1.xml
)
if [[ -z $cmdlineToolsVersion ]]; then
echo "Failed to parse latest command-line tools version"
exit 1
fi
fi
download_with_retries "https://dl.google.com/android/repository/${cmdlineToolsVersion}" "." $cmdlineTools
unzip -qq $cmdlineTools -d ${ANDROID_SDK_ROOT}/cmdline-tools
# Command line tools need to be placed in ${ANDROID_SDK_ROOT}/sdk/cmdline-tools/latest to determine SDK root
mv ${ANDROID_SDK_ROOT}/cmdline-tools/cmdline-tools ${ANDROID_SDK_ROOT}/cmdline-tools/latest
rm -f $cmdlineTools
# Check sdk manager installation
${SDKMANAGER} --list 1>/dev/null
if [ $? -eq 0 ]
then
echo "Android SDK manager was installed"
else
echo "Android SDK manager was not installed"
exit 1
fi
minimumBuildToolVersion=$(get_toolset_value '.android.build_tools_min_version')
minimumPlatformVersion=$(get_toolset_value '.android.platform_min_version')
extras=$(get_toolset_value '.android.extra_list[]|"extras;" + .')
addons=$(get_toolset_value '.android.addon_list[]|"add-ons;" + .')
additional=$(get_toolset_value '.android.additional_tools[]')
ANDROID_NDK_MAJOR_VERSIONS=($(get_toolset_value '.android.ndk.versions[]'))
ANDROID_NDK_MAJOR_DEFAULT=$(get_toolset_value '.android.ndk.default')
components=("${extras[@]}" "${addons[@]}" "${additional[@]}")
for ndk_version in "${ANDROID_NDK_MAJOR_VERSIONS[@]}"
do
ndk_full_version=$(get_full_ndk_version $ndk_version)
components+=("ndk;$ndk_full_version")
done
ANDROID_NDK_MAJOR_LATEST=(${ANDROID_NDK_MAJOR_VERSIONS[-1]})
ndkDefaultFullVersion=$(get_full_ndk_version $ANDROID_NDK_MAJOR_DEFAULT)
ndkLatestFullVersion=$(get_full_ndk_version $ANDROID_NDK_MAJOR_LATEST)
ANDROID_NDK="$ANDROID_SDK_ROOT/ndk/$ndkDefaultFullVersion"
# ANDROID_NDK, ANDROID_NDK_HOME, and ANDROID_NDK_ROOT variables should be set as many customer builds depend on them https://github.com/actions/runner-images/issues/5879
echo "ANDROID_NDK=${ANDROID_NDK}" | tee -a /etc/environment
echo "ANDROID_NDK_HOME=${ANDROID_NDK}" | tee -a /etc/environment
echo "ANDROID_NDK_ROOT=${ANDROID_NDK}" | tee -a /etc/environment
echo "ANDROID_NDK_LATEST_HOME=$ANDROID_SDK_ROOT/ndk/$ndkLatestFullVersion" | tee -a /etc/environment
availablePlatforms=($($SDKMANAGER --list | sed -n '/Available Packages:/,/^$/p' | grep "platforms;android-[0-9]" | cut -d"|" -f 1))
allBuildTools=($($SDKMANAGER --list | grep "build-tools;" | cut -d"|" -f 1 | sort -u))
availableBuildTools=$(echo ${allBuildTools[@]//*rc[0-9]/})
filter_components_by_version $minimumPlatformVersion "${availablePlatforms[@]}"
filter_components_by_version $minimumBuildToolVersion "${availableBuildTools[@]}"
echo "y" | $SDKMANAGER ${components[@]}
# Old skdmanager from sdk tools doesn't work with Java > 8, set version 8 explicitly
if isUbuntu20 || isUbuntu22; then
sed -i "2i export JAVA_HOME=${JAVA_HOME_8_X64}" ${ANDROID_SDK_ROOT}/tools/bin/sdkmanager
fi
# Add required permissions
chmod -R a+rwx ${ANDROID_SDK_ROOT}
reloadEtcEnvironment
invoke_tests "Android"
@@ -1,7 +1,7 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################ ################################################################################
## File: install-apache.sh ## File: apache.sh
## Desc: Install Apache HTTP Server ## Desc: Installs Apache HTTP Server
################################################################################ ################################################################################
# Install Apache # Install Apache
@@ -1,18 +1,15 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################ ################################################################################
## File: install-apt-common.sh ## File: apt-common.sh
## Desc: Install basic command line utilities and dev packages ## Desc: Installs basic command line utilities and dev packages
################################################################################ ################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/install.sh source $HELPER_SCRIPTS/install.sh
common_packages=$(get_toolset_value .apt.common_packages[]) common_packages=$(get_toolset_value .apt.common_packages[])
cmd_packages=$(get_toolset_value .apt.cmd_packages[]) cmd_packages=$(get_toolset_value .apt.cmd_packages[])
for package in $common_packages $cmd_packages; do for package in $common_packages $cmd_packages; do
echo "Install $package" echo "Install $package"
apt-get install -y --no-install-recommends $package apt-get install -y --no-install-recommends $package
done done
invoke_tests "Apt" invoke_tests "Apt"
@@ -1,10 +1,8 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################ ################################################################################
## File: install-apt-vital.sh ## File: apt-vital.sh
## Desc: Install vital command line utilities ## Desc: Installs vital command line utilities
################################################################################ ################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/install.sh source $HELPER_SCRIPTS/install.sh
vital_packages=$(get_toolset_value .apt.vital_packages[]) vital_packages=$(get_toolset_value .apt.vital_packages[])
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash -e
################################################################################
## File: aws.sh
## Desc: Installs the AWS CLI, Session Manager plugin for the AWS CLI, and AWS SAM CLI
################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/os.sh
source $HELPER_SCRIPTS/install.sh
download_with_retries "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" "/tmp" "awscliv2.zip"
unzip -qq /tmp/awscliv2.zip -d /tmp
/tmp/aws/install -i /usr/local/aws-cli -b /usr/local/bin
download_with_retries "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_64bit/session-manager-plugin.deb" "/tmp" "session-manager-plugin.deb"
apt install /tmp/session-manager-plugin.deb
# Download & install the latest aws sam cli release
zipName="aws-sam-cli-linux-x86_64.zip"
zipUrl="https://github.com/aws/aws-sam-cli/releases/latest/download/${zipName}"
download_with_retries $zipUrl "/tmp" $zipName
unzip /tmp/${zipName} -d /tmp
/tmp/install
invoke_tests "CLI.Tools" "AWS"
@@ -1,18 +1,17 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################ ################################################################################
## File: install-azcopy.sh ## File: azcopy.sh
## Desc: Install AzCopy ## Desc: Installs AzCopy
################################################################################ ################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/install.sh source $HELPER_SCRIPTS/install.sh
# Install AzCopy10 # Install AzCopy10
archive_path=$(download_with_retry "https://aka.ms/downloadazcopy-v10-linux") download_with_retries "https://aka.ms/downloadazcopy-v10-linux" "/tmp" "azcopy.tar.gz"
tar xzf "$archive_path" --strip-components=1 -C /tmp tar xzf /tmp/azcopy.tar.gz --strip-components=1 -C /tmp
install /tmp/azcopy /usr/local/bin/azcopy mv /tmp/azcopy /usr/local/bin/azcopy
chmod +x /usr/local/bin/azcopy
# Create azcopy 10 alias for backward compatibility # Create azcopy 10 alias for backward compatibility
ln -sf /usr/local/bin/azcopy /usr/local/bin/azcopy10 ln -sf /usr/local/bin/azcopy /usr/local/bin/azcopy10
invoke_tests "Tools" "azcopy" invoke_tests "Tools" "azcopy"
@@ -0,0 +1,13 @@
#!/bin/bash -e
################################################################################
## File: azure-cli.sh
## Desc: Installed Azure CLI (az)
################################################################################
# Install Azure CLI (instructions taken from https://docs.microsoft.com/en-us/cli/azure/install-azure-cli)
curl -fsSL https://aka.ms/InstallAzureCLIDeb | sudo bash
echo "azure-cli https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-linux?pivots=apt" >> $HELPER_SCRIPTS/apt-sources.txt
rm -f /etc/apt/sources.list.d/azure-cli.list
rm -f /etc/apt/sources.list.d/azure-cli.list.save
invoke_tests "CLI.Tools" "Azure CLI"
@@ -1,18 +1,15 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################ ################################################################################
## File: install-azure-devops-cli.sh ## File: azure-devops-cli.sh
## Desc: Install Azure DevOps CLI (az devops) ## Desc: Installed Azure DevOps CLI (az devops)
################################################################################ ################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/etc-environment.sh
# AZURE_EXTENSION_DIR shell variable defines where modules are installed # AZURE_EXTENSION_DIR shell variable defines where modules are installed
# https://docs.microsoft.com/en-us/cli/azure/azure-cli-extensions-overview # https://docs.microsoft.com/en-us/cli/azure/azure-cli-extensions-overview
export AZURE_EXTENSION_DIR=/opt/az/azcliextensions export AZURE_EXTENSION_DIR=/opt/az/azcliextensions
set_etc_environment_variable "AZURE_EXTENSION_DIR" "${AZURE_EXTENSION_DIR}" echo "AZURE_EXTENSION_DIR=$AZURE_EXTENSION_DIR" | tee -a /etc/environment
# install azure devops Cli extension # install azure devops Cli extension
az extension add -n azure-devops az extension add -n azure-devops
invoke_tests "CLI.Tools" "Azure DevOps CLI" invoke_tests "CLI.Tools" "Azure DevOps CLI"
@@ -1,16 +1,15 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################ ################################################################################
## File: install-bazel.sh ## File: bazel.sh
## Desc: Install Bazel and Bazelisk (A user-friendly launcher for Bazel) ## Desc: Installs Bazel and Bazelisk (A user-friendly launcher for Bazel)
################################################################################ ################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/install.sh source $HELPER_SCRIPTS/install.sh
# Install bazelisk # Install bazelisk
npm install -g @bazel/bazelisk npm install -g @bazel/bazelisk
# run bazelisk once in order to install /usr/local/bin/bazel binary # run bazelisk once in order to instal /usr/local/bin/bazel binary
sudo -u $SUDO_USER bazel version sudo -u $SUDO_USER bazel version
invoke_tests "Tools" "Bazel" invoke_tests "Tools" "Bazel"
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash -e
################################################################################
## File: bicep.sh
## Desc: Installs bicep cli
################################################################################
source $HELPER_SCRIPTS/install.sh
# Install Bicep CLI
download_with_retries "https://github.com/Azure/bicep/releases/latest/download/bicep-linux-x64" "." "bicep.bin"
# Mark it as executable
chmod +x ./bicep.bin
# Add bicep to PATH (requires admin)
sudo mv ./bicep.bin /usr/local/bin/bicep
invoke_tests "Tools" "Bicep"
@@ -1,20 +1,20 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################ ################################################################################
## File: install-clang.sh ## File: clang.sh
## Desc: Install Clang compiler ## Desc: Installs Clang compiler
################################################################################ ################################################################################
# Source the helpers for use with the script # Source the helpers for use with the script
source $HELPER_SCRIPTS/install.sh source $HELPER_SCRIPTS/install.sh
install_clang() { function InstallClang {
local version=$1 local version=$1
echo "Installing clang-$version..." echo "Installing clang-$version..."
apt-get install -y "clang-$version" "lldb-$version" "lld-$version" "clang-format-$version" "clang-tidy-$version" apt-get install -y "clang-$version" "lldb-$version" "lld-$version" "clang-format-$version" "clang-tidy-$version"
} }
set_default_clang() { function SetDefaultClang {
local version=$1 local version=$1
echo "Make Clang ${version} default" echo "Make Clang ${version} default"
@@ -30,11 +30,11 @@ default_clang_version=$(get_toolset_value '.clang.default_version')
for version in ${versions[*]}; do for version in ${versions[*]}; do
if [[ $version != $default_clang_version ]]; then if [[ $version != $default_clang_version ]]; then
install_clang $version InstallClang $version
fi fi
done done
install_clang $default_clang_version InstallClang $default_clang_version
set_default_clang $default_clang_version SetDefaultClang $default_clang_version
invoke_tests "Tools" "clang" invoke_tests "Tools" "clang"
@@ -1,8 +1,4 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################
## File: cleanup.sh
## Desc: Perform cleanup
################################################################################
# before cleanup # before cleanup
before=$(df / -Pm | awk 'NR==2{print $4}') before=$(df / -Pm | awk 'NR==2{print $4}')
@@ -26,19 +22,13 @@ find /var/log -type f -regex ".*\.[0-9]$" -delete
# wipe log files # wipe log files
find /var/log/ -type f -exec cp /dev/null {} \; find /var/log/ -type f -exec cp /dev/null {} \;
# delete symlink for tests running
rm -f /usr/local/bin/invoke_tests
# remove apt mock
prefix=/usr/local/bin
for tool in apt apt-get apt-key;do
sudo rm -f $prefix/$tool
done
# after cleanup # after cleanup
after=$(df / -Pm | awk 'NR==2{print $4}') after=$(df / -Pm | awk 'NR==2{print $4}')
# display size # display size
echo "Before: $before MB" echo "Before: $before MB"
echo "After : $after MB" echo "After : $after MB"
echo "Delta : $(($after-$before)) MB" echo "Delta : $(($after-$before)) MB"
# delete symlink for tests running
rm -f /usr/local/bin/invoke_tests
+22
View File
@@ -0,0 +1,22 @@
#!/bin/bash -e
################################################################################
## File: cmake.sh
## Desc: Installs CMake
################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/install.sh
# Test to see if the software in question is already installed, if not install it
echo "Checking to see if the installer script has already been run"
if command -v cmake; then
echo "cmake is already installed"
else
downloadUrl=$(get_github_package_download_url "Kitware/CMake" "endswith(\"inux-x86_64.sh\")")
curl -fsSL ${downloadUrl} -o cmakeinstall.sh \
&& chmod +x cmakeinstall.sh \
&& ./cmakeinstall.sh --prefix=/usr/local --exclude-subdir \
&& rm cmakeinstall.sh
fi
invoke_tests "Tools" "Cmake"
@@ -1,10 +1,9 @@
#!/bin/bash -e #!/bin/bash -e
################################################################################ ################################################################################
## File: install-codeql-bundle.sh ## File: codeql-bundle.sh
## Desc: Install CodeQL CLI Bundle to the toolcache. ## Desc: Install the CodeQL CLI Bundle to the toolcache.
################################################################################ ################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/install.sh source $HELPER_SCRIPTS/install.sh
# Retrieve the CLI version of the latest CodeQL bundle. # Retrieve the CLI version of the latest CodeQL bundle.
@@ -15,7 +14,8 @@ bundle_tag_name="codeql-bundle-v$bundle_version"
echo "Downloading CodeQL bundle $bundle_version..." echo "Downloading CodeQL bundle $bundle_version..."
# Note that this is the all-platforms CodeQL bundle, to support scenarios where customers run # Note that this is the all-platforms CodeQL bundle, to support scenarios where customers run
# different operating systems within containers. # different operating systems within containers.
codeql_archive=$(download_with_retry "https://github.com/github/codeql-action/releases/download/$bundle_tag_name/codeql-bundle.tar.gz") download_with_retries "https://github.com/github/codeql-action/releases/download/$bundle_tag_name/codeql-bundle.tar.gz" "/tmp" "codeql-bundle.tar.gz"
codeql_archive="/tmp/codeql-bundle.tar.gz"
codeql_toolcache_path="$AGENT_TOOLSDIRECTORY/CodeQL/$bundle_version/x64" codeql_toolcache_path="$AGENT_TOOLSDIRECTORY/CodeQL/$bundle_version/x64"
mkdir -p "$codeql_toolcache_path" mkdir -p "$codeql_toolcache_path"
@@ -0,0 +1,12 @@
#!/bin/bash -e
################################################################################
## File: snap-environment.sh
## Desc: Update /etc/environment to include /snap/bin in PATH
## because /etc/profile.d is ignored by `--norc` shell launch option
################################################################################
# Source the helpers
source $HELPER_SCRIPTS/etc-environment.sh
# Update /etc/environemnt
prependEtcEnvironmentPath "/snap/bin"

Some files were not shown because too many files have changed in this diff Show More