feature: initial commit for all new image changes

This commit is contained in:
Subir Ghosh
2024-11-13 17:16:01 -07:00
parent de6aa9e70e
commit fcf3d0ac96
1042 changed files with 45086 additions and 1 deletions
@@ -0,0 +1,44 @@
################################################################################
## File: Configure-Toolset.ps1
## Team: CI-Build
## Desc: Configure toolset
################################################################################
Import-Module "~/image-generation/helpers/Common.Helpers.psm1"
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
}
$arch = Get-Architecture
$toolcache = (Get-ToolsetContent).toolcache
foreach ($tool in $toolcache) {
$toolName = $tool.name
$toolEnvironment = $tool.arch.$arch.variable_template
if (-not $toolEnvironment) {
continue
}
foreach ($toolVersion in $tool.arch.$arch.versions) {
Write-Host "Set $toolName $toolVersion environment variable..."
$toolPath = Get-ToolsetToolFullPath -ToolName $toolName -ToolVersion $toolVersion -ToolArchitecture $arch
$envName = $toolEnvironment -f $toolVersion.split(".")
# Add environment variable name=value
$envVar = "export {0}={1}" -f $envName, $toolPath
Add-Content -Path "${env:HOME}/.bashrc" -Value $envVar
}
}
@@ -0,0 +1,68 @@
################################################################################
## File: Configure-Xcode-Simulators.ps1
## Team: CI-Build
## Desc: CHeck and remove duplicate simulators
################################################################################
Import-Module "~/image-generation/helpers/Common.Helpers.psm1"
Import-Module "~/image-generation/helpers/Xcode.Helpers.psm1"
$arch = Get-Architecture
$xcodeVersions = (Get-ToolsetContent).xcode.${arch}.versions
# Switch to each Xcode version
foreach ($xcodeVersion in $xcodeVersions.link) {
write-host "Switching to Xcode $xcodeVersion"
Switch-Xcode -Version $XcodeVersion
# Make object of all simulators
$devicesList = $(xcrun simctl list -j devices | ConvertFrom-Json)
$devicesObject = [System.Collections.ArrayList]@()
foreach ($runtime in $devicesList.devices.psobject.Properties.name) {
foreach ($device in $devicesList.devices.$runtime) {
$devicesObject += [PSCustomObject]@{
runtime = $runtime
DeviceName = $($device.name)
DeviceId = $($device.udid)
DeviceCreationTime = (Get-Item $HOME/Library/Developer/CoreSimulator/Devices/$($device.udid)).CreationTime
}
}
}
# Remove duplicates
foreach ($simRuntume in $devicesObject.runtime | Sort-Object -Unique) {
[System.Collections.ArrayList]$sameRuntimeDevices = [array]$($devicesObject | Where-Object {$_.runtime -eq $simRuntume} | Sort-Object -Property DeviceName)
Write-Host "///////////////////////////////////////////////////////////////////"
Write-Host "// Checking for duplicates in $simRuntume "
$devicesAsHashTable = $sameRuntimeDevices | Group-Object -Property DeviceName -AsHashTable -AsString
foreach ($key in $devicesAsHashTable.Keys) {
if ( $devicesAsHashTable[$key].count -gt 1) {
Write-Host "// Duplicates for $key - $($devicesAsHashTable[$key].count)"
}
}
Write-Host "///////////////////////////////////////////////////////////////////"
for ($i = 0; $i -lt $sameRuntimeDevices.Count; $i++) {
if ( [string]::IsNullOrEmpty($($sameRuntimeDevices[$i+1].DeviceName)) ){
Write-Host "No more devices to compare in $simRuntume"
Write-Host "-------------------------------------------------------------------"
continue
}
Write-Host "$($sameRuntimeDevices[$i].DeviceName) - DeviceId $($sameRuntimeDevices[$i].DeviceId) comparing with"
Write-Host "$($sameRuntimeDevices[$i+1].DeviceName) - DeviceId $($sameRuntimeDevices[$i+1].DeviceId)"
Write-Host "-------------------------------------------------------------------"
if ($sameRuntimeDevices[$i].DeviceName -eq $sameRuntimeDevices[$i+1].DeviceName) {
write-host "*******************************************************************"
write-host "** Duplicate found"
if ($sameRuntimeDevices[$i].DeviceCreationTime -lt $sameRuntimeDevices[$i+1].DeviceCreationTime) {
Write-Host "** will be removed $($sameRuntimeDevices[$i+1].DeviceName) with id $($sameRuntimeDevices[$i+1].DeviceId)"
xcrun simctl delete $sameRuntimeDevices[$i+1].DeviceId
$sameRuntimeDevices.RemoveAt($i+1)
} else {
Write-Host "** will be removed $($sameRuntimeDevices[$i].DeviceName) with id $($sameRuntimeDevices[$i].DeviceId)"
xcrun simctl delete $sameRuntimeDevices[$i].DeviceId
$sameRuntimeDevices.RemoveAt($i)
}
write-host "*******************************************************************"
}
}
}
}
@@ -0,0 +1,57 @@
################################################################################
## File: Install-Toolset.ps1
## Team: CI-Build
## Desc: Install toolset
################################################################################
Import-Module "~/image-generation/tests/Helpers.psm1"
Import-Module "~/image-generation/helpers/Common.Helpers.psm1"
Function Install-Asset {
param(
[Parameter(Mandatory=$true)]
[object] $ReleaseAsset
)
Write-Host "Download $($ReleaseAsset.filename) archive..."
$assetArchivePath = Invoke-DownloadWithRetry $ReleaseAsset.download_url
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
Write-Host "Invoke installation script..."
Push-Location -Path $assetFolderPath
Invoke-Expression "bash ./setup.sh"
Pop-Location
}
$arch = Get-Architecture
# Get toolcache content from toolset
$toolsToInstall = @("Python", "Node", "Go")
$tools = (Get-ToolsetContent).toolcache | Where-Object {$toolsToInstall -contains $_.Name}
foreach ($tool in $tools) {
# Get versions manifest for current tool
$assets = Invoke-RestMethod $tool.url -MaximumRetryCount 10 -RetryIntervalSec 30
# Get github release asset for each version
foreach ($version in $tool.arch.$arch.versions) {
$asset = $assets | Where-Object version -like $version `
| Select-Object -ExpandProperty files `
| Where-Object { ($_.platform -eq $tool.platform) -and ($_.arch -eq $arch)} `
| Select-Object -First 1
Write-Host "Installing $($tool.name) $version..."
if ($null -ne $asset) {
Install-Asset -ReleaseAsset $asset
} else {
Write-Host "Asset was not found in versions manifest"
exit 1
}
}
}
Invoke-PesterTests "Toolcache"
@@ -0,0 +1,71 @@
################################################################################
## File: Install-Xcode.ps1
## Desc: Install Xcode
################################################################################
$ErrorActionPreference = "Stop"
Import-Module "$env:HOME/image-generation/helpers/Common.Helpers.psm1"
Import-Module "$env:HOME/image-generation/helpers/Xcode.Installer.psm1" -DisableNameChecking
$arch = Get-Architecture
[Array]$xcodeVersions = (Get-ToolsetContent).xcode.$arch.versions
write-host $xcodeVersions
$defaultXcode = (Get-ToolsetContent).xcode.default
[Array]::Reverse($xcodeVersions)
$threadCount = "5"
Write-Host "Installing Xcode versions..."
$xcodeVersions | ForEach-Object -ThrottleLimit $threadCount -Parallel {
$ErrorActionPreference = "Stop"
Import-Module "$env:HOME/image-generation/helpers/Common.Helpers.psm1"
Import-Module "$env:HOME/image-generation/helpers/Xcode.Installer.psm1" -DisableNameChecking
Install-XcodeVersion -Version $_.version -LinkTo $_.link -Sha256Sum $_.sha256
Confirm-XcodeIntegrity -Version $_.link
}
$xcodeVersions | ForEach-Object {
Approve-XcodeLicense -Version $_.link
}
Write-Host "Configuring Xcode versions..."
$xcodeVersions | ForEach-Object {
Write-Host "Configuring Xcode $($_.link) ..."
Invoke-XcodeRunFirstLaunch -Version $_.link
if ($_.install_runtimes -eq 'true') {
# Additional simulator runtimes are included by default for Xcode < 14
Install-AdditionalSimulatorRuntimes -Version $_.link
}
ForEach($runtime in $_.runtimes) {
Write-Host "Installing Additional runtimes for Xcode '$runtime' ..."
$xcodebuildPath = Get-XcodeToolPath -Version $_.link -ToolName 'xcodebuild'
Invoke-ValidateCommand "sudo $xcodebuildPath -downloadPlatform $runtime" | Out-Null
}
}
Invoke-XcodeRunFirstLaunch -Version $defaultXcode
Write-Host "Configuring Xcode symlinks..."
$xcodeVersions | ForEach-Object {
Build-XcodeSymlinks -Version $_.link -Symlinks $_.symlinks
# Skip creating symlink to install multiple releases of the same Xcode version side-by-side
if ($_."skip-symlink" -ne "true") {
Build-ProvisionatorSymlink -Version $_.link
}
}
Write-Host "Rebuilding Launch Services database ..."
$xcodeVersions | ForEach-Object {
Initialize-XcodeLaunchServicesDb -Version $_.link
}
Write-Host "Setting default Xcode to $defaultXcode"
Switch-Xcode -Version $defaultXcode
New-Item -Path "/Applications/Xcode.app" -ItemType SymbolicLink -Value (Get-XcodeRootPath -Version $defaultXcode) | Out-Null
Write-Host "Setting environment variables 'XCODE_<VERSION>_DEVELOPER_DIR'"
Set-XcodeDeveloperDirEnvironmentVariables -XcodeList $xcodeVersions.link
@@ -0,0 +1,56 @@
################################################################################
## File: Update-XcodeSimulators.ps1
## Desc: Check available Xcode simulators and create missing ones
################################################################################
$ErrorActionPreference = "Stop"
Import-Module "$env:HOME/image-generation/helpers/Xcode.Helpers.psm1" -DisableNameChecking
Import-Module "$env:HOME/image-generation/software-report/SoftwareReport.Xcode.psm1" -DisableNameChecking
function Test-SimulatorInstalled {
param(
[Parameter(Mandatory)]
[string] $RuntimeId,
[Parameter(Mandatory)]
[string] $DeviceId,
[Parameter(Mandatory)]
[string] $SimulatorName,
[Parameter(Mandatory)]
[string] $XcodeVersion
)
$simctlPath = Get-XcodeToolPath -Version $XcodeVersion -ToolName "simctl"
if (-not (Test-Path $simctlPath)) {
Write-Host "Skip validating simulator '$SimulatorName [$RuntimeId]' because Xcode $XcodeVersion is not installed"
return
}
$simulatorFullNameDebug = "$SimulatorName [$RuntimeId]"
Write-Host "Checking Xcode simulator '$simulatorFullNameDebug' (Xcode $XcodeVersion)..."
# Get all available devices
[string]$rawDevicesInfo = Invoke-Expression "$simctlPath list devices --json"
$jsonDevicesInfo = ($rawDevicesInfo | ConvertFrom-Json).devices
# Checking if simulator already exists
$existingSimulator = $jsonDevicesInfo.$RuntimeId | Where-Object { $_.deviceTypeIdentifier -eq $DeviceId } | Select-Object -First 1
if ($null -eq $existingSimulator) {
Write-Host "Simulator '$simulatorFullNameDebug' is missed. Creating it..."
Invoke-Expression "$simctlPath create '$SimulatorName' '$DeviceId' '$RuntimeId'"
} elseif ($existingSimulator.name -ne $SimulatorName) {
Write-Host "Simulator '$simulatorFullNameDebug' is named incorrectly. Renaming it from '$($existingSimulator.name)' to '$SimulatorName'..."
Invoke-Expression "$simctlPath rename '$($existingSimulator.udid)' '$SimulatorName'"
} else {
Write-Host "Simulator '$simulatorFullNameDebug' is installed correctly."
}
}
# First run doesn't provide full data about devices
Get-XcodeInfoList | Out-Null
Write-Host "Validating and fixing Xcode simulators..."
Get-BrokenXcodeSimulatorsList | ForEach-Object {
Test-SimulatorInstalled -RuntimeId $_.RuntimeId -DeviceId $_.DeviceId -SimulatorName $_.SimulatorName -XcodeVersion $_.XcodeVersion
}
@@ -0,0 +1,11 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-auto-updates.sh
## Desc: Disabling automatic updates
################################################################################
sudo softwareupdate --schedule off
defaults write com.apple.SoftwareUpdate AutomaticDownload -int 0
defaults write com.apple.SoftwareUpdate CriticalUpdateInstall -int 0
defaults write com.apple.commerce AutoUpdate -bool false
defaults write com.apple.SoftwareUpdate AutomaticCheckEnabled -bool false
@@ -0,0 +1,20 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-autologin.sh
## Desc: add a Daemon to re-detect the attached network interfaces after vm is booted.
## Maintainer: @timsutton
## script was taken from https://github.com/timsutton/osx-vm-templates/blob/master/scripts/autologin.sh
################################################################################
echo "Enabling automatic GUI login for the '$USERNAME' user.."
python3 $HOME/bootstrap/kcpassword.py "$PASSWORD"
/usr/bin/defaults write /Library/Preferences/com.apple.loginwindow autoLoginUser "$USERNAME"
/usr/bin/defaults write /Library/Preferences/com.apple.loginwindow autoLoginUserScreenLocked -bool false
: '
The MIT License (MIT)
Copyright (c) 2013-2017 Timothy Sutton
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
'
@@ -0,0 +1,32 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-hostname.sh
## Desc: Change the hostname at startup to prevent duplicates
## Hostname and Computername should contain .local in name to avoid name resolution issues
################################################################################
tee -a /usr/local/bin/change_hostname.sh > /dev/null <<\EOF
#!/bin/bash -e -o pipefail
name="Mac-$(python3 -c 'from time import time; print(int(round(time() * 1000)))')"
scutil --set HostName "${name}.local"
scutil --set LocalHostName $name
scutil --set ComputerName "${name}.local"
EOF
chmod +x /usr/local/bin/change_hostname.sh
sudo tee -a /Library/LaunchDaemons/change_hostname.plist > /dev/null <<\EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>change-hostname</string>
<key>Program</key>
<string>/usr/local/bin/change_hostname.sh</string>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
EOF
@@ -0,0 +1,99 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-machine.sh
## Desc: Configure guest OS settings
################################################################################
source ~/utils/utils.sh
echo "Enabling developer mode..."
sudo /usr/sbin/DevToolsSecurity --enable
# Turn off hibernation and get rid of the sleepimage
sudo pmset hibernatemode 0
sudo rm -f /var/vm/sleepimage
# Disable App Nap System Wide
defaults write NSGlobalDomain NSAppSleepDisabled -bool YES
# Disable Keyboard Setup Assistant window
sudo defaults write /Library/Preferences/com.apple.keyboardtype "keyboardtype" -dict-add "3-7582-0" -int 40
# Update VoiceOver Utility to allow VoiceOver to be controlled with AppleScript
# by creating a special Accessibility DB file (SIP must be disabled) and
# updating the user defaults system to reflect this change.
if csrutil status | grep -Eq "System Integrity Protection status: (disabled|unknown)"; then
sudo bash -c 'echo -n "a" > /private/var/db/Accessibility/.VoiceOverAppleScriptEnabled'
fi
defaults write com.apple.VoiceOver4/default SCREnableAppleScript -bool YES
# https://developer.apple.com/support/expiration/
# Enterprise iOS Distribution Certificates generated between February 7 and September 1st, 2020 will expire on February 7, 2023.
# Rotate the certificate before expiration to ensure your apps are installed and signed with an active certificate.
# Confirm that the correct intermediate certificate is installed by verifying the expiration date is set to 2030.
# sudo security delete-certificate -Z FF6797793A3CD798DC5B2ABEF56F73EDC9F83A64 /Library/Keychains/System.keychain
swiftc -suppress-warnings "${HOME}/image-generation/add-certificate.swift"
certs=(
AppleWWDRCAG3.cer
DeveloperIDG2CA.cer
)
for cert in ${certs[@]}; do
echo "Adding ${cert} certificate"
cert_path="${HOME}/${cert}"
curl -fsSL "https://www.apple.com/certificateauthority/${cert}" --output ${cert_path}
sudo ./add-certificate ${cert_path}
rm ${cert_path}
done
rm -f ./add-certificate
# enable-automationmode-without-authentication
brew install expect
retry=10
while [[ $retry -gt 0 ]]; do
{
/usr/bin/expect <<EOF
spawn automationmodetool enable-automationmode-without-authentication
expect "password"
send "${PASSWORD}\r"
expect {
"succeeded." { puts "Automation mode enabled successfully"; exit 0 }
eof
}
EOF
} && break
retry=$((retry-1))
if [[ $retry -eq 0 ]]; then
echo "No retry attempts left"
exit 1
fi
sleep 10
done
echo "Getting terminal windows"
launchctl_output=$(launchctl list | grep -i terminal || true)
if [ -n "$launchctl_output" ]; then
term_service=$(echo "$launchctl_output" | cut -f3)
echo "Close terminal windows: gui/501/${term_service}"
launchctl bootout gui/501/${term_service} && sleep 5
else
echo "No open terminal windows found."
fi
# test enable-automationmode-without-authentication
if [[ ! "$(automationmodetool)" =~ "DOES NOT REQUIRE" ]]; then
echo "Failed to enable enable-automationmode-without-authentication option"
exit 1
fi
# Create symlink for tests running
if [[ ! -d "/usr/local/bin" ]];then
sudo mkdir -p -m 775 /usr/local/bin
sudo chown $USER:admin /usr/local/bin
fi
chmod +x $HOME/utils/invoke-tests.sh
sudo ln -s $HOME/utils/invoke-tests.sh /usr/local/bin/invoke_tests
@@ -0,0 +1,44 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-max-files-limitation.sh
## Desc: Configure max files limitation
################################################################################
Launch_Daemons="/Library/LaunchDaemons"
# EOF in quotes to disable variable expansion
echo "Creating limit.maxfiles.plist"
cat > ${Launch_Daemons}/limit.maxfiles.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>limit.maxfiles</string>
<key>Program</key>
<string>/Users/runner/limit-maxfiles.sh</string>
<key>RunAtLoad</key>
<true/>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>
EOF
# Creating script for applying workaround https://developer.apple.com/forums/thread/735798
cat > /Users/runner/limit-maxfiles.sh << EOF
#!/bin/bash
sudo launchctl limit maxfiles 256 unlimited
sudo launchctl limit maxfiles 65536 524288
EOF
echo "limit.maxfiles.sh permissions changing"
chmod +x /Users/runner/limit-maxfiles.sh
echo "limit.maxfiles.plist permissions changing"
chown root:wheel "${Launch_Daemons}/limit.maxfiles.plist"
chmod 0644 ${Launch_Daemons}/limit.maxfiles.plist
echo "Done, limit.maxfiles has been updated"
@@ -0,0 +1,39 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-network-interface-detection.sh
## Desc: add a Daemon to re-detect the attached network interfaces after vm is booted.
## Maintainer: @timsutton
## script was taken from https://github.com/timsutton/osx-vm-templates/blob/master/scripts/add-network-interface-detection.sh
################################################################################
PLIST=/Library/LaunchDaemons/sonoma.detectnewhardware.plist
cat <<EOF > ${PLIST}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>sonoma.detectnewhardware</string>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/networksetup</string>
<string>-detectnewhardware</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
EOF
# These should be already set as follows, but since they're required
# in order to load properly, we set them explicitly.
/bin/chmod 644 ${PLIST}
/usr/sbin/chown root:wheel ${PLIST}
: '
The MIT License (MIT)
Copyright (c) 2013-2017 Timothy Sutton
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
'
@@ -0,0 +1,19 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-ntpconf.sh
## Desc: Configure NTP servers and set the timezone to UTC
################################################################################
echo Additional NTP servers adding into /etc/ntp.conf file...
cat > /etc/ntp.conf << EOF
server 0.pool.ntp.org
server 1.pool.ntp.org
server 2.pool.ntp.org
server 3.pool.ntp.org
server time.apple.com
server time.windows.com
EOF
# Set the timezone to UTC.
echo "The Timezone setting to UTC..."
ln -sf /usr/share/zoneinfo/UTC /etc/localtime
@@ -0,0 +1,40 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-preimagedata.sh
## Desc: Configure data used in the image
################################################################################
source ~/utils/utils.sh
arch=$(get_arch)
imagedata_file="$HOME/imagedata.json"
image_version=$(echo $IMAGE_VERSION | cut -d _ -f 2)
os_name=$(sw_vers -productName)
os_version=$(sw_vers -productVersion)
os_build=$(sw_vers -buildVersion)
label_version=$(echo $os_version | cut -d. -f1)
if [[ $arch == "arm64" ]]; then
image_label="macos-${label_version}-arm64"
else
image_label="macos-${label_version}"
fi
software_url="https://github.com/actions/runner-images/blob/${image_label}/${image_version}/images/macos/${image_label}-Readme.md"
releaseUrl="https://github.com/actions/runner-images/releases/tag/${image_label}%2F${image_version}"
cat <<EOF > $imagedata_file
[
{
"group": "Operating System",
"detail": "${os_name}\n${os_version}\n${os_build}"
},
{
"group": "Runner Image",
"detail": "Image: ${image_label}\nVersion: ${image_version}\nIncluded Software: ${software_url}\nImage Release: ${releaseUrl}"
}
]
EOF
echo "export ImageVersion=$image_version" >> $HOME/.bashrc
echo "export ImageOS=$IMAGE_OS" >> $HOME/.bashrc
@@ -0,0 +1,30 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-screensaver.sh
## Desc: Configure screensaver
################################################################################
# set screensaver idleTime to 0, to prevent turning screensaver on
macUUID=$(ioreg -rd1 -c IOPlatformExpertDevice | grep -i "UUID" | cut -c27-62)
rm -rf /Users/$USERNAME/Library/Preferences/com.apple.screensaver.$macUUID.plist
rm -rf /Users/$USERNAME/Library/Preferences/ByHost/com.apple.screensaver.$macUUID.plist
rm -rf /Users/$USERNAME/Library/Preferences/com.apple.screensaver.plist
rm -rf /Users/$USERNAME/Library/Preferences/ByHost/com.apple.screensaver.plist
defaults write /Users/$USERNAME/Library/Preferences/com.apple.screensaver.$macUUID.plist idleTime -string 0
defaults write /Users/$USERNAME/Library/Preferences/com.apple.screensaver.$macUUID.plist CleanExit "YES"
defaults write /Users/$USERNAME/Library/Preferences/ByHost/com.apple.screensaver.$macUUID.plist idleTime -string 0
defaults write /Users/$USERNAME/Library/Preferences/ByHost/com.apple.screensaver.$macUUID.plist CleanExit "YES"
defaults write /Users/$USERNAME/Library/Preferences/com.apple.screensaver.plist idleTime -string 0
defaults write /Users/$USERNAME/Library/Preferences/com.apple.screensaver.plist CleanExit "YES"
defaults write /Users/$USERNAME/Library/Preferences/ByHost/com.apple.screensaver.plist idleTime -string 0
defaults write /Users/$USERNAME/Library/Preferences/ByHost/com.apple.screensaver.plist CleanExit "YES"
chown -R $USERNAME:staff /Users/$USERNAME/Library/Preferences/ByHost/
chown -R $USERNAME:staff /Users/$USERNAME/Library/Preferences/
killall cfprefsd
# Set values to 0, to prevent sleep at all
pmset -a displaysleep 0 sleep 0 disksleep 0
@@ -0,0 +1,19 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-shell.sh
## Desc: Configure shell to use bash
################################################################################
source ~/utils/utils.sh
arch=$(get_arch)
echo "Changing shell to bash"
sudo chsh -s /bin/bash $USERNAME
sudo chsh -s /bin/bash root
# Check MacOS architecture and add HOMEBREW PATH to bashrc
if [[ $arch == "arm64" ]]; then
echo "Adding Homebrew environment to bash"
# Discussed here: https://github.com/Homebrew/brew/pull/18366
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.bashrc
fi
@@ -0,0 +1,11 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-ssh.sh
## Desc: Configure ssh
################################################################################
[[ ! -d ~/.ssh ]] && mkdir ~/.ssh 2>/dev/null
chmod 777 ~/.ssh
ssh-keyscan -t rsa,ecdsa,ed25519 github.com >> ~/.ssh/known_hosts
ssh-keyscan -t rsa ssh.dev.azure.com >> ~/.ssh/known_hosts
@@ -0,0 +1,55 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-system.sh
## Desc: Post deployment system configuration actions
################################################################################
source ~/utils/utils.sh
# Close all finder windows because they can interfere with UI tests
close_finder_window
# Remove Parallels Desktop
# https://github.com/actions/runner-images/issues/6105
# https://github.com/actions/runner-images/issues/10143
if is_Monterey || is_SonomaX64 || is_VenturaX64; then
brew uninstall parallels
fi
# Put documentation to $HOME root
cp $HOME/image-generation/output/software-report/systeminfo.* $HOME/
# Put build vm assets (xamarin-selector) scripts to proper directory
if is_Monterey || is_Sonoma || is_Ventura; then
mkdir -p /usr/local/opt/$USER/scripts
mv $HOME/image-generation/assets/* /usr/local/opt/$USER/scripts
find /usr/local/opt/$USER/scripts -type f -name "*\.sh" -exec chmod +x {} \;
fi
# Remove fastlane cached cookie
rm -rf ~/.fastlane
# Clean up npm cache which collected during image-generation
# we have to do that here because `npm install` is run in a few different places during image-generation
npm cache clean --force
# Clean yarn cache
yarn cache clean
# Clean up temporary directories
sudo rm -rf ~/utils /tmp/*
# Erase all indexes and wait until the rebuilding process ends,
# for now there is no way to get status of indexing process, it takes around 3 minutes to accomplish
sudo mdutil -E /
sudo log stream | grep -q -E 'mds.*Released.*BackgroundTask' || true
echo "Indexing completed"
# delete symlink for tests running
sudo rm -f /usr/local/bin/invoke_tests
# Clean Homebrew downloads
sudo rm -rf /Users/$USER/Library/Caches/Homebrew/downloads/*
# Uninstall expect used in configure-machine.sh
brew uninstall expect
@@ -0,0 +1,75 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-tccdb-macos.sh
## Desc: Configure permissions to the TCC.db
################################################################################
source ~/utils/utils.sh
# /Library/Application\ Support/com.apple.TCC/TCC.db
systemValuesArray=(
"'kTCCServiceAccessibility','/usr/local/opt/runner/runprovisioner.sh',1,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,0,1566321319"
"'kTCCServicePostEvent','/usr/local/opt/runner/runprovisioner.sh',1,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,0,1566321326"
"'kTCCServiceSystemPolicyAllFiles','/usr/local/opt/runner/runprovisioner.sh',1,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,0,1583997993"
"'kTCCServiceAccessibility','com.apple.dt.Xcode-Helper',0,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,NULL,1551941368"
"'kTCCServiceSystemPolicyAllFiles','/bin/bash',1,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,0,1583997993"
"'kTCCServiceSystemPolicyAllFiles','/usr/libexec/sshd-keygen-wrapper',1,0,4,1,X'fade0c000000003c0000000100000006000000020000001d636f6d2e6170706c652e737368642d6b657967656e2d7772617070657200000000000003',NULL,0,'UNUSED',NULL,0,1639660695"
"'kTCCServiceSystemPolicyAllFiles','com.apple.Terminal',0,2,4,1,X'fade0c000000003000000001000000060000000200000012636f6d2e6170706c652e5465726d696e616c000000000003',NULL,0,'UNUSED',NULL,0,1678990068"
"'kTCCServiceAccessibility','/usr/libexec/sshd-keygen-wrapper',1,2,4,1,X'fade0c000000003c0000000100000006000000020000001d636f6d2e6170706c652e737368642d6b657967656e2d7772617070657200000000000003',NULL,0,'UNUSED',NULL,0,1644564233"
"'kTCCServiceAccessibility','com.apple.Terminal',0,2,0,1,X'fade0c000000003000000001000000060000000200000012636f6d2e6170706c652e5465726d696e616c000000000003',NULL,NULL,'UNUSED',NULL,0,1591180502"
"'kTCCServiceAccessibility','/bin/bash',1,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,0,1583997993"
"'kTCCServiceMicrophone','/usr/local/opt/runner/runprovisioner.sh',1,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,NULL,1576661342"
"'kTCCServiceScreenCapture','/bin/bash',1,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,0,1599831148"
"'kTCCServiceScreenCapture','com.devexpress.testcafe-browser-tools',0,2,3,1,X'fade0c0000000068000000010000000700000007000000080000001443fa4ca5141baeda21aeca1f50894673b440d4690000000800000014f8afcf6e69791b283e55bd0b03e39e422745770e0000000800000014bf4fc1aed64c871a49fc6bc9dd3878ce5d4d17c6',NULL,0,'UNUSED',NULL,0,1687952810"
"'kTCCServicePostEvent','/Library/Application Support/Veertu/Anka/addons/ankarund',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1644565949"
"'kTCCServiceScreenCapture','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
"'kTCCServiceAppleEvents','/usr/local/opt/runner/provisioner/provisioner',1,2,3,1,NULL,NULL,0,'com.apple.finder',X'fade0c000000002c00000001000000060000000200000010636f6d2e6170706c652e66696e64657200000003',NULL,1592919552"
"'kTCCServiceAccessibility','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,NULL,1592919552"
# Allow Full Disk Access for "Microsoft Defender for macOS" to bypass installation on-flight
"'kTCCServiceSystemPolicyAllFiles','com.microsoft.wdav',0,2,4,1,NULL,NULL,NULL,'UNUSED',NULL,0,1643970979"
"'kTCCServiceSystemPolicyAllFiles','com.microsoft.wdav.epsext',0,2,4,1,NULL,NULL,NULL,'UNUSED',NULL,0,1643970979"
"'kTCCServiceSystemPolicyNetworkVolumes','/bin/bash',1,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,0,1583997993"
"'kTCCServiceSystemPolicyNetworkVolumes','com.apple.Terminal',0,2,4,1,X'fade0c000000003000000001000000060000000200000012636f6d2e6170706c652e5465726d696e616c000000000003',NULL,0,'UNUSED',NULL,0,1678990068"
)
for values in "${systemValuesArray[@]}"; do
if is_Sonoma || is_Sequoia; then
# TCC access table in Sonoma has extra 4 columns: pid, pid_version, boot_uuid, last_reminded
configure_system_tccdb "$values,NULL,NULL,'UNUSED',${values##*,}"
else
configure_system_tccdb "$values"
fi
done
# $HOME/Library/Application\ Support/com.apple.TCC/TCC.db
userValuesArray=(
"'kTCCServiceUbiquity','com.apple.mail',0,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,NULL,1551941469"
"'kTCCServiceUbiquity','com.apple.TextEdit',0,2,0,1,X'fade0c000000003000000001000000060000000200000012636f6d2e6170706c652e5465787445646974000000000003',NULL,NULL,'UNUSED',NULL,0,1566368356"
"'kTCCServiceUbiquity','com.apple.CloudDocs.MobileDocumentsFileProvider',0,2,0,1,X'fade0c000000004c0000000100000006000000020000002f636f6d2e6170706c652e436c6f7564446f63732e4d6f62696c65446f63756d656e747346696c6550726f76696465720000000003',NULL,NULL,'UNUSED',NULL,0,1570793290"
"'kTCCServiceAppleEvents','/usr/local/opt/runner/runprovisioner.sh',1,2,0,1,NULL,NULL,0,'com.apple.systemevents',NULL,NULL,1574241374"
"'kTCCServiceSystemPolicyAllFiles','/usr/local/opt/runner/runprovisioner.sh',1,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,0,1583997993"
"'kTCCServiceAppleEvents','/usr/libexec/sshd-keygen-wrapper',1,2,3,1,X'fade0c000000003c0000000100000006000000020000001d636f6d2e6170706c652e737368642d6b657967656e2d7772617070657200000000000003',NULL,0,'com.apple.systemevents',X'fade0c000000003400000001000000060000000200000016636f6d2e6170706c652e73797374656d6576656e7473000000000003',NULL,1644564201"
"'kTCCServiceAppleEvents','com.apple.Terminal',0,2,0,1,X'fade0c000000003000000001000000060000000200000012636f6d2e6170706c652e5465726d696e616c000000000003',NULL,0,'com.apple.systemevents',X'fade0c000000003400000001000000060000000200000016636f6d2e6170706c652e73797374656d6576656e7473000000000003',NULL,1591180478"
"'kTCCServiceAppleEvents','/usr/libexec/sshd-keygen-wrapper',1,2,0,1,X'fade0c000000003c0000000100000006000000020000001d636f6d2e6170706c652e737368642d6b657967656e2d7772617070657200000000000003',NULL,0,'com.apple.finder',X'fade0c000000002c00000001000000060000000200000010636f6d2e6170706c652e66696e64657200000003',NULL,1591357685"
"'kTCCServiceAppleEvents','/bin/bash',1,2,0,1,NULL,NULL,0,'com.apple.systemevents',NULL,NULL,1591532620"
"'kTCCServiceAppleEvents','/bin/bash',1,2,0,1,NULL,NULL,0,'com.apple.finder',NULL,NULL,1592919552"
"'kTCCServiceMicrophone','com.apple.CoreSimulator.SimulatorTrampoline',0,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,NULL,1576347152"
"'kTCCServiceMicrophone','/usr/local/opt/runner/runprovisioner.sh',1,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,NULL,1576661342"
"'kTCCServiceUbiquity','/System/Library/PrivateFrameworks/PhotoLibraryServices.framework/Versions/A/Support/photolibraryd',1,2,5,1,NULL,NULL,NULL,'UNUSED',NULL,0,1619461750"
"'kTCCServiceUbiquity','com.apple.PassKitCore',0,2,5,1,NULL,NULL,NULL,'UNUSED',NULL,0,1619516250"
"'kTCCServiceAppleEvents','/Library/Application Support/Veertu/Anka/addons/ankarund',1,2,3,1,NULL,NULL,0,'com.apple.finder',X'fade0c000000002c00000001000000060000000200000010636f6d2e6170706c652e66696e64657200000003',NULL,1629294900"
"'kTCCServiceAppleEvents','/Library/Application Support/Veertu/Anka/addons/ankarund',1,2,3,1,NULL,NULL,0,'com.apple.systemevents',X'fade0c000000003400000001000000060000000200000016636f6d2e6170706c652e73797374656d6576656e7473000000000003',NULL,164456761"
"'kTCCServiceAppleEvents','/Library/Application Support/Veertu/Anka/addons/ankarund',1,2,3,1,NULL,NULL,0,'com.apple.Terminal',X'fade0c000000003000000001000000060000000200000012636f6d2e6170706c652e5465726d696e616c000000000003',NULL,1655808179"
"'kTCCServiceAppleEvents','/usr/libexec/sshd-keygen-wrapper',1,2,3,1,X'fade0c000000003c0000000100000006000000020000001d636f6d2e6170706c652e737368642d6b657967656e2d7772617070657200000000000003',NULL,0,'com.apple.Terminal',X'fade0c000000003000000001000000060000000200000012636f6d2e6170706c652e5465726d696e616c000000000003',NULL,1650386089"
"'kTCCServicePostEvent','/bin/bash',1,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,0,1583997993"
"'kTCCServiceAppleEvents','/usr/local/opt/runner/provisioner/provisioner',1,2,3,1,NULL,NULL,0,'com.apple.finder',X'fade0c000000002c00000001000000060000000200000010636f6d2e6170706c652e66696e64657200000003',NULL,1592919552"
"'kTCCServiceScreenCapture','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
"'kTCCServiceAppleEvents','/usr/local/opt/runner/provisioner/provisioner',1,2,3,1,NULL,NULL,0,'com.apple.systemevents',X'fade0c000000003400000001000000060000000200000016636f6d2e6170706c652e73797374656d6576656e7473000000000003',NULL,1592919552"
)
for values in "${userValuesArray[@]}"; do
if is_Sonoma || is_Sequoia; then
# TCC access table in Sonoma has extra 4 columns: pid, pid_version, boot_uuid, last_reminded
configure_user_tccdb "$values,NULL,NULL,'UNUSED',${values##*,}"
else
configure_user_tccdb "$values"
fi
done
@@ -0,0 +1,42 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-windows.sh
## Desc: Close open windows
################################################################################
source ~/utils/utils.sh
# Close System Preferences window because in Ventura arm64 it is opened by default on Apperance tab
if is_Arm64; then
echo "Close System Preferences window"
osascript -e 'tell application "System Preferences" to quit'
fi
retry=10
while [[ $retry -gt 0 ]]; do
openwindows=$(osascript -e 'tell application "System Events" to get every window of (every process whose class of windows contains window)') && break
retry=$((retry-1))
if [[ $retry -eq 0 ]]; then
echo "No retry attempts left"
exit 1
fi
sleep 30
done
IFS=',' read -r -a windowslist <<< "$openwindows"
if [[ -n ${openwindows} ]]; then
echo "Found opened window:"
fi
for key in ${!windowslist[@]}; do
if [[ ${windowslist[$key]} =~ "NotificationCenter" ]]; then
echo "[Warning] ${windowslist[$key]}"
else
echo " - ${windowslist[$key]}" | xargs
scripterror=true
fi
done
if [[ ${scripterror} = true ]]; then
exit 1
fi
@@ -0,0 +1,144 @@
#!/usr/bin/env ruby
################################################################################
## File: configure-xcode-simulators.rb
## Desc: List all simulators, find duplicate type and delete them.
## Maintainer: @vlas-voloshin
## script was taken from https://gist.github.com/vlas-voloshin/f9982128200345cd3fb7
################################################################################
class SimDevice
attr_accessor :runtime
attr_accessor :name
attr_accessor :identifier
attr_accessor :timestamp
def initialize(runtime, name, identifier, timestamp)
@runtime = runtime
@name = name
@identifier = identifier
@timestamp = timestamp
end
def to_s
return "#{@name} - #{@runtime} (#{@identifier}) [#{@timestamp}]"
end
def equivalent_to_device(device)
return @runtime == device.runtime && @name == device.name
end
end
# Executes a shell command and returns the result from stdout
def execute_simctl_command(command)
return %x[xcrun simctl #{command}]
end
# Retrieves the creation date/time of simulator with specified identifier
def simulator_creation_date(identifier)
directory = Dir.home() + "/Library/Developer/CoreSimulator/Devices/" + identifier
if (Dir.exists?(directory))
if (File::Stat.method_defined?(:birthtime))
return File.stat(directory).birthtime
else
return File.stat(directory).ctime
end
else
# Simulator directory is not yet created - treat it as if it was created right now (happens with new iOS 9 sims)
return Time.now
end
end
# Deletes specified simulator
def delete_device(device)
execute_simctl_command("delete #{device.identifier}")
end
puts("Searching for simulators...")
# Retrieve the list of existing simulators
devices = []
runtime = ""
execute_simctl_command("list devices").lines.each do |line|
case line[0]
when '='
# First header, skip it
when '-'
# Runtime header
runtime = line.scan(/-- (.+?) --/).flatten[0]
else
name_and_identifier = line.scan(/\s+(.+?) \(([\w\d]+-[\w\d]+-[\w\d-]+)\)/)[0]
name = name_and_identifier[0]
identifier = name_and_identifier[1]
timestamp = simulator_creation_date(identifier)
device = SimDevice.new(runtime, name, identifier, timestamp)
devices.push(device)
end
end
# Sort the simulators by their creation timestamp, ascending
devices = devices.sort { |a, b| a.timestamp <=> b.timestamp }
duplicates = {}
# Enumerate all devices except for the last one
for i in 0..devices.count-2
device = devices[i]
# Enumerate all devices *after* this one (created *later*)
for j in i+1..devices.count-1
potential_duplicate = devices[j]
if potential_duplicate.equivalent_to_device(device)
duplicates[potential_duplicate] = device
# Break out of the inner loop if a duplicate is found - if another duplicate exists,
# it will be found when this one is reached in the outer loop
break
end
end
end
if duplicates.count == 0
puts("You don't have duplicate simulators!")
exit()
end
puts("Looks like you have #{duplicates.count} duplicate simulator#{duplicates.count > 1 ? "s" : ""}:")
duplicates.each_pair do |duplicate, original|
puts
puts("#{duplicate}")
puts("--- duplicate of ---")
puts("#{original}")
end
puts
puts("Each duplicate was determined as the one created later than the 'original'.")
puts("Deleting...")
duplicates.each_key do |duplicate|
delete_device(duplicate)
end
puts("Done!")
=begin
MIT License
Copyright (c) 2015-2019 Vlas Voloshin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
=end
@@ -0,0 +1,34 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: configure-xcode.sh
## Desc: Configure Xcode after installation
################################################################################
source ~/utils/utils.sh
XCODE_LIST=($(get_toolset_value '.xcode.versions | reverse | .[].link'))
DEFAULT_XCODE_VERSION=$(get_toolset_value '.xcode.default')
# https://github.com/microsoft/appcenter/issues/847
# Assets.xcassets : error : CoreData: error: (6922) I/O error for database
# at $HOME/Library/Developer/Xcode/UserData/IB Support/Simulator Devices/{GUID}
echo "Erase a device's contents and settings:"
for XCODE_VERSION in ${XCODE_LIST[@]}; do
echo " Xcode Version: ${XCODE_VERSION}"
launchctl remove com.apple.CoreSimulator.CoreSimulatorService || true
#add sleep to let CoreSimulatorService to exit
sleep 3
# Select xcode version by default
sudo xcode-select -s /Applications/Xcode_${XCODE_VERSION}.app/Contents/Developer
# Erase a device's contents and settings
xcrun simctl erase all
#add sleep due to sometimes "xcrun simctl list" takes more than a few moments and script fails when trying to remove CoreSimulatorSerivce
sleep 10
done
# Select xcode version by default
echo "Setting Xcode ${DEFAULT_XCODE_VERSION} as default"
sudo xcode-select -s /Applications/Xcode_${DEFAULT_XCODE_VERSION}.app/Contents/Developer
@@ -0,0 +1,20 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-actions-cache.sh
## Desc: Download latest release from https://github.com/actions/action-versions
## Maintainer: #actions-runtime and @TingluoHuang
################################################################################
source ~/utils/utils.sh
echo "Check if ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE folder exist..."
if [[ ! -d $ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE ]]; then
mkdir -p $ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE
fi
download_url=$(resolve_github_release_asset_url "actions/action-versions" "contains(\"action-versions.tar.gz\")" "latest" "$API_PAT")
echo "Downloading action-versions $download_url"
archive_path=$(download_with_retry $download_url)
tar -xzf $archive_path -C $ACTIONS_RUNNER_ACTION_ARCHIVE_CACHE
invoke_tests "ActionArchiveCache"
@@ -0,0 +1,132 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-android-sdk.sh
## Desc: Install Android SDK, NDK and tools
################################################################################
source ~/utils/utils.sh
add_filtered_installation_components() {
local minimum_version=$1
shift
local tools_array=("$@")
for item in ${tools_array[@]}; do
# take the last argument after splitting string by ';'' and '-''
version=$(echo "${item##*[-;]}")
if [[ "$(printf "${minimum_version}\n${version}\n" | sort -V | head -n1)" == "$minimum_version" ]]; then
components+=($item)
fi
done
}
get_full_ndk_version() {
local majorVersion=$1
ndkVersion=$(${SDKMANAGER} --list | grep "ndk;${majorVersion}.*" | awk '{gsub("ndk;", ""); print $1}' | sort -V | tail -n1)
echo "$ndkVersion"
}
components=()
android_platform=$(get_toolset_value '.android.platform_min_version')
android_build_tool=$(get_toolset_value '.android.build_tools_min_version')
android_extra_list=($(get_toolset_value '.android."extras"[]'))
android_addon_list=($(get_toolset_value '.android."addons"[]'))
android_additional_tools=($(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')
android_ndk_major_latest=$(get_toolset_value '.android.ndk."versions"[-1]')
# Get the latest command line tools from https://developer.android.com/studio#cmdline-tools
# Newer version(s) require Java 11 by default
# See https://github.com/actions/runner-images/issues/6960
ANDROID_HOME=$HOME/Library/Android/sdk
# 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
repository_xml_url="https://dl.google.com/android/repository/repository2-1.xml"
repository_xml_path=$(download_with_retry $repository_xml_url)
cmdlineToolsVersion=$(
yq -p=xml \
'.sdk-repository.remotePackage[] | select(."+@path" == "cmdline-tools;latest" and .channelRef."+@ref" == "channel-0").archives.archive[].complete.url | select(contains("commandlinetools-mac"))' \
"$repository_xml_path"
)
if [[ -z $cmdlineToolsVersion ]]; then
echo "Failed to parse latest command-line tools version"
exit 1
fi
fi
echo "Downloading android command line tools..."
archive_path=$(download_with_retry "https://dl.google.com/android/repository/${cmdlineToolsVersion}")
echo "Uncompressing android command line tools..."
mkdir -p "$ANDROID_HOME"
unzip -q "$archive_path" -d "$ANDROID_HOME/cmdline-tools"
# Command line tools need to be placed in $ANDROID_HOME/cmdline-tools/latest to function properly
mv "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/latest"
echo ANDROID_HOME is "$ANDROID_HOME"
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest:$ANDROID_HOME/cmdline-tools/latest/bin
SDKMANAGER=$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager
echo "Installing latest tools & platform tools..."
echo y | $SDKMANAGER "tools" "platform-tools"
echo "Installing latest ndk..."
for ndk_version in "${android_ndk_major_versions[@]}"
do
ndk_full_version=$(get_full_ndk_version $ndk_version)
echo y | $SDKMANAGER "ndk;$ndk_full_version"
done
ndkDefault=$(get_full_ndk_version $android_ndk_major_default)
ANDROID_NDK_HOME=$ANDROID_HOME/ndk/$ndkDefault
ndkLatest=$(get_full_ndk_version $android_ndk_major_latest)
ANDROID_NDK_LATEST_HOME=$ANDROID_HOME/ndk/$ndkLatest
# 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 "export ANDROID_NDK=$ANDROID_NDK_HOME" >> "${HOME}/.bashrc"
echo "export ANDROID_NDK_HOME=$ANDROID_NDK_HOME" >> "${HOME}/.bashrc"
echo "export ANDROID_NDK_ROOT=$ANDROID_NDK_HOME" >> "${HOME}/.bashrc"
echo "export ANDROID_NDK_LATEST_HOME=$ANDROID_NDK_LATEST_HOME" >> "${HOME}/.bashrc"
availablePlatforms=($($SDKMANAGER --list | grep "platforms;android-[0-9]" | cut -d"|" -f 1 | sort -u))
add_filtered_installation_components $android_platform "${availablePlatforms[@]}"
allBuildTools=($($SDKMANAGER --list --include_obsolete | grep "build-tools;" | cut -d"|" -f 1 | sort -u))
availableBuildTools=$(echo ${allBuildTools[@]//*rc[0-9]/})
add_filtered_installation_components $android_build_tool "${availableBuildTools[@]}"
echo "y" | $SDKMANAGER ${components[@]}
for extra_name in "${android_extra_list[@]}"
do
echo "Installing extra $extra_name ..."
echo y | $SDKMANAGER "extras;$extra_name"
done
for addon_name in "${android_addon_list[@]}"
do
echo "Installing add-on $addon_name ..."
echo y | $SDKMANAGER "add-ons;$addon_name"
done
for tool_name in "${android_additional_tools[@]}"
do
echo "Installing additional tool $tool_name ..."
echo y | $SDKMANAGER "$tool_name"
done
# Download SDK tools to preserve backward compatibility
sdk_tools_version=$(get_toolset_value '.android."sdk-tools"')
if [ "$sdk_tools_version" != "null" ]; then
sdk_tools_archive_path=$(download_with_retry "https://dl.google.com/android/repository/${sdk_tools_version}")
unzip -o -qq "$sdk_tools_archive_path" -d "${ANDROID_SDK_ROOT}"
fi
invoke_tests "Android"
@@ -0,0 +1,12 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-apache.sh
## Desc: Install Apache HTTP Server
################################################################################
source ~/utils/utils.sh
brew_smart_install httpd
sudo sed -Ei '' 's/Listen .*/Listen 80/' $(brew --prefix)/etc/httpd/httpd.conf
invoke_tests "WebServers" "Apache"
@@ -0,0 +1,15 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-audiodevice.sh
## Desc: Install audio device
################################################################################
source ~/utils/utils.sh
echo "install switchaudio-osx"
brew_smart_install "switchaudio-osx"
echo "install sox"
brew_smart_install "sox"
invoke_tests "System" "Audio Device"
@@ -0,0 +1,20 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-aws-tools.sh
## Desc: Install the AWS CLI, Session Manager plugin for the AWS CLI, and AWS SAM CLI
################################################################################
source ~/utils/utils.sh
echo "Installing aws..."
awscliv2_pkg_path=$(download_with_retry "https://awscli.amazonaws.com/AWSCLIV2.pkg")
sudo installer -pkg "$awscliv2_pkg_path" -target /
echo "Installing aws sam cli..."
brew tap aws/tap
brew_smart_install aws-sam-cli
echo "Install aws cli session manager"
brew install --cask session-manager-plugin
invoke_tests "Common" "AWS"
@@ -0,0 +1,23 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-azcopy.sh
## Desc: Install AzCopy
################################################################################
source ~/utils/utils.sh
if is_Arm64; then
url="https://aka.ms/downloadazcopy-v10-mac-arm64"
else
url="https://aka.ms/downloadazcopy-v10-mac"
fi
# Install AzCopy
archive_path=$(download_with_retry ${url})
unzip -qq $archive_path -d /tmp/azcopy
extract_path=$(echo /tmp/azcopy/azcopy*)
cp $extract_path/azcopy /usr/local/bin/azcopy
chmod +x /usr/local/bin/azcopy
invoke_tests "Common" "AzCopy"
@@ -0,0 +1,13 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-bicep.sh
## Desc: Install bicep cli
################################################################################
source ~/utils/utils.sh
echo "Installing bicep cli..."
brew tap azure/bicep
brew_smart_install bicep
invoke_tests "Common" "Bicep"
@@ -0,0 +1,52 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-chrome.sh
## Desc: Install chrome and chrome for testing browsers
################################################################################
source ~/utils/utils.sh
arch=$(get_arch)
echo "Installing Google Chrome..."
brew install --cask google-chrome
# Parse Google Chrome version
full_chrome_version=$("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --version)
full_chrome_version=${full_chrome_version#Google Chrome }
chrome_version=${full_chrome_version%.*}
echo "Google Chrome version is $full_chrome_version"
# Get Google Chrome versions information
chrome_platform="mac-$arch"
CHROME_VERSIONS_URL="https://googlechromelabs.github.io/chrome-for-testing/latest-patch-versions-per-build-with-downloads.json"
chrome_versions_json=$(download_with_retry "$CHROME_VERSIONS_URL")
# Download and unpack the latest release of Chrome Driver
chromedriver_version=$(cat $chrome_versions_json | jq -r '.builds["'"$chrome_version"'"].version')
echo "Installing Chrome Driver version $chromedriver_version"
chromedriver_url=$(cat $chrome_versions_json | jq -r '.builds["'"$chrome_version"'"].downloads.chromedriver[] | select(.platform=="'"${chrome_platform}"'").url')
chromedriver_dir="/usr/local/share/chromedriver-$chrome_platform"
chromedriver_bin="$chromedriver_dir/chromedriver"
chromedriver_archive_path=$(download_with_retry $chromedriver_url)
unzip -qq $chromedriver_archive_path -d /tmp/
sudo mv /tmp/chromedriver-$chrome_platform $chromedriver_dir
ln -s $chromedriver_bin /usr/local/bin/chromedriver
echo "export CHROMEWEBDRIVER=$chromedriver_dir" >> ${HOME}/.bashrc
# Download and unpack the latest release of Google Chrome for Testing
chrome_for_testing_version=$(cat $chrome_versions_json | jq -r '.builds["'"$chrome_version"'"].version')
echo "Installing Google Chrome for Testing version $chrome_for_testing_version"
chrome_for_testing_url=$(cat $chrome_versions_json | jq -r '.builds["'"$chrome_version"'"].downloads.chrome[] | select(.platform=="'"${chrome_platform}"'").url')
chrome_for_testing_app="Google Chrome for Testing.app"
chrome_for_testing_archive_path=$(download_with_retry $chrome_for_testing_url)
unzip -qq $chrome_for_testing_archive_path -d /tmp/
mv "/tmp/chrome-$chrome_platform/$chrome_for_testing_app" "/Applications/$chrome_for_testing_app"
echo "Installing Selenium"
brew_smart_install "selenium-server"
invoke_tests "Browsers" "Chrome"
@@ -0,0 +1,14 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-cocoapods.sh
## Desc: Install Cocoapods
################################################################################
# Setup the Cocoapods
echo "Installing Cocoapods..."
pod setup
# Create a symlink to /usr/local/bin since it was removed due to Homebrew change.
ln -sf $(which pod) /usr/local/bin/pod
invoke_tests "Common" "CocoaPods"
@@ -0,0 +1,32 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-codeql-bundle.sh
## Desc: Install CodeQL bundle
################################################################################
source ~/utils/utils.sh
# Retrieve the CLI version of the latest CodeQL bundle.
defaults_json_path=$(download_with_retry https://raw.githubusercontent.com/github/codeql-action/v2/src/defaults.json)
bundle_version=$(jq -r '.cliVersion' $defaults_json_path)
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.
archive_path=$(download_with_retry "https://github.com/github/codeql-action/releases/download/$bundle_tag_name/codeql-bundle.tar.gz")
codeql_toolcache_path=$AGENT_TOOLSDIRECTORY/CodeQL/$bundle_version/x64
mkdir -p $codeql_toolcache_path
echo "Unpacking the downloaded CodeQL bundle archive..."
tar -xzf $archive_path -C $codeql_toolcache_path
# Touch a file to indicate to the CodeQL Action that this bundle shipped with the toolcache. This is
# to support overriding the CodeQL version specified in defaults.json on GitHub Enterprise.
touch $codeql_toolcache_path/pinned-version
# Touch a file to indicate to the toolcache that setting up CodeQL is complete.
touch $codeql_toolcache_path.complete
invoke_tests "Common" "CodeQL Bundle"
@@ -0,0 +1,118 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-common-utils.sh
## Desc: Install utils listed in toolset file
################################################################################
source ~/utils/utils.sh
# Monterey needs future review:
# aliyun-cli, gnupg, helm have issues with building from the source code.
# Added gmp for now, because toolcache ruby needs its libs. Remove it when php starts to build from source code.
common_packages=$(get_toolset_value '.brew.common_packages[]')
for package in $common_packages; do
echo "Installing $package..."
if is_Monterey && [[ $package == "xcbeautify" ]]; then
# Pin the version on Monterey as 2.0.x requires Xcode >=15.0 which is not available on OS12
xcbeautify_path=$(download_with_retry "https://raw.githubusercontent.com/Homebrew/homebrew-core/d3653e83f9c029a3fddb828ac804b07ac32f7b3b/Formula/x/xcbeautify.rb")
brew install "$xcbeautify_path"
else
if [[ $package == "packer" ]]; then
# Packer has been deprecated in Homebrew. Use tap to install Packer.
brew install hashicorp/tap/packer
else
brew_smart_install "$package"
fi
fi
done
cask_packages=$(get_toolset_value '.brew.cask_packages[]')
for package in $cask_packages; do
echo "Installing $package..."
if is_Monterey && [[ $package == "virtualbox" ]]; then
# Do not update VirtualBox on macOS 12 due to the issue with VMs in gurumediation state which blocks Vagrant on macOS: https://github.com/actions/runner-images/issues/8730
# macOS host: Dropped all kernel extensions. VirtualBox relies fully on the hypervisor and vmnet frameworks provided by Apple now.
virtualbox_cask_path=$(download_with_retry "https://raw.githubusercontent.com/Homebrew/homebrew-cask/aa3c55951fc9d687acce43e5c0338f42c1ddff7b/Casks/virtualbox.rb")
brew install $virtualbox_cask_path
else
if is_Arm64 && [[ $package == "parallels" ]]; then
echo "Parallels installation is skipped for arm64 architecture"
else
brew install --cask $package
fi
fi
done
# Load "Parallels International GmbH"
if is_Monterey || is_SonomaX64 || is_VenturaX64; then
sudo kextload /Applications/Parallels\ Desktop.app/Contents/Library/Extensions/10.9/prl_hypervisor.kext || true
fi
# Execute AppleScript to change security preferences for macOS12, macOS13 and macOS14
# System Preferences -> Security & Privacy -> General -> Unlock -> Allow -> Not now
if is_Monterey || is_SonomaX64 || is_VenturaX64; then
for retry in {4..0}; do
echo "Executing AppleScript to change security preferences. Retries left: $retry"
{
set -e
osascript -e 'tell application "System Events" to get application processes where visible is true'
if is_Monterey; then
osascript $HOME/utils/confirm-identified-developers.scpt $USER_PASSWORD
fi
if is_VenturaX64; then
osascript $HOME/utils/confirm-identified-developers-macos13.scpt $USER_PASSWORD
fi
if is_SonomaX64; then
osascript $HOME/utils/confirm-identified-developers-macos14.scpt $USER_PASSWORD
fi
} && break
if [[ $retry -eq 0 ]]; then
echo "Executing AppleScript failed. No retries left"
exit 1
fi
echo "Executing AppleScript failed. Sleeping for 10 seconds and retrying"
sleep 10
done
fi
# Validate "Parallels International GmbH" kext
if is_Monterey || is_SonomaX64 || is_VenturaX64; then
if is_Monterey; then
echo "Closing System Preferences window if it is still opened"
killall "System Preferences" || true
fi
if is_SonomaX64 || is_VenturaX64; then
echo "Closing System Settings window if it is still opened"
killall "System Settings" || true
fi
echo "Checking parallels kexts"
dbName="/var/db/SystemPolicyConfiguration/KextPolicy"
dbQuery="SELECT * FROM kext_policy WHERE bundle_id LIKE 'com.parallels.kext.%';"
kext=$(sudo sqlite3 $dbName "$dbQuery")
if [[ -z $kext ]]; then
echo "Parallels International GmbH not found"
exit 1
fi
# Create env variable
url=$(brew info --json=v2 --installed | jq -r '.casks[] | select(.name[] == "Parallels Desktop").url')
if [[ -z $url ]]; then
echo "Unable to parse url for Parallels Desktop cask"
exit 1
fi
echo "export PARALLELS_DMG_URL=$url" >> ${HOME}/.bashrc
fi
# Install Azure DevOps extension for Azure Command Line Interface
az extension add -n azure-devops
# Invoke tests for all basic tools
invoke_tests "BasicTools"
@@ -0,0 +1,15 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-compilable-brew-packages.sh
## Desc: Install compilable brew packages
################################################################################
source ~/utils/utils.sh
compilable_packages=$(get_toolset_value '.brew.compilable_packages[]')
for package in $compilable_packages; do
echo "Installing $package..."
brew_smart_install "$package"
done
invoke_tests "Common" "Compiled"
@@ -0,0 +1,57 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-dotnet.sh
## Desc: Install dotnet
################################################################################
source ~/utils/utils.sh
export DOTNET_CLI_TELEMETRY_OPTOUT=1
arch=$(get_arch)
# Download installer from dot.net and keep it locally
DOTNET_INSTALL_SCRIPT="https://dot.net/v1/dotnet-install.sh"
install_script_path=$(download_with_retry $DOTNET_INSTALL_SCRIPT)
chmod +x $install_script_path
args_list=()
echo "Parsing dotnet SDK (except rc and preview versions) from .json..."
dotnet_versions=($(get_toolset_value ".dotnet.arch[\"$arch\"].versions | .[]"))
for dotnet_version in ${dotnet_versions[@]}; do
release_url="https://raw.githubusercontent.com/dotnet/core/main/release-notes/${dotnet_version}/releases.json"
releases_json_file=$(download_with_retry "$release_url")
if [[ $dotnet_version == "6.0" ]]; then
args_list+=(
$(cat $releases_json_file | jq -r 'first(.releases[].sdks[]?.version | select(contains("preview") or contains("rc") | not))')
)
else
args_list+=(
$(cat $releases_json_file | \
jq -r '.releases[].sdk."version"' | grep -v -E '\-(preview|rc)\d*' | \
sort -r | rev | uniq -s 2 | rev)
)
fi
done
for ARGS in ${args_list[@]}; do
$install_script_path --version $ARGS -NoPath --arch $arch
done
# dotnet installer doesn't create symlink to executable in /user/local/bin
# Moreover at that moment /user/local/bin doesn't exist (though already added to $PATH)
ln -s ~/.dotnet/dotnet /usr/local/bin/dotnet
# Validate installation
if [[ $(dotnet --list-sdks | wc -l) -lt "1" ]]; then
echo "The .NET Core SDK is not installed"
exit 1
fi
echo 'export PATH="$PATH:$HOME/.dotnet/tools"' >> $HOME/.bashrc
echo "Dotnet operations have been completed successfully..."
invoke_tests "Common" ".NET"
@@ -0,0 +1,62 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-edge.sh
## Desc: Install edge browser
################################################################################
source ~/utils/utils.sh
echo "Installing Microsoft Edge..."
brew install --cask microsoft-edge
EDGE_INSTALLATION_PATH="/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"
edge_version=$("$EDGE_INSTALLATION_PATH" --version | cut -d' ' -f 3)
edge_version_major=$(echo $edge_version | cut -d'.' -f 1)
echo "Version of Microsoft Edge: ${edge_version}"
echo "Installing Microsoft Edge WebDriver..."
edge_driver_version_file_path=$(download_with_retry "https://msedgedriver.azureedge.net/LATEST_RELEASE_${edge_version_major}_MACOS")
edge_driver_latest_version=$(iconv -f utf-16 -t utf-8 "$edge_driver_version_file_path" | tr -d '\r')
edge_driver_url="https://msedgedriver.azureedge.net/${edge_driver_latest_version}/edgedriver_mac64.zip"
echo "Compatible version of WebDriver: ${edge_driver_latest_version}"
edge_driver_archive_path=$(download_with_retry "$edge_driver_url")
# Move webdriver to the separate directory to be consistent with the docs
# https://docs.microsoft.com/en-us/azure/devops/pipelines/test/continuous-test-selenium?view=azure-devops#decide-how-you-will-deploy-and-test-your-app
EDGE_DRIVER_DIR="/usr/local/share/edge_driver"
mkdir -p $EDGE_DRIVER_DIR
unzip -qq $edge_driver_archive_path -d $EDGE_DRIVER_DIR
ln -s $EDGE_DRIVER_DIR/msedgedriver /usr/local/bin/msedgedriver
echo "export EDGEWEBDRIVER=${EDGE_DRIVER_DIR}" >> ${HOME}/.bashrc
# Configure Edge Updater to prevent auto update
# https://learn.microsoft.com/en-us/deployedge/edge-learnmore-edgeupdater-for-macos
sudo mkdir "/Library/Managed Preferences"
cat <<EOF | sudo tee "/Library/Managed Preferences/com.microsoft.EdgeUpdater.plist" > /dev/null
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>updatePolicies</key>
<dict>
<key>global</key>
<dict>
<key>UpdateDefault</key>
<integer>3</integer>
</dict>
</dict>
</dict>
</plist>
EOF
sudo chown root:wheel "/Library/Managed Preferences/com.microsoft.EdgeUpdater.plist"
invoke_tests "Browsers" "Edge"
@@ -0,0 +1,19 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-firefox.sh
## Desc: Install firefox browser
################################################################################
source ~/utils/utils.sh
echo "Installing Firefox..."
brew install --cask firefox
echo "Installing Geckodriver..."
brew_smart_install "geckodriver"
geckoPath="$(brew --prefix geckodriver)/bin"
echo "Add GECKOWEBDRIVER to bashrc..."
echo "export GECKOWEBDRIVER=${geckoPath}" >> ${HOME}/.bashrc
invoke_tests "Browsers" "Firefox"
+21
View File
@@ -0,0 +1,21 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-gcc.sh
## Desc: Install GCC
################################################################################
source ~/utils/utils.sh
gccVersions=$(get_toolset_value '.gcc.versions | .[]')
for gccVersion in $gccVersions; do
brew_smart_install "gcc@${gccVersion}"
done
# Delete default gfortran link if it exists https://github.com/actions/runner-images/issues/1280
gfortranPath=$(which gfortran) || true
if [[ $gfortranPath ]]; then
rm $gfortranPath
fi
invoke_tests "Common" "GCC"
+38
View File
@@ -0,0 +1,38 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-git.sh
## Desc: Install Git and Git LFS
################################################################################
source ~/utils/utils.sh
echo "Installing Git..."
brew_smart_install "git"
git config --global --add safe.directory "*"
echo "Installing Git LFS"
brew_smart_install "git-lfs"
# Update global git config
git lfs install
# Update system git config
sudo git lfs install --system
echo "Disable all the Git help messages..."
git config --global advice.pushUpdateRejected false
git config --global advice.pushNonFFCurrent false
git config --global advice.pushNonFFMatching false
git config --global advice.pushAlreadyExists false
git config --global advice.pushFetchFirst false
git config --global advice.pushNeedsForce false
git config --global advice.statusHints false
git config --global advice.statusUoption false
git config --global advice.commitBeforeMerge false
git config --global advice.resolveConflict false
git config --global advice.implicitIdentity false
git config --global advice.detachedHead false
git config --global advice.amWorkDir false
git config --global advice.rmHints false
invoke_tests "Git"
@@ -0,0 +1,16 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-golang.sh
## Desc: Install Go
################################################################################
source ~/utils/utils.sh
default_go_version=$(get_toolset_value '.go.default')
echo "Installing Go..."
brew_smart_install "go@${default_go_version}"
# Create symlinks to preserve backward compatibility. Symlinks are not created when non-latest go is being installed
ln -sf $(brew --prefix go@${default_go_version})/bin/* /usr/local/bin/
invoke_tests "Common" "Go"
@@ -0,0 +1,31 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-haskell.sh
## Desc: Install Haskell
################################################################################
source ~/utils/utils.sh
curl --proto '=https' --tlsv1.2 -fsSL https://get-ghcup.haskell.org | bash
export PATH="$HOME/.ghcup/bin:$PATH"
echo 'export PATH="$PATH:$HOME/.ghcup/bin"' >> $HOME/.bashrc
# ghcup output looks like this "ghc 8.6.4 base-4.12.0.0 hls-powered", need to take all the first versions only(8.6.4 in that case) and avoid pre-release ones
availableVersions=$(ghcup list -t ghc -r | grep -v "prerelease" | awk '{print $2}')
# Install 3 latest major versions(For instance 8.6.5, 8.8.4, 8.10.2)
minorMajorVersions=$(echo "$availableVersions" | cut -d"." -f 1,2 | uniq | tail -n3)
for majorMinorVersion in $minorMajorVersions; do
fullVersion=$(echo "$availableVersions" | grep "$majorMinorVersion." | tail -n1)
echo "install ghc version $fullVersion..."
ghcup install $fullVersion
ghcup set $fullVersion
done
echo "install cabal..."
ghcup install-cabal
echo "Updating stack..."
ghcup install stack latest
invoke_tests "Haskell"
@@ -0,0 +1,43 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-homebrew.sh
## Desc: Install Homebrew
################################################################################
source ~/utils/utils.sh
arch=$(get_arch)
echo "Installing Homebrew..."
homebrew_installer_path=$(download_with_retry "https://raw.githubusercontent.com/Homebrew/install/master/install.sh")
/bin/bash $homebrew_installer_path
if [[ $arch == "arm64" ]]; then
/opt/homebrew/bin/brew update
/opt/homebrew/bin/brew upgrade
/opt/homebrew/bin/brew upgrade --cask
/opt/homebrew/bin/brew cleanup
eval "$(/opt/homebrew/bin/brew shellenv)"
fi
git clone https://github.com/Homebrew/homebrew-cask $(brew --repository)/Library/Taps/homebrew/homebrew-cask --origin=origin --template= --config core.fsmonitor=false --depth 1
git clone https://github.com/Homebrew/homebrew-core $(brew --repository)/Library/Taps/homebrew/homebrew-core --origin=origin --template= --config core.fsmonitor=false --depth 1
brew tap homebrew/cask
brew tap homebrew/core
echo "Disabling Homebrew analytics..."
brew analytics off
# jq is required for further installation scripts
echo "Installing jq..."
brew_smart_install jq
echo "Installing curl..."
brew_smart_install curl
echo "Installing wget..."
brew_smart_install "wget"
# init brew bundle feature
brew tap Homebrew/bundle
@@ -0,0 +1,13 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-llvm.sh
## Desc: Install LLVM
################################################################################
source ~/utils/utils.sh
llvmVersion=$(get_toolset_value '.llvm.version')
brew_smart_install "llvm@${llvmVersion}"
invoke_tests "LLVM"
@@ -0,0 +1,24 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-miniconda.sh
## Desc: Install Miniconda
################################################################################
source ~/utils/utils.sh
miniconda_installer_path=$(download_with_retry "https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh")
chmod +x $miniconda_installer_path
sudo $miniconda_installer_path -b -p /usr/local/miniconda
# Chmod with full permissions recursively to avoid permissions restrictions
sudo chmod -R 777 /usr/local/miniconda
sudo ln -s /usr/local/miniconda/bin/conda /usr/local/bin/conda
if [[ -d $HOME/.conda ]]; then
sudo chown -R $USER $HOME/.conda
fi
echo "export CONDA=/usr/local/miniconda" >> $HOME/.bashrc
invoke_tests "Common" "Miniconda"
@@ -0,0 +1,23 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-mongodb.sh
## Desc: Install MongoDB
################################################################################
source ~/utils/utils.sh
# MongoDB object-value database
# Install latest release version of MongoDB Community Edition
# https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x
toolsetVersion=$(get_toolset_value '.mongodb.version')
brew tap mongodb/brew
versionToInstall=$(brew search --formulae /mongodb-community@$toolsetVersion/ | awk -F'/' '{print $3}' | tail -1)
echo "Installing mongodb $versionToInstall"
brew_smart_install $versionToInstall
if ! which mongo ; then
brew link $versionToInstall
fi
invoke_tests "Databases" "MongoDB"
@@ -0,0 +1,51 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-mono.sh
## Desc: Install Mono Framework
################################################################################
source ~/utils/utils.sh
# Install Mono Framework
mono_version_full=$(get_toolset_value '.mono.framework.version')
mono_pkg_sha256=$(get_toolset_value '.mono.framework.sha256')
mono_version=$(echo $mono_version_full | cut -d. -f 1,2,3)
mono_version_short=$(echo $mono_version_full | cut -d. -f 1,2)
mono_pkg_url="https://download.mono-project.com/archive/${mono_version}/macos-10-universal/MonoFramework-MDK-${mono_version_full}.macos10.xamarin.universal.pkg"
MONO_VERSIONS_PATH='/Library/Frameworks/Mono.framework/Versions'
mono_pkg_path=$(download_with_retry $mono_pkg_url)
use_checksum_comparison $mono_pkg_path $mono_pkg_sha256
echo "Installing Mono Framework ${mono_version_full}..."
sudo installer -pkg $mono_pkg_path -target /
# Download and install NUnit console
nunit_version=$(get_toolset_value '.mono.nunit.version')
nunit_archive_url="https://github.com/nunit/nunit-console/releases/download/${nunit_version}/NUnit.Console-${nunit_version}.zip"
nunit_archive_sha256=$(get_toolset_value '.mono.nunit.sha256')
NUNIT_PATH="/Library/Developer/nunit"
nunit_version_path=$NUNIT_PATH/$nunit_version
nunit_archive_path=$(download_with_retry $nunit_archive_url)
use_checksum_comparison $nunit_archive_path $nunit_archive_sha256
echo "Installing NUnit ${nunit_version}..."
sudo mkdir -p $nunit_version_path
sudo unzip -q $nunit_archive_path -d $nunit_version_path
# Create a wrapper script for nunit3-console
echo "Creating nunit3-console wrapper..."
nunit3_console_wrapper=$(mktemp)
cat <<EOF > "$nunit3_console_wrapper"
#!/bin/bash -e -o pipefail
exec ${MONO_VERSIONS_PATH}/${mono_version}/bin/mono --debug \$MONO_OPTIONS $nunit_version_path/nunit3-console.exe "\$@"
EOF
cat $nunit3_console_wrapper
sudo chmod +x $nunit3_console_wrapper
sudo mv $nunit3_console_wrapper "${MONO_VERSIONS_PATH}/${mono_version}/Commands/nunit3-console"
# Create a symlink for the short version of Mono (e.g., 6.12)
echo "Creating short symlink '${mono_version_short}'..."
sudo ln -s ${MONO_VERSIONS_PATH}/${mono_version} ${MONO_VERSIONS_PATH}/${mono_version_short}
# Invoke tests for Xamarin and Mono
invoke_tests "Xamarin" "Mono"
@@ -0,0 +1,12 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-nginx.sh
## Desc: Install Nginx
################################################################################
source ~/utils/utils.sh
brew_smart_install nginx
sudo sed -Ei '' 's/listen.*/listen 80;/' $(brew --prefix)/etc/nginx/nginx.conf
invoke_tests "WebServers" "Nginx"
@@ -0,0 +1,27 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-node.sh
## Desc: Install Node.js
################################################################################
source ~/utils/utils.sh
defaultVersion=$(get_toolset_value '.node.default')
echo "Installing Node.js $defaultVersion"
brew_smart_install "node@$defaultVersion"
brew link node@$defaultVersion --force --overwrite
echo Installing yarn...
yarn_installer_path=$(download_with_retry "https://yarnpkg.com/install.sh")
bash $yarn_installer_path
if is_Monterey; then
npm_global_packages=$(get_toolset_value '.npm.global_packages[].name')
for module in ${npm_global_packages[@]}; do
echo "Install $module"
npm install -g $module
done
fi
invoke_tests "Node" "Node.js"
+36
View File
@@ -0,0 +1,36 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-nvm.sh
## Desc: Install node version manager
################################################################################
source ~/utils/utils.sh
[[ -n $API_PAT ]] && authString=(-H "Authorization: token ${API_PAT}")
nvm_version=$(get_toolset_value '.node.nvm_installer')
if [[ -z $nvm_version || "$nvm_version" == "latest" ]]; then
nvm_version=$(curl "${authString[@]}" -fsSL https://api.github.com/repos/nvm-sh/nvm/releases/latest | jq -r '.tag_name')
fi
if [[ $nvm_version != "v*" ]]; then
nvm_version="v${nvm_version}"
fi
nvm_installer_path=$(download_with_retry "https://raw.githubusercontent.com/nvm-sh/nvm/$nvm_version/install.sh")
if bash $nvm_installer_path; then
source ~/.bashrc
nvm --version
for version in $(get_toolset_value '.node.nvm_versions[]'); do
nvm install "v${version}"
done
# set system node as default
nvm alias default system
echo "Node version manager has been installed successfully"
else
echo "Node version manager installation failed"
fi
invoke_tests "Node" "nvm"
@@ -0,0 +1,101 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-openjdk.sh
## Desc: Install openjdk
################################################################################
source ~/utils/utils.sh
createEnvironmentVariable() {
local JAVA_VERSION=$1
local DEFAULT=$2
if [[ $arch == "arm64" ]]; then
INSTALL_PATH_PATTERN=$(echo ${AGENT_TOOLSDIRECTORY}/Java_Temurin-Hotspot_jdk/${JAVA_VERSION}*/arm64/Contents/Home/)
else
INSTALL_PATH_PATTERN=$(echo ${AGENT_TOOLSDIRECTORY}/Java_Temurin-Hotspot_jdk/${JAVA_VERSION}*/x64/Contents/Home/)
fi
if [[ ${DEFAULT} == "True" ]]; then
echo "Setting up JAVA_HOME variable to ${INSTALL_PATH_PATTERN}"
echo "export JAVA_HOME=${INSTALL_PATH_PATTERN}" >> ${HOME}/.bashrc
fi
if [[ $arch == "arm64" ]]; then
echo "Setting up JAVA_HOME_${JAVA_VERSION}_arm64 variable to ${INSTALL_PATH_PATTERN}"
echo "export JAVA_HOME_${JAVA_VERSION}_arm64=${INSTALL_PATH_PATTERN}" >> ${HOME}/.bashrc
else
echo "Setting up JAVA_HOME_${JAVA_VERSION}_X64 variable to ${INSTALL_PATH_PATTERN}"
echo "export JAVA_HOME_${JAVA_VERSION}_X64=${INSTALL_PATH_PATTERN}" >> ${HOME}/.bashrc
fi
}
installOpenJDK() {
local JAVA_VERSION=$1
# Get link for Java binaries and Java version
hotspot_json_path=$(download_with_retry "https://api.adoptium.net/v3/assets/latest/${JAVA_VERSION}/hotspot")
if [[ $arch == "arm64" ]]; then
asset=$(jq -r '.[] | select(.binary.os=="mac" and .binary.image_type=="jdk" and .binary.architecture=="aarch64")' "$hotspot_json_path")
else
asset=$(jq -r '.[] | select(.binary.os=="mac" and .binary.image_type=="jdk" and .binary.architecture=="x64")' "$hotspot_json_path")
fi
archive_url=$(echo "$asset" | jq -r '.binary.package.link')
fullVersion=$(echo "$asset" | jq -r '.version.semver' | tr '+' '-')
# Remove 'LTS' suffix from the version if present
fullVersion="${fullVersion//.LTS/}"
JAVA_TOOLCACHE_PATH=${AGENT_TOOLSDIRECTORY}/Java_Temurin-Hotspot_jdk
javaToolcacheVersionPath=$JAVA_TOOLCACHE_PATH/${fullVersion}
if [[ $arch == "arm64" ]]; then
javaToolcacheVersionArchPath=${javaToolcacheVersionPath}/arm64
else
javaToolcacheVersionArchPath=${javaToolcacheVersionPath}/x64
fi
# Download and extract Java binaries
archive_path=$(download_with_retry $archive_url)
echo "Creating ${javaToolcacheVersionArchPath} directory"
mkdir -p ${javaToolcacheVersionArchPath}
tar -xf $archive_path -C ${javaToolcacheVersionArchPath} --strip-components=1
# Create complete file
if [[ $arch == "arm64" ]]; then
touch ${javaToolcacheVersionPath}/arm64.complete
else
touch ${javaToolcacheVersionPath}/x64.complete
fi
# Create a symlink to '/Library/Java/JavaVirtualMachines'
# so '/usr/libexec/java_home' will be able to find Java
sudo ln -sf ${javaToolcacheVersionArchPath} /Library/Java/JavaVirtualMachines/Temurin-Hotspot-${JAVA_VERSION}.jdk
}
arch=$(get_arch)
defaultVersion=$(get_toolset_value '.java.'$arch'.default')
jdkVersionsToInstall=($(get_toolset_value ".java.${arch}.versions[]"))
for jdkVersionToInstall in ${jdkVersionsToInstall[@]}; do
installOpenJDK ${jdkVersionToInstall}
if [[ ${jdkVersionToInstall} == ${defaultVersion} ]]
then
createEnvironmentVariable ${jdkVersionToInstall} True
else
createEnvironmentVariable ${jdkVersionToInstall} False
fi
done
echo Installing Maven...
brew_smart_install "maven"
echo Installing Gradle ...
brew_smart_install "gradle"
invoke_tests "Java"
@@ -0,0 +1,25 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-openssl.sh
## Desc: Install openssl
################################################################################
source ~/utils/utils.sh
echo "Install [email protected]"
brew_smart_install "[email protected]"
if ! is_Arm64; then
# Symlink brew [email protected] to `/usr/local/bin` as Homebrew refuses
ln -sf $(brew --prefix [email protected])/bin/openssl /usr/local/bin/openssl
else
# arm64 has a different installation prefix for brew
ln -sf $(brew --prefix [email protected])/bin/openssl /opt/homebrew/bin/openssl
fi
if ! is_Arm64; then
# Most of build systems and scripts look up ssl here
ln -sf $(brew --cellar [email protected])/1.1* /usr/local/opt/openssl
fi
invoke_tests "OpenSSL"
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-php.sh
## Desc: Install PHP
################################################################################
source ~/utils/utils.sh
echo Installing PHP
phpVersionToolset=$(get_toolset_value '.php.version')
brew_smart_install "php@${phpVersionToolset}"
echo Installing composer
brew_smart_install "composer"
invoke_tests "PHP"
@@ -0,0 +1,18 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-pipx-packages.sh
## Desc: Install Pipx Packages
################################################################################
source ~/utils/utils.sh
export PATH="$PATH:/opt/pipx_bin"
pipx_packages=$(get_toolset_value '.pipx[].package')
for package in $pipx_packages; do
echo "Install $package into default python"
pipx install $package
done
invoke_tests "PipxPackages"
@@ -0,0 +1,38 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-postgresql.sh
## Desc: Install PostgreSQL
################################################################################
source ~/utils/utils.sh
# Fetch PostgreSQL version to install from the toolset
toolsetVersion=$(get_toolset_value '.postgresql.version')
# Install latest version of PostgreSQL
brew_smart_install postgresql@$toolsetVersion
# Service PostgreSQL should be started before use
postgreService=$(brew services list | grep -oe "postgresql\S*")
brew services start $postgreService
# Verify PostgreSQL is ready for accept incoming connections
echo "Check PostgreSQL service is running"
i=10
COMMAND='pg_isready'
while [[ $i -gt 0 ]]; do
echo "Check PostgreSQL service status"
eval $COMMAND && break
((i--))
if [[ $i == 0 ]]; then
echo "PostgreSQL service not ready, all attempts exhausted"
exit 1
fi
echo "PostgreSQL service not ready, wait 10 more sec, attempts left: $i"
sleep 10
done
# Stop PostgreSQL
brew services stop $postgreService
invoke_tests "Databases" "PostgreSQL"
@@ -0,0 +1,67 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-powershell.sh
## Desc: Install PowerShell
################################################################################
source ~/utils/utils.sh
echo Installing PowerShell...
arch=$(get_arch)
metadata_json_path=$(download_with_retry "https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/metadata.json")
pwshVersionToolset=$(get_toolset_value '.pwsh.version')
pwshVersions=$(jq -r '.LTSReleaseTag[]' $metadata_json_path)
for version in ${pwshVersions[@]}; do
if [[ "$version" =~ "$pwshVersionToolset" ]]; then
download_url=$(resolve_github_release_asset_url "PowerShell/PowerShell" "contains(\"osx-$arch.pkg\")" "$version" "$API_PAT")
break
fi
done
pkg_path=$(download_with_retry $download_url)
# Work around the issue on macOS Big Sur 11.5 or higher for possible error message ("can't be opened because Apple cannot check it for malicious software") when installing the package
sudo xattr -rd com.apple.quarantine $pkg_path
sudo installer -pkg $pkg_path -target /
# Install PowerShell modules
psModules=$(get_toolset_value '.powershellModules[].name')
for module in ${psModules[@]}; do
echo "Installing $module module"
moduleVersions="$(get_toolset_value ".powershellModules[] | select(.name==\"$module\") | .versions[]?")"
if [[ -z $moduleVersions ]];then
# Check MacOS architecture and sudo on Arm64
if [[ $arch == "arm64" ]]; then
sudo pwsh -command "& {Install-Module $module -Force -Scope AllUsers}"
else
pwsh -command "& {Install-Module $module -Force -Scope AllUsers}"
fi
else
for version in ${moduleVersions[@]}; do
# Check MacOS architecture and sudo on Arm64
if [[ $arch == "arm64" ]]; then
echo " - $version"
sudo pwsh -command "& {Install-Module $module -RequiredVersion $version -Force -Scope AllUsers}"
else
echo " - $version"
pwsh -command "& {Install-Module $module -RequiredVersion $version -Force -Scope AllUsers}"
fi
done
fi
done
# Fix permission root => runner after installing powershell for arm64 arch
if [[ $arch == "arm64" ]]; then
sudo chown -R $USER ~/.local ~/.cache ~/.config
fi
# A dummy call to initialize .IdentityService directory
pwsh -command "& {Import-Module Az}"
# powershell link was removed in powershell-6.0.0-beta9
sudo ln -s /usr/local/bin/pwsh /usr/local/bin/powershell
invoke_tests "Powershell"
@@ -0,0 +1,87 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-pypy.sh
## Desc: Install PyPy
################################################################################
source ~/utils/utils.sh
InstallPyPy() {
local package_url=$1
PACKAGE_TAR_NAME=$(basename $package_url)
echo "Downloading tar archive '$PACKAGE_TAR_NAME'"
archive_path=$(download_with_retry $package_url)
echo "Expand '$PACKAGE_TAR_NAME' to the /tmp folder"
tar xf $archive_path -C /tmp
# Get Python version
PACKAGE_NAME=${PACKAGE_TAR_NAME/.tar.bz2/}
MAJOR_VERSION=$(echo ${PACKAGE_NAME/pypy/} | cut -d. -f1)
PYTHON_MAJOR="python$MAJOR_VERSION"
if [[ $MAJOR_VERSION != 2 ]]; then
PYPY_MAJOR="pypy$MAJOR_VERSION"
else
PYPY_MAJOR="pypy"
fi
PACKAGE_TEMP_FOLDER="/tmp/$PACKAGE_NAME"
PYTHON_FULL_VERSION=$("$PACKAGE_TEMP_FOLDER/bin/$PYPY_MAJOR" -c "import sys;print('{}.{}.{}'.format(sys.version_info[0],sys.version_info[1],sys.version_info[2]))")
PYPY_FULL_VERSION=$("$PACKAGE_TEMP_FOLDER/bin/$PYPY_MAJOR" -c "import sys;print('{}.{}.{}'.format(*sys.pypy_version_info[0:3]))")
echo "Put '$PYPY_FULL_VERSION' to PYPY_VERSION file"
echo $PYPY_FULL_VERSION > "$PACKAGE_TEMP_FOLDER/PYPY_VERSION"
# PyPy folder structure
PYPY_TOOLCACHE_PATH=$AGENT_TOOLSDIRECTORY/PyPy
PYPY_TOOLCACHE_VERSION_PATH=$PYPY_TOOLCACHE_PATH/$PYTHON_FULL_VERSION
PYPY_TOOLCACHE_VERSION_ARCH_PATH=$PYPY_TOOLCACHE_VERSION_PATH/x64
echo "Check if PyPy hostedtoolcache folder exist..."
if [[ ! -d $PYPY_TOOLCACHE_PATH ]]; then
mkdir -p $PYPY_TOOLCACHE_PATH
fi
echo "Create PyPy '$PYPY_TOOLCACHE_VERSION_PATH' folder"
mkdir $PYPY_TOOLCACHE_VERSION_PATH
echo "Move PyPy $PACKAGE_TEMP_FOLDER binaries to $PYPY_TOOLCACHE_VERSION_ARCH_PATH folder"
mv $PACKAGE_TEMP_FOLDER $PYPY_TOOLCACHE_VERSION_ARCH_PATH
echo "Create additional symlinks (Required for UsePythonVersion Azure DevOps task)"
cd $PYPY_TOOLCACHE_VERSION_ARCH_PATH/bin
PYPY_FULL_VERSION=$(./$PYPY_MAJOR -c "import sys;print('{}.{}.{}'.format(*sys.pypy_version_info[0:3]))")
echo "PYPY_FULL_VERSION is $PYPY_FULL_VERSION"
echo $PYPY_FULL_VERSION > "PYPY_VERSION"
# Starting from PyPy 7.3.4 these links are already included in the package
[[ -f ./$PYTHON_MAJOR ]] || ln -s $PYPY_MAJOR $PYTHON_MAJOR
[[ -f ./python ]] || ln -s $PYTHON_MAJOR python
chmod +x ./python ./$PYTHON_MAJOR
echo "Install latest Pip"
./python -m ensurepip
./python -m pip install --ignore-installed pip
echo "Create complete file"
touch $PYPY_TOOLCACHE_VERSION_PATH/x64.complete
}
arch=$(get_arch)
versions_json_path=$(download_with_retry "https://downloads.python.org/pypy/versions.json")
toolsetVersions=$(get_toolset_value '.toolcache[] | select(.name | contains("PyPy")) | .arch.'$arch'.versions[]')
for toolsetVersion in $toolsetVersions; do
latestMajorPyPyVersion=$(cat $versions_json_path |
jq -r --arg toolsetVersion $toolsetVersion '.[]
| select((.python_version | startswith($toolsetVersion)) and .stable == true).files[]
| select(.platform == "darwin").download_url' | head -1)
if [[ -z $latestMajorPyPyVersion ]]; then
echo "Failed to get PyPy version $toolsetVersion"
exit 1
fi
InstallPyPy $latestMajorPyPyVersion
done
@@ -0,0 +1,57 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-python.sh
## Desc: Install Python
################################################################################
source ~/utils/utils.sh
echo "Installing Python Tooling"
if is_Monterey; then
echo "Install latest Python 2"
python2_pkg=$(download_with_retry "https://www.python.org/ftp/python/2.7.18/python-2.7.18-macosx10.9.pkg")
python2_pkg_sha256="c570f38b05dd8b112ad21b418cdf51a9816d62f9f44746452739d421be24d50c"
use_checksum_comparison $python2_pkg $python2_pkg_sha256
choice_changes_xml=$(mktemp /tmp/python2_choice_changes.xml.XXXXXX)
sudo installer -showChoiceChangesXML -pkg $python2_pkg -target / | tee $choice_changes_xml > /dev/null
# To avoid symlink conflicts, remove tools installation in /usr/local/bin using installer choices
xmllint --shell $choice_changes_xml <<EOF
cd //array/dict[string[text()='org.python.Python.PythonUnixTools-2.7']]/integer
set 0
save
EOF
sudo installer -applyChoiceChangesXML $choice_changes_xml -pkg $python2_pkg -target /
pip install --upgrade pip
echo "Install Python2 certificates"
bash -c "/Applications/Python\ 2.7/Install\ Certificates.command"
fi
# Close Finder window
close_finder_window
echo "Brew Installing Python 3"
brew_smart_install "[email protected]"
echo "Installing pipx"
if is_Arm64; then
export PIPX_BIN_DIR="$HOME/.local/bin"
export PIPX_HOME="$HOME/.local/pipx"
else
export PIPX_BIN_DIR=/usr/local/opt/pipx_bin
export PIPX_HOME=/usr/local/opt/pipx
fi
brew_smart_install "pipx"
echo "export PIPX_BIN_DIR=${PIPX_BIN_DIR}" >> ${HOME}/.bashrc
echo "export PIPX_HOME=${PIPX_HOME}" >> ${HOME}/.bashrc
echo 'export PATH="$PIPX_BIN_DIR:$PATH"' >> ${HOME}/.bashrc
invoke_tests "Python"
@@ -0,0 +1,8 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-rosetta.sh
## Desc: Install Rosetta
################################################################################
echo "Installing Rosetta"
/usr/sbin/softwareupdate --install-rosetta --agree-to-license
@@ -0,0 +1,60 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-ruby.sh
## Desc: Install Ruby
################################################################################
source ~/utils/utils.sh
arch=$(get_arch)
DEFAULT_RUBY_VERSION=$(get_toolset_value '.ruby.default')
echo "Installing Ruby..."
brew_smart_install "ruby@${DEFAULT_RUBY_VERSION}"
if [[ $arch == "arm64" ]]; then
export PATH=/opt/homebrew/opt/ruby@${DEFAULT_RUBY_VERSION}/bin:$PATH
else
export PATH=/usr/local/opt/ruby@${DEFAULT_RUBY_VERSION}/bin:$PATH
fi
GEM_PATH=$(gem env|awk '/EXECUTABLE DIRECTORY/ {print $4}')
echo "GEM_PATH=$GEM_PATH" >> $HOME/.bashrc
if [[ $arch == "arm64" ]]; then
echo 'export PATH="$GEM_PATH:/opt/homebrew/opt/ruby@'${DEFAULT_RUBY_VERSION}'/bin:$PATH"' >> $HOME/.bashrc
else
echo 'export PATH="$GEM_PATH:/usr/local/opt/ruby@'${DEFAULT_RUBY_VERSION}'/bin:$PATH"' >> $HOME/.bashrc
fi
if ! is_Arm64; then
echo "Install Ruby from toolset..."
[ -n "$API_PAT" ] && authString=(-H "Authorization: token ${API_PAT}")
PACKAGE_TAR_NAMES=$(curl "${authString[@]}" -fsSL "https://api.github.com/repos/ruby/ruby-builder/releases/latest" | jq -r '.assets[].name')
TOOLSET_VERSIONS=$(get_toolset_value '.toolcache[] | select(.name | contains("Ruby")) | .arch.'$arch'.versions[]')
RUBY_PATH=$AGENT_TOOLSDIRECTORY/Ruby
echo "Check if Ruby hostedtoolcache folder exists..."
if [[ ! -d $RUBY_PATH ]]; then
mkdir -p $RUBY_PATH
fi
echo "ruby path - $RUBY_PATH "
for TOOLSET_VERSION in ${TOOLSET_VERSIONS[@]}; do
PACKAGE_TAR_NAME=$(echo "$PACKAGE_TAR_NAMES" | grep "^ruby-${TOOLSET_VERSION}-macos-latest.tar.gz$" | egrep -v "rc|preview" | sort -V | tail -1)
RUBY_VERSION=$(echo "$PACKAGE_TAR_NAME" | cut -d'-' -f 2)
RUBY_VERSION_PATH="$RUBY_PATH/$RUBY_VERSION"
echo "Create Ruby $RUBY_VERSION directory..."
mkdir -p $RUBY_VERSION_PATH
echo "Downloading tar archive $PACKAGE_TAR_NAME"
ARCHIVE_PATH=$(download_with_retry "https://github.com/ruby/ruby-builder/releases/download/toolcache/${PACKAGE_TAR_NAME}")
echo "Expand $PACKAGE_TAR_NAME to the $RUBY_VERSION_PATH folder"
tar xf $ARCHIVE_PATH -C $RUBY_VERSION_PATH
COMPLETE_FILE_PATH=$RUBY_VERSION_PATH/x64.complete
if [[ ! -f $COMPLETE_FILE_PATH ]]; then
echo "Create complete file"
touch $COMPLETE_FILE_PATH
fi
done
fi
invoke_tests "Ruby.$arch"
@@ -0,0 +1,23 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-rubygems.sh
## Desc: Install RubyGems
################################################################################
source ~/utils/utils.sh
echo "Updating RubyGems..."
gem update --system
# Temporarily install activesupport 7.0.8 due to compatibility issues with cocoapods https://github.com/CocoaPods/CocoaPods/issues/12081
gem install activesupport -v 7.0.8
gemsToInstall=$(get_toolset_value '.ruby.rubygems | .[]')
if [[ -n $gemsToInstall ]]; then
for gem in $gemsToInstall; do
echo "Installing gem $gem"
gem install $gem
done
fi
invoke_tests "RubyGem"
@@ -0,0 +1,28 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-rust.sh
## Desc: Install Rust
################################################################################
source ~/utils/utils.sh
echo "Installing Rustup..."
brew_smart_install "rustup-init"
echo "Installing Rust language..."
rustup-init -y --no-modify-path --default-toolchain=stable --profile=minimal
echo "Initialize environment variables..."
CARGO_HOME=$HOME/.cargo
echo "Install common tools..."
rustup component add rustfmt clippy
if is_Monterey; then
cargo install bindgen-cli cbindgen cargo-audit cargo-outdated
fi
echo "Cleanup Cargo registry cached data..."
rm -rf $CARGO_HOME/registry/*
invoke_tests "Rust"
@@ -0,0 +1,20 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-safari.sh
## Desc: Install Safari browser
################################################################################
echo "Enabling safari driver..."
# https://developer.apple.com/documentation/webkit/testing_with_webdriver_in_safari
# Safaris executable is located at /usr/bin/safaridriver
# Configure Safari to Enable WebDriver Support
sudo safaridriver --enable
echo "Enabling the 'Allow Remote Automation' option in Safari's Develop menu"
mkdir -p $HOME/Library/WebDriver
safari_plist="$HOME/Library/WebDriver/com.apple.Safari.plist"
# "|| true" is needed to suppress exit code 1 in case if property or file doesn't exist
/usr/libexec/PlistBuddy -c 'delete AllowRemoteAutomation' $safari_plist || true
/usr/libexec/PlistBuddy -c 'add AllowRemoteAutomation bool true' $safari_plist
invoke_tests "Browsers" "Safari"
@@ -0,0 +1,21 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-swiftlint.sh
## Desc: Install SwiftLint
################################################################################
source ~/utils/utils.sh
echo "Installing Swiftlint..."
if is_Monterey; then
# SwiftLint now requires Xcode 15.3 or higher to build https://github.com/realm/SwiftLint/releases/tag/0.55.1
COMMIT=d91dabd087cb0b906c92a825df9e5e5e1a4f59f8
FORMULA_URL="https://raw.githubusercontent.com/Homebrew/homebrew-core/$COMMIT/Formula/s/swiftlint.rb"
curl -fsSL $FORMULA_URL > $(find $(brew --repository) -name swiftlint.rb)
HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_FROM_API=1 brew install swiftlint
else
brew_smart_install "swiftlint"
fi
invoke_tests "Linters" "SwiftLint"
@@ -0,0 +1,27 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-vcpkg.sh
## Desc: Install vcpkg
################################################################################
source ~/utils/utils.sh
# Set env variable for vcpkg
VCPKG_INSTALLATION_ROOT=/usr/local/share/vcpkg
echo "export VCPKG_INSTALLATION_ROOT=${VCPKG_INSTALLATION_ROOT}" | tee -a ~/.bashrc
# workaround https://github.com/microsoft/vcpkg/issues/27786
mkdir -p /Users/runner/.vcpkg
touch /Users/runner/.vcpkg/vcpkg.path.txt
# Install vcpkg
git clone https://github.com/Microsoft/vcpkg $VCPKG_INSTALLATION_ROOT
$VCPKG_INSTALLATION_ROOT/bootstrap-vcpkg.sh
$VCPKG_INSTALLATION_ROOT/vcpkg integrate install
chmod -R 0777 $VCPKG_INSTALLATION_ROOT
ln -sf $VCPKG_INSTALLATION_ROOT/vcpkg /usr/local/bin
rm -rf /Users/runner/.vcpkg
invoke_tests "Common" "vcpkg"
@@ -0,0 +1,52 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-visualstudio.sh
## Desc: Install Visual Studio
################################################################################
source ~/utils/utils.sh
source ~/utils/xamarin-utils.sh
install_vsmac() {
local vsmac_version=$1
local vsmac_default=$2
if [[ $vsmac_version == "2019" ]]; then
vsmac_download_url=$(curl -fsSL "https://aka.ms/manifest/stable" | jq -r '.items[] | select(.genericName=="VisualStudioMac").url')
elif [[ $vsmac_version == "2022" ]]; then
vsmac_download_url=$(curl -fsSL "https://aka.ms/manifest/stable-2022" | jq -r '.items[] | select(.genericName=="VisualStudioMac").url')
elif [[ $vsmac_version == "preview" ]]; then
vsmac_download_url=$(curl -fsSL "https://aka.ms/manifest/preview" | jq -r '.items[] | select(.genericName=="VisualStudioMac").url')
else
vsmac_download_url=$(buildVSMacDownloadUrl $vsmac_version)
fi
echo "Installing Visual Studio ${vsmac_version} for Mac"
TMPMOUNT=$(/usr/bin/mktemp -d /tmp/visualstudio.XXXX)
mkdir -p "$TMPMOUNT/downloads"
vsmac_installer=$(download_with_retry $vsmac_download_url "$TMPMOUNT/downloads/${vsmac_download_url##*/}")
echo "Mounting Visual Studio..."
hdiutil attach $vsmac_installer -mountpoint $TMPMOUNT
echo "Moving Visual Studio to /Applications/..."
pushd $TMPMOUNT
tar cf - "./Visual Studio.app" | tar xf - -C /Applications/
if [[ $vsmac_version != $vsmac_default ]]; then
mv "/Applications/Visual Studio.app" "/Applications/Visual Studio ${vsmac_version}.app"
fi
popd
sudo hdiutil detach $TMPMOUNT
sudo rm -rf $TMPMOUNT
}
vsmac_versions=($(get_toolset_value '.xamarin.vsmac.versions[]'))
default_vsmac_version=$(get_toolset_value '.xamarin.vsmac.default')
for version in ${vsmac_versions[@]}; do
install_vsmac $version $default_vsmac_version
done
invoke_tests "Common" "VSMac"
@@ -0,0 +1,92 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-xamarin.sh
## Desc: Install Xamarin
################################################################################
source ~/utils/utils.sh
source ~/utils/xamarin-utils.sh
mono_versions=($(get_toolset_value '.xamarin."mono_versions" | reverse | .[]'))
xamarin_ios_versions=($(get_toolset_value '.xamarin."ios_versions" | reverse | .[]'))
xamarin_mac_versions=($(get_toolset_value '.xamarin."mac_versions" | reverse | .[]'))
xamarin_android_versions=($(get_toolset_value '.xamarin."android_versions" | reverse | .[]'))
latest_sdk_symlink=$(get_toolset_value '.xamarin.bundles[0].symlink')
current_sdk_symlink=$(get_toolset_value '.xamarin."bundle_default"')
default_xcode_version=$(get_toolset_value '.xcode.default')
if [[ $current_sdk_symlink == "latest" ]]; then
current_sdk_symlink=$latest_sdk_symlink
fi
MONO_VERSIONS_PATH="/Library/Frameworks/Mono.framework/Versions"
IOS_VERSIONS_PATH="/Library/Frameworks/Xamarin.iOS.framework/Versions"
ANDROID_VERSIONS_PATH="/Library/Frameworks/Xamarin.Android.framework/Versions"
MAC_VERSIONS_PATH="/Library/Frameworks/Xamarin.Mac.framework/Versions"
TMPMOUNT=$(/usr/bin/mktemp -d /tmp/visualstudio.XXXX)
TMPMOUNT_FRAMEWORKS=$TMPMOUNT/frameworks
createBackupFolders
pushd $TMPMOUNT
# Download NUnit console
downloadNUnitConsole
# Install Mono sdks
for version in ${mono_versions[@]}; do installMono $version; done
sudo mv -v $TMPMOUNT_FRAMEWORKS/mono/* $MONO_VERSIONS_PATH/
# Install Xamarin.iOS sdks
for version in ${xamarin_ios_versions[@]}; do installXamarinIOS $version; done
sudo mv -v $TMPMOUNT_FRAMEWORKS/ios/* $IOS_VERSIONS_PATH/
# Install Xamarin.Mac sdks
for version in ${xamarin_mac_versions[@]}; do installXamarinMac $version; done
sudo mv -v $TMPMOUNT_FRAMEWORKS/mac/* $MAC_VERSIONS_PATH/
# Install Xamarin.Android sdks
for version in ${xamarin_android_versions[@]}; do installXamarinAndroid $version; done
sudo mv -v $TMPMOUNT_FRAMEWORKS/android/* $ANDROID_VERSIONS_PATH/
# Create bundles
bundles_count=$(get_toolset_value '.xamarin.bundles | length')
for ((bundle_index=0; bundle_index<bundles_count; bundle_index++)); do
symlink=$(get_toolset_value ".xamarin.bundles[$bundle_index].symlink")
mono=$(get_toolset_value ".xamarin.bundles[$bundle_index].mono")
ios=$(get_toolset_value ".xamarin.bundles[$bundle_index].ios")
mac=$(get_toolset_value ".xamarin.bundles[$bundle_index].mac")
android=$(get_toolset_value ".xamarin.bundles[$bundle_index].android")
createBundle $symlink $mono $ios $mac $android
done
# Symlinks for the latest Xamarin bundle
createBundleLink $latest_sdk_symlink "Latest"
createBundleLink $current_sdk_symlink "Current"
#
# Fix nuget in some mono versions because of known bugs
#
# Creating UWP Shim to hack UWP build failure
createUWPShim
popd
echo "Clean up packages..."
sudo rm -rf $TMPMOUNT
# Fix Xamarin issue with Xcode symlink: https://github.com/xamarin/xamarin-macios/issues/9960
PREFERENCES_XAMARIN_DIR="${HOME}/Library/Preferences/Xamarin"
mkdir -p $PREFERENCES_XAMARIN_DIR
/usr/libexec/PlistBuddy -c "add :AppleSdkRoot string /Applications/Xcode_${default_xcode_version}.app" $PREFERENCES_XAMARIN_DIR/Settings.plist
# Temporary workaround to recreate nuget.config file with a correct feed https://github.com/actions/runner-images/issues/5768
rm -rf $HOME/.config/NuGet/NuGet.Config
nuget config
# Temporary workaround to point Mono to the proper NUnit console
sudo sed -Ei '' 's/3.6.0/3.6.1/' /Library/Frameworks/Mono.framework/Versions/Current/Commands/nunit3-console
invoke_tests "Xamarin"
@@ -0,0 +1,51 @@
#!/bin/bash -e -o pipefail
################################################################################
## File: install-xcode-clt.sh
## Desc: Install Xcode Command Line Tools
################################################################################
source ~/utils/utils.sh
is_clt_installed() {
clt_path=$(xcode-select -p 2>&1)
[[ -d $clt_path ]]
}
install_clt() {
echo "Searching online for the Command Line Tools"
# This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools
clt_placeholder="/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress"
sudo touch $clt_placeholder
cltPattern="Command Line Tools"
clt_label_command="/usr/sbin/softwareupdate -l |
grep -B 1 -E '${cltPattern}' |
awk -F'*' '/^ *\\*/ {print \$2}' |
sed -e 's/^ *Label: //' -e 's/^ *//' |
sort -V |
tail -n1"
clt_label=$(eval $clt_label_command) || true
if [[ -n "$clt_label" ]]; then
echo "Installing $clt_label"
sudo "/usr/sbin/softwareupdate" "-i" "$clt_label"
fi
sudo "/bin/rm" "-f" "$clt_placeholder"
}
echo "Installing Command Line Tools..."
install_clt
# Retry the installation if tools are not installed from the first attempt
retries=30
sleepInterval=60
while ! is_clt_installed; do
if [[ $retries -eq 0 ]]; then
echo "Unable to find the Command Line Tools, all the attempts exhausted"
exit 1
fi
echo "Command Line Tools not found, trying to install them via software updates, $retries attempts left"
install_clt
((retries--))
echo "Wait $sleepInterval seconds before the next check for installed Command Line Tools"
sleep $sleepInterval
done