Compare commits

...
Author SHA1 Message Date
Nikolay Edigaryev a9f16e07e6 Provide a default when stdinpass variable is not set 2025-02-11 23:03:01 +01:00
Nikolay Edigaryev 998bbf8ca8 Parse available updates to avoid upgrading to the next macOS version (#208)
* Parse available updates to avoid upgrading to the next macOS version

* Do not override ANSIBLE_CONFIG with our ansible.cfg

Otherwise Packer + Ansible integration goes haywire.

Instead, only modify the required variables through ansible_env_vars.

* Support Monterey
2025-02-12 01:45:40 +04:00
Nikolay Edigaryev 5a55351c81 Use xargs fix for all vanilla images, not just Sequoia (#207) 2025-02-06 18:55:36 +04:00
Nikolay Edigaryev 64b1190f65 Only pass a single item to "softwareupdate --install" each time (#206) 2025-02-06 17:39:40 +04:00
Nikolay Edigaryev 4df29efc66 Run "softwareupdate" on vanilla images (#204)
* Run "softwareupdate" on vanilla images

* Install Command Line Tools for Xcode

* Run Ansible after password-less sudo is configured

* Don't use SFTP

* Fix Ansible playbook path

* No updates are available → No new software available

* stderr_lines → stderr

* Dynamically resolve MACOS_NUMBER
2025-02-01 01:23:11 +04:00
Fedor Korotkov b205e70322 macOS Sequoia 15.3 (#205) 2025-01-27 14:38:08 -05:00
Nikolay Edigaryev c18ef9c553 Use Slack workflows (#201)
* Use Slack workflows

* Use SLACK_WEBHOOK_URL
2025-01-14 23:47:30 +04:00
fedor cec270adb3 No software updates 2025-01-06 17:54:53 -05:00
fedor 6d14eaee8c Install recommended updates 2025-01-06 17:36:50 -05:00
Fedor Korotkov f1a9e22ed2 Fixed known host creation (#202)
`~/.ssh` should exist for `file` provisioner.
2025-01-06 14:35:10 -05:00
Fedor Korotkov 2545826772 Add github.com keys to ~/.ssh/known_hosts (#200)
* Add github.com keys to `~/.ssh/known_hosts`

* Static known hosts

* Fixed path
2025-01-06 09:54:14 -05:00
fedor 0b49ba6651 Xcode 16.2 2024-12-30 09:29:55 -05:00
jxlwqq e5474440fc Sequoia 15.2 (#199) 2024-12-28 05:31:37 -05:00
Nikolay Edigaryev 0c165a93d2 Compatibility with GitHub Actions Runner Images for /usr/local/bin (#198) 2024-12-11 19:56:48 +04:00
fedor d3ad77c873 Xcode 16.2 RC 2024-12-05 16:06:21 -05:00
Kevin M. Cox 40128d40e2 Update vanilla-sequoia.pkr.hcl (#196)
It looks like the tab sequence for the Time Zone screen changed in one of the releases after 15.0.

I've testing this key sequence manually and via a packer build and it works with macOS 15.1.1.
2024-12-05 01:27:54 +04:00
Fedor Korotkov 7920f0cda2 Include Xcode 15.1 in Somoma runner (#197)
We unintentionally pushed Xcode 16.1 variant for `sonoma-xcode` image. We plan to only include new versions of Xcode with Sequoia images.

Instead for removing the 16.1 artifact. Let's include it in the runner image for consistency.
2024-12-04 16:08:58 -05:00
Fedor Korotkov b3b4dafc83 Update cirrus.release.yml 2024-12-04 11:36:28 -05:00
fedor ae70c6052d Ignore curl failure 2024-11-26 10:18:40 -05:00
fedor 1ea5f77e35 Build Monterey 2024-11-26 09:02:31 -05:00
fedor 8392fd1b30 Xcode 16.2 Beta 3 2024-11-20 16:04:50 -05:00
Fedor Korotkov fdff7d8daf Sequoia 15.1.1 2024-11-19 22:15:26 -05:00
Michal Moczulski 6a01707630 Update Android dependencies (#195)
* Use latest stable versions of Android dependencies

* Fix link to Android command line tools
2024-11-13 09:05:09 -05:00
fedor 49718082b2 Updated disk sizes 2024-11-13 07:09:41 -05:00
Nikolay Edigaryev 5b17f4e264 Wait 30 minutes instead of 15 (#194)
Just to be sure.
2024-11-12 21:29:32 +04:00
Nikolay Edigaryev 14fb85f5b3 Disable apsd daemon and wait before shutting down (#193) 2024-11-12 21:26:35 +04:00
fedor c8a1e808b6 Xcode 16.2 Beta 2 2024-11-06 10:50:07 -05:00
Fedor Korotkov 8c1f0c213f Release Sequoia IPSW
Fixes #192
2024-11-04 13:43:48 -05:00
Fedor Korotkov 9875d24c4b Added 15.1 and 15.0.1 2024-11-03 22:37:22 -05:00
fedor 8425f62a71 Update one runner image at a time
So while the second one is building runners can download the first one.
2024-11-02 09:49:05 -04:00
fedor 7ebaf88c48 Include {15.1,15.0.1} into runner 2024-11-01 11:51:50 -04:00
fedor 639b46cb2f Update sonoma-xcode:{15.1,15.0.1} 2024-11-01 11:26:11 -04:00
fedor 77cc104d6d Updated release cadence to highlight supported Xcode version. 2024-10-31 15:55:48 -04:00
fedor 159d4c1c36 Xcode 16.1 2024-10-30 10:19:34 -07:00
fedor 2a0a476e3b Sequoia 15.1 2024-10-28 09:19:43 -07:00
fedor 74040f6870 Sort Xcodes to always install the freshest first
Seems it's leading to things like:

> Unable to connect to simulator.
2024-10-27 08:42:58 -07:00
fedor 9f061dacb4 Sort Xcodes to always install the freshest first
Seems it's leading to things like:

> Unable to connect to simulator.
2024-10-27 08:38:03 -07:00
Fedor Korotkov f8fd129df6 Xcode 16.2 Beta 1 2024-10-24 09:14:43 -07:00
17 changed files with 376 additions and 86 deletions
-2
View File
@@ -1,8 +1,6 @@
task:
name: "Release Xcode $CIRRUS_TAG ($MACOS_VERSION)"
matrix:
- env:
MACOS_VERSION: sonoma
- env:
MACOS_VERSION: sequoia
<<: *defaults
+7 -4
View File
@@ -1,17 +1,20 @@
task:
name: "Update Runner Image ($MACOS_VERSION)"
execution_lock: runner-image-update
env:
matrix:
- MACOS_VERSION: sonoma
XCODE_VERSIONS: 16,15.4,15.3,15.2
XCODE_VERSIONS: "16.1,16,15.4,15.3,15.2,15.1,\"15.0.1\""
DISK_SIZE: 375
- MACOS_VERSION: sequoia
XCODE_VERSIONS: "16,\"16.1-rc\",15.4"
XCODE_VERSIONS: "16.2,16.1,16,15.4"
DISK_SIZE: 320
<<: *defaults
pull_base_script:
- tart pull ghcr.io/cirruslabs/macos-$MACOS_VERSION-base:latest
init_xcode_script: packer init templates/xcode.pkr.hcl
build_xcode_script: |
packer build -var tag=runner -var disk_size=300 \
packer build -var tag=runner -var disk_size=$DISK_SIZE \
-var disk_free_mb=100000 \
-var macos_version="$MACOS_VERSION" \
-var xcode_version="[$XCODE_VERSIONS]" \
@@ -21,4 +24,4 @@ task:
tart push "$MACOS_VERSION-xcode:runner" ghcr.io/cirruslabs/macos-runner:$MACOS_VERSION
always:
cleanup_script:
- tart delete "$MACOS_VERSION-xcode:runner"
- tart delete "$MACOS_VERSION-xcode:runner"
+22 -36
View File
@@ -1,44 +1,30 @@
task:
name: "Update Vanilla Sonoma Image"
only_if: $CIRRUS_BRANCH == $CIRRUS_DEFAULT_BRANCH && changesInclude("templates/vanilla-sonoma.pkr.hcl")
<<: *defaults
build_script:
- packer init templates/vanilla-sonoma.pkr.hcl
- packer build templates/vanilla-sonoma.pkr.hcl
disable_sip_script:
- packer build -var vm_name=sonoma-vanilla templates/disable-sip.pkr.hcl
push_script:
- tart push sonoma-vanilla ghcr.io/cirruslabs/macos-sonoma-vanilla:latest ghcr.io/cirruslabs/macos-sonoma-vanilla:14.6
always:
cleanup_script:
- tart delete sonoma-vanilla
env:
RESOLVE_VM_BASE_NAME: "ghcr.io/cirruslabs/macos-${MACOS_VERSION}-vanilla:latest"
RESOLVE_VM_NAME: "resolve-macos-number-task-id-${CIRRUS_TASK_ID}"
RESOLVE_FILE: "${RESOLVE_VM_NAME}.txt"
task:
name: "Update Vanilla Sequoia Image"
only_if: $CIRRUS_BRANCH == $CIRRUS_DEFAULT_BRANCH && changesInclude("templates/vanilla-sequoia.pkr.hcl")
name: "Update Vanilla Image ($MACOS_VERSION)"
env:
matrix:
- MACOS_VERSION: sequoia
- MACOS_VERSION: sonoma
- MACOS_VERSION: ventura
- MACOS_VERSION: monterey
only_if: $CIRRUS_BRANCH == $CIRRUS_DEFAULT_BRANCH && changesInclude("templates/vanilla-$MACOS_VERSION.pkr.hcl")
<<: *defaults
build_script:
- packer init templates/vanilla-sequoia.pkr.hcl
- packer build templates/vanilla-sequoia.pkr.hcl
- packer init templates/vanilla-$MACOS_VERSION.pkr.hcl
- packer build templates/vanilla-$MACOS_VERSION.pkr.hcl
disable_sip_script:
- packer build -var vm_name=sequoia-vanilla templates/disable-sip.pkr.hcl
- packer build -var vm_name=$MACOS_VERSION-vanilla templates/disable-sip.pkr.hcl
resolve_macos_number_script:
- packer build -var vm_base_name=$RESOLVE_VM_BASE_NAME -var vm_name=$RESOLVE_VM_NAME -var resolve_file=$RESOLVE_FILE templates/resolve-macos-number.pkr.hcl
- echo "MACOS_NUMBER=$(cat $RESOLVE_FILE)" >> $CIRRUS_ENV
- rm $RESOLVE_FILE
- tart delete $RESOLVE_VM_NAME
push_script:
- tart push sequoia-vanilla ghcr.io/cirruslabs/macos-sequoia-vanilla:latest ghcr.io/cirruslabs/macos-sequoia-vanilla:15.0.1
- tart push $MACOS_VERSION-vanilla ghcr.io/cirruslabs/macos-$MACOS_VERSION-vanilla:latest ghcr.io/cirruslabs/macos-$MACOS_VERSION-vanilla:$MACOS_NUMBER
always:
cleanup_script:
- tart delete sequoia-vanilla
task:
name: "Update Vanilla Sequoia Beta Image"
only_if: $CIRRUS_BRANCH == $CIRRUS_DEFAULT_BRANCH && changesInclude("templates/vanilla-sequoia-beta.pkr.hcl")
<<: *defaults
build_script:
- packer init templates/vanilla-sequoia-beta.pkr.hcl
- packer build templates/vanilla-sequoia-beta.pkr.hcl
disable_sip_script:
- packer build -var vm_name=sequoia-vanilla templates/disable-sip.pkr.hcl
push_script:
- tart push sequoia-vanilla ghcr.io/cirruslabs/macos-sequoia-vanilla:15.1-rc ghcr.io/cirruslabs/macos-sequoia-vanilla:15.1
always:
cleanup_script:
- tart delete sequoia-vanilla
- tart delete $MACOS_VERSION-vanilla
+12 -2
View File
@@ -4,19 +4,29 @@ task:
env:
matrix:
- MACOS_VERSION: sequoia
XCODE_VERSION: 16.1-rc
XCODE_VERSION: 16.2
LATEST: true
- MACOS_VERSION: sequoia
XCODE_VERSION: 16.1
- MACOS_VERSION: sequoia
XCODE_VERSION: 16
- MACOS_VERSION: sequoia
XCODE_VERSION: 15.4
- MACOS_VERSION: sonoma
XCODE_VERSION: 16.1
LATEST: true
- MACOS_VERSION: sonoma
XCODE_VERSION: 16
LATEST: true
- MACOS_VERSION: sonoma
XCODE_VERSION: 15.4
- MACOS_VERSION: sonoma
XCODE_VERSION: 15.3
- MACOS_VERSION: sonoma
XCODE_VERSION: 15.2
- MACOS_VERSION: sonoma
XCODE_VERSION: 15.1
- MACOS_VERSION: sonoma
XCODE_VERSION: 15.0.1
<<: *defaults
pull_base_script:
- tart pull ghcr.io/cirruslabs/macos-$MACOS_VERSION-base:latest
+10 -6
View File
@@ -16,14 +16,18 @@ def on_build_failed(ctx):
if "Cron" not in ctx.payload.data.build.changeMessageTitle:
return
resp = http.post("https://slack.com/api/chat.postMessage", headers={
resp = http.post(env.get("SLACK_WEBHOOK_URL"), headers={
"Content-Type": "application/json",
"Authorization": "Bearer " + env.get("SLACK_TOKEN"),
}, json_body={
"channel": "#image-updates",
"text": "Build <https://cirrus-ci.com/build/{build_id}|{build_id} (\"{change_message_title}\")> failed on branch \"{branch_name}\" in repository \"{repository_name}\".".format(
build_id=ctx.payload.data.build.id, change_message_title=ctx.payload.data.build.changeMessageTitle,
branch_name=ctx.payload.data.build.branch, repository_name=ctx.payload.data.repository.name),
"text": "Build {build_id} (\"{change_message_title}\") failed on branch \"{branch_name}\" in repository \"{repository_name}\".".format(
build_id=ctx.payload.data.build.id,
change_message_title=ctx.payload.data.build.changeMessageTitle,
branch_name=ctx.payload.data.build.branch,
repository_name=ctx.payload.data.repository.name,
),
"url": "https://cirrus-ci.com/build/{build_id}".format(
build_id=ctx.payload.data.build.id,
),
})
if resp.status_code != 200:
+8 -6
View File
@@ -7,15 +7,17 @@ The following image variants are currently available:
* `macos-{sequoia,sonoma}-base` image has only `brew` pre-installed and the latest version of `macOS` available
* `macos-{sequoia,sonoma}-xcode:N` image is based on `macos-{sequoia,sonoma}-base` image and has `Xcode N` with [`Flutter`](https://flutter.dev/) pre-installed
* `macos-runner:sonoma` image is a variant of `xcode:N` with 3 latest versions of `Xcode` pre-installed and [`xcodes` tool](https://github.com/XcodesOrg/xcodes) to switch between them.
* `macos-runner:{sequoia,sonoma}` image is a variant of `xcode:N` with several versions of `Xcode` pre-installed and [`xcodes` tool](https://github.com/XcodesOrg/xcodes) to switch between them.
See a full list of VMs available [here](https://github.com/orgs/cirruslabs/packages?tab=packages&q=macos-).
## Release Cadence
Once a new version of Xcode is released, we will initiate a GitHub release which will automatically build and push
a new version of the `macos-{sequoia,sonoma}-xcode:N` image as well as `macos-runner:sonoma`. This generally happens within 24 hours
of a release. Please watch this repository releases to get notified about new images.
a new version of the `macos-sequoia-xcode:N`. This generally happens within 24 hours of a release.
Please watch this repository releases to get notified about new images.
For an Xcode release which is non beta and not an RC `ghcr.io/cirruslabs/macos-runner:sequoia` image will also be updated.
## Update Cadence
@@ -23,8 +25,8 @@ Some of the images are regularly getting rebuild in order to update the pre-inst
monthly on the first Saturday of the month:
* `ghcr.io/cirruslabs/macos-{sequoia,sonoma}-base`
* `ghcr.io/cirruslabs/macos-sonoma-xcode:{16-beta,latest,15.4,15.3,15.2}`
* `ghcr.io/cirruslabs/macos-sequoia-xcode:{16-beta}`
* `ghcr.io/cirruslabs/macos-runner:sonoma` which is a superset of `ghcr.io/cirruslabs/macos-sonoma-xcode:{latest,16.1,16,15.4,15.3,15.2,15.1,15.0.1}`
* `ghcr.io/cirruslabs/macos-runner:sequoia` which is a superset of `ghcr.io/cirruslabs/macos-sequoia-xcode:{latest,16.2,16.1,16,15.4}`
Note that `ghcr.io/cirruslabs/macos-runner:sonoma` is updated every Sunday and this image is [optimised for startup](https://cirrus-runners.app/blog/2024/04/11/optimizing-startup-time-of-cirrus-runners/)
Note that `ghcr.io/cirruslabs/macos-runner:{sequoia,sonoma}` are updated every Sunday and these images are [optimised for startup](https://cirrus-runners.app/blog/2024/04/11/optimizing-startup-time-of-cirrus-runners/)
on Cirrus Runners and Cirrus CI services.
+5
View File
@@ -0,0 +1,5 @@
- hosts: default
roles:
- system-updater
vars:
ansible_password: admin
@@ -0,0 +1,37 @@
- name: Perform first "softwareupdate" invocation
include_tasks: softwareupdate.yml
# Needed after a major macOS update, otherwise things like
# Command Line Tools won't be updated
- name: Perform second "softwareupdate" invocation
include_tasks: softwareupdate.yml
# This one looks weird, but unfortunately there's no other way around, because Homebrew
# is not designed to run as root (see https://gist.github.com/irazasyed/7732946
# for more details).
- name: fix up /usr/local permissions for Homebrew
file:
path: /usr/local/share/man
state: directory
owner: "{{ ansible_user_id }}"
recurse: yes
become: yes
- name: "ensure that there are no more software updates available: check for available updates"
command:
cmd: "softwareupdate --all --list"
register: software_updates_result
- name: "ensure that there are no more software updates available: parse available updates"
set_fact:
software_updates: "{{ software_updates_result.stdout | regex_findall('\\* Label: (.*)\\n\\tTitle: (.*), Version: (.*), Size: (.*), Recommended: (.*), Action: (.*), .*') | map('zip', ['label', 'title', 'version', 'size', 'recommended', 'action']) | map('map', 'reverse') | map('community.general.dict') }}"
- name: "ensure that there are no more software updates available: print available updates"
debug:
var: software_updates
- name: "ensure that there are no more software updates available: fail if some updates were not installed"
fail:
msg: "Found unapplied update: {{ item.label }}"
loop: "{{ software_updates }}"
when: "not item.label.startswith('macOS') or item.version.split('.')[0] == ansible_facts['distribution_version'].split('.')[0]"
@@ -0,0 +1,43 @@
- name: check for available updates
command:
cmd: "softwareupdate --all --list"
register: software_updates_result
- name: parse available updates
set_fact:
software_updates: "{{ software_updates_result.stdout | regex_findall('\\* Label: (.*)\\n\\tTitle: (.*), Version: (.*), Size: (.*), Recommended: (.*), Action: (.*), .*') | map('zip', ['label', 'title', 'version', 'size', 'recommended', 'action']) | map('map', 'reverse') | map('community.general.dict') }}"
- name: print available updates
debug:
var: software_updates
# It seems that we must always pass "--restart" command-line argument to "softwareupdate",
# otherwise on the OS update the "softwareupdate" will be stuck at "Downloaded: macOS [...]"
- name: install available update
command:
cmd: "softwareupdate --install --agree-to-license --force --restart --user admin --stdinpass {{ stdinpass | default("") }} '{{ item.label }}'"
stdin: "{{ ansible_password }}"
register: update_result
# Work around the following:
# > Data could not be sent to remote host [...].
# > Make sure this host can be reached over ssh:
# > ssh: connect to host [...] port 22: Connection refused.
ignore_unreachable: yes
# Ignore SIGTERM/SIGKILL sent "softwareupdate" process
# when the system reboots due to --restart
failed_when: update_result.rc not in [0, 9, -9, 15, -15]
become: yes
loop: "{{ software_updates }}"
when: "not item.label.startswith('macOS') or item.version.split('.')[0] == ansible_facts['distribution_version'].split('.')[0]"
# Wait for the connection since the previous command could restart the host
- name: wait for connection
wait_for_connection:
# We need to wait long enough for the "softwareupdate" to initiate the reboot,
# otherwise it's possible that we'll interrupt the process by running
# the commands below on a non-restarted system.
delay: 60
timeout: 1800
when:
- update_result is defined
- not update_result.skipped
+3
View File
@@ -0,0 +1,3 @@
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
+22 -2
View File
@@ -56,16 +56,34 @@ build {
"echo 'eval \"$(/opt/homebrew/bin/brew shellenv)\"' >> ~/.zprofile",
"echo \"export HOMEBREW_NO_AUTO_UPDATE=1\" >> ~/.zprofile",
"echo \"export HOMEBREW_NO_INSTALL_CLEANUP=1\" >> ~/.zprofile",
]
}
provisioner "shell" {
inline = [
"source ~/.zprofile",
"brew --version",
"brew update",
"brew install curl 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 curl || true", // doesn't work on Monterey
"brew install --cask git-credential-manager",
"git lfs install",
"sudo softwareupdate --install-rosetta --agree-to-license"
]
}
// Add GitHub to known hosts
// Similar to https://github.com/actions/runner-images/blob/main/images/macos/scripts/build/configure-ssh.sh
provisioner "shell" {
inline = [
"mkdir -p ~/.ssh"
]
}
provisioner "file" {
source = "data/github_known_hosts"
destination = "~/.ssh/known_hosts"
}
// Install the GitHub Actions runner
provisioner "shell" {
script = "scripts/install-actions-runner.sh"
@@ -126,7 +144,9 @@ build {
provisioner "shell" {
inline = [
"source ~/.zprofile",
"test -d /Users/runner"
"test -d /Users/runner",
"test -f ~/.ssh/known_hosts",
"brew doctor"
]
}
}
+46
View File
@@ -0,0 +1,46 @@
packer {
required_plugins {
tart = {
version = ">= 1.12.0"
source = "github.com/cirruslabs/tart"
}
}
}
variable "vm_base_name" {
type = string
}
variable "vm_name" {
type = string
}
variable "resolve_file" {
type = string
}
source "tart-cli" "tart" {
vm_base_name = "${var.vm_base_name}"
vm_name = "${var.vm_name}"
cpu_count = 4
memory_gb = 8
ssh_password = "admin"
ssh_username = "admin"
ssh_timeout = "120s"
}
build {
sources = ["source.tart-cli.tart"]
provisioner "shell" {
inline = [
"sw_vers --productVersion > /tmp/sw-vers-product-version.txt",
]
}
provisioner "file" {
source = "/tmp/sw-vers-product-version.txt"
destination = "${var.resolve_file}"
direction = "download"
}
}
@@ -1,21 +1,26 @@
packer {
required_plugins {
tart = {
version = ">= 1.12.0"
version = ">= 1.2.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/2024FallFCS/fullrestores/062-24344/4BBFA6BD-C58F-4C82-B793-6ECA98024379/UniversalMac_15.1_24B82_Restore.ipsw"
vm_name = "sequoia-vanilla"
# You can find macOS IPSW URLs on various websites like https://ipsw.me/
from_ipsw = "https://updates.cdn-apple.com/2022FallFCS/fullrestores/012-66032/8D8D90C6-A876-4FFF-BBF4-D158939B3841/UniversalMac_12.6.1_21G217_Restore.ipsw"
vm_name = "monterey-vanilla"
cpu_count = 4
memory_gb = 8
disk_size_gb = 40
ssh_password = "admin"
ssh_username = "admin"
ssh_timeout = "300s"
ssh_timeout = "120s"
boot_command = [
# hello, hola, bonjour, etc.
"<wait60s><spacebar>",
@@ -48,41 +53,39 @@ source "tart-cli" "tart" {
# Create a Computer Account
"<wait10s>admin<tab><tab>admin<tab>admin<tab><tab><tab><spacebar>",
# Enable Location Services
"<wait120s><leftShiftOn><tab><leftShiftOff><spacebar>",
"<wait10s><leftShiftOn><tab><leftShiftOff><spacebar>",
# Are you sure you don't want to use Location Services?
"<wait10s><tab><spacebar>",
# Select Your Time Zone
"<wait10s><tab>UTC<enter><leftShiftOn><tab><leftShiftOff><spacebar>",
# Analytics
"<wait10s><leftShiftOn><tab><leftShiftOff><spacebar>",
"<wait10s><tab><spacebar><leftShiftOn><tab><leftShiftOff><spacebar>",
# Screen Time
"<wait10s><tab><spacebar>",
# Siri
"<wait10s><tab><spacebar><leftShiftOn><tab><leftShiftOff><spacebar>",
# Choose Your Look
"<wait10s><leftShiftOn><tab><leftShiftOff><spacebar>",
# Welcome to Mac
"<wait10s><spacebar>",
# Enable Keyboard navigation
# This is so that we can navigate the System Settings app using the keyboard
"<wait10s><leftAltOn><spacebar><leftAltOff>Terminal<enter>",
"<wait10s>defaults write NSGlobalDomain AppleKeyboardUIMode -int 3<enter>",
"<wait10s><leftAltOn>q<leftAltOff>",
# Now that the installation is done, open "System Settings"
"<wait10s><leftAltOn><spacebar><leftAltOff>System Settings<enter>",
# Enable Voice Over
"<wait10s><leftAltOn><f5><leftAltOff><wait5s>v",
# Now that the installation is done, open "System Preferences"
"<wait10s><leftAltOn><spacebar><leftAltOff>System Preferences<enter>",
# Navigate to "Sharing"
"<wait10s><leftAltOn>f<leftAltOff>sharing<enter>",
# Navigate to "Screen Sharing" and enable it
"<wait10s><tab><tab><tab><tab><tab><spacebar>",
# Navigate to "Remote Login" and enable it
"<wait10s><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><spacebar>",
# Quit System Settings
"<wait10s><leftAltOn>q<leftAltOff>",
"<wait10s>sharing<enter>",
# Enable Screen Sharing
"<wait10s><tab><tab><tab><tab><spacebar>",
# Enable Remote Login
"<wait10s><down><down><down><down><spacebar><tab><tab><spacebar>",
# Disable Voice Over
"<leftAltOn><f5><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 {
@@ -91,7 +94,7 @@ build {
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\"",
"echo admin | sudo -S sh -c \"echo 'admin ALL=(ALL) NOPASSWD: ALL' | EDITOR=tee visudo /etc/sudoers.d/admin-nopasswd\"",
// Enable auto-login
//
// See https://github.com/xfreebird/kcpassword for details.
@@ -102,7 +105,9 @@ build {
// Disable screensaver for admin user
"defaults -currentHost write com.apple.screensaver idleTime 0",
// Prevent the VM from sleeping
"sudo systemsetup -setdisplaysleep Off 2>/dev/null",
"sudo systemsetup -setsleep Off 2>/dev/null",
"sudo systemsetup -setcomputersleep Off 2>/dev/null",
// Launch Safari to populate the defaults
"/Applications/Safari.app/Contents/MacOS/Safari &",
"SAFARI_PID=$!",
@@ -118,4 +123,25 @@ build {
"sysadminctl -screenLock off -password admin",
]
}
provisioner "shell" {
inline = [
# Install command-line tools
"touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress",
"softwareupdate --list | sed -n 's/.*Label: \\(Command Line Tools for Xcode-.*\\)/\\1/p' | xargs -I {} softwareupdate --install '{}'",
"rm /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress",
]
}
provisioner "ansible" {
playbook_file = "ansible/playbook-system-updater.yml"
extra_arguments = [
"--extra-vars", "stdinpass=admin",
]
ansible_env_vars = [
"ANSIBLE_TRANSPORT=paramiko",
"ANSIBLE_HOST_KEY_CHECKING=False",
]
use_proxy = false
}
}
+27 -2
View File
@@ -4,11 +4,15 @@ packer {
version = ">= 1.12.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/2024FallFCS/fullrestores/072-01423/566E5B4E-1100-4643-91B3-131247351844/UniversalMac_15.0.1_24A348_Restore.ipsw"
from_ipsw = "https://updates.cdn-apple.com/2025WinterFCS/fullrestores/072-08269/7CAAB9F7-E970-428D-8764-4CD7BCD105CD/UniversalMac_15.3_24D60_Restore.ipsw"
vm_name = "sequoia-vanilla"
cpu_count = 4
memory_gb = 8
@@ -52,7 +56,7 @@ source "tart-cli" "tart" {
# Are you sure you don't want to use Location Services?
"<wait10s><tab><spacebar>",
# Select Your Time Zone
"<wait10s><tab>UTC<enter><leftShiftOn><tab><leftShiftOff><spacebar>",
"<wait10s><tab><tab>UTC<enter><leftShiftOn><tab><tab><leftShiftOff><spacebar>",
# Analytics
"<wait10s><leftShiftOn><tab><leftShiftOff><spacebar>",
# Screen Time
@@ -83,6 +87,9 @@ source "tart-cli" "tart" {
// 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 {
@@ -118,4 +125,22 @@ build {
"sysadminctl -screenLock off -password admin",
]
}
provisioner "shell" {
inline = [
# Install command-line tools
"touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress",
"softwareupdate --list | sed -n 's/.*Label: \\(Command Line Tools for Xcode-.*\\)/\\1/p' | xargs -I {} softwareupdate --install '{}'",
"rm /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress",
]
}
provisioner "ansible" {
playbook_file = "ansible/playbook-system-updater.yml"
ansible_env_vars = [
"ANSIBLE_TRANSPORT=paramiko",
"ANSIBLE_HOST_KEY_CHECKING=False",
]
use_proxy = false
}
}
+25
View File
@@ -4,6 +4,10 @@ packer {
version = ">= 1.12.0"
source = "github.com/cirruslabs/tart"
}
ansible = {
version = "~> 1"
source = "github.com/hashicorp/ansible"
}
}
}
@@ -78,6 +82,9 @@ source "tart-cli" "tart" {
// 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 {
@@ -115,4 +122,22 @@ build {
"sysadminctl -screenLock off -password admin",
]
}
provisioner "shell" {
inline = [
# Install command-line tools
"touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress",
"softwareupdate --list | sed -n 's/.*Label: \\(Command Line Tools for Xcode-.*\\)/\\1/p' | xargs -I {} softwareupdate --install '{}'",
"rm /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress",
]
}
provisioner "ansible" {
playbook_file = "ansible/playbook-system-updater.yml"
ansible_env_vars = [
"ANSIBLE_TRANSPORT=paramiko",
"ANSIBLE_HOST_KEY_CHECKING=False",
]
use_proxy = false
}
}
+25
View File
@@ -4,6 +4,10 @@ packer {
version = ">= 1.12.0"
source = "github.com/cirruslabs/tart"
}
ansible = {
version = "~> 1"
source = "github.com/hashicorp/ansible"
}
}
}
@@ -86,6 +90,9 @@ source "tart-cli" "tart" {
// 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 {
@@ -124,4 +131,22 @@ build {
"defaults -currentHost write com.apple.screensaver idleTime 0"
]
}
provisioner "shell" {
inline = [
# Install command-line tools
"touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress",
"softwareupdate --list | sed -n 's/.*Label: \\(Command Line Tools for Xcode-.*\\)/\\1/p' | xargs -I {} softwareupdate --install '{}'",
"rm /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress",
]
}
provisioner "ansible" {
playbook_file = "ansible/playbook-system-updater.yml"
ansible_env_vars = [
"ANSIBLE_TRANSPORT=paramiko",
"ANSIBLE_HOST_KEY_CHECKING=False",
]
use_proxy = false
}
}
+35 -3
View File
@@ -37,7 +37,7 @@ variable "disk_free_mb" {
variable "android_sdk_tools_version" {
type = string
default = "11076708" # https://developer.android.com/studio/#command-tools
default = "11076708" # https://developer.android.com/studio#command-line-tools-only
}
source "tart-cli" "tart" {
@@ -55,7 +55,7 @@ source "tart-cli" "tart" {
locals {
xcode_install_provisioners = [
for version in var.xcode_version : {
for version in reverse(sort(var.xcode_version)) : {
type = "shell"
inline = [
"source ~/.zprofile",
@@ -112,7 +112,7 @@ build {
"rm android-sdk-tools.zip",
"mv $ANDROID_HOME/cmdline-tools/cmdline-tools $ANDROID_HOME/cmdline-tools/latest",
"yes | sdkmanager --licenses",
"yes | sdkmanager 'platform-tools' 'platforms;android-33' 'build-tools;34.0.0' 'ndk;25.2.9519653'"
"yes | sdkmanager 'platform-tools' 'platforms;android-35' 'build-tools;35.0.0' 'ndk;27.2.12479018'"
]
}
@@ -229,4 +229,36 @@ build {
"test -d /Users/runner"
]
}
# Disable apsd[1][2] daemon as it causes high CPU usage after boot
#
# [1]: https://iboysoft.com/wiki/apsd-mac.html
# [2]: https://discussions.apple.com/thread/4459153
provisioner "shell" {
inline = [
"sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.apsd.plist"
]
}
# Compatibility with GitHub Actions Runner Images, where
# /usr/local/bin belongs to the default user. Also see [2].
#
# [1]: https://github.com/actions/runner-images/blob/6bbddd20d76d61606bea5a0133c950cc44c370d3/images/macos/scripts/build/configure-machine.sh#L96
# [2]: https://github.com/actions/runner-images/discussions/7607
provisioner "shell" {
inline = [
"sudo chown admin /usr/local/bin"
]
}
# Wait for the "update_dyld_sim_shared_cache" process[1][2] to finish
# to avoid wasting CPU cycles after boot
#
# [1]: https://apple.stackexchange.com/questions/412101/update-dyld-sim-shared-cache-is-taking-up-a-lot-of-memory
# [2]: https://stackoverflow.com/a/68394101/9316533
provisioner "shell" {
inline = [
"sleep 1800"
]
}
}