Compare commits

..
626 changed files with 15652 additions and 19300 deletions
+2 -4
View File
@@ -38,12 +38,9 @@ body:
options:
- label: Ubuntu 20.04
- label: Ubuntu 22.04
- label: Ubuntu 24.04
- label: macOS 11
- label: macOS 12
- label: macOS 13
- label: macOS 13 Arm64
- label: macOS 14
- label: macOS 14 Arm64
- label: Windows Server 2019
- label: Windows Server 2022
- type: textarea
@@ -52,3 +49,4 @@ body:
description: Steps or options for impact mitigation
validations:
required: true
+1 -4
View File
@@ -21,12 +21,9 @@ body:
options:
- label: Ubuntu 20.04
- label: Ubuntu 22.04
- label: Ubuntu 24.04
- label: macOS 11
- label: macOS 12
- label: macOS 13
- label: macOS 13 Arm64
- label: macOS 14
- label: macOS 14 Arm64
- label: Windows Server 2019
- label: Windows Server 2022
- type: textarea
+2 -5
View File
@@ -59,12 +59,9 @@ body:
options:
- label: Ubuntu 20.04
- label: Ubuntu 22.04
- label: Ubuntu 24.04
- label: macOS 11
- label: macOS 12
- label: macOS 13
- label: macOS 13 Arm64
- label: macOS 14
- label: macOS 14 Arm64
- label: Windows Server 2019
- label: Windows Server 2022
- type: textarea
@@ -79,4 +76,4 @@ body:
- type: input
attributes:
label: Are you willing to submit a PR?
description: We accept contributions!
description: We accept contributions!
+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:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# 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).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@v2
# ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -69,4 +69,4 @@ jobs:
# make release
- 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
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- 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:
tag: ${{ github.event.client_payload.ReleaseBranchName }}
name: ${{ github.event.client_payload.ReleaseTitle }}
tag_name: ${{ github.event.client_payload.ReleaseBranchName }}
release_name: ${{ github.event.client_payload.ReleaseTitle }}
body: ${{ github.event.client_payload.ReleaseBody }}
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
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
with:
fetch-depth: 0
@@ -22,11 +22,11 @@ jobs:
- name: Create pull request for ${{ github.event.client_payload.ReleaseBranchName }}
id: create-pr
uses: actions/github-script@v7
uses: actions/github-script@v2
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
let response = await github.rest.pulls.create({
let response = await github.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: "${{ github.event.client_payload.PullRequestTitle }}",
@@ -37,11 +37,11 @@ jobs:
return response.data.number
- name: Request reviewers
uses: actions/github-script@v7
uses: actions/github-script@v2
with:
github-token: ${{secrets.PRAPPROVAL_SECRET}}
script: |
github.rest.pulls.requestReviewers({
github.pulls.requestReviewers({
owner: context.repo.owner,
repo: context.repo.repo,
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:
# github.event.client_payload.agentSpec - Current YAML Label
# github.event.client_payload.ReleaseID - Current release ID
@@ -14,35 +14,8 @@ defaults:
run:
shell: pwsh
jobs:
#Checking current release for SBOM
sbom-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' }}
#Checking image version on available runner
version-check:
runs-on: ${{ github.event.client_payload.agentSpec }}
steps:
- 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 }}') {
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
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
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.
- name: Run SYFT on Windows
if: ${{ runner.os == 'Windows' }}
@@ -74,7 +53,7 @@ jobs:
- name: Compress SBOM file
run: Compress-Archive sbom.json sbom.json.zip
#Upload artifact action
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v3
with:
name: sbom-${{ github.event.client_payload.agentSpec }}-${{ github.event.client_payload.imageVersion }}
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}"
asset_path: ./sbom.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:
- name: Checkout Code
uses: actions/checkout@v4
uses: actions/checkout@v3
with:
fetch-depth: 0
+5 -5
View File
@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
with:
fetch-depth: 0
@@ -24,11 +24,11 @@ jobs:
sleep 30
- name: Approve pull request by GitHub-Actions bot
uses: actions/github-script@v7
uses: actions/github-script@v2
with:
github-token: ${{secrets.PRAPPROVAL_SECRET}}
script: |
github.rest.pulls.createReview({
github.pulls.createReview({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: ${{ github.event.client_payload.PullRequestNumber }},
@@ -36,11 +36,11 @@ jobs:
});
- name: Merge pull request for ${{ github.event.client_payload.ReleaseBranchName }}
uses: actions/github-script@v7
uses: actions/github-script@v2
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
github.rest.pulls.merge({
github.pulls.merge({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: ${{ github.event.client_payload.PullRequestNumber }},
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: Run Software Report module tests
shell: pwsh
+1 -1
View File
@@ -5,7 +5,7 @@ on:
pull_request_target:
types: labeled
paths:
- 'images/ubuntu/**'
- 'images/linux/**'
defaults:
run:
+1 -1
View File
@@ -5,7 +5,7 @@ on:
pull_request_target:
types: labeled
paths:
- 'images/ubuntu/**'
- 'images/linux/**'
defaults:
run:
-20
View File
@@ -1,20 +0,0 @@
name: Trigger Ubuntu24.04 CI
run-name: Ubuntu24.04 - ${{ github.event.pull_request.title }}
on:
pull_request_target:
types: labeled
paths:
- 'images/ubuntu/**'
defaults:
run:
shell: pwsh
jobs:
Ubuntu_2404:
if: contains(github.event.pull_request.labels.*.name, 'CI ubuntu-all') || contains(github.event.pull_request.labels.*.name, 'CI ubuntu-2404')
uses: ./.github/workflows/trigger-ubuntu-win-build.yml
with:
image_type: 'ubuntu2404'
secrets: inherit
+4 -4
View File
@@ -10,19 +10,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Update release for ${{ github.event.client_payload.ReleaseBranchName }}
uses: actions/github-script@v7
uses: actions/github-script@v2
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const response = await github.rest.repos.getReleaseByTag({
const response = await github.repos.getReleaseByTag({
owner: context.repo.owner,
repo: context.repo.repo,
tag: "${{ github.event.client_payload.ReleaseBranchName }}"
});
github.rest.repos.updateRelease({
github.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: response.data.id,
+1 -1
View File
@@ -5,7 +5,7 @@ on:
pull_request_target:
types: labeled
paths:
- 'images/windows/**'
- 'images/win/**'
defaults:
run:
+1 -1
View File
@@ -5,7 +5,7 @@ on:
pull_request_target:
types: labeled
paths:
- 'images/windows/**'
- 'images/win/**'
defaults:
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.
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
1. [Fork][fork] and clone the repository.
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. Test your changes by [creating an image and deploying a VM](docs/create-image-and-azure-resources.md).
1. Push to your fork and [submit a pull request][pr].
1. [Fork][fork] and clone the repository
1. Create a new branch: `git checkout -b my-branch-name`
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 image and deploying a VM](docs/create-image-and-azure-resources.md).
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:
@@ -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.
- Write [good commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
- For new tools:
- Make sure that the tool satisfies the [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.
- Make sure that the tool satisfies [Software Guidelines](README.md#software-guidelines).
- 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
- For every new tool, add validation scripts and update the software report script to ensure that it is included in the documentation.
- If the tool is available on multiple platforms (macOS, Windows, Linux), make sure you include it on 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.
- Use consistent naming across all files.
- Validation scripts should be simple and shouldn't change the image content.
- 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 in other platforms (macOS, Windows, Linux), make sure you include it in as many as possible.
- 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
- Validation scripts should be simple and shouldn't change image content
### Windows
- Add a script that will install the tool and put the script in the `scripts/build` 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)).
- 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.
Add `Invoke-PesterTests -TestFile <testFileName> [-TestName <describeName>]` at the end of the installation script to ensure 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 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: `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.
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 make sure that your tests will be run.
- 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
- Add a script that will install and validate the tool and put the script in the `scripts/build` folder.
Use existing scripts such as [github-cli.sh](images/ubuntu/scripts/build/github-cli.sh) as a starting point.
- Use [helpers](images/ubuntu/scripts/helpers/install.sh) to simplify the installation process.
- The validation part should `exit 1` if there is any issue with the 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 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/linux/scripts/installers/github-cli.sh) as a starting point.
- Use [helpers](images/linux/scripts/helpers/install.sh) to simplify installation process.
- Validation part should `exit 1` if any issue with installation.
- 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
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.
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.
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 macOS CI to accept contributions. Until then, we appreciate your patience and ask you continue to make tool requests by filing issues.
## Resources
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2024 GitHub
Copyright (c) 2023 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+202 -212
View File
@@ -1,212 +1,202 @@
# GitHub Actions Runner Images
**Table of Contents**
- [About](#about)
- [Available Images](#available-images)
- [Announcements](#announcements)
- [Image Definitions](#image-definitions)
- [Image Releases](#image-releases)
- [Software and Image Support](#software-and-image-support)
- [How to Interact with the Repo](#how-to-interact-with-the-repo)
- [FAQs](#faqs)
## 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.
To build a VM machine from this repo's source, see the [instructions](docs/create-image-and-azure-resources.md).
## Available Images
| Image | YAML Label | Included Software | Rollout Status 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%2Fijunaidm%2F0b5459bbe18604a639e1d2f7accd204f%2Fraw%2Fubuntu24.json) |
| 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%2Fijunaidm%2F0b5459bbe18604a639e1d2f7accd204f%2Fraw%2Fubuntu22.json) |
| Ubuntu 20.04 | `ubuntu-20.04` | [ubuntu-20.04] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fijunaidm%2F0b5459bbe18604a639e1d2f7accd204f%2Fraw%2Fubuntu20.json) |
| 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%2Fijunaidm%2F0b5459bbe18604a639e1d2f7accd204f%2Fraw%2Fmacos-14.json) |
| 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%2Fijunaidm%2F0b5459bbe18604a639e1d2f7accd204f%2Fraw%2Fmacos-14-arm64.json) |
| macOS 13 | `macos-13` or `macos-13-large` | [macOS-13] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fijunaidm%2F0b5459bbe18604a639e1d2f7accd204f%2Fraw%2Fmacos-13.json) |
| macOS 13 Arm64 | `macos-13-xlarge` | [macOS-13-arm64] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fijunaidm%2F0b5459bbe18604a639e1d2f7accd204f%2Fraw%2Fmacos-13-arm64.json) |
| macOS 12 | `macos-12` or `macos-12-large`| [macOS-12] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fijunaidm%2F0b5459bbe18604a639e1d2f7accd204f%2Fraw%2Fmacos-12.json) |
| Windows Server 2022 | `windows-latest` or `windows-2022` | [windows-2022] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fijunaidm%2F0b5459bbe18604a639e1d2f7accd204f%2Fraw%2Fwin22.json) |
| Windows Server 2019 | `windows-2019` | [windows-2019] | ![Endpoint Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Fijunaidm%2F0b5459bbe18604a639e1d2f7accd204f%2Fraw%2Fwin19.json) |
### Label scheme
- 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
[ubuntu-24.04]: https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md
[ubuntu-22.04]: https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md
[ubuntu-20.04]: https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2004-Readme.md
[windows-2022]: https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md
[windows-2019]: https://github.com/actions/runner-images/blob/main/images/windows/Windows2019-Readme.md
[macOS-12]: https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md
[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
[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
[self-hosted runners]: https://help.github.com/en/actions/hosting-your-own-runners
## Announcements
See notable upcoming changes by viewing issues with the [Announcement](https://github.com/actions/runner-images/labels/Announcement) label.
## Image Definitions
### Beta
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
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.
### GA
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:
1. Has been through a Beta period (public or private)
2. Most major software we install on the image has a compatible
version for the underlying OS and
3. All major bugs reported during the Beta period have been addressed.
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.
#### Latest Migration Process
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.
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).
## Image Releases
*How to best follow along with changes*
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)
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.
- 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).
- Ex: breaking changes, GA or deprecation of images
*Cadence*
- We typically deploy weekly updates to the software on the runner images.
## Software and Image Support
### Support Policy
- 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.
- The images generally contain the latest versions of packages installed except for Ubuntu LTS where we mostly rely on the Canonical-provided repositories.
- Popular tools can have several versions installed side-by-side with the following strategy:
| Tool name | Installation strategy |
|-----------|-----------------------|
| 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 |
| Node.js | 3 latest LTS versions |
| Go | 3 latest minor versions |
| Python <br/> Ruby | 5 most popular `major.minor` versions |
| PyPy | 3 most popular `major.minor` versions |
| .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 |
| Android NDK | 1 latest non-LTS, 2 latest LTS 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 |
### Package managers usage
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.
> **Note**: third-party repositories are re-evaluated every year to identify if they are still useful and secure.
| Operating system | Package manager | Third-party repos and packages |
| :--- | :---: | ---: |
| 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) |
| | [pipx](https://pypa.github.io/pipx) | ansible-core <br/>yamllint |
| 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) |
| | [pipx](https://pypa.github.io/pipx/) | yamllint |
### Image Deprecation Policy
- Images begin the deprecation process of the oldest image label once a new GA OS version has been released.
- 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
- 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
### Preinstallation Policy
In general, these are the guidelines we follow when deciding what to pre-install on our images:
- Popularity: widely-used tools and ecosystems will be given priority.
- Latest Technology: recent versions of tools will be given priority.
- Deprecation: end-of-life tools and versions will not be added.
- Licensing: MIT, Apache, or GNU licenses are allowed.
- 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.
### Default Version Update Policy
- In general, once a new version is installed on the image, we announce the default version update 2 weeks prior to deploying it.
- For potentially dangerous updates, we may extend the timeline up to 1 month between the announcement and deployment.
## How to Interact with the Repo
- **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)
- **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 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).
## FAQs
<details>
<summary><b><i>What images are available for GitHub Actions and Azure DevOps?</b></i></summary>
The availability of images for GitHub Actions and Azure DevOps is the same. However, deprecation policies may differ. See documentation for more details:
- [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 image version is used in my build?</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">
</details>
<details>
<summary><b><i>Looking for other Linux distributions?</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.
</details>
<details>
<summary><b><i>How do I contribute to the macOS source?</b></i></summary>
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.
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 does GitHub determine what tools are installed on the images?</b></i></summary>
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>
<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>
# GitHub Actions Runner Images
**Table of Contents**
- [About](#about)
- [Available Images](#available-images)
- [Announcements](#announcements)
- [Image Definitions](#image-definitions)
- [Image Releases](#image-releases)
- [Software and Image Support](#software-and-image-support)
- [How to Interact with the Repo](#how-to-interact-with-the-repo)
- [FAQs](#faqs)
## 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.
To build a VM machine from this repo's source, see the [instructions](docs/create-image-and-azure-resources.md).
## Available Images
| Image | YAML Label | Included Software | Rollout Progress of Latest Image Release |
| --------------------|---------------------|--------------------|---------------------|
| 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 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)
| 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 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 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)
| 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) |
| 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)
### Label scheme
- 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
[ubuntu-22.04]: https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2204-Readme.md
[ubuntu-20.04]: https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2004-Readme.md
[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
[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
[macOS-13]: https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md
[macOS-10.15]: https://github.com/actions/runner-images/blob/main/images/macos/macos-10.15-Readme.md
[self-hosted runners]: https://help.github.com/en/actions/hosting-your-own-runners
## Announcements
See notable upcoming changes by viewing issues with the [Announcement](https://github.com/actions/runner-images/labels/Announcement) label.
## Image Definitions
### Beta
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
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.
### GA
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:
1. Has been through a Beta period (public or private)
2. Most major software we install on the image has a compatible
version for the underlying OS and
3. All major bugs reported during the Beta period have been addressed.
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.
#### Latest Migration Process
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.
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).
## Image Releases
*How to best follow along with changes*
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)
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.
- 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).
- Ex: breaking changes, GA or deprecation of images
*Cadence*
- We typically deploy weekly updates to the software on the runner images.
## Software and Image Support
### Support Policy
- 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.
- The images generally contain the latest versions of packages installed except for Ubuntu LTS where we mostly rely on the Canonical-provided repositories.
- Popular tools can have several versions installed side-by-side with the following strategy:
| Tool name | Installation strategy |
|-----------|-----------------------|
| 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 |
| Node.js | 3 latest LTS versions |
| Go | 3 latest minor versions |
| Python <br/> Ruby | 5 most popular `major.minor` versions |
| PyPy | 3 most popular `major.minor` versions |
| .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 |
| Android NDK | 1 latest non-LTS, 2 latest LTS 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 |
### Package managers usage
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.
> **Note**: third-party repositories are re-evaluated every year to identify if they are still useful and secure.
| Operating system | Package manager | Third-party repos and packages |
| :--- | :---: | ---: |
| 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) |
| | [pipx](https://pypa.github.io/pipx) | ansible-core </br>yamllint |
| 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) |
| | [pipx](https://pypa.github.io/pipx/) | yamllint |
### Image Deprecation Policy
- Images begin the deprecation process of the oldest image label once a new GA OS version has been released.
- 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
- 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
### Preinstallation Policy
In general, these are the guidelines we follow when deciding what to pre-install on our images:
- Popularity: widely-used tools and ecosystems will be given priority.
- Latest Technology: recent versions of tools will be given priority.
- Deprecation: end-of-life tools and versions will not be added.
- Licensing: MIT, Apache, or GNU licenses are allowed.
- 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.
### Default Version Update Policy
- In general, once a new version is installed on the image, we announce the default version update 2 weeks prior to deploying it.
- For potentially dangerous updates, we may extend the timeline up to 1 month between the announcement and deployment.
## How to Interact with the Repo
- **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)
- **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 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).
## FAQs
<details>
<summary><b><i>What images are available for GitHub Actions and Azure DevOps?</b></i></summary>
The availability of images for GitHub Actions and Azure DevOps is the same. However, deprecation policies may differ. See documentation for more details:
- [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 image version is used in my build?</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">
</details>
<details>
<summary><b><i>Looking for other Linux distributions?</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.
</details>
<details>
<summary><b><i>How do I contribute to the macOS source?</b></i></summary>
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.
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 does GitHub determine what tools are installed on the images?</b></i></summary>
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>
<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>
+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.
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.
The Packer process initializes a connection to the 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.
The Packer process initializes a connection to Azure subscription using Azure CLI and creates temporary resources
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 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).
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.
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 Customization](#manual-image-generation-customization)
- [Network Security](#network-security)
- [Azure Subscription Authentication](#azure-subscription-authentication)
- [Generated Machine Deployment](#generated-machine-deployment)
- [Manual image generation customization](#manual-image-generation-customization)
- [Network security](#network-security)
- [Azure subscription authentication](#azure-subscription-authentication)
- [Generated machine deployment](#generated-machine-deployment)
- [Automated image generation](#automated-image-generation)
- [Required variables](#required-variables)
- [Optional variables](#optional-variables)
@@ -27,15 +27,15 @@ After successful completion of all installation steps, Packer creates a managed
- [Toolset](#toolset)
- [Post-generation scripts](#post-generation-scripts)
- [Running scripts](#running-scripts)
- [Script Details: Ubuntu](#script-details-ubuntu)
- [Script Details: Windows](#script-details-windows)
- [Script details: Ubuntu](#script-details-ubuntu)
- [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.
You can use any physical or virtual machine running Windows or Linux OS.
Of course, you may also use an [Azure VM](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/quick-create-cli).
In any case, you will need these software installed:
Build agent is a machine where Packer process will be started.
You can use any physical or virtual machine running OS Windows or Linux.
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:
- 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.
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.
Follow the 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:
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:
```powershell
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
This repository includes a script that assists in generating images in Azure.
All you need is an Azure subscription and a 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.
This repo bundles script that helps generating images in Azure.
All you need are Azure subscription and build agent configured as described above.
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
git clone https://github.com/actions/runner-images.git
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
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;
- `ResourceGroupName` - the 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");
- `ImageType` - the type of image to build (we suggest choosing "UbuntuMinimal" here; other valid options are "Windows2019", "Windows2022", "Ubuntu2004", "Ubuntu2204").
- `SubscriptionId` - your Azure Subscription ID
- `ResourceGroupName` - name of the resource group that will be created within your subscription (e.g. "imagegen-test")
- `AzureLocation` - location where resources will be created (e.g. "East US")
- `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.
In this case, pass a HashTable of tags as a value for the `Tags` parameter.
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 `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`.
You can find more details in the [corresponding section below](#azure-subscription-authentication).
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 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.
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.
Also, if you don't want the temporary VM to be accessible from everywhere, set the `RestrictToAgentIpAddress` parameter value to `$true`
to set up firewall rules allowing access only from your build agent's public IP address.
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 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 temporary VM to be accessible from everywhere, set `RestrictToAgentIpAddress` parameter value to `$true`
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.
To achieve this, set proper values for the environment variables `VNET_RESOURCE_GROUP`, `VNET_NAME` and `VNET_SUBNET`.
If your build agent and temporary VM are in the same subscription you can configure Packer to connect using private virtual network.
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.
For more information about Service Principals, refer to the
Packer uses Service Principal to authenticate in Azure infrastructure.
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).
The `GenerateResourcesAndImage` function is able to create a Service Principal to be used by Packer.
It uses the Connect-AzAccount cmdlet that invokes an 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
and provide proper values for the parameters `AzureClientId`, `AzureClientSecret` and `AzureTenantId`.
Function `GenerateResourcesAndImage` is able to create Service Principle to be used by Packer.
It uses Connect-AzAccount cmdlet that invokes interactive authentication process by default.
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 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
$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
Import-Module .\helpers\CreateAzureVMFromPackerTemplate.ps1
@@ -173,29 +172,29 @@ CreateAzureVMFromPackerTemplate -SubscriptionId {YourSubscriptionId} -ResourceGr
Where:
- `SubscriptionId` - the Azure subscription ID where resources 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;
- `VirtualMachineName` - the name of the virtual machine to be generated;
- `AdminUserName` - the administrator username 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").
- `SubscriptionId` - The Azure subscription Id where resources 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.
- `VirtualMachineName` - The name of the virtual machine to be generated.
- `AdminUserName` - The administrator username 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. 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
If you want to generate images automatically (e.g., as a part of a CI/CD pipeline),
you can use Packer directly. To do this, you will need:
If you want to generate images automatically (e.g. as a part of CI/CD pipeline)
you can use Packer directly. To do that you will need:
- a build agent configured as described in the
[Build agent preparation](#build-agent-preparation) section;
- an Azure subscription and Service Principal configured as described in the
[Azure subscription authentication](#azure-subscription-authentication) section;
- a resource group created in your Azure subscription where the managed image will be stored;
- a string to be used as a password for the user used to install software (Windows only).
- A build agent configured as described in
[Build agent preparation](#build-agent-preparation) section.
- Azure subscription and Service Principal configured as described in
[Azure subscription authentication](#azure-subscription-authentication) section.
- Resource group created in your Azure subscription where managed image will be stored.
- 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
packer build -var "subscription_id=$SubscriptionId" `
@@ -211,54 +210,54 @@ packer build -var "subscription_id=$SubscriptionId" `
Where:
- `SubscriptionId` - your Azure Subscription ID;
- `ClientId` and `ClientSecret` - Service Principal credentials;
- `TenantId` - Azure Tenant ID;
- `InstallPassword` - password for the user used to install software (Windows only);
- `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;
- `TemplatePath` - path to the Packer template file (e.g., "images/windows/templates/windows-2022.pkr.hcl").
- `SubscriptionId` - your Azure Subscription ID
- `ClientId` and `ClientSecret` - Service Principal credentials
- `TenantId` - Azure Tenant ID
- `InstallPassword` - password for the user used to install software (Windows only)
- `Location` - location where resources will be created (e.g. "East US")
- `ImageName` and `ImageResourceGroupName` - name of the resource group where managed image will be stored
- `TemplatePath` - path to the Packer template file (e.g. "images/win/windows2022.json")
### 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
| ------------ | ------- | -----------
| `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_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.
| `location` | `ARM_RESOURCE_LOCATION` | The Azure datacenter in which your VM will be built.
| `managed_image_resource_group_name` | `ARM_RESOURCE_GROUP` | The resource group under which the final artifact will be stored.
| `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` | Azure datacenter in which your VM will build.
| `managed_image_resource_group_name` | `ARM_RESOURCE_GROUP` | Resource group under which the final artifact will be stored.
### Optional variables
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;
- `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;
- `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`;
- `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;
- `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_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.
- `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 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.
- `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` - 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.
- `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_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
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;
- `image_os` - the type of OS that will be deployed as a temporary VM;
- `image_version` - specify the version of an OS to boot from.
- `vm_size` - Size of the VM used for building. This can be changed when you deploy a VM from your image.
- `image_os` - Type of OS that will be deployed as a temporary VM.
- `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
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:
@@ -268,12 +267,12 @@ Generated tool versions and details can be found in related projects:
## 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>
- Linux: <https://github.com/actions/runner-images/tree/main/images/ubuntu/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/linux/post-generation>
**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 }
```
### Script Details: Ubuntu
### Script details: Ubuntu
- **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;
- **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;
- **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).
- **cleanup-logs.sh** - removes all build process logs from the machine
- **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 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. 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;
- **InternetExplorerConfiguration.ps1** - turns off the Internet Explorer Enhanced Security feature;
- **Msys2FirstLaunch.ps1** - initializes the bash user profile in MSYS2;
- **VSConfiguration.ps1** - performs initial Visual Studio configuration.
- **GenerateIISExpressCertificate.ps1** - generates and imports a certificate to run applications with IIS Express through HTTPS
- **InternetExplorerConfiguration** - turns off the Internet Explorer Enhanced Security feature
- **Msys2FirstLaunch.ps1** - initializes bash user profile in MSYS2
- **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"
.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 (
[Parameter(Mandatory = $True)]
+37 -43
View File
@@ -5,8 +5,7 @@ enum ImageType {
Windows2022 = 2
Ubuntu2004 = 3
Ubuntu2204 = 4
Ubuntu2404 = 5
UbuntuMinimal = 6
UbuntuMinimal = 5
}
Function Get-PackerTemplatePath {
@@ -18,24 +17,20 @@ Function Get-PackerTemplatePath {
)
switch ($ImageType) {
# Note: Double Join-Path is required to support PowerShell 5.1
([ImageType]::Windows2019) {
$relativeTemplatePath = Join-Path (Join-Path "windows" "templates") "windows-2019.pkr.hcl"
$relativeTemplatePath = Join-Path "win" "windows2019.json"
}
([ImageType]::Windows2022) {
$relativeTemplatePath = Join-Path (Join-Path "windows" "templates") "windows-2022.pkr.hcl"
$relativeTemplatePath = Join-Path "win" "windows2022.json"
}
([ImageType]::Ubuntu2004) {
$relativeTemplatePath = Join-Path (Join-Path "ubuntu" "templates") "ubuntu-20.04.pkr.hcl"
$relativeTemplatePath = Join-Path "linux" "ubuntu2004.json"
}
([ImageType]::Ubuntu2204) {
$relativeTemplatePath = Join-Path (Join-Path "ubuntu" "templates") "ubuntu-22.04.pkr.hcl"
}
([ImageType]::Ubuntu2404) {
$relativeTemplatePath = Join-Path (Join-Path "ubuntu" "templates") "ubuntu-24.04.pkr.hcl"
$relativeTemplatePath = Join-Path "linux" "ubuntu2204.pkr.hcl"
}
([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" }
}
@@ -101,10 +96,8 @@ Function GenerateResourcesAndImage {
This parameter cannot be used in combination with the virtual_network_name packer parameter.
.PARAMETER Force
Delete the resource group if it exists without user confirmation.
This parameter is deprecated and will be removed in a future release.
.PARAMETER ReuseResourceGroup
Reuse the resource group if it exists without user confirmation.
This parameter is deprecated and will be removed in a future release.
.PARAMETER OnError
Specify how packer handles an error during image creation.
Options:
@@ -152,14 +145,10 @@ Function GenerateResourcesAndImage {
[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) {
throw "Force and ReuseResourceGroup cannot be used together."
}
Show-LatestCommit -ErrorAction SilentlyContinue
# 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."
if ($PSVersionTable.PSVersion.Major -eq 5) {
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."
$AllowedInboundIpAddresses = '[\"{0}\"]' -f $AgentIp
if ($TemplatePath.Contains("pkr.hcl")) {
if ($PSVersionTable.PSVersion.Major -eq 5) {
Write-Verbose "PowerShell 5 detected. Replacing double quotes with escaped double quotes in allowed inbound IP addresses."
$AllowedInboundIpAddresses = '[\"{0}\"]' -f $AgentIp
}
else {
$AllowedInboundIpAddresses = '["{0}"]' -f $AgentIp
}
}
else {
$AllowedInboundIpAddresses = '["{0}"]' -f $AgentIp
$AllowedInboundIpAddresses = $AgentIp
}
}
else {
$AllowedInboundIpAddresses = "[]"
if ($TemplatePath.Contains("pkr.hcl")) {
$AllowedInboundIpAddresses = "[]"
}
else {
$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."
$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."
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()
Write-Host "Downloading packer plugins..."
& $PackerBinary init $TemplatePath
if ($LastExitCode -ne 0) {
throw "Packer plugins download failed."
}
Write-Host "Validating packer template..."
& $PackerBinary validate `
"-var=client_id=fake" `
@@ -233,7 +227,7 @@ Function GenerateResourcesAndImage {
"-var=allowed_inbound_ip_addresses=$($AllowedInboundIpAddresses)" `
"-var=azure_tags=$($TagsJson)" `
$TemplatePath
if ($LastExitCode -ne 0) {
throw "Packer template validation failed."
}
@@ -246,7 +240,7 @@ Function GenerateResourcesAndImage {
}
else {
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
if ($LastExitCode -ne 0) {
@@ -281,7 +275,7 @@ Function GenerateResourcesAndImage {
# Resource group already exists, ask the user what to do
$title = "Resource group '$ResourceGroupName' already exists"
$message = "Do you want to delete the resource group and all resources in it?"
$options = @(
[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."),
@@ -337,7 +331,7 @@ Function GenerateResourcesAndImage {
if ($LastExitCode -ne 0) {
throw "Failed to create service principal '$ServicePrincipalName'."
}
$ServicePrincipalAppId = $ServicePrincipal.appId
$ServicePrincipalPassword = $ServicePrincipal.password
$TenantId = $ServicePrincipal.tenant
@@ -374,7 +368,7 @@ Function GenerateResourcesAndImage {
Write-Error $_
} finally {
Write-Verbose "`nCleaning up..."
# Remove ADServicePrincipal and ADApplication
if ($ADCleanupRequired) {
Write-Host "Removing ADServicePrincipal..."
@@ -13,15 +13,15 @@ class BaseNode {
}
[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) {
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) {
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() {
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) {
@@ -53,4 +53,4 @@ class BaseToolNode: BaseNode {
[Boolean] IsIdenticalTo([BaseNode] $OtherNode) {
return $this.IsSimilarTo($OtherNode) -and ($this.GetValue() -eq $OtherNode.GetValue())
}
}
}
@@ -12,9 +12,6 @@ parameters:
- name: image_type
type: string
- name: image_template_name
type: string
- name: image_readme_name
type: string
@@ -59,38 +56,37 @@ jobs:
arguments: -RepoUrl $(CUSTOM_REPOSITORY_URL) `
-RepoBranch $(CUSTOM_REPOSITORY_BRANCH)
- task: AzureCLI@2
- task: PowerShell@2
displayName: 'Set variables'
inputs:
azureSubscription: 'spn-hosted-runners'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
targetType: 'inline'
script: |
$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
$TemplateFileName = "${{ parameters.image_template_name }}"
$TemplatePath = Join-Path $TemplateDirectoryPath $TemplateFileName
$TemplatePath = Join-Path $TemplateDirectoryPath "$ImageType.pkr.hcl"
if ( -not (Test-Path $TemplatePath) ) {
$TemplatePath = Join-Path $TemplateDirectoryPath "$ImageType.json"
}
Write-Host "##vso[task.setvariable variable=TemplateDirectoryPath;]$TemplateDirectoryPath"
Write-Host "##vso[task.setvariable variable=TemplatePath;]$TemplatePath"
$ManagedImageName = "${{ parameters.image_type }}-$(Build.BuildId)"
Write-Host "##vso[task.setvariable variable=ManagedImageName;]$ManagedImageName"
$VhdName = "$ManagedImageName.vhd"
Write-Host "##vso[task.setvariable variable=VhdName;]$VhdName"
$TempResourceGroupName = "packer-temp-$ManagedImageName"
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
displayName: 'Build VM'
inputs:
targetType: filePath
filePath: ./images.CI/linux-and-win/build-image.ps1
arguments: -ClientId $(CLIENT_ID) `
-ClientSecret "$(ClientSecret)" `
-ClientSecret $(CLIENT_SECRET) `
-TemplatePath $(TemplatePath) `
-ImageName "$(ManagedImageName)" `
-ImageResourceGroupName $(AZURE_RESOURCE_GROUP) `
@@ -111,12 +107,8 @@ jobs:
inputs:
targetType: 'inline'
script: |
$ImageType = "${{ parameters.image_type }}"
$rootDirectoryName = if ($ImageType.StartsWith("ubuntu")) { "ubuntu" } else { "windows" }
$rootDirectoryPath = Join-Path "images" $rootDirectoryName | Resolve-Path
$readmePath = Join-Path $rootDirectoryPath "${{ parameters.image_readme_name }}"
$softwareReportPath = Join-Path $rootDirectoryPath "software-report.json"
$readmePath = Join-Path "$(TemplateDirectoryPath)" "${{ parameters.image_readme_name }}"
$softwareReportPath = Join-Path "$(TemplateDirectoryPath)" "software-report.json"
Copy-Item -Path $readmePath -Destination "$(Build.ArtifactStagingDirectory)/"
if (Test-Path $softwareReportPath) {
@@ -154,6 +146,26 @@ jobs:
-PrefixToPathTrim "$(TemplateDirectoryPath)" `
-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) }}:
- task: PowerShell@2
displayName: 'Create release for VM deployment'
@@ -164,8 +176,9 @@ jobs:
-Organization $(RELEASE_TARGET_ORGANIZATION) `
-DefinitionId $(RELEASE_TARGET_DEFINITION_ID) `
-Project $(RELEASE_TARGET_PROJECT) `
-ImageType "${{ parameters.image_type }}" `
-ManagedImageName "$(ManagedImageName)" `
-ImageName "${{ parameters.image_type }}" `
-StorageAccountContainerName "images" `
-VhdName "$(VhdName)" `
-AccessToken $(RELEASE_TARGET_TOKEN)
- task: PowerShell@2
@@ -175,7 +188,8 @@ jobs:
targetType: filePath
filePath: ./images.CI/linux-and-win/cleanup.ps1
arguments: -TempResourceGroupName "$(TempResourceGroupName)" `
-StorageAccount $(AZURE_STORAGE_ACCOUNT) `
-SubscriptionId $(AZURE_SUBSCRIPTION) `
-ClientId $(CLIENT_ID) `
-ClientSecret "$(ClientSecret)" `
-ClientSecret $(CLIENT_SECRET) `
-TenantId $(AZURE_TENANT)
@@ -17,5 +17,4 @@ jobs:
- template: image-generation.yml
parameters:
image_type: ubuntu2004
image_readme_name: Ubuntu2004-Readme.md
image_template_name: ubuntu-20.04.pkr.hcl
image_readme_name: Ubuntu2004-Readme.md
@@ -17,5 +17,4 @@ jobs:
- template: image-generation.yml
parameters:
image_type: ubuntu2204
image_readme_name: Ubuntu2204-Readme.md
image_template_name: ubuntu-22.04.pkr.hcl
image_readme_name: Ubuntu2204-Readme.md
@@ -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
parameters:
image_type: windows2019
image_readme_name: Windows2019-Readme.md
image_template_name: windows-2019.pkr.hcl
image_readme_name: Windows2019-Readme.md
@@ -17,5 +17,4 @@ jobs:
- template: image-generation.yml
parameters:
image_type: windows2022
image_readme_name: Windows2022-Readme.md
image_template_name: windows-2022.pkr.hcl
image_readme_name: Windows2022-Readme.md
+3 -6
View File
@@ -22,6 +22,8 @@ if (-not (Test-Path $TemplatePath))
$ImageTemplateName = [io.path]::GetFileName($TemplatePath).Split(".")[0]
$InstallPassword = [System.GUID]::NewGuid().ToString().ToUpper()
packer validate -syntax-only $TemplatePath
$SensitiveData = @(
'OSType',
'StorageAccountLocation',
@@ -35,12 +37,6 @@ $SensitiveData = @(
Write-Host "Show 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"
packer build -var "client_id=$ClientId" `
-var "client_secret=$ClientSecret" `
@@ -54,6 +50,7 @@ packer build -var "client_id=$ClientId" `
-var "virtual_network_name=$VirtualNetworkName" `
-var "virtual_network_resource_group_name=$VirtualNetworkRG" `
-var "virtual_network_subnet_name=$VirtualNetworkSubnet" `
-var "run_validation_diskspace=$env:RUN_VALIDATION_FLAG" `
-color=false `
$TemplatePath `
| Where-Object {
+14 -10
View File
@@ -1,19 +1,23 @@
param(
[Parameter (Mandatory=$true)] [string] $TempResourceGroupName,
[Parameter (Mandatory=$true)] [string] $SubscriptionId,
[Parameter (Mandatory=$true)] [string] $ClientId,
[Parameter (Mandatory=$true)] [string] $ClientSecret,
[Parameter (Mandatory=$true)] [string] $TenantId
[String] [Parameter (Mandatory=$true)] $TempResourceGroupName,
[String] [Parameter (Mandatory=$true)] $StorageAccount,
[String] [Parameter (Mandatory=$true)] $SubscriptionId,
[String] [Parameter (Mandatory=$true)] $ClientId,
[String] [Parameter (Mandatory=$true)] $ClientSecret,
[String] [Parameter (Mandatory=$true)] $TenantId
)
az login --service-principal --username $ClientId --password=$ClientSecret --tenant $TenantId | Out-Null
az account set --subscription $SubscriptionId | Out-Null
az login --service-principal --username $ClientId --password $ClientSecret --tenant $TenantId | Out-Null
$groupExist = az group exists --name $TempResourceGroupName
$groupExist = az group exists --name $TempResourceGroupName --subscription $SubscriptionId
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"
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 "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 {
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(
[Parameter (Mandatory)] [UInt32] $BuildId,
[Parameter (Mandatory)] [string] $Organization,
[Parameter (Mandatory)] [string] $Project,
[Parameter (Mandatory)] [string] $ImageType,
[Parameter (Mandatory)] [string] $ManagedImageName,
[Parameter (Mandatory)] [string] $DefinitionId,
[Parameter (Mandatory)] [string] $AccessToken
[UInt32] [Parameter (Mandatory)] $BuildId,
[String] [Parameter (Mandatory)] $Organization,
[String] [Parameter (Mandatory)] $Project,
[String] [Parameter (Mandatory)] $ImageName,
[String] [Parameter (Mandatory)] $StorageAccountContainerName,
[String] [Parameter (Mandatory)] $VhdName,
[String] [Parameter (Mandatory)] $DefinitionId,
[String] [Parameter (Mandatory)] $AccessToken
)
$Body = @{
@@ -14,11 +15,14 @@ $Body = @{
ImageBuildId = @{
value = $BuildId
}
ImageType = @{
value = $ImageType
ImageName = @{
value = $ImageName
}
ManagedImageName = @{
value = $ManagedImageName
ImageStorageContainerName = @{
value = $StorageAccountContainerName
}
ImageBlobPath = @{
value = $VhdName
}
}
isDraft = "false"
@@ -33,4 +37,4 @@ $headers = @{
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13
$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
)
# 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"
$images = anka --machine-readable registry --cacert $AnkaCaCrtPath --registry-path $RegistryUrl list | ConvertFrom-Json | ForEach-Object body
$images | Where-Object name -eq $TemplateName | ForEach-Object {
@@ -76,7 +76,7 @@ function Invoke-SoftwareUpdate {
$ipAddress = Get-AnkaVMIPAddress -VMName $TemplateName
# 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
# Install Software Updates
@@ -89,46 +89,42 @@ function Invoke-SoftwareUpdate {
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:"
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:"
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) {
# Check software updates have been installed
$updates = Get-SoftwareUpdate -HostName $ipAddress
if ($updates.Contains("Action: restart") -and !($updates -match $nextOSVersion)) {
Write-Host "`t[x] Software updates failed to install: "
Show-StringWithFormat $updates
exit 1
# Will be True if the value is not Venture, not empty, and contains "Action: restart" words
if ($newupdate.Contains("Action: restart") -and !$newupdate.Contains("macOS Ventura") -and !$newupdate.Contains("macOS Sonoma") -and (-not [String]::IsNullOrEmpty($newupdate))) {
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 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:"
$hUpdates = Get-SoftwareUpdateHistory -HostName $ipAddress
Show-StringWithFormat $hUpdates
Write-Host "`t[*] The current macOS version:"
$command = "sw_vers"
Invoke-SSHPassCommand -HostName $ipAddress -Command $command | Show-StringWithFormat
}
function Invoke-UpdateSettings {
param (
[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"
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[*] CPU Count: $CPUCount, RamSize: ${RamSizeGb}G, DiskSizeGb: ${DiskSizeGb}G, InstallerPath: $macOSInstaller, TemplateName: $TemplateName"
New-AnkaVMTemplate -InstallerPath "$macOSInstaller" `
+57 -68
View File
@@ -13,7 +13,7 @@ function Enable-AutoLogon {
[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
$base64 = [Convert]::ToBase64String($script.ToCharArray())
$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)]
[ValidateNotNullOrEmpty()]
[string] $Password,
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[array] $ListOfUpdates
[string] $Password
)
# Define the next macOS version
$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"
$url = "https://raw.githubusercontent.com/actions/runner-images/main/images/macos/provision/configuration/auto-software-update-arm64.exp"
$script = Invoke-RestMethod -Uri $url
foreach ($update in $listOfUpdates) {
if ($update -notmatch "$nextOSVersion") {
$updatedScript = $script.Replace("MACOSUPDATE", $($($update.trim()).Replace(" ","\ ")))
$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
}
}
$base64 = [Convert]::ToBase64String($script.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 {
@@ -80,24 +63,24 @@ function Get-AvailableIPSWVersions {
)
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) {
$command = { mist list firmware "$MacOSCodeNameOrVersion" --compatible --latest --export "/Applications/export.json" }
$command = { mist list firmware "$MacOSCodeNameOrVersion" --latest --export "/Applications/export.json" }
} else {
$command = { mist list firmware "$MacOSCodeNameOrVersion" --compatible --export "/Applications/export.json" }
$command = { mist list firmware "$MacOSCodeNameOrVersion" --export "/Applications/export.json" }
}
$condition = { $LASTEXITCODE -eq 0 }
Invoke-WithRetry -Command $command -BreakCondition $condition | Out-Null
$softwareList = get-content -Path "/Applications/export.json"
$availableBuilds = ($softwareList | ConvertFrom-Json).build
if ($null -eq $availableBuilds) {
$turgetVersion = ($softwareList | ConvertFrom-Json).version
if ($null -eq $turgetVersion) {
Write-Host "Requested macOS '$MacOSCodeNameOrVersion' version not found in the list of available installers."
$command = { mist list firmware "$($MacOSCodeNameOrVersion.split('.')[0])" }
Invoke-WithRetry -Command $command -BreakCondition $condition
exit 1
}
return $availableBuilds
return $turgetVersion
}
function Get-MacOSIPSWInstaller {
@@ -113,26 +96,21 @@ function Get-MacOSIPSWInstaller {
$MacOSName = "macOS Monterey"
} elseif ($MacOSVersion -eq [version] "13.0") {
$MacOSName = "macOS Ventura"
} elseif ($MacOSVersion -eq [version] "14.0") {
$MacOSName = "macOS Sonoma"
} else {
$MacOSName = $MacOSVersion.ToString()
}
Write-Host "`t[*] Finding available full installers"
if ($DownloadLatestVersion -eq $true) {
$targetBuild = Get-AvailableIPSWVersions -IsLatest $true -MacOSCodeNameOrVersion $MacOSName
Write-Host "`t[*] The 'DownloadLatestVersion' flag is set to true. Latest compatible macOS build of '$MacOSName' is '$targetBuild'"
$targetVersion = Get-AvailableIPSWVersions -IsLatest $true -MacOSCodeNameOrVersion $MacOSName
Write-host "`t[*] The 'DownloadLatestVersion' flag is set to true. Latest macOS version is '$MacOSName' - '$targetVersion' now"
} elseif ($BetaSearch -eq $true) {
$targetBuild = 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'"
$targetVersion = Get-AvailableIPSWVersions -IsBeta $true -MacOSCodeNameOrVersion $MacOSName
Write-host "`t[*] The 'BetaSearch' flag is set to true. Latestbeta macOS version is '$MacOSName' - '$targetVersion' now"
} else {
$targetBuild = Get-AvailableIPSWVersions -MacOSCodeNameOrVersion $MacOSName -IsLatest $false
Write-Host "`t[*] Available compatible macOS builds of '$MacOSName' are: $($targetBuild -join ', ')"
if ($targetBuild.Count -gt 1) {
Write-Error "`t[*] Please specify the exact build number of macOS you want to install"
exit 1
}
$targetVersion = Get-AvailableIPSWVersions -MacOSCodeNameOrVersion $MacOSName -IsLatest $false
Write-host "`t[*] The exact version was specified - '$MacOSName' "
}
$installerPathPattern = "/Applications/Install ${macOSName}*.ipsw"
@@ -145,12 +123,12 @@ function Get-MacOSIPSWInstaller {
# Download macOS installer
$installerDir = "/Applications/"
$installerName = "Install ${macOSName}.ipsw"
Write-Host "`t[*] Requested macOS '$targetBuild' 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
Write-Host "`t[*] Requested macOS '$targetVersion' version installer found, fetching it from mist database"
Invoke-WithRetry { mist download firmware "$targetVersion" --output-directory $installerDir --firmware-name "$installerName" } {$LASTEXITCODE -eq 0} | Out-Null
if (Test-Path "$installerDir$installerName") {
$result = "$installerDir$installerName"
} 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
}
return $result
@@ -171,11 +149,11 @@ function Get-MacOSInstaller {
Write-Host "`t[*] Beta Version requested. Enrolling machine to DeveloperSeed"
sudo $seedutil enroll DeveloperSeed | Out-Null
} 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
}
# Validate there is no software update at the moment
# Validate there is no softwareupdate at the moment
Test-SoftwareUpdate
# Validate availability OSVersion
@@ -191,7 +169,7 @@ function Get-MacOSInstaller {
exit 1
}
Show-StringWithFormat $filteredVersions
$osVersions = $filteredVersions.OSVersion | Sort-Object { [version]$_ }
$osVersions = $filteredVersions.OSVersion | Sort-Object {[version]$_}
$MacOSVersion = $osVersions | Select-Object -Last 1
Write-Host "`t[*] The 'DownloadLatestVersion' flag is set. Latest macOS version is '$MacOSVersion' now"
}
@@ -266,13 +244,31 @@ function Install-SoftwareUpdate {
[array] $listOfUpdates,
[string] $Password
)
# If an update is happening on macOS arm64 we will use the additional tool to install updates.
$osArch = $(arch)
if ($osArch -eq "arm64") {
Invoke-SoftwareUpdateArm64 -HostName $HostName -Password $Password -ListOfUpdates $listOfUpdates
# If an update is happening on macOS 12 or 13 we will use the prepared list of updates, otherwise, we will install all updates.
$command = "sw_vers"
$guestMacosVersion = Invoke-SSHPassCommand -HostName $HostName -Command $command
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 {
foreach ($update in $listOfUpdates) {
$command = "sudo /usr/sbin/softwareupdate --restart --verbose --install '$($update.trim())'"
$osArch = $(arch)
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
}
}
@@ -306,11 +302,7 @@ function Invoke-SSHPassCommand {
"${env:SSHUSER}@${HostName}"
)
$sshPassOptions = $sshArg -join " "
if ($PSVersionTable.PSVersion.Major -eq 7 -and $PSVersionTable.PSVersion.Minor -le 2) {
$result = bash -c "$sshPassOptions \""$Command\"" 2>&1"
} else {
$result = bash -c "$sshPassOptions `"$Command`" 2>&1"
}
$result = bash -c "$sshPassOptions \""$Command\"" 2>&1"
if ($LASTEXITCODE -ne 0) {
Write-Error "There is an error during command execution:`n$result"
exit 1
@@ -325,17 +317,14 @@ function Invoke-WithRetry {
[int] $RetryCount = 20,
[int] $Seconds = 60
)
while ($RetryCount -gt 0) {
try {
if ($Command) {
$result = & $Command
}
if (& $BreakCondition) {
return $result
}
} catch {
Write-Host "`t [!] Error during command execution: $_"
while ($RetryCount -gt 0) {
if ($Command) {
$result = & $Command
}
if (& $BreakCondition) {
return $result
}
$RetryCount--
@@ -1,13 +1,11 @@
jobs:
- job: Image_generation
displayName: Image Generation (${{ parameters.image_label }})
timeoutInMinutes: 1200
timeoutInMinutes: 720
pool:
name: Mac-Cloud Image Generation
demands:
- PrimaryRackAgent -equals ${{ parameters.primary_agent }}
variables:
- group: ${{ parameters.variable_group_name }}
- group: Mac-Cloud Image Generation
steps:
- pwsh: |
@@ -65,7 +63,6 @@ jobs:
'Using ssh communicator to connect:'
)
packer init ${{ parameters.template_path }}
packer build -on-error=abort `
-var="vcenter_server=$(vcenter-server-v2)" `
-var="vcenter_username=$(vcenter-username-v2)" `
+1 -6
View File
@@ -14,15 +14,10 @@ pr:
include:
- main
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'
template_path: 'templates/macOS-11.json'
target_datastore: 'ds-image'
variable_group_name: 'Mac-Cloud Image Generation'
primary_agent: 'true'
+1 -6
View File
@@ -14,15 +14,10 @@ pr:
include:
- main
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'
template_path: 'templates/macOS-12.json'
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
}
$PathUbuntu = "./images/ubuntu/scripts"
$PathMacOS = "./images/macos"
$PathUbuntu = "./images/linux/scripts"
$PathMacOS = "./images/macos/provision"
$PatternUbuntu = "#!/bin/bash -e"
$PatternMacOS = "#!/bin/bash -e -o pipefail"
$ScriptsWithBrokenShebang = @()
@@ -34,10 +34,10 @@ if ($ScriptsWithBrokenShebang.Length -gt 0) {
$ScriptsWithBrokenShebang | ForEach-Object {
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'"
exit 1
else {
Write-Host "All scripts have correct shebang."
}
}
}
@@ -1,13 +1,13 @@
| Announcements |
|-|
| [Ubuntu 24.04 is now available](https://github.com/actions/runner-images/issues/9848) |
| [[Ubuntu, Windows] Docker Compose v1 will be removed from images on July, 29](https://github.com/actions/runner-images/issues/9692) |
| [[All OS] Android NDK r23 will be removed from images on October 9](https://github.com/actions/runner-images/issues/8383) |
| [[All OS] hub utility will be removed on October 2](https://github.com/actions/runner-images/issues/8362) |
***
# Ubuntu 20.04
- OS Version: 20.04.6 LTS
- Kernel Version: 5.15.0-1067-azure
- Image Version: 20240714.1.0
- Systemd version: 245.4-4ubuntu3.23
- Kernel Version: 5.15.0-1047-azure
- Image Version: 20231002.1.0
- Systemd version: 245.4-4ubuntu3.22
## Installed Software
@@ -18,32 +18,32 @@
- Clang-tidy: 10.0.0, 11.0.0, 12.0.0
- Dash 0.5.10.2-6
- Erlang 25.3 (Eshell 13.2)
- Erlang rebar3 3.23.0
- GNU C++: 10.5.0
- GNU Fortran: 10.5.0
- Julia 1.10.4
- Kotlin 2.0.0-release-341
- Erlang rebar3 3.22.1
- GNU C++: 9.4.0, 10.5.0
- GNU Fortran: 9.4.0, 10.5.0
- Julia 1.9.3
- Kotlin 1.9.10-release-459
- Mono 6.12.0.200
- MSBuild 16.10.1.31701 (Mono 6.12.0.200)
- Node.js 18.20.4
- Node.js 18.18.0
- Perl 5.30.0
- Python 3.8.10
- Ruby 2.7.0p0
- Swift 5.10.1
- Swift 5.9
### Package Management
- cpan 1.64
- Helm 3.15.3
- Homebrew 4.3.9
- Miniconda 24.5.0
- Npm 10.7.0
- Helm 3.13.0
- Homebrew 4.1.13
- Miniconda 23.5.2
- Npm 9.8.1
- NuGet 6.6.1.2
- Pip 20.0.2
- Pip3 20.0.2
- Pipx 1.6.0
- Pipx 1.2.0
- RubyGems 3.1.2
- Vcpkg (build from commit 7aeffc910)
- Yarn 1.22.22
- Vcpkg (build from commit c6d6efed3)
- Yarn 1.22.19
#### Environment variables
| Name | Value |
@@ -61,119 +61,118 @@ to accomplish this.
### Project Management
- Ant 1.10.7
- Gradle 8.9
- Lerna 8.1.6
- Gradle 8.3
- Lerna 7.3.0
- Maven 3.8.8
- Sbt 1.10.1
- Sbt 1.9.6
### Tools
- Ansible 2.13.13
- apt-fast 1.10.0
- AzCopy 10.25.1 - available by `azcopy` and `azcopy10` aliases
- Bazel 7.2.1
- Bazelisk 1.19.0
- Bicep 0.28.1
- Ansible 2.13.12
- apt-fast 1.9.12
- AzCopy 10.21.0 - available by `azcopy` and `azcopy10` aliases
- Bazel 6.3.2
- Bazelisk 1.18.0
- Bicep 0.21.1
- Buildah 1.22.3
- CMake 3.30.0
- CodeQL Action Bundle 2.18.0
- Docker Amazon ECR Credential Helper 0.8.0
- CMake 3.27.6
- CodeQL Action Bundle 2.14.6
- Docker Amazon ECR Credential Helper 0.7.1
- Docker Compose v1 1.29.2
- Docker Compose v2 2.27.1
- Docker-Buildx 0.16.0
- Docker Client 26.1.3
- Docker Server 26.1.3
- Fastlane 2.221.1
- Git 2.45.2
- Git LFS 3.5.1
- Docker Compose v2 2.22.0
- Docker-Buildx 0.11.2
- Docker Client 24.0.6
- Docker Server 24.0.6
- Fastlane 2.216.0
- Git 2.42.0
- Git LFS 3.4.0
- Git-ftp 1.6.0
- Haveged 1.9.1
- Heroku 8.11.5
- Heroku 8.5.0
- HHVM (HipHop VM) 4.172.1
- jq 1.6
- Kind 0.23.0
- Kubectl 1.30.2
- Kustomize 5.4.2
- Leiningen 2.11.2
- Kind 0.20.0
- Kubectl 1.28.2
- Kustomize 5.1.1
- Leiningen 2.10.0
- MediaInfo 19.09
- Mercurial 5.3.1
- Minikube 1.33.1
- n 9.2.3
- Newman 6.1.3
- nvm 0.39.7
- OpenSSL 1.1.1f-1ubuntu2.22
- Packer 1.11.1
- Parcel 2.12.0
- Minikube 1.31.2
- n 9.1.0
- Newman 6.0.0
- nvm 0.39.5
- OpenSSL 1.1.1f-1ubuntu2.19
- Packer 1.9.4
- Parcel 2.9.3
- PhantomJS 2.1.1 2.1.1
- Podman 3.4.2
- Pulumi 3.124.0
- R 4.4.1
- Pulumi 3.86.0
- R 4.3.1
- Skopeo 1.5.0
- Sphinx Open Source Search Server 2.2.11
- SVN 1.13.0
- Terraform 1.9.2
- yamllint 1.35.1
- yq 4.44.2
- zstd 1.5.6
- Terraform 1.5.7
- yamllint 1.32.0
- yq 4.35.2
- zstd 1.5.5
### CLI Tools
- Alibaba Cloud CLI 3.0.174
- AWS CLI 2.17.13
- AWS CLI Session Manager Plugin 1.2.650.0
- AWS SAM CLI 1.120.0
- Azure CLI 2.62.0
- Azure CLI (azure-devops) 1.0.1
- GitHub CLI 2.52.0
- Google Cloud CLI 483.0.0
- Netlify CLI 17.33.3
- OpenShift CLI 4.15.19
- ORAS CLI 1.2.0
- Vercel CLI 34.3.1
- AWS CLI 2.13.22
- AWS CLI Session Manager Plugin 1.2.497.0
- AWS SAM CLI 1.97.0
- Azure CLI 2.53.0
- Azure CLI (azure-devops) 0.26.0
- GitHub CLI 2.35.0
- Google Cloud CLI 448.0.0
- Netlify CLI 16.4.2
- OpenShift CLI 4.13.13
- ORAS CLI 1.1.0
- Vercel CLI 32.3.1
### Java
| Version | Environment Variable |
| ------------------- | -------------------- |
| 8.0.412+8 | JAVA_HOME_8_X64 |
| 11.0.23+9 (default) | JAVA_HOME_11_X64 |
| 17.0.11+9 | JAVA_HOME_17_X64 |
| 21.0.3+9 | JAVA_HOME_21_X64 |
| 8.0.382+5 | JAVA_HOME_8_X64 |
| 11.0.20+1 (default) | JAVA_HOME_11_X64 |
| 17.0.8+1 | JAVA_HOME_17_X64 |
### PHP Tools
- PHP: 7.4.33, 8.0.30, 8.1.29, 8.2.21, 8.3.9
- Composer 2.7.7
- PHPUnit 8.5.39
- PHP: 7.4.33, 8.0.30, 8.1.23, 8.2.10
- Composer 2.6.4
- PHPUnit 8.5.34
```
Both Xdebug and PCOV extensions are installed, but only Xdebug is enabled.
```
### Haskell Tools
- Cabal 3.12.1.0
- GHC 9.10.1
- GHCup 0.1.30.0
- Stack 2.15.7
- Cabal 3.10.1.0
- GHC 9.6.3
- GHCup 0.1.19.4
- Stack 2.13.1
### Rust Tools
- Cargo 1.79.0
- Rust 1.79.0
- Rustdoc 1.79.0
- Rustup 1.27.1
- Cargo 1.72.1
- Rust 1.72.1
- Rustdoc 1.72.1
- Rustup 1.26.0
#### Packages
- Bindgen 0.69.4
- Cargo audit 0.20.0
- Cargo clippy 0.1.79
- Cargo outdated 0.15.0
- Bindgen 0.68.1
- Cargo audit 0.18.2
- Cargo clippy 0.1.72
- Cargo outdated 0.13.1
- Cbindgen 0.26.0
- Rustfmt 1.7.0
- Rustfmt 1.6.0
### Browsers and Drivers
- Google Chrome 126.0.6478.126
- ChromeDriver 126.0.6478.126
- Chromium 126.0.6478.0
- Microsoft Edge 126.0.2592.102
- Microsoft Edge WebDriver 126.0.2592.102
- Selenium server 4.22.0
- Mozilla Firefox 128.0
- Geckodriver 0.34.0
- Google Chrome 117.0.5938.132
- ChromeDriver 117.0.5938.92
- Chromium 117.0.5938.0
- Microsoft Edge 117.0.2045.47
- Microsoft Edge WebDriver 117.0.2045.47
- Selenium server 4.13.0
- Mozilla Firefox 118.0.1
- Geckodriver 0.33.0
#### Environment variables
| 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 |
### .NET Tools
- .NET Core SDK: 6.0.424, 7.0.410, 8.0.303
- nbgv 3.6.139+a9e8765620
- .NET Core SDK: 6.0.414, 7.0.111, 7.0.203, 7.0.308, 7.0.401
- nbgv 3.6.133+2d32d93cb1
### Databases
- MongoDB 5.0.27
- MongoDB 5.0.21
- sqlite3 3.31.1
#### PostgreSQL
- PostgreSQL 14.12
- PostgreSQL 14.9
```
User: postgres
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 8.0.37-0ubuntu0.20.04.3
- MySQL 8.0.34-0ubuntu0.20.04.1
```
User: root
Password: root
@@ -210,50 +209,53 @@ Use the following command as a part of your job to start the service: 'sudo syst
#### MS SQL
- sqlcmd 17.10.0001.1
- SqlPackage 162.3.566.1
- SqlPackage 162.0.52.1
### Cached Tools
#### Go
- 1.20.14
- 1.21.12
- 1.22.5
- 1.19.13
- 1.20.8
- 1.21.1
#### Node.js
- 14.21.3
- 16.20.2
- 18.20.4
- 20.15.1
- 18.18.0
- 20.8.0
#### Python
- 3.7.17
- 3.8.18
- 3.9.19
- 3.10.14
- 3.11.9
- 3.12.4
- 3.9.18
- 3.10.13
- 3.11.5
#### PyPy
- 2.7.18 [PyPy 7.3.16]
- 2.7.18 [PyPy 7.3.13]
- 3.6.12 [PyPy 7.3.3]
- 3.7.13 [PyPy 7.3.9]
- 3.8.16 [PyPy 7.3.11]
- 3.9.19 [PyPy 7.3.16]
- 3.10.14 [PyPy 7.3.16]
- 3.9.18 [PyPy 7.3.13]
- 3.10.13 [PyPy 7.3.13]
#### Ruby
- 3.0.7
- 3.1.6
- 3.2.4
- 2.5.9
- 2.6.10
- 2.7.8
- 3.0.6
- 3.1.4
### PowerShell Tools
- PowerShell 7.4.3
- PowerShell 7.2.14
#### PowerShell Modules
- Az: 11.3.1
- MarkdownPS: 1.10
- Microsoft.Graph: 2.20.0
- Pester: 5.6.1
- PSScriptAnalyzer: 1.22.0
- 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
- Microsoft.Graph: 2.6.1
- Pester: 5.5.0
- PSScriptAnalyzer: 1.21.0
### Web Servers
| Name | Version | ConfigFile | ServiceStatus | ListenPort |
@@ -263,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 |
### Android
| Package Name | Version |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Android Command Line Tools | 9.0 |
| Android SDK Build-tools | 35.0.0<br>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 SDK Platforms | android-35 (rev 1)<br>android-34-ext8 (rev 1)<br>android-34-ext12 (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 Support Repository | 47.0.0 |
| CMake | 3.10.2<br>3.18.1<br>3.22.1 |
| Google Play services | 49 |
| Google Repository | 58 |
| NDK | 24.0.8215888<br>25.2.9519653 (default)<br>26.3.11579264 |
| Package Name | Version |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Android Command Line Tools | 9.0 |
| Android Emulator | 32.1.15 |
| 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 SDK Platform-Tools | 34.0.4 |
| 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) |
| Android SDK Tools | 26.1.1 |
| Android Support Repository | 47.0.0 |
| 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
| Name | Value |
@@ -280,28 +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_NDK | /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_SDK_ROOT | /usr/local/lib/android/sdk |
### Cached Docker images
| Repository:Tag | Digest | Created |
| -------------------- | ------------------------------------------------------------------------ | ---------- |
| alpine:3.16 | sha256:452e7292acee0ee16c332324d7de05fa2c99f9994ecc9f0779c602916a672ae4 | 2024-01-27 |
| alpine:3.17 | sha256:a6063e988bcd597b4f1f7cfd4ec38402b02edd0c79250f00c9e14dc1e94bebbc | 2024-06-20 |
| alpine:3.18 | sha256:1875c923b73448b558132e7d4a44b815d078779ed7a73f76209c6372de95ea8d | 2024-06-20 |
| alpine:3.19 | sha256:af4785ccdbcd5cde71bfd5b93eabd34250b98651f19fe218c91de6c8d10e21c5 | 2024-06-20 |
| debian:10 | sha256:58ce6f1271ae1c8a2006ff7d3e54e9874d839f573d8009c20154ad0f2fb0a225 | 2024-06-13 |
| debian:11 | sha256:b6b4a479a3bc1b8dfda5544f00b72aafb230bb835a43974a147b220c38df882e | 2024-07-02 |
| debian:9 | sha256:c5c5200ff1e9c73ffbf188b4a67eb1c91531b644856b4aefe86a58d2f0cb05be | 2022-06-23 |
| moby/buildkit:latest | sha256:33fe47b4c06972ac6720a7ee34d6fdea3b61972f81bcc9b1f73e46ed2a090fa1 | 2024-07-11 |
| node:16 | sha256:f77a1aef2da8d83e45ec990f45df50f1a286c5fe8bbfb8c6e4246c6389705c0b | 2023-09-07 |
| node:16-alpine | sha256:a1f9d027912b58a7c75be7716c97cfbc6d3099f3a97ed84aa490be9dee20e787 | 2023-08-10 |
| node:18 | sha256:aabbaf118c7c0a6e9a3bda69bd2a94b0f6c4150bf80c501ef1c87ffcb5687365 | 2024-07-09 |
| node:18-alpine | sha256:1edb14175eeb14a14a3abe059339cbd97a0bbb76b6a210d2bb395d63fa4bc4ef | 2024-07-09 |
| node:20 | sha256:786005cf39792f7046bcd66491056c26d2dbcc669c072d1a1e4ef4fcdddd26eb | 2024-07-09 |
| node:20-alpine | sha256:34b7aa411056c85dbf71d240d26516949b3f72b318d796c26b57caaa1df5639a | 2024-07-09 |
| ubuntu:20.04 | sha256:0b897358ff6624825fb50d20ffb605ab0eaea77ced0adb8c6a4b756513dec6fc | 2024-06-03 |
| Repository:Tag | Digest | Created |
| ----------------------- | ------------------------------------------------------------------------ | ---------- |
| alpine:3.16 | sha256:a8cbb8c69ee71561f4b69c066bad07f7e510caaa523da26fbfc606b10bd7934b | 2023-08-07 |
| alpine:3.17 | sha256:f71a5f071694a785e064f05fed657bf8277f1b2113a8ed70c90ad486d6ee54dc | 2023-08-07 |
| alpine:3.18 | sha256:eece025e432126ce23f223450a0326fbebde39cdf496a85d8c016293fc851978 | 2023-09-28 |
| buildpack-deps:bullseye | sha256:8ee57204a7af0468a61a3e47fbf8412d6ad1d479050bb702d99fd1d3664d7173 | 2023-09-20 |
| buildpack-deps:buster | sha256:0bc568b581ed3e9a13f818fd20258edb623cf67e6d354afadf77fb9095d798a2 | 2023-09-20 |
| buildpack-deps:stretch | sha256:78e995165a5788c2f55aed6e548d8f6c1534830d4310c870408fccb2da8c5b2e | 2022-06-23 |
| debian:10 | sha256:484cc8ab0d73f513e3f9bacd03424eb081bd90f594d7ebde42587843fdc242f3 | 2023-09-20 |
| debian:11 | sha256:54d33aaad0bc936a9a40d856764c7bc35c0afaa9cab51f88bb95f6cd8004438d | 2023-09-20 |
| debian:9 | sha256:c5c5200ff1e9c73ffbf188b4a67eb1c91531b644856b4aefe86a58d2f0cb05be | 2022-06-23 |
| moby/buildkit:latest | sha256:890dcae054e3039f6c6b76bf0da80a130fa6e6bb1f3624063ef0210ac2c57b06 | 2023-08-24 |
| node:14 | sha256:a158d3b9b4e3fa813fa6c8c590b8f0a860e015ad4e59bbce5744d2f6fd8461aa | 2023-04-12 |
| node:14-alpine | sha256:434215b487a329c9e867202ff89e704d3a75e554822e07f3e0c0f9e606121b33 | 2023-03-29 |
| node:16 | sha256:f77a1aef2da8d83e45ec990f45df50f1a286c5fe8bbfb8c6e4246c6389705c0b | 2023-09-07 |
| 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
| Name | Version |
@@ -310,19 +322,18 @@ Use the following command as a part of your job to start the service: 'sudo syst
| aria2 | 1.35.0-1build1 |
| autoconf | 2.69-11.1 |
| automake | 1:1.16.1-4ubuntu6 |
| binutils | 2.34-6ubuntu1.9 |
| binutils | 2.34-6ubuntu1.6 |
| bison | 2:3.5.1+dfsg-1 |
| brotli | 1.0.7-6ubuntu0.1 |
| bzip2 | 1.0.8-2 |
| coreutils | 8.30-3ubuntu2 |
| curl | 7.68.0-1ubuntu2.22 |
| curl | 7.68.0-1ubuntu2.19 |
| 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-dev | 1.19.7ubuntu3.2 |
| fakeroot | 1.24-1 |
| file | 1:5.38-4 |
| findutils | 4.7.0-1ubuntu1 |
| flex | 2.6.4-6.2 |
| fonts-noto-color-emoji | 0\~20200916-1\~ubuntu20.04.1 |
| ftp | 0.17-34.1 |
@@ -332,35 +343,35 @@ Use the following command as a part of your job to start the service: 'sudo syst
| haveged | 1.9.1-6ubuntu1 |
| imagemagick | 8:6.9.10.23+dfsg-2.1ubuntu11.9 |
| iproute2 | 5.5.0-1ubuntu1 |
| iputils-ping | 3:20190709-3ubuntu1 |
| iputils-ping | 3:20190709-3 |
| jq | 1.6-1ubuntu0.20.04.1 |
| lib32z1 | 1:1.2.11.dfsg-2ubuntu1.5 |
| libc++-dev | 1:10.0-50\~exp1 |
| libc++abi-dev | 1:10.0-50\~exp1 |
| libc6-dev | 2.31-0ubuntu9.16 |
| libcurl4 | 7.68.0-1ubuntu2.22 |
| libc6-dev | 2.31-0ubuntu9.9 |
| libcurl4 | 7.68.0-1ubuntu2.19 |
| libgbm-dev | 21.2.6-0ubuntu0.1\~20.04.2 |
| 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 |
| libmagic-dev | 1:5.38-4 |
| libmagickcore-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 |
| libsqlite3-dev | 3.31.1-4ubuntu0.6 |
| libsqlite3-dev | 3.31.1-4ubuntu0.5 |
| libtool | 2.4.6-14 |
| libunwind8 | 1.2.1-9ubuntu0.1 |
| libxkbfile-dev | 1:1.1.0-1 |
| libxss1 | 1:1.2.3-1 |
| libyaml-dev | 0.2.2-1 |
| locales | 2.31-0ubuntu9.16 |
| locales | 2.31-0ubuntu9.9 |
| m4 | 1.4.18-4 |
| make | 4.2.1-1.2 |
| mediainfo | 19.09-1build1 |
| mercurial | 5.3.1-1ubuntu1 |
| net-tools | 1.60+git20180626.aebd88e-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-rar | 16.02-3build1 |
| parallel | 20161222-1.1 |
@@ -374,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 |
| shellcheck | 0.7.0-2build2 |
| sphinxsearch | 2.2.11-2ubuntu2 |
| sqlite3 | 3.31.1-4ubuntu0.6 |
| ssh | 1:8.2p1-4ubuntu0.11 |
| sqlite3 | 3.31.1-4ubuntu0.5 |
| ssh | 1:8.2p1-4ubuntu0.9 |
| sshpass | 1.06-1 |
| subversion | 1.13.0-3ubuntu0.2 |
| sudo | 1.8.31-1ubuntu1.5 |
| 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 |
| texinfo | 6.7.0.dfsg.2-5 |
| time | 1.7-25.1build1 |
| tk | 8.6.9+1 |
| tzdata | 2024a-0ubuntu0.20.04.1 |
| unzip | 6.0-25ubuntu1.2 |
| tzdata | 2023c-0ubuntu0.20.04.2 |
| unzip | 6.0-25ubuntu1.1 |
| upx | 3.95-2build1 |
| wget | 1.20.3-1ubuntu2.1 |
| wget | 1.20.3-1ubuntu2 |
| 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 |
| zip | 3.0-11build1 |
| zsync | 0.6.2-3ubuntu1 |
@@ -1,47 +1,47 @@
| Announcements |
|-|
| [Ubuntu 24.04 is now available](https://github.com/actions/runner-images/issues/9848) |
| [[Ubuntu, Windows] Docker Compose v1 will be removed from images on July, 29](https://github.com/actions/runner-images/issues/9692) |
| [[All OS] Android NDK r23 will be removed from images on October 9](https://github.com/actions/runner-images/issues/8383) |
| [[All OS] hub utility will be removed on October 2](https://github.com/actions/runner-images/issues/8362) |
***
# Ubuntu 22.04
- OS Version: 22.04.4 LTS
- Kernel Version: 6.5.0-1023-azure
- Image Version: 20240714.1.0
- Systemd version: 249.11-0ubuntu3.12
- OS Version: 22.04.3 LTS
- Kernel Version: 6.2.0-1012-azure
- Image Version: 20231001.1.0
- Systemd version: 249.11-0ubuntu3.10
## Installed Software
### Language and Runtime
- Bash 5.1.16(1)-release
- Clang: 13.0.1, 14.0.0, 15.0.7
- Clang-format: 13.0.1, 14.0.0, 15.0.7
- Clang: 13.0.1, 14.0.0
- Clang-format: 13.0.1, 14.0.0
- Clang-tidy: 13.0.1, 14.0.0, 15.0.7
- Dash 0.5.11+git20210903+057cd650a4ed-3build1
- GNU C++: 10.5.0, 11.4.0, 12.3.0
- GNU Fortran: 10.5.0, 11.4.0, 12.3.0
- Julia 1.10.4
- Kotlin 2.0.0-release-341
- GNU C++: 9.5.0, 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.9.3
- Kotlin 1.9.10-release-459
- Mono 6.12.0.200
- MSBuild 16.10.1.31701 (Mono 6.12.0.200)
- Node.js 18.20.4
- Node.js 18.18.0
- Perl 5.34.0
- Python 3.10.12
- Ruby 3.0.2p107
- Swift 5.10.1
- Swift 5.9
### Package Management
- cpan 1.64
- Helm 3.15.3
- Homebrew 4.3.9
- Miniconda 24.5.0
- Npm 10.7.0
- Helm 3.13.0
- Homebrew 4.1.13
- Miniconda 23.5.2
- Npm 9.8.1
- NuGet 6.6.1.2
- Pip 22.0.2
- Pip3 22.0.2
- Pipx 1.6.0
- Pipx 1.2.0
- RubyGems 3.3.5
- Vcpkg (build from commit 7aeffc910)
- Yarn 1.22.22
- Vcpkg (build from commit c6d6efed3)
- Yarn 1.22.19
#### Environment variables
| Name | Value |
@@ -58,118 +58,114 @@ to accomplish this.
```
### Project Management
- Ant 1.10.12
- Gradle 8.9
- Lerna 8.1.6
- Lerna 7.3.0
- Maven 3.8.8
- Sbt 1.10.1
### Tools
- Ansible 2.17.1
- apt-fast 1.10.0
- AzCopy 10.25.1 - available by `azcopy` and `azcopy10` aliases
- Bazel 7.2.1
- Bazelisk 1.19.0
- Bicep 0.28.1
- Ansible 2.15.4
- apt-fast 1.9.12
- AzCopy 10.21.0 - available by `azcopy` and `azcopy10` aliases
- Bazel 6.3.2
- Bazelisk 1.18.0
- Bicep 0.21.1
- Buildah 1.23.1
- CMake 3.30.0
- CodeQL Action Bundle 2.18.0
- Docker Amazon ECR Credential Helper 0.8.0
- CMake 3.27.6
- CodeQL Action Bundles 2.14.5 2.14.6
- Docker Amazon ECR Credential Helper 0.7.1
- Docker Compose v1 1.29.2
- Docker Compose v2 2.27.1
- Docker-Buildx 0.16.0
- Docker Client 26.1.3
- Docker Server 26.1.3
- Fastlane 2.221.1
- Git 2.45.2
- Git LFS 3.5.1
- Docker Compose v2 2.22.0
- Docker-Buildx 0.11.2
- Docker Client 24.0.6
- Docker Server 24.0.6
- Fastlane 2.216.0
- Git 2.42.0
- Git LFS 3.4.0
- Git-ftp 1.6.0
- Haveged 1.9.14
- Heroku 8.11.5
- Heroku 8.5.0
- jq 1.6
- Kind 0.23.0
- Kubectl 1.30.2
- Kustomize 5.4.2
- Leiningen 2.11.2
- Kind 0.20.0
- Kubectl 1.28.2
- Kustomize 5.1.1
- Leiningen 2.10.0
- MediaInfo 21.09
- Mercurial 6.1.1
- Minikube 1.33.1
- n 9.2.3
- Newman 6.1.3
- nvm 0.39.7
- OpenSSL 3.0.2-0ubuntu1.16
- Packer 1.11.1
- Parcel 2.12.0
- Minikube 1.31.2
- n 9.1.0
- Newman 6.0.0
- nvm 0.39.5
- OpenSSL 3.0.2-0ubuntu1.10
- Packer 1.9.4
- Parcel 2.9.3
- Podman 3.4.4
- Pulumi 3.124.0
- R 4.4.1
- Pulumi 3.86.0
- R 4.3.1
- Skopeo 1.4.1
- Sphinx Open Source Search Server 2.2.11
- SVN 1.14.1
- Terraform 1.9.2
- yamllint 1.35.1
- yq 4.44.2
- zstd 1.5.6
- Terraform 1.5.7
- yamllint 1.32.0
- yq 4.35.2
- zstd 1.5.5
### CLI Tools
- Alibaba Cloud CLI 3.0.213
- AWS CLI 2.17.13
- AWS CLI Session Manager Plugin 1.2.650.0
- AWS SAM CLI 1.120.0
- Azure CLI 2.62.0
- Azure CLI (azure-devops) 1.0.1
- GitHub CLI 2.52.0
- Google Cloud CLI 483.0.0
- Netlify CLI 17.33.3
- OpenShift CLI 4.16.2
- ORAS CLI 1.2.0
- Vercel CLI 34.3.1
- Alibaba Cloud CLI 3.0.181
- AWS CLI 2.13.22
- AWS CLI Session Manager Plugin 1.2.497.0
- AWS SAM CLI 1.97.0
- Azure CLI 2.53.0
- Azure CLI (azure-devops) 0.26.0
- GitHub CLI 2.35.0
- Google Cloud CLI 448.0.0
- Netlify CLI 16.4.2
- OpenShift CLI 4.13.13
- ORAS CLI 1.1.0
- Vercel CLI 32.3.1
### Java
| Version | Environment Variable |
| ------------------- | -------------------- |
| 8.0.412+8 | JAVA_HOME_8_X64 |
| 11.0.23+9 (default) | JAVA_HOME_11_X64 |
| 17.0.11+9 | JAVA_HOME_17_X64 |
| 21.0.3+9 | JAVA_HOME_21_X64 |
| 8.0.382+5 | JAVA_HOME_8_X64 |
| 11.0.20+1 (default) | JAVA_HOME_11_X64 |
| 17.0.8+1 | JAVA_HOME_17_X64 |
### PHP Tools
- PHP: 8.1.2
- Composer 2.7.7
- PHPUnit 8.5.39
- Composer 2.6.4
- PHPUnit 8.5.34
```
Both Xdebug and PCOV extensions are installed, but only Xdebug is enabled.
```
### Haskell Tools
- Cabal 3.12.1.0
- GHC 9.10.1
- GHCup 0.1.30.0
- Stack 2.15.7
- Cabal 3.10.1.0
- GHC 9.6.3
- GHCup 0.1.19.4
- Stack 2.13.1
### Rust Tools
- Cargo 1.79.0
- Rust 1.79.0
- Rustdoc 1.79.0
- Rustup 1.27.1
- Cargo 1.72.1
- Rust 1.72.1
- Rustdoc 1.72.1
- Rustup 1.26.0
#### Packages
- Bindgen 0.69.4
- Cargo audit 0.20.0
- Cargo clippy 0.1.79
- Cargo outdated 0.15.0
- Bindgen 0.68.1
- Cargo audit 0.18.2
- Cargo clippy 0.1.72
- Cargo outdated 0.13.1
- Cbindgen 0.26.0
- Rustfmt 1.7.0
- Rustfmt 1.6.0
### Browsers and Drivers
- Google Chrome 126.0.6478.126
- ChromeDriver 126.0.6478.126
- Chromium 126.0.6478.0
- Microsoft Edge 126.0.2592.102
- Microsoft Edge WebDriver 126.0.2592.102
- Selenium server 4.22.0
- Mozilla Firefox 128.0
- Geckodriver 0.34.0
- Google Chrome 117.0.5938.132
- ChromeDriver 117.0.5938.92
- Chromium 117.0.5938.0
- Microsoft Edge 117.0.2045.47
- Microsoft Edge WebDriver 117.0.2045.47
- Selenium server 4.13.0
- Mozilla Firefox 118.0.1
- Geckodriver 0.33.0
#### Environment variables
| 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 |
### .NET Tools
- .NET Core SDK: 6.0.424, 7.0.410, 8.0.303
- nbgv 3.6.139+a9e8765620
- .NET Core SDK: 6.0.414, 7.0.111, 7.0.203, 7.0.308, 7.0.401
- nbgv 3.6.133+2d32d93cb1
### Databases
- sqlite3 3.37.2
#### PostgreSQL
- PostgreSQL 14.12
- PostgreSQL 14.9
```
User: postgres
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 8.0.37-0ubuntu0.22.04.3
- MySQL 8.0.34-0ubuntu0.22.04.1
```
User: root
Password: root
@@ -205,47 +201,46 @@ Use the following command as a part of your job to start the service: 'sudo syst
#### MS SQL
- sqlcmd 17.10.0001.1
- SqlPackage 162.3.566.1
- SqlPackage 162.0.52.1
### Cached Tools
#### Go
- 1.20.14
- 1.21.12
- 1.22.5
- 1.19.13
- 1.20.8
- 1.21.1
#### Node.js
- 14.21.3
- 16.20.2
- 18.20.4
- 20.15.1
- 18.18.0
- 20.8.0
#### Python
- 3.7.17
- 3.8.18
- 3.9.19
- 3.10.14
- 3.11.9
- 3.12.4
- 3.9.18
- 3.10.13
- 3.11.5
#### PyPy
- 3.7.13 [PyPy 7.3.9]
- 3.8.16 [PyPy 7.3.11]
- 3.9.19 [PyPy 7.3.16]
- 3.10.14 [PyPy 7.3.16]
- 3.9.18 [PyPy 7.3.13]
- 3.10.13 [PyPy 7.3.13]
#### Ruby
- 3.1.6
- 3.2.4
- 3.1.4
### PowerShell Tools
- PowerShell 7.4.3
- PowerShell 7.2.14
#### PowerShell Modules
- Az: 11.3.1
- MarkdownPS: 1.10
- Microsoft.Graph: 2.20.0
- Pester: 5.6.1
- PSScriptAnalyzer: 1.22.0
- Az: 9.3.0
- MarkdownPS: 1.9
- Microsoft.Graph: 2.6.1
- Pester: 5.5.0
- PSScriptAnalyzer: 1.21.0
### Web Servers
| Name | Version | ConfigFile | ServiceStatus | ListenPort |
@@ -254,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 |
### Android
| Package Name | Version |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Android Command Line Tools | 9.0 |
| Android SDK Build-tools | 35.0.0<br>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 SDK Platforms | android-35 (rev 1)<br>android-34-ext8 (rev 1)<br>android-34-ext12 (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 Support Repository | 47.0.0 |
| CMake | 3.10.2<br>3.18.1<br>3.22.1 |
| Google Play services | 49 |
| Google Repository | 58 |
| NDK | 24.0.8215888<br>25.2.9519653 (default)<br>26.3.11579264 |
| Package Name | Version |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Android Command Line Tools | 9.0 |
| Android Emulator | 32.1.15 |
| 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 SDK Platform-Tools | 34.0.4 |
| 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) |
| Android SDK Tools | 26.1.1 |
| Android Support Repository | 47.0.0 |
| 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
| Name | Value |
@@ -271,28 +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_NDK | /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_SDK_ROOT | /usr/local/lib/android/sdk |
### Cached Docker images
| Repository:Tag | Digest | Created |
| -------------------- | ------------------------------------------------------------------------ | ---------- |
| alpine:3.16 | sha256:452e7292acee0ee16c332324d7de05fa2c99f9994ecc9f0779c602916a672ae4 | 2024-01-27 |
| alpine:3.17 | sha256:a6063e988bcd597b4f1f7cfd4ec38402b02edd0c79250f00c9e14dc1e94bebbc | 2024-06-20 |
| alpine:3.18 | sha256:1875c923b73448b558132e7d4a44b815d078779ed7a73f76209c6372de95ea8d | 2024-06-20 |
| alpine:3.19 | sha256:af4785ccdbcd5cde71bfd5b93eabd34250b98651f19fe218c91de6c8d10e21c5 | 2024-06-20 |
| debian:10 | sha256:58ce6f1271ae1c8a2006ff7d3e54e9874d839f573d8009c20154ad0f2fb0a225 | 2024-06-13 |
| debian:11 | sha256:b6b4a479a3bc1b8dfda5544f00b72aafb230bb835a43974a147b220c38df882e | 2024-07-02 |
| moby/buildkit:latest | sha256:33fe47b4c06972ac6720a7ee34d6fdea3b61972f81bcc9b1f73e46ed2a090fa1 | 2024-07-11 |
| node:16 | sha256:f77a1aef2da8d83e45ec990f45df50f1a286c5fe8bbfb8c6e4246c6389705c0b | 2023-09-07 |
| node:16-alpine | sha256:a1f9d027912b58a7c75be7716c97cfbc6d3099f3a97ed84aa490be9dee20e787 | 2023-08-10 |
| node:18 | sha256:aabbaf118c7c0a6e9a3bda69bd2a94b0f6c4150bf80c501ef1c87ffcb5687365 | 2024-07-09 |
| node:18-alpine | sha256:1edb14175eeb14a14a3abe059339cbd97a0bbb76b6a210d2bb395d63fa4bc4ef | 2024-07-09 |
| node:20 | sha256:786005cf39792f7046bcd66491056c26d2dbcc669c072d1a1e4ef4fcdddd26eb | 2024-07-09 |
| node:20-alpine | sha256:34b7aa411056c85dbf71d240d26516949b3f72b318d796c26b57caaa1df5639a | 2024-07-09 |
| ubuntu:20.04 | sha256:0b897358ff6624825fb50d20ffb605ab0eaea77ced0adb8c6a4b756513dec6fc | 2024-06-03 |
| ubuntu:22.04 | sha256:340d9b015b194dc6e2a13938944e0d016e57b9679963fdeb9ce021daac430221 | 2024-06-27 |
| Repository:Tag | Digest | Created |
| ----------------------- | ------------------------------------------------------------------------ | ---------- |
| alpine:3.16 | sha256:a8cbb8c69ee71561f4b69c066bad07f7e510caaa523da26fbfc606b10bd7934b | 2023-08-07 |
| alpine:3.17 | sha256:f71a5f071694a785e064f05fed657bf8277f1b2113a8ed70c90ad486d6ee54dc | 2023-08-07 |
| alpine:3.18 | sha256:eece025e432126ce23f223450a0326fbebde39cdf496a85d8c016293fc851978 | 2023-09-28 |
| buildpack-deps:bullseye | sha256:8ee57204a7af0468a61a3e47fbf8412d6ad1d479050bb702d99fd1d3664d7173 | 2023-09-20 |
| buildpack-deps:buster | sha256:0bc568b581ed3e9a13f818fd20258edb623cf67e6d354afadf77fb9095d798a2 | 2023-09-20 |
| debian:10 | sha256:484cc8ab0d73f513e3f9bacd03424eb081bd90f594d7ebde42587843fdc242f3 | 2023-09-20 |
| debian:11 | sha256:54d33aaad0bc936a9a40d856764c7bc35c0afaa9cab51f88bb95f6cd8004438d | 2023-09-20 |
| moby/buildkit:latest | sha256:890dcae054e3039f6c6b76bf0da80a130fa6e6bb1f3624063ef0210ac2c57b06 | 2023-08-24 |
| node:14 | sha256:a158d3b9b4e3fa813fa6c8c590b8f0a860e015ad4e59bbce5744d2f6fd8461aa | 2023-04-12 |
| node:14-alpine | sha256:434215b487a329c9e867202ff89e704d3a75e554822e07f3e0c0f9e606121b33 | 2023-03-29 |
| node:16 | sha256:f77a1aef2da8d83e45ec990f45df50f1a286c5fe8bbfb8c6e4246c6389705c0b | 2023-09-07 |
| 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: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
| Name | Version |
@@ -301,21 +304,20 @@ Use the following command as a part of your job to start the service: 'sudo syst
| aria2 | 1.36.0-1 |
| autoconf | 2.71-2 |
| automake | 1:1.16.5-1.3 |
| binutils | 2.38-4ubuntu2.6 |
| binutils | 2.38-4ubuntu2.3 |
| bison | 2:3.8.2+dfsg-1build1 |
| brotli | 1.0.9-2build6 |
| bzip2 | 1.0.8-5build1 |
| coreutils | 8.32-4.1ubuntu1.2 |
| curl | 7.81.0-1ubuntu1.16 |
| coreutils | 8.32-4.1ubuntu1 |
| curl | 7.81.0-1ubuntu1.13 |
| dbus | 1.12.20-2ubuntu4.1 |
| dnsutils | 1:9.18.24-0ubuntu0.22.04.1 |
| dpkg | 1.21.1ubuntu2.3 |
| dpkg-dev | 1.21.1ubuntu2.3 |
| dnsutils | 1:9.18.12-0ubuntu0.22.04.3 |
| dpkg | 1.21.1ubuntu2.2 |
| dpkg-dev | 1.21.1ubuntu2.2 |
| fakeroot | 1.28-1ubuntu1 |
| file | 1:5.41-3ubuntu0.1 |
| findutils | 4.8.0-1ubuntu3 |
| 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 |
| g++ | 4:11.2.0-1ubuntu1 |
| gcc | 4:11.2.0-1ubuntu1 |
@@ -328,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 |
| libc++-dev | 1:14.0-55\~exp2 |
| libc++abi-dev | 1:14.0-55\~exp2 |
| libc6-dev | 2.35-0ubuntu3.8 |
| libcurl4 | 7.81.0-1ubuntu1.16 |
| libgbm-dev | 23.2.1-1ubuntu3.1\~22.04.2 |
| libc6-dev | 2.35-0ubuntu3.3 |
| libcurl4 | 7.81.0-1ubuntu1.13 |
| libgbm-dev | 23.0.4-0ubuntu1\~22.04.1 |
| libgconf-2-4 | 3.2.6-7ubuntu2 |
| 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 |
| 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 |
| libsecret-1-dev | 0.20.5-2 |
| libsqlite3-dev | 3.37.2-2ubuntu0.3 |
| libssl-dev | 3.0.2-0ubuntu1.16 |
| libsqlite3-dev | 3.37.2-2ubuntu0.1 |
| libssl-dev | 3.0.2-0ubuntu1.10 |
| libtool | 2.4.6-15build2 |
| libunwind8 | 1.3.2-2build2.1 |
| libxkbfile-dev | 1:1.1.0-1build3 |
| libxss1 | 1:1.2.3-1build2 |
| libyaml-dev | 0.2.2-1build2 |
| locales | 2.35-0ubuntu3.8 |
| locales | 2.35-0ubuntu3.3 |
| lz4 | 1.9.3-2build2 |
| m4 | 1.4.18-5ubuntu2 |
| make | 4.3-4.1build1 |
@@ -353,7 +355,7 @@ Use the following command as a part of your job to start the service: 'sudo syst
| mercurial | 6.1.1-1ubuntu1 |
| net-tools | 1.60+git20181103.0eebece-1ubuntu5 |
| netcat | 1.218-4ubuntu1 |
| openssh-client | 1:8.9p1-3ubuntu0.10 |
| openssh-client | 1:8.9p1-3ubuntu0.4 |
| p7zip-full | 16.02+dfsg-8 |
| p7zip-rar | 16.02-3build1 |
| parallel | 20210822+ds-2 |
@@ -367,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 |
| shellcheck | 0.8.0-2 |
| sphinxsearch | 2.2.11-8 |
| sqlite3 | 3.37.2-2ubuntu0.3 |
| ssh | 1:8.9p1-3ubuntu0.10 |
| sqlite3 | 3.37.2-2ubuntu0.1 |
| ssh | 1:8.9p1-3ubuntu0.4 |
| sshpass | 1.09-1 |
| subversion | 1.14.1-3ubuntu0.22.04.1 |
| sudo | 1.9.9-1ubuntu2.4 |
| 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 |
| texinfo | 6.8-4build1 |
| time | 1.9-0.1build2 |
| tk | 8.6.11+1build2 |
| tzdata | 2024a-0ubuntu0.22.04.1 |
| unzip | 6.0-26ubuntu3.2 |
| tzdata | 2023c-0ubuntu0.22.04.2 |
| unzip | 6.0-26ubuntu3.1 |
| upx | 3.96-3 |
| wget | 1.21.2-2ubuntu1.1 |
| wget | 1.21.2-2ubuntu1 |
| xorriso | 1.5.4-2 |
| xvfb | 2:21.1.4-2ubuntu1.7\~22.04.11 |
| xvfb | 2:21.1.4-2ubuntu1.7\~22.04.1 |
| xz-utils | 5.2.5-2ubuntu1 |
| zip | 3.0-12build2 |
| zsync | 0.6.2-3ubuntu1 |
@@ -20,6 +20,7 @@ function Get-AndroidInstalledPackages {
return $androidSDKManagerList
}
function Build-AndroidTable {
$packageInfo = Get-AndroidInstalledPackages
return @(
@@ -43,6 +44,10 @@ function Build-AndroidTable {
"Package" = "Android SDK Platforms"
"Version" = Get-AndroidPlatformVersions -PackageInfo $packageInfo
},
@{
"Package" = "Android SDK Tools"
"Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Android SDK Tools"
},
@{
"Package" = "Android Support Repository"
"Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Android Support Repository"
@@ -74,7 +79,7 @@ function Build-AndroidTable {
) | Where-Object { $_.Version } | ForEach-Object {
[PSCustomObject] @{
"Package Name" = $_.Package
"Version" = $_.Version
"Version" = $_.Version
}
}
}
@@ -87,7 +92,7 @@ function Get-AndroidPackageVersions {
[object] $MatchedString
)
$versions = $PackageInfo | Where-Object { $_ -Match $MatchedString } | ForEach-Object {
$versions = $packageInfo | Where-Object { $_ -Match $MatchedString } | ForEach-Object {
$packageInfoParts = Split-TableRowByColumns $_
return $packageInfoParts[1]
}
@@ -100,7 +105,7 @@ function Get-AndroidPlatformVersions {
[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 $_
$revision = $packageInfoParts[1]
$version = $packageInfoParts[0].split(";")[1]
@@ -123,7 +128,7 @@ function Get-AndroidBuildToolVersions {
[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 $_
return $packageInfoParts[1]
}
@@ -141,7 +146,7 @@ function Get-AndroidGoogleAPIsVersions {
[object] $PackageInfo
)
$versions = $PackageInfo | Where-Object { $_ -Match "Google APIs" } | ForEach-Object {
$versions = $packageInfo | Where-Object { $_ -Match "Google APIs" } | ForEach-Object {
$packageInfoParts = Split-TableRowByColumns $_
return $packageInfoParts[0].split(";")[1]
}
@@ -151,7 +156,7 @@ function Get-AndroidGoogleAPIsVersions {
function Get-AndroidNDKVersions {
$ndkFolderPath = Join-Path (Get-AndroidSDKRoot) "ndk"
$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
return ($versions | ForEach-Object {
@@ -166,7 +171,7 @@ function Build-AndroidEnvironmentTable {
$shouldResolveLink = 'ANDROID_NDK', 'ANDROID_NDK_HOME', 'ANDROID_NDK_ROOT', 'ANDROID_NDK_LATEST_HOME'
return $androidVersions | Sort-Object -Property Name | ForEach-Object {
[PSCustomObject] @{
"Name" = $_.Name
"Name" = $_.Name
"Value" = if ($shouldResolveLink.Contains($_.Name )) { Get-PathWithLink($_.Value) } else {$_.Value}
}
}
@@ -1,59 +1,60 @@
function Get-ChromeVersion {
$googleChromeVersion = google-chrome --version | Get-StringPart -Part 2
$googleChromeVersion = google-chrome --version | Take-OutputPart -Part 2
return $googleChromeVersion
}
function Get-ChromeDriverVersion {
$chromeDriverVersion = chromedriver --version | Get-StringPart -Part 1
$chromeDriverVersion = chromedriver --version | Take-OutputPart -Part 1
return $chromeDriverVersion
}
function Get-FirefoxVersion {
$firefoxVersion = $(firefox --version) | Get-StringPart -Part 2
$firefoxVersion = $(firefox --version) | Take-OutputPart -Part 2
return $firefoxVersion
}
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
}
function Get-ChromiumVersion {
$chromiumVersion = chromium-browser --version | Get-StringPart -Part 1
$chromiumVersion = chromium-browser --version | Take-OutputPart -Part 1
return $chromiumVersion
}
function Get-EdgeVersion {
$edgeVersion = (microsoft-edge --version).Trim() | Get-StringPart -Part 2
$edgeVersion = (microsoft-edge --version).Trim() | Take-OutputPart -Part 2
return $edgeVersion
}
function Get-EdgeDriverVersion {
$edgeDriverVersion = msedgedriver --version | Get-StringPart -Part 3
$edgeDriverVersion = msedgedriver --version | Take-OutputPart -Part 3
return $edgeDriverVersion
}
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
}
function Build-BrowserWebdriversEnvironmentTable {
return @(
[PSCustomObject] @{
"Name" = "CHROMEWEBDRIVER"
"Name" = "CHROMEWEBDRIVER"
"Value" = $env:CHROMEWEBDRIVER
},
[PSCustomObject] @{
"Name" = "EDGEWEBDRIVER"
"Name" = "EDGEWEBDRIVER"
"Value" = $env:EDGEWEBDRIVER
},
[PSCustomObject] @{
"Name" = "GECKOWEBDRIVER"
"Name" = "GECKOWEBDRIVER"
"Value" = $env:GECKOWEBDRIVER
},
[PSCustomObject] @{
"Name" = "SELENIUM_JAR_PATH"
"Name" = "SELENIUM_JAR_PATH"
"Value" = $env:SELENIUM_JAR_PATH
}
)
@@ -1,18 +1,18 @@
function Get-ToolcacheRubyVersions {
$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 {
$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 {
$toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "PyPy"
Get-ChildItem -Path $toolcachePath -Name | Sort-Object { [Version] $_ } | ForEach-Object {
$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
return "{0} [PyPy {1}]" -f $Matches[1], $Matches[2]
}
@@ -20,10 +20,10 @@ function Get-ToolcachePyPyVersions {
function Get-ToolcacheNodeVersions {
$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 {
$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 {
$result = Get-CommandResult "apt list --installed" -Multiline
$cppVersions = $result.Output | Where-Object { $_ -match "g\+\+-\d\d\/" } | ForEach-Object {
& $_.Split("/")[0] --version | Select-Object -First 1 | Get-StringPart -Part 3
} | Sort-Object {[Version] $_}
$cppVersions = $result.Output | Where-Object { $_ -match "g\+\+-\d+"} | ForEach-Object {
& $_.Split("/")[0] --version | Select-Object -First 1 | Take-OutputPart -Part 3
} | Sort-Object {[Version]$_}
return $cppVersions
}
function Get-FortranVersions {
$result = Get-CommandResult "apt list --installed" -Multiline
$fortranVersions = $result.Output | Where-Object { $_ -match "^gfortran-\d\d\/" } | ForEach-Object {
& $_.Split("/")[0] --version | Select-Object -First 1 | Get-StringPart -Part 4
} | Sort-Object {[Version] $_}
$fortranVersions = $result.Output | Where-Object { $_ -match "^gfortran-\d+"} | ForEach-Object {
$_ -match "now (?<version>\d+\.\d+\.\d+)-" | Out-Null
$Matches.version
} | Sort-Object {[Version]$_}
return $fortranVersions
}
@@ -29,25 +30,24 @@ function Get-ClangToolVersions {
[Parameter(Mandatory = $true)]
[string] $ToolName,
[string] $VersionLineMatcher = "${ToolName} version",
[string] $VersionPattern = "\d+\.\d+\.\d+)"
[string] $VersionPattern = "\d+\.\d+\.\d+)-"
)
$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]
Invoke-Expression "$clangCommand --version" | Where-Object { $_ -match "${VersionLineMatcher}" } | ForEach-Object {
$_ -match "${VersionLineMatcher} (?<version>${VersionPattern}" | Out-Null
$Matches.version
}
} | Sort-Object {[Version] $_}
} | Sort-Object {[Version]$_}
return $toolVersions
}
function Get-ClangTidyVersions {
$clangVersions = Get-ClangToolVersions -ToolName "clang-tidy" -VersionLineMatcher "LLVM version" -VersionPattern "\d+\.\d+\.\d+)"
return $clangVersions
return Get-ClangToolVersions -ToolName "clang-tidy" -VersionLineMatcher "LLVM version" -VersionPattern "\d+\.\d+\.\d+)"
}
@@ -64,7 +64,7 @@ function Get-ErlangRebar3Version {
}
function Get-MonoVersion {
$monoVersion = mono --version | Out-String | Get-StringPart -Part 4
$monoVersion = mono --version | Out-String | Take-OutputPart -Part 4
return $monoVersion
}
@@ -75,7 +75,7 @@ function Get-MsbuildVersion {
}
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
}
@@ -85,8 +85,7 @@ function Get-NodeVersion {
}
function Get-OpensslVersion {
$opensslVersion = $(dpkg-query -W -f '${Version}' openssl)
return $opensslVersion
return $(dpkg-query -W -f '${Version}' openssl)
}
function Get-PerlVersion {
@@ -96,32 +95,31 @@ function Get-PerlVersion {
function Get-PythonVersion {
$result = Get-CommandResult "python --version"
$version = $result.Output | Get-StringPart -Part 1
$version = $result.Output | Take-OutputPart -Part 1
return $version
}
function Get-PowershellVersion {
$pwshVersion = $(pwsh --version) | Get-StringPart -Part 1
return $pwshVersion
return $(pwsh --version) | Take-OutputPart -Part 1
}
function Get-RubyVersion {
$rubyVersion = ruby --version | Out-String | Get-StringPart -Part 1
$rubyVersion = ruby --version | Out-String | Take-OutputPart -Part 1
return $rubyVersion
}
function Get-SwiftVersion {
$swiftVersion = swift --version | Out-String | Get-StringPart -Part 2
$swiftVersion = swift --version | Out-String | Take-OutputPart -Part 2
return $swiftVersion
}
function Get-KotlinVersion {
$kotlinVersion = kotlin -version | Out-String | Get-StringPart -Part 2
$kotlinVersion = kotlin -version | Out-String | Take-OutputPart -Part 2
return $kotlinVersion
}
function Get-JuliaVersion {
$juliaVersion = julia --version | Get-StringPart -Part 2
$juliaVersion = julia --version | Take-OutputPart -Part 2
return $juliaVersion
}
@@ -137,7 +135,7 @@ function Get-HomebrewVersion {
}
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
return $Matches.version
}
@@ -149,7 +147,7 @@ function Get-GemVersion {
}
function Get-MinicondaVersion {
$condaVersion = conda --version | Get-StringPart -Part 1
$condaVersion = conda --version | Take-OutputPart -Part 1
return $condaVersion
}
@@ -174,13 +172,15 @@ function Get-ParcelVersion {
}
function Get-PipVersion {
$pipVersion = pip --version | Get-StringPart -Part 1
return $pipVersion
$result = Get-CommandResult "pip --version"
$result.Output -match "pip (?<version>\d+\.\d+\.\d+)" | Out-Null
return $Matches.version
}
function Get-Pip3Version {
$pip3Version = pip3 --version | Get-StringPart -Part 1
return $pip3Version
$result = Get-CommandResult "pip3 --version"
$result.Output -match "pip (?<version>\d+\.\d+\.\d+)" | Out-Null
return $Matches.version
}
function Get-VcpkgVersion {
@@ -195,7 +195,7 @@ function Get-AntVersion {
}
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
}
@@ -213,14 +213,14 @@ function Get-SbtVersion {
function Get-PHPVersions {
$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
$Matches.version
}
}
function Get-ComposerVersion {
$composerVersion = (composer --version) -replace " version" | Get-StringPart -Part 1
$composerVersion = (composer --version) -replace " version" | Take-OutputPart -Part 1
return $composerVersion
}
@@ -281,7 +281,7 @@ function Get-PowerShellModules {
}
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
}
@@ -307,8 +307,8 @@ function Get-CachedDockerImagesTableData {
$parts = $_.Split("|")
[PSCustomObject] @{
"Repository:Tag" = $parts[0]
"Digest" = $parts[1]
"Created" = $parts[2].split(' ')[0]
"Digest" = $parts[1]
"Created" = $parts[2].split(' ')[0]
}
} | Sort-Object -Property "Repository:Tag"
}
@@ -318,10 +318,10 @@ function Get-AptPackages {
$output = @()
ForEach ($pkg in ($apt.vital_packages + $apt.common_packages + $apt.cmd_packages)) {
$version = $(dpkg-query -W -f '${Version}' $pkg)
if ($null -eq $version) {
if ($Null -eq $version) {
$version = $(dpkg-query -W -f '${Version}' "$pkg*")
}
$version = $version -replace '~','\~'
$output += [PSCustomObject] @{
@@ -341,18 +341,18 @@ function Get-PipxVersion {
function Build-PackageManagementEnvironmentTable {
return @(
[PSCustomObject] @{
"Name" = "CONDA"
"Name" = "CONDA"
"Value" = $env:CONDA
},
[PSCustomObject] @{
"Name" = "VCPKG_INSTALLATION_ROOT"
"Name" = "VCPKG_INSTALLATION_ROOT"
"Value" = $env:VCPKG_INSTALLATION_ROOT
}
)
}
function Get-SystemdVersion {
$matchCollection = [regex]::Matches((systemctl --version | head -n 1), "\((.*?)\)")
$result = foreach ($match in $matchCollection) {$match.Groups[1].Value}
$matches = [regex]::Matches((systemctl --version | head -n 1), "\((.*?)\)")
$result = foreach ($match in $matches) {$match.Groups[1].Value}
return $result
}
}
@@ -1,25 +1,25 @@
function Get-PostgreSqlVersion {
$postgreSQLVersion = psql --version | Get-StringPart -Part 2
$postgreSQLVersion = psql --version | Take-OutputPart -Part 2
return $postgreSQLVersion
}
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
}
function Get-SqliteVersion {
$sqliteVersion = sqlite3 --version | Get-StringPart -Part 0
$sqliteVersion = sqlite3 --version | Take-OutputPart -Part 0
return $sqliteVersion
}
function Get-MySQLVersion {
$mySQLVersion = mysqld --version | Get-StringPart -Part 2
$mySQLVersion = mysqld --version | Take-OutputPart -Part 2
return $mySQLVersion
}
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
}
@@ -2,8 +2,8 @@ using module ./software-report-base/SoftwareReport.psm1
using module ./software-report-base/SoftwareReport.Nodes.psm1
param (
[Parameter(Mandatory)]
[string] $OutputDirectory
[Parameter(Mandatory)][string]
$OutputDirectory
)
$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.Common.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 (Join-Path $PSScriptRoot "SoftwareReport.Java.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
# Restore file owner in user profile
sudo chown -R ${env:USER}: $env:HOME
Restore-UserOwner
# Software report
$softwareReport = [SoftwareReport]::new("Ubuntu $(Get-OSVersionShort)")
@@ -48,20 +48,14 @@ if (Test-IsUbuntu20) {
$languageAndRuntime.AddToolVersionsListInline("GNU C++", $(Get-CPPVersions), "^\d+")
$languageAndRuntime.AddToolVersionsListInline("GNU Fortran", $(Get-FortranVersions), "^\d+")
$languageAndRuntime.AddToolVersion("Julia", $(Get-JuliaVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) {
$languageAndRuntime.AddToolVersion("Kotlin", $(Get-KotlinVersion))
}
if (-not $(Test-IsUbuntu24)) {
$languageAndRuntime.AddToolVersion("Mono", $(Get-MonoVersion))
$languageAndRuntime.AddToolVersion("MSBuild", $(Get-MsbuildVersion))
}
$languageAndRuntime.AddToolVersion("Kotlin", $(Get-KotlinVersion))
$languageAndRuntime.AddToolVersion("Mono", $(Get-MonoVersion))
$languageAndRuntime.AddToolVersion("MSBuild", $(Get-MsbuildVersion))
$languageAndRuntime.AddToolVersion("Node.js", $(Get-NodeVersion))
$languageAndRuntime.AddToolVersion("Perl", $(Get-PerlVersion))
$languageAndRuntime.AddToolVersion("Python", $(Get-PythonVersion))
$languageAndRuntime.AddToolVersion("Ruby", $(Get-RubyVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) {
$languageAndRuntime.AddToolVersion("Swift", $(Get-SwiftVersion))
}
$languageAndRuntime.AddToolVersion("Swift", $(Get-SwiftVersion))
# Package Management
$packageManagement = $installedSoftware.AddHeader("Package Management")
@@ -70,9 +64,7 @@ $packageManagement.AddToolVersion("Helm", $(Get-HelmVersion))
$packageManagement.AddToolVersion("Homebrew", $(Get-HomebrewVersion))
$packageManagement.AddToolVersion("Miniconda", $(Get-MinicondaVersion))
$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("Pip3", $(Get-Pip3Version))
$packageManagement.AddToolVersion("Pipx", $(Get-PipxVersion))
@@ -89,20 +81,22 @@ to accomplish this.
# Project Management
$projectManagement = $installedSoftware.AddHeader("Project Management")
$projectManagement.AddToolVersion("Ant", $(Get-AntVersion))
$projectManagement.AddToolVersion("Gradle", $(Get-GradleVersion))
$projectManagement.AddToolVersion("Lerna", $(Get-LernaVersion))
$projectManagement.AddToolVersion("Maven", $(Get-MavenVersion))
if (Test-IsUbuntu20) {
$projectManagement.AddToolVersion("Ant", $(Get-AntVersion))
$projectManagement.AddToolVersion("Gradle", $(Get-GradleVersion))
}
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) {
$projectManagement.AddToolVersion("Lerna", $(Get-LernaVersion))
}
$projectManagement.AddToolVersion("Maven", $(Get-MavenVersion))
if (Test-IsUbuntu20) {
$projectManagement.AddToolVersion("Sbt", $(Get-SbtVersion))
}
# Tools
$tools = $installedSoftware.AddHeader("Tools")
$tools.AddToolVersion("Ansible", $(Get-AnsibleVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) {
$tools.AddToolVersion("apt-fast", $(Get-AptFastVersion))
}
$tools.AddToolVersion("apt-fast", $(Get-AptFastVersion))
$tools.AddToolVersion("AzCopy", $(Get-AzCopyVersion))
$tools.AddToolVersion("Bazel", $(Get-BazelVersion))
$tools.AddToolVersion("Bazelisk", $(Get-BazeliskVersion))
@@ -111,21 +105,19 @@ $tools.AddToolVersion("Buildah", $(Get-BuildahVersion))
$tools.AddToolVersion("CMake", $(Get-CMakeVersion))
$tools.AddToolVersion("CodeQL Action Bundle", $(Get-CodeQLBundleVersion))
$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-Buildx", $(Get-DockerBuildxVersion))
$tools.AddToolVersion("Docker Client", $(Get-DockerClientVersion))
$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 LFS", $(Get-GitLFSVersion))
$tools.AddToolVersion("Git-ftp", $(Get-GitFTPVersion))
$tools.AddToolVersion("Haveged", $(Get-HavegedVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) {
$tools.AddToolVersion("Heroku", $(Get-HerokuVersion))
}
$tools.AddToolVersion("Heroku", $(Get-HerokuVersion))
if (Test-IsUbuntu20) {
$tools.AddToolVersion("HHVM (HipHop VM)", $(Get-HHVMVersion))
}
@@ -133,119 +125,89 @@ $tools.AddToolVersion("jq", $(Get-JqVersion))
$tools.AddToolVersion("Kind", $(Get-KindVersion))
$tools.AddToolVersion("Kubectl", $(Get-KubectlVersion))
$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("Mercurial", $(Get-HGVersion))
$tools.AddToolVersion("Minikube", $(Get-MinikubeVersion))
$tools.AddToolVersion("n", $(Get-NVersion))
$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))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) {
$tools.AddToolVersion("Packer", $(Get-PackerVersion))
}
$tools.AddToolVersion("Packer", $(Get-PackerVersion))
$tools.AddToolVersion("Parcel", $(Get-ParcelVersion))
if (Test-IsUbuntu20) {
$tools.AddToolVersion("PhantomJS", $(Get-PhantomJSVersion))
}
$tools.AddToolVersion("Podman", $(Get-PodManVersion))
$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("Sphinx Open Source Search Server", $(Get-SphinxVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) {
$tools.AddToolVersion("SVN", $(Get-SVNVersion))
$tools.AddToolVersion("Terraform", $(Get-TerraformVersion))
}
$tools.AddToolVersion("SVN", $(Get-SVNVersion))
$tools.AddToolVersion("Terraform", $(Get-TerraformVersion))
$tools.AddToolVersion("yamllint", $(Get-YamllintVersion))
$tools.AddToolVersion("yq", $(Get-YqVersion))
$tools.AddToolVersion("zstd", $(Get-ZstdVersion))
# 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 Session Manager Plugin", $(Get-AWSCliSessionManagerPluginVersion))
$cliTools.AddToolVersion("AWS SAM CLI", $(Get-AWSSAMVersion))
$cliTools.AddToolVersion("Azure CLI", $(Get-AzureCliVersion))
$cliTools.AddToolVersion("Azure CLI (azure-devops)", $(Get-AzureDevopsVersion))
$cliTools.AddToolVersion("GitHub CLI", $(Get-GitHubCliVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) {
$cliTools.AddToolVersion("Google Cloud CLI", $(Get-GoogleCloudCLIVersion))
$cliTools.AddToolVersion("Netlify CLI", $(Get-NetlifyCliVersion))
$cliTools.AddToolVersion("OpenShift CLI", $(Get-OCCliVersion))
$cliTools.AddToolVersion("ORAS CLI", $(Get-ORASCliVersion))
$cliTools.AddToolVersion("Vercel CLI", $(Get-VerselCliversion))
}
$cliTools.AddToolVersion("Google Cloud CLI", $(Get-GoogleCloudCLIVersion))
$cliTools.AddToolVersion("Netlify CLI", $(Get-NetlifyCliVersion))
$cliTools.AddToolVersion("OpenShift CLI", $(Get-OCCliVersion))
$cliTools.AddToolVersion("ORAS CLI", $(Get-ORASCliVersion))
$cliTools.AddToolVersion("Vercel CLI", $(Get-VerselCliversion))
# Java
$installedSoftware.AddHeader("Java").AddTable($(Get-JavaVersionsTable))
# PHP Tools
$phpTools = $installedSoftware.AddHeader("PHP Tools")
$phpTools.AddToolVersionsListInline("PHP", $(Get-PHPVersions), "^\d+\.\d+")
$phpTools.AddToolVersion("Composer", $(Get-ComposerVersion))
$phpTools.AddToolVersion("PHPUnit", $(Get-PHPUnitVersion))
$phpTools.AddNote("Both Xdebug and PCOV extensions are installed, but only Xdebug is enabled.")
# Haskell Tools
$haskellTools = $installedSoftware.AddHeader("Haskell Tools")
$haskellTools.AddToolVersion("Cabal", $(Get-CabalVersion))
$haskellTools.AddToolVersion("GHC", $(Get-GHCVersion))
$haskellTools.AddToolVersion("GHCup", $(Get-GHCupVersion))
$haskellTools.AddToolVersion("Stack", $(Get-StackVersion))
# Rust Tools
Initialize-RustEnvironment
$rustTools = $installedSoftware.AddHeader("Rust Tools")
$rustTools.AddToolVersion("Cargo", $(Get-CargoVersion))
$rustTools.AddToolVersion("Rust", $(Get-RustVersion))
$rustTools.AddToolVersion("Rustdoc", $(Get-RustdocVersion))
$rustTools.AddToolVersion("Rustup", $(Get-RustupVersion))
# Packages
$rustToolsPackages = $rustTools.AddHeader("Packages")
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) {
$rustToolsPackages.AddToolVersion("Bindgen", $(Get-BindgenVersion))
$rustToolsPackages.AddToolVersion("Cargo audit", $(Get-CargoAuditVersion))
$rustToolsPackages.AddToolVersion("Cargo clippy", $(Get-CargoClippyVersion))
$rustToolsPackages.AddToolVersion("Cargo outdated", $(Get-CargoOutdatedVersion))
$rustToolsPackages.AddToolVersion("Cbindgen", $(Get-CbindgenVersion))
}
$rustToolsPackages.AddToolVersion("Bindgen", $(Get-BindgenVersion))
$rustToolsPackages.AddToolVersion("Cargo audit", $(Get-CargoAuditVersion))
$rustToolsPackages.AddToolVersion("Cargo clippy", $(Get-CargoClippyVersion))
$rustToolsPackages.AddToolVersion("Cargo outdated", $(Get-CargoOutdatedVersion))
$rustToolsPackages.AddToolVersion("Cbindgen", $(Get-CbindgenVersion))
$rustToolsPackages.AddToolVersion("Rustfmt", $(Get-RustfmtVersion))
# Browsers and Drivers
$browsersTools = $installedSoftware.AddHeader("Browsers and Drivers")
$browsersTools.AddToolVersion("Google Chrome", $(Get-ChromeVersion))
$browsersTools.AddToolVersion("ChromeDriver", $(Get-ChromeDriverVersion))
$browsersTools.AddToolVersion("Chromium", $(Get-ChromiumVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) {
$browsersTools.AddToolVersion("Microsoft Edge", $(Get-EdgeVersion))
$browsersTools.AddToolVersion("Microsoft Edge WebDriver", $(Get-EdgeDriverVersion))
}
$browsersTools.AddToolVersion("Microsoft Edge", $(Get-EdgeVersion))
$browsersTools.AddToolVersion("Microsoft Edge WebDriver", $(Get-EdgeDriverVersion))
$browsersTools.AddToolVersion("Selenium server", $(Get-SeleniumVersion))
if ((Test-IsUbuntu20) -or (Test-IsUbuntu22)) {
$browsersTools.AddToolVersion("Mozilla Firefox", $(Get-FirefoxVersion))
$browsersTools.AddToolVersion("Geckodriver", $(Get-GeckodriverVersion))
}
# Environment variables
$browsersTools.AddToolVersion("Mozilla Firefox", $(Get-FirefoxVersion))
$browsersTools.AddToolVersion("Geckodriver", $(Get-GeckodriverVersion))
$browsersTools.AddHeader("Environment variables").AddTable($(Build-BrowserWebdriversEnvironmentTable))
# .NET Tools
$netCoreTools = $installedSoftware.AddHeader(".NET Tools")
$netCoreTools.AddToolVersionsListInline(".NET Core SDK", $(Get-DotNetCoreSdkVersions), "^\d+\.\d+\.\d")
$netCoreTools.AddNodes($(Get-DotnetTools))
# Databases
$databasesTools = $installedSoftware.AddHeader("Databases")
if (Test-IsUbuntu20) {
$databasesTools.AddToolVersion("MongoDB", $(Get-MongoDbVersion))
@@ -253,21 +215,15 @@ if (Test-IsUbuntu20) {
$databasesTools.AddToolVersion("sqlite3", $(Get-SqliteVersion))
$databasesTools.AddNode($(Build-PostgreSqlSection))
$databasesTools.AddNode($(Build-MySQLSection))
if (-not $(Test-IsUbuntu24)) {
$databasesTools.AddNode($(Build-MSSQLToolsSection))
}
$databasesTools.AddNode($(Build-MSSQLToolsSection))
# Cached Tools
$cachedTools = $installedSoftware.AddHeader("Cached Tools")
$cachedTools.AddToolVersionsList("Go", $(Get-ToolcacheGoVersions), "^\d+\.\d+")
$cachedTools.AddToolVersionsList("Node.js", $(Get-ToolcacheNodeVersions), "^\d+")
$cachedTools.AddToolVersionsList("Python", $(Get-ToolcachePythonVersions), "^\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.AddToolVersion("PowerShell", $(Get-PowershellVersion))
$powerShellTools.AddHeader("PowerShell Modules").AddNodes($(Get-PowerShellModules))
@@ -276,12 +232,9 @@ $installedSoftware.AddHeader("Web Servers").AddTable($(Build-WebServersTable))
$androidTools = $installedSoftware.AddHeader("Android")
$androidTools.AddTable($(Build-AndroidTable))
$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))
$softwareReport.ToJson() | Out-File -FilePath "${OutputDirectory}/software-report.json" -Encoding UTF8NoBOM
@@ -1,5 +1,5 @@
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 {
$majorVersion = $_.Name.split(".")[0]
@@ -5,51 +5,51 @@ function Initialize-RustEnvironment {
}
function Get-RustVersion {
$rustVersion = $(rustc --version) | Get-StringPart -Part 1
$rustVersion = $(rustc --version) | Take-OutputPart -Part 1
return $rustVersion
}
function Get-BindgenVersion {
$bindgenVersion = $(bindgen --version) | Get-StringPart -Part 1
$bindgenVersion = $(bindgen --version) | Take-OutputPart -Part 1
return $bindgenVersion
}
function Get-CargoVersion {
$cargoVersion = $(cargo --version) | Get-StringPart -Part 1
$cargoVersion = $(cargo --version) | Take-OutputPart -Part 1
return $cargoVersion
}
function Get-CargoAuditVersion {
$cargoAuditVersion = $(cargo-audit --version) | Get-StringPart -Part 1
$cargoAuditVersion = $(cargo-audit --version) | Take-OutputPart -Part 1
return $cargoAuditVersion
}
function Get-CargoOutdatedVersion {
$cargoOutdatedVersion = cargo outdated --version | Get-StringPart -Part 1
$cargoOutdatedVersion = cargo outdated --version | Take-OutputPart -Part 1
return $cargoOutdatedVersion
}
function Get-CargoClippyVersion {
$cargoClippyVersion = $(cargo-clippy --version) | Get-StringPart -Part 1
$cargoClippyVersion = $(cargo-clippy --version) | Take-OutputPart -Part 1
return $cargoClippyVersion
}
function Get-CbindgenVersion {
$cbindgenVersion = $(cbindgen --version) | Get-StringPart -Part 1
$cbindgenVersion = $(cbindgen --version) | Take-OutputPart -Part 1
return $cbindgenVersion
}
function Get-RustupVersion {
$rustupVersion = $(rustup --version) | Get-StringPart -Part 1
$rustupVersion = $(rustup --version) | Take-OutputPart -Part 1
return $rustupVersion
}
function Get-RustdocVersion {
$rustdocVersion = $(rustdoc --version) | Get-StringPart -Part 1
$rustdocVersion = $(rustdoc --version) | Take-OutputPart -Part 1
return $rustdocVersion
}
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
}
@@ -10,18 +10,18 @@ function Get-AptFastVersion {
}
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"
}
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
}
function Get-BazeliskVersion {
$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
}
@@ -39,32 +39,32 @@ function Get-CodeQLBundleVersion {
}
function Get-PodManVersion {
$podmanVersion = podman --version | Get-StringPart -Part 2
$podmanVersion = podman --version | Take-OutputPart -Part 2
return $podmanVersion
}
function Get-BuildahVersion {
$buildahVersion = buildah --version | Get-StringPart -Part 2
$buildahVersion = buildah --version | Take-OutputPart -Part 2
return $buildahVersion
}
function Get-SkopeoVersion {
$skopeoVersion = skopeo --version | Get-StringPart -Part 2
$skopeoVersion = skopeo --version | Take-OutputPart -Part 2
return $skopeoVersion
}
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
}
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
}
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
}
@@ -79,62 +79,62 @@ function Get-DockerServerVersion {
}
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
}
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
}
function Get-GitVersion {
$gitVersion = git --version | Get-StringPart -Part -1
$gitVersion = git --version | Take-OutputPart -Part -1
return $gitVersion
}
function Get-GitLFSVersion {
$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
}
function Get-GitFTPVersion {
$gitftpVersion = git-ftp --version | Get-StringPart -Part 2
$gitftpVersion = git-ftp --version | Take-OutputPart -Part 2
return $gitftpVersion
}
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 {
$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
}
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
}
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
}
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
}
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
}
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
}
@@ -144,21 +144,21 @@ function Get-KubectlVersion {
}
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
}
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
}
function Get-LeiningenVersion {
return "$(lein -v | Get-StringPart -Part 1)"
return "$(lein -v | Take-OutputPart -Part 1)"
}
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
}
@@ -177,7 +177,7 @@ function Get-NvmVersion {
}
function Get-PackerVersion {
$packerVersion = (packer --version | Select-String "^Packer").Line.Replace('v','') | Get-StringPart -Part 1
$packerVersion = packer --version
return $packerVersion
}
@@ -187,11 +187,11 @@ function Get-PhantomJSVersion {
}
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 {
$jqVersion = jq --version | Get-StringPart -Part 1 -Delimiter "-"
$jqVersion = jq --version | Take-OutputPart -Part 1 -Delimiter "-"
return $jqVersion
}
@@ -211,7 +211,7 @@ function Get-AlibabaCloudCliVersion {
function Get-AWSCliVersion {
$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
}
@@ -221,21 +221,21 @@ function Get-AWSCliSessionManagerPluginVersion {
}
function Get-AWSSAMVersion {
return $(sam --version | Get-StringPart -Part -1)
return $(sam --version | Take-OutputPart -Part -1)
}
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
}
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
}
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
}
@@ -245,7 +245,7 @@ function Get-OCCliVersion {
}
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
}
@@ -255,30 +255,30 @@ function Get-VerselCliversion {
}
function Get-PulumiVersion {
$pulumiVersion = pulumi version | Get-StringPart -Part 0 -Delimiter "v"
$pulumiVersion = pulumi version | Take-OutputPart -Part 0 -Delimiter "v"
return $pulumiVersion
}
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
}
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
}
function Get-YamllintVersion {
return $(yamllint --version) | Get-StringPart -Part 1
return $(yamllint --version) | Take-OutputPart -Part 1
}
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"
}
function Get-YqVersion {
$yqVersion = $(yq -V) | Get-StringPart -Part 3
$yqVersion = $(yq -V) | Take-OutputPart -Part 3
return $yqVersion.TrimStart("v").Trim()
}
@@ -1,15 +1,15 @@
function Get-ApacheVersion {
$name = "apache2"
$port = 80
$version = bash -c "apache2 -v | grep -Po 'Apache/(\d+.){2}\d+'" | Get-StringPart -Part 1 -Delimiter "/"
$serviceStatus = systemctl status apache2 | grep "Active:" | Get-StringPart -Part 1
$version = bash -c "apache2 -v | grep -Po 'Apache/(\d+.){2}\d+'" | Take-OutputPart -Part 1 -Delimiter "/"
$serviceStatus = systemctl status apache2 | grep "Active:" | Take-OutputPart -Part 1
$configFile = "/etc/apache2/apache2.conf"
return [PsCustomObject]@{
"Name" = $name
"Version" = $version
"ConfigFile" = $configFile
"Name" = $name
"Version" = $version
"ConfigFile" = $configFile
"ServiceStatus" = $serviceStatus
"ListenPort" = $port
"ListenPort" = $port
}
}
@@ -17,14 +17,14 @@ function Get-NginxVersion {
$name = "nginx"
$port = 80
$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"
return [PsCustomObject]@{
"Name" = $name
"Version" = $version
"ConfigFile" = $configFile
"Name" = $name
"Version" = $version
"ConfigFile" = $configFile
"ServiceStatus" = $serviceStatus
"ListenPort" = $port
"ListenPort" = $port
}
}
@@ -35,11 +35,11 @@ function Get-Xsp4Version {
$serviceStatus = systemctl show -p ActiveState --value mono-xsp4
$configFile = "/etc/default/mono-xsp4"
return [PsCustomObject]@{
"Name" = $name
"Version" = $version
"ConfigFile" = $configFile
"Name" = $name
"Version" = $version
"ConfigFile" = $configFile
"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
################################################################################
## File: configure-apt-mock.sh
## Desc: A temporary workaround for https://github.com/Azure/azure-linux-extensions/issues/1238.
## Cleaned up during cleanup.sh.
################################################################################
# A temporary workaround for https://github.com/Azure/azure-linux-extensions/issues/1238
prefix=/usr/local/bin
for real_tool in /usr/bin/apt /usr/bin/apt-get /usr/bin/apt-key; do
tool=$(basename $real_tool)
cat >$prefix/$tool <<EOT
for real_tool in /usr/bin/apt /usr/bin/apt-get /usr/bin/apt-fast /usr/bin/apt-key;do
tool=`basename $real_tool`
cat >$prefix/$tool <<EOT
#!/bin/sh
i=1
@@ -50,5 +47,5 @@ while [ \$i -le 30 ];do
i=\$((i + 1))
done
EOT
chmod +x $prefix/$tool
chmod +x $prefix/$tool
done
@@ -1,7 +1,7 @@
#!/bin/bash -e
################################################################################
## File: configure-apt-sources.sh
## Desc: Configure apt sources with failover from Azure to Ubuntu archives.
## File: apt-ubuntu-archive.sh
## 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
@@ -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
# 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,10 +1,4 @@
#!/bin/bash -e
################################################################################
## File: configure-apt.sh
## Desc: Configure apt, install jq and apt-fast packages.
################################################################################
source $HELPER_SCRIPTS/os.sh
# Stop and disable apt-daily upgrade services;
systemctl stop apt-daily.timer
@@ -38,18 +32,12 @@ EOF
apt-get purge unattended-upgrades
echo 'APT sources'
if ! is_ubuntu24; then
cat /etc/apt/sources.list
else
cat /etc/apt/sources.list.d/ubuntu.sources
fi
cat /etc/apt/sources.list
apt-get update
# Install jq
apt-get install jq
if ! is_ubuntu24; then
# Install apt-fast using quick-install.sh
# https://github.com/ilikenwf/apt-fast
bash -c "$(curl -fsSL https://raw.githubusercontent.com/ilikenwf/apt-fast/master/quick-install.sh)"
fi
# Install apt-fast using quick-install.sh
# https://github.com/ilikenwf/apt-fast
bash -c "$(curl -fsSL https://raw.githubusercontent.com/ilikenwf/apt-fast/master/quick-install.sh)"
@@ -1,8 +1,4 @@
#!/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-noninteractive
@@ -1,6 +1,8 @@
#!/bin/bash -e
################################################################################
## File: Install-TortoiseSvn.ps1
## Desc: Install TortoiseSvn
## File: reboot.sh
## Desc: Reboot VM
################################################################################
Install-ChocoPackage tortoisesvn
echo "Reboot VM"
sudo reboot
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash -e
################################################################################
## File: repos.sh
## Desc: Installs official Microsoft package repos for the distribution
################################################################################
LSB_RELEASE=$(lsb_release -rs)
# Install Microsoft repository
wget https://packages.microsoft.com/config/ubuntu/$LSB_RELEASE/packages-microsoft-prod.deb
dpkg -i packages-microsoft-prod.deb
# update
apt-get install -y apt-transport-https ca-certificates curl software-properties-common
apt-get -yq update
apt-get -yq dist-upgrade
@@ -1,16 +1,4 @@
#!/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
# 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
# Validates that tool is installed and in PATH
function Validate-ToolExist($tool) {
Get-Command $tool -ErrorAction SilentlyContinue | Should -BeTrue
}
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(
[Parameter(Mandatory = $true)]
[string] $TestFile,
[Parameter(Mandatory)][string] $TestFile,
[string] $TestName
)
@@ -36,12 +17,12 @@ function Invoke-PesterTests {
}
# Check that Pester module is imported
if (-not (Get-Module "Pester")) {
if (!(Get-Module "Pester")) {
Import-Module Pester
}
$configuration = [PesterConfiguration] @{
Run = @{ Path = $testPath; PassThru = $true }
Run = @{ Path = $testPath; PassThru = $true }
Output = @{ Verbosity = "Detailed"; RenderMode = "Plaintext" }
}
if ($TestName) {
@@ -62,29 +43,6 @@ function Invoke-PesterTests {
}
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(
[string] $ActualValue,
[switch] $Negate,
@@ -93,10 +51,11 @@ function ShouldReturnZeroExitCode {
$result = Get-CommandResult $ActualValue -ValidateExitCode $false
[bool] $succeeded = $result.ExitCode -eq 0
[bool]$succeeded = $result.ExitCode -eq 0
if ($Negate) { $succeeded = -not $succeeded }
if (-not $succeeded) {
if (-not $succeeded)
{
$commandOutputIndent = " " * 4
$commandOutput = ($result.Output | ForEach-Object { "${commandOutputIndent}${_}" }) -join "`n"
$failureMessage = "Command '${ActualValue}' has finished with exit code`n${commandOutput}"
@@ -108,30 +67,7 @@ function ShouldReturnZeroExitCode {
}
}
function ShouldOutputTextMatchingRegex {
<#
.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
#>
function ShouldMatchCommandOutput {
Param(
[string] $ActualValue,
[string] $RegularExpression,
@@ -141,14 +77,17 @@ function ShouldOutputTextMatchingRegex {
$output = (Get-CommandResult $ActualValue -ValidateExitCode $false).Output | Out-String
[bool] $succeeded = $output -cmatch $RegularExpression
if ($Negate) { $succeeded = -not $succeeded }
if ($Negate) {
$succeeded = -not $succeeded
}
$failureMessage = ''
if (-not $succeeded) {
if ($Negate) {
$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."
}
}
@@ -161,5 +100,5 @@ function ShouldOutputTextMatchingRegex {
If (Get-Command -Name Add-ShouldOperator -ErrorAction SilentlyContinue) {
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)
# The values containing '%' will break the functions
get_etc_environment_variable() {
local variable_name=$1
function getEtcEnvironmentVariable {
variable_name="$1"
# 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() {
local variable_name=$1
local variable_value=$2
function addEtcEnvironmentVariable {
variable_name="$1"
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() {
local variable_name=$1
local variable_value=$2
function replaceEtcEnvironmentVariable {
variable_name="$1"
variable_value="$2"
# 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() {
local variable_name=$1
local variable_value=$2
function setEtcEnvironmentVariable {
variable_name="$1"
variable_value="$2"
if grep "^${variable_name}=" /etc/environment > /dev/null; then
replace_etc_environment_variable $variable_name $variable_value
if grep "$variable_name" /etc/environment > /dev/null; then
replaceEtcEnvironmentVariable $variable_name $variable_value
else
add_etc_environment_variable $variable_name $variable_value
addEtcEnvironmentVariable $variable_name $variable_value
fi
}
prepend_etc_environment_variable() {
local variable_name=$1
local element=$2
function prependEtcEnvironmentVariable {
variable_name="$1"
element="$2"
# TODO: handle the case if the variable does not exist
existing_value=$(get_etc_environment_variable "${variable_name}")
set_etc_environment_variable "${variable_name}" "${element}:${existing_value}"
existing_value=$(getEtcEnvironmentVariable "${variable_name}")
setEtcEnvironmentVariable "${variable_name}" "${element}:${existing_value}"
}
append_etc_environment_variable() {
local variable_name=$1
local element=$2
function appendEtcEnvironmentVariable {
variable_name="$1"
element="$2"
# TODO: handle the case if the variable does not exist
existing_value=$(get_etc_environment_variable "${variable_name}")
set_etc_environment_variable "${variable_name}" "${existing_value}:${element}"
existing_value=$(getEtcEnvironmentVariable "${variable_name}")
setEtcEnvironmentVariable "${variable_name}" "${existing_value}:${element}"
}
prepend_etc_environment_path() {
local element=$1
prepend_etc_environment_variable PATH "${element}"
function prependEtcEnvironmentPath {
element="$1"
prependEtcEnvironmentVariable PATH "${element}"
}
append_etc_environment_path() {
local element=$1
append_etc_environment_variable PATH "${element}"
function appendEtcEnvironmentPath {
element="$1"
appendEtcEnvironmentVariable PATH "${element}"
}
# 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
# ie MANPATH, INFOPATH, LD_*, etc. In the current implementation the values from /etc/evironments
# 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
eval $(grep -v '^PATH=' /etc/environment | sed -e 's%^%export %')
# handle PATH specially
etc_path=$(get_etc_environment_variable PATH)
etc_path=$(getEtcEnvironmentVariable 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
################################################################################
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\""
+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 @@
################################################################################
## File: Install-PowerShellModules.ps1
## Desc: Install modules for PowerShell
################################################################################
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
Import-Module "$env:HELPER_SCRIPTS/../tests/Helpers.psm1"
# Specifies the installation policy
Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
# Try to update PowerShellGet before the actual installation
Install-Module -Name PowerShellGet -Force
Update-Module -Name PowerShellGet -Force
# Install PowerShell modules
$modules = (Get-ToolsetContent).powershellModules
foreach($module in $modules) {
$moduleName = $module.name
Write-Host "Installing ${moduleName} module"
if ($module.versions) {
foreach ($version in $module.versions) {
Write-Host " - $version"
Install-Module -Name $moduleName -RequiredVersion $version -Scope AllUsers -SkipPublisherCheck -Force
}
} else {
Install-Module -Name $moduleName -Scope AllUsers -SkipPublisherCheck -Force
}
}
Invoke-PesterTests -TestFile "PowerShellModules" -TestName "PowerShellModules"
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
Import-Module "$env:HELPER_SCRIPTS/Tests.Helpers.psm1" -DisableNameChecking
# Specifies the installation policy
Set-PSRepository -InstallationPolicy Trusted -Name PSGallery
# Try to update PowerShellGet before the actual installation
Install-Module -Name PowerShellGet -Force
Update-Module -Name PowerShellGet -Force
# Install PowerShell modules
$modules = (Get-ToolsetContent).powershellModules
foreach($module in $modules)
{
$moduleName = $module.name
Write-Host "Installing ${moduleName} module"
if ($module.versions)
{
foreach ($version in $module.versions)
{
Write-Host " - $version"
Install-Module -Name $moduleName -RequiredVersion $version -Scope AllUsers -SkipPublisherCheck -Force
}
continue
}
Install-Module -Name $moduleName -Scope AllUsers -SkipPublisherCheck -Force
}
Invoke-PesterTests -TestFile "PowerShellModules" -TestName "PowerShellModules"
@@ -4,21 +4,19 @@
## Desc: Install toolset
################################################################################
Import-Module "$env:HELPER_SCRIPTS/../tests/Helpers.psm1"
function Install-Asset {
Function Install-Asset {
param(
[Parameter(Mandatory = $true)]
[object] $ReleaseAsset
)
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..."
$assetFolderPath = Join-Path "/tmp" "$($ReleaseAsset.filename)-temp-dir"
New-Item -ItemType Directory -Path $assetFolderPath | Out-Null
tar -xzf $assetArchivePath -C $assetFolderPath
$assetFolderPath = Join-Path "/tmp" $($ReleaseAsset.filename)
New-Item -ItemType Directory -Path $assetFolderPath
tar -xzf $ReleaseAsset.filename -C $assetFolderPath
Write-Host "Invoke installation script..."
Push-Location -Path $assetFolderPath
@@ -28,8 +26,10 @@ function Install-Asset {
$ErrorActionPreference = "Stop"
# Get toolcache content from toolset
$tools = (Get-ToolsetContent).toolcache | Where-Object { $_.url -ne $null }
# Get toolset content
$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) {
# Get versions manifest for current tool
@@ -38,18 +38,17 @@ foreach ($tool in $tools) {
# Get github release asset for each version
foreach ($toolVersion in $tool.versions) {
$asset = $assets | Where-Object version -like $toolVersion `
| Select-Object -ExpandProperty files `
| Where-Object { ($_.platform -eq $tool.platform) -and ($_.arch -eq $tool.arch) -and ($_.platform_version -eq $tool.platform_version)} `
| Select-Object -First 1
if (-not $asset) {
Write-Host "Asset for $($tool.name) $toolVersion $($tool.arch) not found in versions manifest"
exit 1
}
| Select-Object -ExpandProperty files `
| Where-Object { ($_.platform -eq $tool.platform) -and ($_.platform_version -eq $tool.platform_version)} `
| Select-Object -First 1
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)"
}
@@ -1,7 +1,8 @@
#!/bin/bash -e
################################################################################
## File: install-actions-cache.sh
## Desc: Download latest release from https://github.com/actions/action-versions
## File: action-archive-cache.sh
## Desc: Download latest release from https://github.com/actions/action-verions
## and un-tar to /opt/actionarchivecache
## Maintainer: #actions-runtime and @TingluoHuang
################################################################################
@@ -14,11 +15,12 @@ ACTION_ARCHIVE_CACHE_DIR=/opt/actionarchivecache
mkdir -p $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}"
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_url=$(resolve_github_release_asset_url "actions/action-versions" "endswith(\"action-versions.tar.gz\")" "latest")
archive_path=$(download_with_retry "$download_url")
tar -xzf "$archive_path" -C $ACTION_ARCHIVE_CACHE_DIR
downloadUrl=$(get_github_package_download_url "actions/action-versions" "contains(\"action-versions.tar.gz\")")
echo "Downloading action-versions $downloadUrl"
download_with_retries "$downloadUrl" "/tmp" action-versions.tar.gz
tar -xzf /tmp/action-versions.tar.gz -C $ACTION_ARCHIVE_CACHE_DIR
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,11 +1,11 @@
#!/bin/bash -e
################################################################################
## File: install-apache.sh
## Desc: Install Apache HTTP Server
## File: apache.sh
## Desc: Installs Apache HTTP Server
################################################################################
# Install Apache
apt-get install apache2
apt-get install apache2 -y
# Disable apache2.service
systemctl is-active --quiet apache2.service && systemctl stop apache2.service
@@ -1,18 +1,15 @@
#!/bin/bash -e
################################################################################
## File: install-apt-common.sh
## Desc: Install basic command line utilities and dev packages
## File: apt-common.sh
## Desc: Installs basic command line utilities and dev packages
################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/install.sh
common_packages=$(get_toolset_value .apt.common_packages[])
cmd_packages=$(get_toolset_value .apt.cmd_packages[])
for package in $common_packages $cmd_packages; do
echo "Install $package"
apt-get install --no-install-recommends $package
apt-get install -y --no-install-recommends $package
done
invoke_tests "Apt"
invoke_tests "Apt"
@@ -1,11 +1,9 @@
#!/bin/bash -e
################################################################################
## File: install-apt-vital.sh
## Desc: Install vital command line utilities
## File: apt-vital.sh
## Desc: Installs vital command line utilities
################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/install.sh
vital_packages=$(get_toolset_value .apt.vital_packages[])
apt-get install --no-install-recommends $vital_packages
apt-get install -y --no-install-recommends $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
################################################################################
## File: install-azcopy.sh
## Desc: Install AzCopy
## File: azcopy.sh
## Desc: Installs AzCopy
################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/install.sh
# Install AzCopy10
archive_path=$(download_with_retry "https://aka.ms/downloadazcopy-v10-linux")
tar xzf "$archive_path" --strip-components=1 -C /tmp
install /tmp/azcopy /usr/local/bin/azcopy
download_with_retries "https://aka.ms/downloadazcopy-v10-linux" "/tmp" "azcopy.tar.gz"
tar xzf /tmp/azcopy.tar.gz --strip-components=1 -C /tmp
mv /tmp/azcopy /usr/local/bin/azcopy
chmod +x /usr/local/bin/azcopy
# Create azcopy 10 alias for backward compatibility
ln -sf /usr/local/bin/azcopy /usr/local/bin/azcopy10
invoke_tests "Tools" "azcopy"
invoke_tests "Tools" "azcopy"
@@ -1,14 +1,12 @@
#!/bin/bash -e
################################################################################
## File: install-azure-cli.sh
## Desc: Install Azure CLI (az)
## 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
@@ -1,18 +1,15 @@
#!/bin/bash -e
################################################################################
## File: install-azure-devops-cli.sh
## Desc: Install Azure DevOps CLI (az devops)
## File: azure-devops-cli.sh
## 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
# https://docs.microsoft.com/en-us/cli/azure/azure-cli-extensions-overview
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
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
################################################################################
## File: install-bazel.sh
## Desc: Install Bazel and Bazelisk (A user-friendly launcher for Bazel)
## File: bazel.sh
## Desc: Installs Bazel and Bazelisk (A user-friendly launcher for Bazel)
################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/install.sh
# Install 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
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
################################################################################
## File: install-clang.sh
## Desc: Install Clang compiler
## File: clang.sh
## Desc: Installs Clang compiler
################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/install.sh
install_clang() {
function InstallClang {
local version=$1
echo "Installing clang-$version..."
apt-get install "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
echo "Make Clang ${version} default"
@@ -30,11 +30,11 @@ default_clang_version=$(get_toolset_value '.clang.default_version')
for version in ${versions[*]}; do
if [[ $version != $default_clang_version ]]; then
install_clang $version
InstallClang $version
fi
done
install_clang $default_clang_version
set_default_clang $default_clang_version
InstallClang $default_clang_version
SetDefaultClang $default_clang_version
invoke_tests "Tools" "clang"
@@ -1,8 +1,4 @@
#!/bin/bash -e
################################################################################
## File: cleanup.sh
## Desc: Perform cleanup
################################################################################
# before cleanup
before=$(df / -Pm | awk 'NR==2{print $4}')
@@ -26,19 +22,13 @@ find /var/log -type f -regex ".*\.[0-9]$" -delete
# wipe log files
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=$(df / -Pm | awk 'NR==2{print $4}')
# display size
echo "Before: $before MB"
echo "After : $after MB"
echo "Delta : $(($after-$before)) MB"
echo "Before: $before MB"
echo "After : $after 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
################################################################################
## File: install-codeql-bundle.sh
## Desc: Install CodeQL CLI Bundle to the toolcache.
## File: codeql-bundle.sh
## Desc: Install the CodeQL CLI Bundle to the toolcache.
################################################################################
# Source the helpers for use with the script
source $HELPER_SCRIPTS/install.sh
# 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..."
# Note that this is the all-platforms CodeQL bundle, to support scenarios where customers run
# 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"
mkdir -p "$codeql_toolcache_path"

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