Compare commits
14 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
d6ee41d6d5 | |
|
|
741758b9ba | |
|
|
f03344599b | |
|
|
16e9ad7d00 | |
|
|
85b77e41bc | |
|
|
9be4b9dc86 | |
|
|
46050816d8 | |
|
|
d358da6f50 | |
|
|
b4926493fb | |
|
|
c166ec1698 | |
|
|
3d6445b446 | |
|
|
f5a7e1e631 | |
|
|
0a9ad1a419 | |
|
|
cd2d1c6698 |
|
|
@ -89,6 +89,8 @@ jobs:
|
||||||
|
|
||||||
release-runner:
|
release-runner:
|
||||||
name: Update Runner Image (${{ matrix.macos_version }})
|
name: Update Runner Image (${{ matrix.macos_version }})
|
||||||
|
# Keep runner refreshes independent from the release-xcode matrix so one
|
||||||
|
# Xcode image failure does not skip the runner matrix.
|
||||||
runs-on: [self-hosted, macOS, ARM64]
|
runs-on: [self-hosted, macOS, ARM64]
|
||||||
timeout-minutes: 180
|
timeout-minutes: 180
|
||||||
strategy:
|
strategy:
|
||||||
|
|
@ -103,7 +105,7 @@ jobs:
|
||||||
xcode_components: '"MetalToolchain"'
|
xcode_components: '"MetalToolchain"'
|
||||||
disk_size: 380
|
disk_size: 380
|
||||||
- macos_version: tahoe
|
- macos_version: tahoe
|
||||||
xcode_versions: '"26.6","27-beta-2","26.5","27-beta","26.4.1","26.3","26.2","26.1.1","26.0.1"'
|
xcode_versions: '"26.6","27-beta-4","26.5","27-beta","26.4.1","26.3","26.2","26.1.1","26.0.1"'
|
||||||
additional_ios_builds: "18.6"
|
additional_ios_builds: "18.6"
|
||||||
additional_tvos_builds: ""
|
additional_tvos_builds: ""
|
||||||
xcode_components: '"MetalToolchain"'
|
xcode_components: '"MetalToolchain"'
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ jobs:
|
||||||
max-parallel: 1
|
max-parallel: 1
|
||||||
matrix:
|
matrix:
|
||||||
macos_version:
|
macos_version:
|
||||||
|
- golden-gate
|
||||||
- tahoe
|
- tahoe
|
||||||
- sequoia
|
- sequoia
|
||||||
- sonoma
|
- sonoma
|
||||||
|
|
@ -185,7 +186,7 @@ jobs:
|
||||||
git diff --name-only "$BASE_SHA" "$HEAD_SHA" > changed-files.txt
|
git diff --name-only "$BASE_SHA" "$HEAD_SHA" > changed-files.txt
|
||||||
|
|
||||||
build=false
|
build=false
|
||||||
if grep -Eq '^(templates/base\.pkr\.hcl|templates/disable-sip.*\.pkr\.hcl|data/(github_known_hosts|limit\.maxfiles\.plist|setup-info-template\.json|tart-guest-.*\.plist)|scripts/install-actions-runner\.sh|ansible/)' changed-files.txt; then
|
if grep -Eq '^(templates/base\.pkr\.hcl|templates/disable-sip.*\.pkr\.hcl|data/(github_known_hosts|limit\.maxfiles\.plist|setup-info-template\.json|tart-guest-.*\.plist)|scripts/(install-actions-runner|update-tcc-database)\.sh|ansible/)' changed-files.txt; then
|
||||||
build=true
|
build=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ on:
|
||||||
type: choice
|
type: choice
|
||||||
options:
|
options:
|
||||||
- all
|
- all
|
||||||
|
- golden-gate
|
||||||
- tahoe
|
- tahoe
|
||||||
- sequoia
|
- sequoia
|
||||||
- sonoma
|
- sonoma
|
||||||
|
|
@ -46,6 +47,7 @@ jobs:
|
||||||
max-parallel: 1
|
max-parallel: 1
|
||||||
matrix:
|
matrix:
|
||||||
macos_version:
|
macos_version:
|
||||||
|
- golden-gate
|
||||||
- tahoe
|
- tahoe
|
||||||
- sequoia
|
- sequoia
|
||||||
- sonoma
|
- sonoma
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ GitHub Actions runners, [Cirrus Runners](https://cirrus-runners.app/) or [any ot
|
||||||
|
|
||||||
The following image variants are currently available:
|
The following image variants are currently available:
|
||||||
|
|
||||||
* `macos-{tahoe,sequoia,sonoma}-vanilla` — a vanilla macOS installation with helpful tweaks such as auto-login, but no additional software preinstalled
|
* `macos-{golden-gate,tahoe,sequoia,sonoma}-vanilla` — a vanilla macOS installation with helpful tweaks such as auto-login, but no additional software preinstalled
|
||||||
* `macos-{tahoe,sequoia,sonoma}-base` — based on `macos-{tahoe,sequoia,sonoma}-vanilla` image, it comes with `brew` and [other useful software](https://github.com/cirruslabs/macos-image-templates/blob/main/templates/base.pkr.hcl) pre-installed, but without Xcode
|
* `macos-{tahoe,sequoia,sonoma}-base` — based on `macos-{tahoe,sequoia,sonoma}-vanilla` image, it comes with `brew` and [other useful software](https://github.com/cirruslabs/macos-image-templates/blob/main/templates/base.pkr.hcl) pre-installed, but without Xcode
|
||||||
* `macos-{tahoe,sequoia,sonoma}-xcode:N` — based on `macos-{tahoe,sequoia,sonoma}-base` image and has `Xcode N` with [`Flutter`](https://flutter.dev/) pre-installed
|
* `macos-{tahoe,sequoia,sonoma}-xcode:N` — based on `macos-{tahoe,sequoia,sonoma}-base` image and has `Xcode N` with [`Flutter`](https://flutter.dev/) pre-installed
|
||||||
* `macos-runner:{tahoe,sequoia,sonoma}` — a variant of `xcode:N` with several versions of `Xcode` pre-installed and [`xcodes` tool](https://github.com/XcodesOrg/xcodes) to switch between them.
|
* `macos-runner:{tahoe,sequoia,sonoma}` — a variant of `xcode:N` with several versions of `Xcode` pre-installed and [`xcodes` tool](https://github.com/XcodesOrg/xcodes) to switch between them.
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,10 @@ source ~/.zprofile
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
update_tcc_database() {
|
update_tcc_database() {
|
||||||
sudo sqlite3 "$1" <<-'EOF'
|
local tart_guest_agent_path
|
||||||
|
tart_guest_agent_path="$(realpath /opt/homebrew/bin/tart-guest-agent)"
|
||||||
|
|
||||||
|
sudo sqlite3 "$1" <<-EOF
|
||||||
INSERT OR REPLACE
|
INSERT OR REPLACE
|
||||||
INTO access (
|
INTO access (
|
||||||
service,
|
service,
|
||||||
|
|
@ -36,7 +39,17 @@ update_tcc_database() {
|
||||||
('kTCCServiceScreenCapture', 1, '/usr/bin/osascript', 2, 0, 1, NULL, 'UNUSED'),
|
('kTCCServiceScreenCapture', 1, '/usr/bin/osascript', 2, 0, 1, NULL, 'UNUSED'),
|
||||||
('kTCCServicePostEvent', 1, '/usr/bin/osascript', 2, 0, 1, NULL, 'UNUSED'),
|
('kTCCServicePostEvent', 1, '/usr/bin/osascript', 2, 0, 1, NULL, 'UNUSED'),
|
||||||
('kTCCServiceAppleEvents', 1, '/usr/bin/osascript', 2, 0, 1, 0, 'com.apple.systemevents'),
|
('kTCCServiceAppleEvents', 1, '/usr/bin/osascript', 2, 0, 1, 0, 'com.apple.systemevents'),
|
||||||
('kTCCServiceAppleEvents', 1, '/usr/bin/osascript', 2, 0, 1, 0, 'com.apple.Safari');
|
('kTCCServiceAppleEvents', 1, '/usr/bin/osascript', 2, 0, 1, 0, 'com.apple.Safari'),
|
||||||
|
-- Direct Python invocation
|
||||||
|
('kTCCServiceAccessibility', 0, 'org.python.python', 2, 0, 1, NULL, 'UNUSED'),
|
||||||
|
('kTCCServiceScreenCapture', 0, 'org.python.python', 2, 0, 1, NULL, 'UNUSED'),
|
||||||
|
('kTCCServiceMicrophone', 0, 'org.python.python', 2, 0, 1, NULL, 'UNUSED'),
|
||||||
|
('kTCCServicePostEvent', 0, 'org.python.python', 2, 0, 1, NULL, 'UNUSED'),
|
||||||
|
-- Commands invoked through the Tart Guest Agent
|
||||||
|
('kTCCServiceAccessibility', 1, '${tart_guest_agent_path}', 2, 0, 1, NULL, 'UNUSED'),
|
||||||
|
('kTCCServiceScreenCapture', 1, '${tart_guest_agent_path}', 2, 0, 1, NULL, 'UNUSED'),
|
||||||
|
('kTCCServiceMicrophone', 1, '${tart_guest_agent_path}', 2, 0, 1, NULL, 'UNUSED'),
|
||||||
|
('kTCCServicePostEvent', 1, '${tart_guest_agent_path}', 2, 0, 1, NULL, 'UNUSED');
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ build {
|
||||||
"brew --version",
|
"brew --version",
|
||||||
"brew update",
|
"brew update",
|
||||||
"brew install wget unzip zip ca-certificates cmake gcc git-lfs jq yq gh gitlab-runner",
|
"brew install wget unzip zip ca-certificates cmake gcc git-lfs jq yq gh gitlab-runner",
|
||||||
"brew install buildkite/buildkite/buildkite-agent",
|
"brew install buildkite/buildkite/buildkite-agent@3",
|
||||||
"brew install equinix-labs/otel-cli/otel-cli",
|
"brew install equinix-labs/otel-cli/otel-cli",
|
||||||
"brew install curl || true", // doesn't work on Monterey
|
"brew install curl || true", // doesn't work on Monterey
|
||||||
"brew install --cask git-credential-manager",
|
"brew install --cask git-credential-manager",
|
||||||
|
|
@ -121,8 +121,12 @@ build {
|
||||||
"echo 'export PATH=\"/opt/homebrew/opt/node@24/bin:$PATH\"' >> ~/.zprofile",
|
"echo 'export PATH=\"/opt/homebrew/opt/node@24/bin:$PATH\"' >> ~/.zprofile",
|
||||||
"source ~/.zprofile",
|
"source ~/.zprofile",
|
||||||
"node --version",
|
"node --version",
|
||||||
"npm install --global yarn",
|
"npm install --global yarn pnpm",
|
||||||
|
"echo 'export PNPM_HOME=\"$HOME/Library/pnpm\"' >> ~/.zprofile",
|
||||||
|
"echo 'export PATH=\"$PNPM_HOME:$PATH\"' >> ~/.zprofile",
|
||||||
|
"source ~/.zprofile",
|
||||||
"yarn --version",
|
"yarn --version",
|
||||||
|
"pnpm --version",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
provisioner "shell" {
|
provisioner "shell" {
|
||||||
|
|
@ -164,7 +168,7 @@ build {
|
||||||
inline = [
|
inline = [
|
||||||
# Install Tart Guest Agent
|
# Install Tart Guest Agent
|
||||||
"source ~/.zprofile",
|
"source ~/.zprofile",
|
||||||
"brew install cirruslabs/cli/tart-guest-agent",
|
"brew install openai/tools/tart-guest-agent",
|
||||||
|
|
||||||
# Install daemon variant of the Tart Guest Agent
|
# Install daemon variant of the Tart Guest Agent
|
||||||
"sudo mv ~/tart-guest-daemon.plist /Library/LaunchDaemons/org.cirruslabs.tart-guest-daemon.plist",
|
"sudo mv ~/tart-guest-daemon.plist /Library/LaunchDaemons/org.cirruslabs.tart-guest-daemon.plist",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
packer {
|
||||||
|
required_plugins {
|
||||||
|
tart = {
|
||||||
|
version = ">= 1.16.0"
|
||||||
|
source = "github.com/cirruslabs/tart"
|
||||||
|
}
|
||||||
|
ansible = {
|
||||||
|
version = "~> 1"
|
||||||
|
source = "github.com/hashicorp/ansible"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
source "tart-cli" "tart" {
|
||||||
|
from_ipsw = "https://updates.cdn-apple.com/2026SummerSeed/fullrestores/140-55718/5809AFC6-1923-4590-AAFC-904A0283E659/UniversalMac_27.0_26A5388g_Restore.ipsw"
|
||||||
|
vm_name = "golden-gate-vanilla"
|
||||||
|
cpu_count = 4
|
||||||
|
memory_gb = 8
|
||||||
|
disk_size_gb = 50
|
||||||
|
disk_format = "asif"
|
||||||
|
ssh_password = "admin"
|
||||||
|
ssh_username = "admin"
|
||||||
|
ssh_timeout = "180s"
|
||||||
|
// Requires Tart 2.33.0+ and macOS 27+ on both the host and guest VM
|
||||||
|
run_extra_args = [
|
||||||
|
"--provisioning-opts=${join(",", [
|
||||||
|
"fullName=Managed via Tart",
|
||||||
|
"username=admin",
|
||||||
|
"password=admin",
|
||||||
|
"logsInAutomatically=true",
|
||||||
|
"enablesRemoteLogin=true",
|
||||||
|
])}",
|
||||||
|
]
|
||||||
|
boot_command = [
|
||||||
|
# Wait for first-boot provisioning to finish automatic login
|
||||||
|
"<wait120s>",
|
||||||
|
# Enable Keyboard navigation
|
||||||
|
# This is so that we can navigate the System Settings app using the keyboard
|
||||||
|
"<wait10s><leftAltOn><spacebar><leftAltOff>Terminal<wait10s><enter>",
|
||||||
|
"<wait10s><wait10s>defaults write NSGlobalDomain AppleKeyboardUIMode -int 3<enter>",
|
||||||
|
# Disable Gatekeeper (1/2)
|
||||||
|
"<wait10s>sudo spctl --global-disable<enter>",
|
||||||
|
"<wait10s>admin<enter>",
|
||||||
|
# Disable Gatekeeper (2/2)
|
||||||
|
# On Tahoe opening System Settings through Spotlight is not very reliable, sometimes opens System information
|
||||||
|
"<wait10s>open '/System/Applications/System Settings.app'<enter>",
|
||||||
|
# Wait for System Settings to fully open before navigating with the keyboard
|
||||||
|
"<wait120s>",
|
||||||
|
"<wait10s><leftCtrlOn><f2><leftCtrlOff><right><right><right><down>Privacy & Security<enter>",
|
||||||
|
"<wait10s><leftShiftOn><tab><tab><tab><tab><tab><tab><leftShiftOff>",
|
||||||
|
"<wait10s><down><wait1s><down><wait1s><enter>",
|
||||||
|
"<wait10s>admin<enter>",
|
||||||
|
"<wait10s><leftShiftOn><tab><leftShiftOff><wait1s><spacebar>",
|
||||||
|
# Quit System Settings
|
||||||
|
"<wait10s><leftAltOn>q<leftAltOff>",
|
||||||
|
]
|
||||||
|
|
||||||
|
// A (hopefully) temporary workaround for Virtualization.Framework's
|
||||||
|
// installation process not fully finishing in a timely manner
|
||||||
|
create_grace_time = "30s"
|
||||||
|
|
||||||
|
// Keep the recovery partition, otherwise it's not possible to "softwareupdate"
|
||||||
|
recovery_partition = "keep"
|
||||||
|
}
|
||||||
|
|
||||||
|
build {
|
||||||
|
sources = ["source.tart-cli.tart"]
|
||||||
|
|
||||||
|
provisioner "shell" {
|
||||||
|
inline = [
|
||||||
|
// Enable passwordless sudo
|
||||||
|
"echo admin | sudo -S sh -c \"mkdir -p /etc/sudoers.d/; echo 'admin ALL=(ALL) NOPASSWD: ALL' | EDITOR=tee visudo /etc/sudoers.d/admin-nopasswd\"",
|
||||||
|
// Enable Screen Sharing for "tart run --vnc"
|
||||||
|
"sudo launchctl enable system/com.apple.screensharing",
|
||||||
|
// Use the same timezone as the previous Setup Assistant flow
|
||||||
|
"sudo systemsetup -settimezone GMT 2>/dev/null",
|
||||||
|
// Disable screensaver at login screen
|
||||||
|
"sudo defaults write /Library/Preferences/com.apple.screensaver loginWindowIdleTime 0",
|
||||||
|
// Disable screensaver for admin user
|
||||||
|
"defaults -currentHost write com.apple.screensaver idleTime 0",
|
||||||
|
// Prevent the VM from sleeping
|
||||||
|
"sudo systemsetup -setsleep Off 2>/dev/null",
|
||||||
|
// Launch Safari to populate the defaults
|
||||||
|
"/Applications/Safari.app/Contents/MacOS/Safari &",
|
||||||
|
"SAFARI_PID=$!",
|
||||||
|
"disown",
|
||||||
|
"sleep 30",
|
||||||
|
"kill -9 $SAFARI_PID",
|
||||||
|
// Enable Safari's remote automation
|
||||||
|
"sudo safaridriver --enable",
|
||||||
|
// Disable screen lock
|
||||||
|
//
|
||||||
|
// Note that this only works if the user is logged-in,
|
||||||
|
// i.e. not on login screen.
|
||||||
|
"sysadminctl -screenLock off -password admin",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
provisioner "shell" {
|
||||||
|
inline = [
|
||||||
|
# Ensure that Gatekeeper is disabled
|
||||||
|
"spctl --status | grep -q 'assessments disabled'",
|
||||||
|
# Ensure that FileVault remains disabled by default
|
||||||
|
"sudo fdesetup status | grep -q 'FileVault is Off'",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,7 @@ packer {
|
||||||
}
|
}
|
||||||
|
|
||||||
source "tart-cli" "tart" {
|
source "tart-cli" "tart" {
|
||||||
from_ipsw = "https://updates.cdn-apple.com/2026SpringFCS/fullrestores/122-58869/DFB1CEEF-5619-4591-9924-E20DB2C8FED0/UniversalMac_26.5_25F71_Restore.ipsw"
|
from_ipsw = "https://updates.cdn-apple.com/2026SummerFCS/fullrestores/140-83079/25315EF6-AEAB-4588-9774-A3723774C47F/UniversalMac_26.6.1_25G76_Restore.ipsw"
|
||||||
vm_name = "tahoe-vanilla"
|
vm_name = "tahoe-vanilla"
|
||||||
cpu_count = 4
|
cpu_count = 4
|
||||||
memory_gb = 8
|
memory_gb = 8
|
||||||
|
|
|
||||||
|
|
@ -235,8 +235,6 @@ build {
|
||||||
"git clone --depth 1 https://github.com/tuist/homebrew-tuist.git \"$(brew --repository)/Library/Taps/tuist/homebrew-tuist\"",
|
"git clone --depth 1 https://github.com/tuist/homebrew-tuist.git \"$(brew --repository)/Library/Taps/tuist/homebrew-tuist\"",
|
||||||
"rm -rf \"$(brew --repository)/Library/Taps/tuist/homebrew-tuist/Casks\"",
|
"rm -rf \"$(brew --repository)/Library/Taps/tuist/homebrew-tuist/Casks\"",
|
||||||
"tuist_version=$(ruby -ne 'if $_ =~ %r{/download/([^/]+)/}; puts $1; exit; end' \"$(brew --repository)/Library/Taps/tuist/homebrew-tuist/Aliases/tuist\") && brew trust --formula \"tuist/tuist/tuist@$tuist_version\" && brew install --formula \"tuist/tuist/tuist@$tuist_version\"",
|
"tuist_version=$(ruby -ne 'if $_ =~ %r{/download/([^/]+)/}; puts $1; exit; end' \"$(brew --repository)/Library/Taps/tuist/homebrew-tuist/Aliases/tuist\") && brew trust --formula \"tuist/tuist/tuist@$tuist_version\" && brew install --formula \"tuist/tuist/tuist@$tuist_version\"",
|
||||||
"rbenv install 3.3.10",
|
|
||||||
"rbenv global 3.3.10", # fastlane conflicts with 3.4.0+ https://github.com/fastlane/fastlane/issues/29527
|
|
||||||
"gem update",
|
"gem update",
|
||||||
"gem install fastlane",
|
"gem install fastlane",
|
||||||
"gem install cocoapods",
|
"gem install cocoapods",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue