Compare commits

..
32 Commits
Author SHA1 Message Date
Fedor Kororkov 2be4479694 Update release.yml (#352) 2026-06-08 16:30:42 -07:00
Fedor Korotkov 206d99a672 Migrate CI to GitHub Actions (#351) 2026-06-03 06:37:04 -07:00
Fedor Korotkov 0ad265b76d macOS and Xcode 26.5 (#349)
* macOS and Xcode 26.5

* Updated expected tahoe runtimes
2026-05-25 19:14:54 -04:00
Nikolay Edigaryev 154a7604f9 vanilla-sequoia.pkr.hcl: click "Select Your Country or Region" (#335) 2026-05-16 10:36:46 -04:00
Fedor Korotkov 5a2d4fd8cc Xcode 26.4.1 (#348) 2026-05-02 19:53:10 -04:00
Diogo Araújo 70cb4395fe feat: boot command changes to tahoe 26.4 (#344)
* feat: boot command changes to tahoe 26.4

* add first time password to enable screen sharing
2026-04-05 12:38:36 -04:00
Fedor Korotkov 7360b62106 Adjusted disk sizes for macOS Tahoe configurations in CI setup. 2026-04-05 12:35:16 -04:00
Fedor Korotkov e46673151d Xcode 26.5-beta (#345)
* Xcode 26.5-beta

* Fixed syntax error in Xcode versions list for Tahoe configuration.

* Updated Tahoe runtimes to include Xcode 26.5 beta versions

* Updated Tahoe runtimes to include Xcode 26.5 beta versions
2026-04-04 20:30:07 -04:00
Jacob Rhoda 5e65e3e712 Update Android SDK tools version and dependencies (#343)
Updated Android SDK tools versions to reflect most up-to-date default versions used by the Android gradle plugin (9.1.0)

- Platform: 36
- Build Tools: 36.0.0
- NDK: 28.2.13676358
2026-03-26 15:40:01 -04:00
Fedor Korotkov 5cf26631b9 macOS & Xcode 26.4 (#340)
* macOS & Xcode 26.4

* No Sonoma runner image

* Updated Tahoe tvOS 26.4 runtime to release version 23L243
2026-03-24 21:26:24 -04:00
Fedor Korotkov 0d8fe3156a Xcode 26.4 RC (#337)
* Xcode 16.4 RC

* Updated disk size for Sonoma CI runner and Tahoe runtimes to final Xcode 26.4 release versions.
2026-03-21 08:07:50 -04:00
Fedor Korotkov 69866eb29b Xcode 26.4 Beta 3 (#332)
* Xcode 26.4 Beta 3

* Updated Tahoe runtimes and added iOS 26.2 builds to Cirrus configuration

* Updated Tahoe runtimes and added iOS 26.2 builds to Cirrus configuration

* Removed iOS 26.2 from Tahoe runtimes list
2026-03-15 16:32:38 -04:00
Nikolay Edigaryev f2e700cda3 xcode.pkr.hcl: increase disk size from 120 to 140 GB (#333) 2026-03-15 13:08:44 -04:00
Nikolay Edigaryev 494e62f0b8 Disable SIP before running templates/base.pkr.hcl (#331)
* Disable SIP before running templates/base.pkr.hcl

* Don't forget to "packer init" before each "packer build"
2026-03-15 10:46:21 +01:00
Nikolay Edigaryev 27def7c5ce Prevent an array with empty element when XCODE_COMPONENTS is unset (#330) 2026-03-13 17:23:50 -04:00
Nikolay Edigaryev f9c2b3c122 base.pkr.hcl: update TCC.db and allow automation tools (#329) 2026-03-12 13:01:54 +01:00
Fedor Korotkov 7132d10945 Xcode 26.3 Release (#326) 2026-02-26 16:03:56 -05:00
Fedor Korotkov 33e373e65b Xcode 26.4 Beta 2 (#325)
* Xcode 26.4 Beta 2

* Updated Tahoe runtimes to latest Xcode 26.4 release versions
2026-02-23 19:52:43 -05:00
Fedor Korotkov cfa9e2361c Xcode 26.3 RC 2 (#324)
* Xcode 26.3 RC 2

* Increase DISK_SIZE from 230 to 240
2026-02-21 08:08:10 -05:00
Fedor Korotkov 09fce08792 Xcode 26.4 Beta (#323)
* Xcode 26.4 Beta

* Updated Tahoe runtimes to Xcode 26.4 Beta versions
2026-02-17 07:00:35 -05:00
Fedor Korotkov 01365193b9 Updated Tahoe template to use macOS 26.3 restore image. (#322)
Fixes #321
2026-02-13 16:20:18 +01:00
Fedor Korotkov 1414d3bf4b Added Buildkite agent installation to base Packer template. (#320) 2026-02-05 06:56:38 -05:00
Fedor Korotkov fbaec2adaa Xcode 26.3 RC (#319)
* Xcode 26.3 RC

* Removed unavailable runtimes from Tahoe list.
2026-02-04 10:13:22 -05:00
Fedor Korotkov f47f8bf08c Added rbenv 3.3.10 installation to address Fastlane compatibility in Xcode packer template. 2026-01-10 18:16:37 +01:00
Fedor Korotkov d56bd82e5d Refined Tuist installation steps in Xcode packer template. 2026-01-10 11:47:22 +01:00
Nikolay Edigaryev 4b95c2c93f Use the new <click 'Select Your Country or Region'> command (#317) 2025-12-16 21:02:14 +01:00
Fedor Korotkov 75924563a8 Updated macOS restore image comments for Sequoia 15.7.2 and Sonoma 14.8.2 2025-12-16 09:35:29 -05:00
Nikolay Edigaryev f3319b8eb8 Revert "Remove explicit FileVault step from Packer boot command for macOS 26.1 compatibility (#305)" (#316) 2025-12-15 19:07:52 -05:00
Fedor Korotkov 5ee829f2c8 macOS Tahoe 26.2 (#315) 2025-12-15 08:55:32 -05:00
Fedor Korotkov 64d9651dca Upgrade Node.js installation from version 20 to 24 (#314)
20 is retiring https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
2025-12-15 08:54:13 -05:00
Fedor Korotkov 0682bdb108 Xcode 26.2 (#313)
* Xcode 26.2

* Corrected Xcode version to 26.1.1 in Cirrus config.

* Updated Tahoe runtime build number for iOS 26.2.
2025-12-13 10:30:58 -05:00
Fedor Korotkov 3abe5ef330 Fixed syntax 2025-12-06 17:44:39 -05:00
19 changed files with 590 additions and 269 deletions
-26
View File
@@ -1,26 +0,0 @@
task:
name: "Update Base Images ($MACOS_VERSION)"
alias: update-base
matrix:
- env:
MACOS_VERSION: sonoma
DISABLE_SIP_TEMPLATE: disable-sip.pkr.hcl
- env:
MACOS_VERSION: sequoia
DISABLE_SIP_TEMPLATE: disable-sip-with-username.pkr.hcl
- env:
MACOS_VERSION: tahoe
DISABLE_SIP_TEMPLATE: disable-sip-with-username.pkr.hcl
<<: *defaults
pull_vanilla_script:
- tart pull ghcr.io/cirruslabs/macos-$MACOS_VERSION-vanilla:latest
build_base_script:
- packer init templates/base.pkr.hcl
- packer build -var macos_version="$MACOS_VERSION" templates/base.pkr.hcl
disable_sip_script:
- packer build -var vm_name=$MACOS_VERSION-base "templates/${DISABLE_SIP_TEMPLATE}"
push_base_script:
- tart push $MACOS_VERSION-base ghcr.io/cirruslabs/macos-$MACOS_VERSION-base:latest
always:
cleanup_script:
- tart delete $MACOS_VERSION-base
-23
View File
@@ -1,23 +0,0 @@
task:
name: "Release Xcode $CIRRUS_TAG ($MACOS_VERSION)"
env:
XCODE_COMPONENTS: "MetalToolchain"
matrix:
- MACOS_VERSION: tahoe
- MACOS_VERSION: sequoia
<<: *defaults
pull_base_script:
- tart pull ghcr.io/cirruslabs/macos-$MACOS_VERSION-base:latest
build_script:
- packer init templates/xcode.pkr.hcl
- packer build -var macos_version="$MACOS_VERSION" -var xcode_version="[\"$CIRRUS_TAG\"]" -var xcode_components="[\"$XCODE_COMPONENTS\"]" templates/xcode.pkr.hcl
push_script: |
if [[ $CIRRUS_TAG == *"beta"* ]]
then
tart push $MACOS_VERSION-xcode:$CIRRUS_TAG ghcr.io/cirruslabs/macos-$MACOS_VERSION-xcode:$CIRRUS_TAG
else
tart push $MACOS_VERSION-xcode:$CIRRUS_TAG ghcr.io/cirruslabs/macos-$MACOS_VERSION-xcode:$CIRRUS_TAG ghcr.io/cirruslabs/macos-$MACOS_VERSION-xcode:latest
fi
always:
cleanup_script:
- tart delete $MACOS_VERSION-xcode:$CIRRUS_TAG || true
-49
View File
@@ -1,49 +0,0 @@
task:
name: "Update Runner Image ($MACOS_VERSION)"
env:
matrix:
- MACOS_VERSION: sonoma
XCODE_VERSIONS: "16.1,16"
DISK_SIZE: 230
- MACOS_VERSION: sequoia
XCODE_VERSIONS: "\"26.0.1\",16.4,16.3,16.2,16.1,16"
ADDITIONAL_IOS_BUILDS: "18.5,18.4,18.2,17.5"
ADDITIONAL_TVOS_BUILDS: "17.5"
XCODE_COMPONENTS: "\"MetalToolchain\""
DISK_SIZE: 400
- MACOS_VERSION: tahoe
XCODE_VERSIONS: "\"26.1.1\",\"26.0.1\",\"26.2-rc\""
XCODE_COMPONENTS: "\"MetalToolchain\""
ADDITIONAL_IOS_BUILDS: "18.6"
DISK_SIZE: 300
<<: *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=$DISK_SIZE \
-var disk_free_mb=100000 \
-var macos_version="$MACOS_VERSION" \
-var xcode_version="[$XCODE_VERSIONS]" \
-var additional_ios_builds="[$ADDITIONAL_IOS_BUILDS]" \
-var additional_tvos_builds="[$ADDITIONAL_TVOS_BUILDS]" \
-var xcode_components="[$XCODE_COMPONENTS]" \
-var expected_runtimes_file="data/expected.$MACOS_VERSION.runtimes.txt" \
templates/xcode.pkr.hcl
finalize_script: |
if [[ -f "scripts/finalize-$MACOS_VERSION.sh" ]]; then
packer build -var vm_name="$MACOS_VERSION-xcode:runner" \
-var script_path="scripts/finalize-$MACOS_VERSION.sh" \
templates/exex-script.pkr.hcl
else
echo "Skipping prepare script for $MACOS_VERSION"
fi
push_script: |
if [[ -z "$CIRRUS_PR" ]]; then
tart push "$MACOS_VERSION-xcode:runner" ghcr.io/cirruslabs/macos-runner:$MACOS_VERSION
else
echo "Skipping pushing for PR..."
fi
always:
cleanup_script:
- tart delete "$MACOS_VERSION-xcode:runner"
-27
View File
@@ -1,27 +0,0 @@
env:
RESOLVE_VM_NAME: "resolve-macos-number-task-id-${CIRRUS_TASK_ID}"
RESOLVE_FILE: "${RESOLVE_VM_NAME}.txt"
task:
name: "Update Vanilla Image ($MACOS_VERSION)"
env:
matrix:
- MACOS_VERSION: tahoe
- MACOS_VERSION: sequoia
- MACOS_VERSION: sonoma
- MACOS_VERSION: monterey
only_if: $CIRRUS_BRANCH == $CIRRUS_DEFAULT_BRANCH && changesInclude("templates/vanilla-$MACOS_VERSION.pkr.hcl")
<<: *defaults
build_script:
- packer init templates/vanilla-$MACOS_VERSION.pkr.hcl
- packer build templates/vanilla-$MACOS_VERSION.pkr.hcl
resolve_macos_number_script:
- packer build -var vm_base_name=$MACOS_VERSION-vanilla -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 $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 $MACOS_VERSION-vanilla
-46
View File
@@ -1,46 +0,0 @@
task:
name: "Update Xcode Images ($MACOS_VERSION $XCODE_VERSION)"
depends_on: update-base
env:
matrix:
- MACOS_VERSION: tahoe
XCODE_VERSION: "26.1.1"
XCODE_COMPONENTS: "MetalToolchain"
LATEST: true
- MACOS_VERSION: tahoe
XCODE_VERSION: "26.0.1"
XCODE_COMPONENTS: "MetalToolchain"
- MACOS_VERSION: sequoia
XCODE_VERSION: 16.4
LATEST: true
- MACOS_VERSION: sequoia
XCODE_VERSION: 16.3
- MACOS_VERSION: sequoia
XCODE_VERSION: 16.2
- MACOS_VERSION: sequoia
XCODE_VERSION: 16.1
- MACOS_VERSION: sequoia
XCODE_VERSION: 16
- MACOS_VERSION: sonoma
XCODE_VERSION: 16.1
LATEST: true
- MACOS_VERSION: sonoma
XCODE_VERSION: 16
- MACOS_VERSION: sonoma
XCODE_VERSION: 15.4
<<: *defaults
pull_base_script:
- tart pull ghcr.io/cirruslabs/macos-$MACOS_VERSION-base:latest
build_xcode_script:
- packer init templates/xcode.pkr.hcl
- packer build -var macos_version="$MACOS_VERSION" -var xcode_version="[\"$XCODE_VERSION\"]" -var xcode_components="[$XCODE_COMPONENTS]" templates/xcode.pkr.hcl
push_script: |
if [[ -z "$LATEST" ]]
then
tart push "$MACOS_VERSION-xcode:$XCODE_VERSION" ghcr.io/cirruslabs/macos-$MACOS_VERSION-xcode:$XCODE_VERSION
else
tart push "$MACOS_VERSION-xcode:$XCODE_VERSION" ghcr.io/cirruslabs/macos-$MACOS_VERSION-xcode:$XCODE_VERSION ghcr.io/cirruslabs/macos-$MACOS_VERSION-xcode:latest
fi
always:
cleanup_script:
- tart delete "$MACOS_VERSION-xcode:$XCODE_VERSION"
-52
View File
@@ -1,52 +0,0 @@
load("cirrus", "env", "http", "fs", "changes_include")
load("github.com/cirrus-modules/graphql", "rerun_task_if_issue_in_logs")
def on_task_failed(ctx):
if ctx.payload.data.task.automaticReRun:
print("Task is already an automatic re-run! Won't even try to re-run it...")
return
rerun_task_if_issue_in_logs(ctx.payload.data.task.id, "The network connection was lost")
def on_build_failed(ctx):
# Only send Slack notifications for failed cron builds[1]
#
# [1]: https://cirrus-ci.org/guide/writing-tasks/#cron-builds
if "Cron" not in ctx.payload.data.build.changeMessageTitle:
return
resp = http.post(env.get("SLACK_WEBHOOK_URL"), headers={
"Content-Type": "application/json",
}, json_body={
"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:
fail("failed to post message to Slack: got unexpected HTTP {}".format(resp.status_code))
resp_json = resp.json()
if resp_json["ok"] != True:
fail("got error when posting message to Slack: {}".format(resp_json["error"]))
def main(ctx):
result = fs.read(".ci/cirrus.vanilla.yml")
if env.get("CIRRUS_TAG") != None:
result += fs.read(".ci/cirrus.release.yml")
if env.get("CIRRUS_CRON") == "monthly":
result += fs.read(".ci/cirrus.base.yml")
result += fs.read(".ci/cirrus.xcode.yml")
prForRunners = env.get("CIRRUS_PR") and changes_include(".ci/cirrus.runner.yml")
if prForRunners or env.get("CIRRUS_TAG") != None:
result += fs.read(".ci/cirrus.runner.yml")
return result
-18
View File
@@ -1,18 +0,0 @@
persistent_worker:
labels:
name: dev-mini
resources:
tart-vms: 1
env:
TART_REGISTRY_HOSTNAME: ghcr.io
TART_REGISTRY_USERNAME: fkorotkov # GitHub supports only PATs
TART_REGISTRY_PASSWORD: ENCRYPTED[!82ed873afdf627284305afef4958c85a8f73127b09978a9786ac521559630ea6c9a5ab6e7f8315abf9ead09b6eff6eae!]
AWS_ACCESS_KEY_ID: ENCRYPTED[c187b670a17eead88c1698849376273991d09678efe37ae2f0c9738c27a2422741a71c501ef4b6a4df7bff3eca5213a9]
AWS_SECRET_ACCESS_KEY: ENCRYPTED[e456254a53b82e3167f2da23e24c389620cb3f7d47e4e5e7d993813bf9bb18c784d5cb8d88d19632073acc9e1f6096c9]
defaults: &defaults
timeout_in: 3h
info_script:
- tart --version
- packer --version
+203
View File
@@ -0,0 +1,203 @@
name: Monthly Images
on:
schedule:
- cron: "0 8 * * 6"
workflow_dispatch:
permissions:
contents: read
packages: write
concurrency:
group: tart-image-builds
cancel-in-progress: false
env:
TART_REGISTRY_HOSTNAME: ghcr.io
TART_REGISTRY_USERNAME: ${{ github.actor }}
TART_REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
jobs:
should-run:
name: Check Monthly Cadence
runs-on: [self-hosted, macOS, ARM64]
outputs:
build: ${{ steps.cadence.outputs.build }}
steps:
- name: Check first Saturday
id: cadence
env:
EVENT_NAME: ${{ github.event_name }}
run: |
set -euo pipefail
build=false
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
build=true
else
day="$(date -u +%d)"
if (( 10#$day <= 7 )); then
build=true
fi
fi
echo "build=$build" >> "$GITHUB_OUTPUT"
if [[ "$build" != "true" ]]; then
echo "Not the first Saturday of the month; skipping image rebuilds."
fi
update-base:
name: Update Base Images (${{ matrix.macos_version }})
needs: should-run
if: needs.should-run.outputs.build == 'true'
runs-on: [self-hosted, macOS, ARM64]
timeout-minutes: 180
strategy:
fail-fast: false
max-parallel: 1
matrix:
include:
- macos_version: sonoma
disable_sip_template: disable-sip.pkr.hcl
- macos_version: sequoia
disable_sip_template: disable-sip-with-username.pkr.hcl
- macos_version: tahoe
disable_sip_template: disable-sip-with-username.pkr.hcl
env:
MACOS_VERSION: ${{ matrix.macos_version }}
DISABLE_SIP_TEMPLATE: ${{ matrix.disable_sip_template }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Tool versions
run: |
tart --version
packer --version
- name: Pull vanilla image
run: |
tart pull "ghcr.io/cirruslabs/macos-$MACOS_VERSION-vanilla:latest"
tart clone "ghcr.io/cirruslabs/macos-$MACOS_VERSION-vanilla:latest" "$MACOS_VERSION-base"
- name: Disable SIP
run: |
packer init "templates/$DISABLE_SIP_TEMPLATE"
packer build -var "vm_name=$MACOS_VERSION-base" "templates/$DISABLE_SIP_TEMPLATE"
- name: Build base image
run: |
packer init templates/base.pkr.hcl
packer build -var "vm_name=$MACOS_VERSION-base" templates/base.pkr.hcl
- name: Push base image
run: |
tart push "$MACOS_VERSION-base" "ghcr.io/cirruslabs/macos-$MACOS_VERSION-base:latest"
- name: Cleanup
if: always()
run: |
tart delete "$MACOS_VERSION-base" || true
update-xcode:
name: Update Xcode Images (${{ matrix.macos_version }} ${{ matrix.xcode_version }})
needs:
- should-run
- update-base
if: needs.should-run.outputs.build == 'true'
runs-on: [self-hosted, macOS, ARM64]
timeout-minutes: 180
strategy:
fail-fast: false
max-parallel: 1
matrix:
include:
- macos_version: tahoe
xcode_version: "26.2"
xcode_components: '"MetalToolchain"'
latest: true
- macos_version: tahoe
xcode_version: "26.1.1"
xcode_components: '"MetalToolchain"'
latest: false
- macos_version: tahoe
xcode_version: "26.0.1"
xcode_components: '"MetalToolchain"'
latest: false
- macos_version: sequoia
xcode_version: "16.4"
xcode_components: ""
latest: true
- macos_version: sequoia
xcode_version: "16.3"
xcode_components: ""
latest: false
- macos_version: sequoia
xcode_version: "16.2"
xcode_components: ""
latest: false
- macos_version: sequoia
xcode_version: "16.1"
xcode_components: ""
latest: false
- macos_version: sequoia
xcode_version: "16"
xcode_components: ""
latest: false
- macos_version: sonoma
xcode_version: "16.1"
xcode_components: ""
latest: true
- macos_version: sonoma
xcode_version: "16"
xcode_components: ""
latest: false
- macos_version: sonoma
xcode_version: "15.4"
xcode_components: ""
latest: false
env:
MACOS_VERSION: ${{ matrix.macos_version }}
XCODE_COMPONENTS: ${{ matrix.xcode_components }}
XCODE_VERSION: ${{ matrix.xcode_version }}
LATEST: ${{ matrix.latest }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Tool versions
run: |
tart --version
packer --version
- name: Pull base image
run: |
tart pull "ghcr.io/cirruslabs/macos-$MACOS_VERSION-base:latest"
- name: Build Xcode image
run: |
packer init templates/xcode.pkr.hcl
packer build \
-var "macos_version=$MACOS_VERSION" \
-var "xcode_version=[\"$XCODE_VERSION\"]" \
-var "xcode_components=[$XCODE_COMPONENTS]" \
templates/xcode.pkr.hcl
- name: Push Xcode image
run: |
if [[ "$LATEST" == "true" ]]; then
tart push "$MACOS_VERSION-xcode:$XCODE_VERSION" \
"ghcr.io/cirruslabs/macos-$MACOS_VERSION-xcode:$XCODE_VERSION" \
"ghcr.io/cirruslabs/macos-$MACOS_VERSION-xcode:latest"
else
tart push "$MACOS_VERSION-xcode:$XCODE_VERSION" \
"ghcr.io/cirruslabs/macos-$MACOS_VERSION-xcode:$XCODE_VERSION"
fi
- name: Cleanup
if: always()
run: |
tart delete "$MACOS_VERSION-xcode:$XCODE_VERSION" || true
+166
View File
@@ -0,0 +1,166 @@
name: Release Images
on:
release:
types:
- published
workflow_dispatch:
inputs:
xcode_version:
description: "Xcode version/tag to release"
required: true
type: string
permissions:
contents: read
packages: write
concurrency:
group: tart-image-builds
cancel-in-progress: false
env:
TART_REGISTRY_HOSTNAME: ghcr.io
TART_REGISTRY_USERNAME: ${{ github.actor }}
TART_REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
XCODE_RELEASE_VERSION: ${{ github.event.release.tag_name || inputs.xcode_version }}
jobs:
release-xcode:
name: Release Xcode ${{ github.event.release.tag_name || inputs.xcode_version }} (${{ matrix.macos_version }})
runs-on: [self-hosted, macOS, ARM64]
timeout-minutes: 180
strategy:
fail-fast: false
max-parallel: 1
matrix:
macos_version:
- tahoe
- sequoia
env:
MACOS_VERSION: ${{ matrix.macos_version }}
XCODE_COMPONENTS: '"MetalToolchain"'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Validate release version
run: |
set -euo pipefail
if [[ -z "$XCODE_RELEASE_VERSION" ]]; then
echo "XCODE_RELEASE_VERSION is required."
exit 1
fi
- name: Tool versions
run: |
tart --version
packer --version
- name: Pull base image
run: |
tart pull "ghcr.io/cirruslabs/macos-$MACOS_VERSION-base:latest"
- name: Build release image
run: |
packer init templates/xcode.pkr.hcl
packer build \
-var "macos_version=$MACOS_VERSION" \
-var "xcode_version=[\"$XCODE_RELEASE_VERSION\"]" \
-var "xcode_components=[$XCODE_COMPONENTS]" \
templates/xcode.pkr.hcl
- name: Push release image
run: |
if [[ "$XCODE_RELEASE_VERSION" == *beta* ]]; then
tart push "$MACOS_VERSION-xcode:$XCODE_RELEASE_VERSION" \
"ghcr.io/cirruslabs/macos-$MACOS_VERSION-xcode:$XCODE_RELEASE_VERSION"
else
tart push "$MACOS_VERSION-xcode:$XCODE_RELEASE_VERSION" \
"ghcr.io/cirruslabs/macos-$MACOS_VERSION-xcode:$XCODE_RELEASE_VERSION" \
"ghcr.io/cirruslabs/macos-$MACOS_VERSION-xcode:latest"
fi
- name: Cleanup
if: always()
run: |
tart delete "$MACOS_VERSION-xcode:$XCODE_RELEASE_VERSION" || true
release-runner:
name: Update Runner Image (${{ matrix.macos_version }})
needs: release-xcode
runs-on: [self-hosted, macOS, ARM64]
timeout-minutes: 180
strategy:
fail-fast: false
max-parallel: 1
matrix:
include:
- macos_version: sequoia
xcode_versions: '"26.0.1",16.4,16.3,16.2,16.1,16'
additional_ios_builds: "18.5,18.4,18.2,17.5"
additional_tvos_builds: "17.5"
xcode_components: '"MetalToolchain"'
disk_size: 380
- macos_version: tahoe
xcode_versions: '"26.5","27-beta","26.4.1","26.3","26.2","26.1.1","26.0.1"'
additional_ios_builds: "18.6"
additional_tvos_builds: ""
xcode_components: '"MetalToolchain"'
disk_size: 330
env:
ADDITIONAL_IOS_BUILDS: ${{ matrix.additional_ios_builds }}
ADDITIONAL_TVOS_BUILDS: ${{ matrix.additional_tvos_builds }}
DISK_SIZE: ${{ matrix.disk_size }}
MACOS_VERSION: ${{ matrix.macos_version }}
XCODE_COMPONENTS: ${{ matrix.xcode_components }}
XCODE_VERSIONS: ${{ matrix.xcode_versions }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Tool versions
run: |
tart --version
packer --version
- name: Pull base image
run: |
tart pull "ghcr.io/cirruslabs/macos-$MACOS_VERSION-base:latest"
- name: Build runner image
run: |
packer init templates/xcode.pkr.hcl
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]" \
-var "additional_ios_builds=[$ADDITIONAL_IOS_BUILDS]" \
-var "additional_tvos_builds=[$ADDITIONAL_TVOS_BUILDS]" \
-var "xcode_components=[$XCODE_COMPONENTS]" \
-var "expected_runtimes_file=data/expected.$MACOS_VERSION.runtimes.txt" \
templates/xcode.pkr.hcl
- name: Finalize runner image
run: |
if [[ -f "scripts/finalize-$MACOS_VERSION.sh" ]]; then
packer build \
-var "vm_name=$MACOS_VERSION-xcode:runner" \
-var "script_path=scripts/finalize-$MACOS_VERSION.sh" \
templates/exex-script.pkr.hcl
else
echo "Skipping prepare script for $MACOS_VERSION"
fi
- name: Push runner image
run: |
tart push "$MACOS_VERSION-xcode:runner" "ghcr.io/cirruslabs/macos-runner:$MACOS_VERSION"
- name: Cleanup
if: always()
run: |
tart delete "$MACOS_VERSION-xcode:runner" || true
+127
View File
@@ -0,0 +1,127 @@
name: Vanilla Images
on:
push:
paths:
- "templates/vanilla-*.pkr.hcl"
workflow_dispatch:
inputs:
macos_version:
description: "macOS vanilla image to build"
required: true
default: all
type: choice
options:
- all
- tahoe
- sequoia
- sonoma
- monterey
permissions:
contents: read
packages: write
concurrency:
group: tart-image-builds
cancel-in-progress: false
env:
TART_REGISTRY_HOSTNAME: ghcr.io
TART_REGISTRY_USERNAME: ${{ github.actor }}
TART_REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
jobs:
update-vanilla:
name: Update Vanilla Image (${{ matrix.macos_version }})
if: >-
${{
github.event_name == 'workflow_dispatch' ||
github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
}}
runs-on: [self-hosted, macOS, ARM64]
timeout-minutes: 180
strategy:
fail-fast: false
max-parallel: 1
matrix:
macos_version:
- tahoe
- sequoia
- sonoma
- monterey
env:
MACOS_VERSION: ${{ matrix.macos_version }}
RESOLVE_VM_NAME: resolve-macos-number-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.macos_version }}
RESOLVE_FILE: resolve-macos-number-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.macos_version }}.txt
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Select image
id: select
env:
BEFORE_SHA: ${{ github.event.before }}
EVENT_NAME: ${{ github.event_name }}
INPUT_MACOS_VERSION: ${{ inputs.macos_version || 'all' }}
run: |
set -euo pipefail
build=false
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
if [[ "$INPUT_MACOS_VERSION" == "all" || "$INPUT_MACOS_VERSION" == "$MACOS_VERSION" ]]; then
build=true
fi
else
if [[ "$BEFORE_SHA" =~ ^0+$ ]]; then
git diff-tree --no-commit-id --name-only -r "$GITHUB_SHA" > changed-files.txt
else
git diff --name-only "$BEFORE_SHA" "$GITHUB_SHA" > changed-files.txt
fi
if grep -Fxq "templates/vanilla-$MACOS_VERSION.pkr.hcl" changed-files.txt; then
build=true
fi
fi
echo "build=$build" >> "$GITHUB_OUTPUT"
- name: Tool versions
if: steps.select.outputs.build == 'true'
run: |
tart --version
packer --version
- name: Build vanilla image
if: steps.select.outputs.build == 'true'
run: |
packer init "templates/vanilla-$MACOS_VERSION.pkr.hcl"
packer build "templates/vanilla-$MACOS_VERSION.pkr.hcl"
- name: Resolve macOS version
id: resolve
if: steps.select.outputs.build == 'true'
run: |
packer build \
-var "vm_base_name=$MACOS_VERSION-vanilla" \
-var "vm_name=$RESOLVE_VM_NAME" \
-var "resolve_file=$RESOLVE_FILE" \
templates/resolve-macos-number.pkr.hcl
echo "macos_number=$(cat "$RESOLVE_FILE")" >> "$GITHUB_OUTPUT"
rm -f "$RESOLVE_FILE"
- name: Push vanilla image
if: steps.select.outputs.build == 'true'
run: |
tart push "$MACOS_VERSION-vanilla" \
"ghcr.io/cirruslabs/macos-$MACOS_VERSION-vanilla:latest" \
"ghcr.io/cirruslabs/macos-$MACOS_VERSION-vanilla:${{ steps.resolve.outputs.macos_number }}"
- name: Cleanup
if: always() && steps.select.outputs.build == 'true'
run: |
tart delete "$MACOS_VERSION-vanilla" || true
tart delete "$RESOLVE_VM_NAME" || true
+1 -1
View File
@@ -15,7 +15,7 @@ packer build -var vm_name=sonoma-vanilla templates/disable-sip.pkr.hcl
## Building Base Image
```bash
packer build -var macos_version=sonoma templates/base.pkr.hcl
packer build -var vm_name=sonoma-vanilla templates/base.pkr.hcl
```
## Building Xcode Image
+3 -3
View File
@@ -1,7 +1,7 @@
## macOS Packer Templates for Tart
Repository with Packer templates to build macOS [Tart](https://tart.run/) virtual machines to use with [Cirrus Runners](https://cirrus-runners.app/),
[Cirrus CI](https://cirrus-ci.org/guide/macOS/) or [any other automation](https://tart.run/integrations/cirrus-cli/).
Repository with Packer templates to build macOS [Tart](https://tart.run/) virtual machines to use with self-hosted
GitHub Actions runners, [Cirrus Runners](https://cirrus-runners.app/) or [any other automation](https://tart.run/integrations/cirrus-cli/).
The following image variants are currently available:
@@ -22,4 +22,4 @@ Please watch this repository releases to get notified about new images.
Some of the images are regularly getting rebuild in order to update the pre-installed packages.
[This configuration file](.ci/cirrus.release.yml) defines images that are getting rebuilt monthly on the first Saturday of the month.
[This workflow](.github/workflows/monthly.yml) defines images that are getting rebuilt monthly on the first Saturday of the month.
+9 -7
View File
@@ -2,13 +2,15 @@
iOS 18.6 (18.6 - 22G86) - com.apple.CoreSimulator.SimRuntime.iOS-18-6
iOS 26.0 (26.0.1 - 23A8464) - com.apple.CoreSimulator.SimRuntime.iOS-26-0
iOS 26.1 (26.1 - 23B86) - com.apple.CoreSimulator.SimRuntime.iOS-26-1
iOS 26.2 (26.2 - 23C52) - com.apple.CoreSimulator.SimRuntime.iOS-26-2
tvOS 26.0 (26.0 - 23J352) - com.apple.CoreSimulator.SimRuntime.tvOS-26-0
tvOS 26.1 (26.1 - 23J579) - com.apple.CoreSimulator.SimRuntime.tvOS-26-1
iOS 26.3 (26.3.1 - 23D8133) - com.apple.CoreSimulator.SimRuntime.iOS-26-3
iOS 26.4 (26.4.1 - 23E254a) - com.apple.CoreSimulator.SimRuntime.iOS-26-4
iOS 26.5 (26.5 - 23F77) - com.apple.CoreSimulator.SimRuntime.iOS-26-5
tvOS 26.2 (26.2 - 23K51) - com.apple.CoreSimulator.SimRuntime.tvOS-26-2
watchOS 26.0 (26.0 - 23R353) - com.apple.CoreSimulator.SimRuntime.watchOS-26-0
watchOS 26.1 (26.1 - 23S36) - com.apple.CoreSimulator.SimRuntime.watchOS-26-1
tvOS 26.4 (26.4 - 23L243a) - com.apple.CoreSimulator.SimRuntime.tvOS-26-4
tvOS 26.5 (26.5 - 23L470) - com.apple.CoreSimulator.SimRuntime.tvOS-26-5
watchOS 26.2 (26.2 - 23S303) - com.apple.CoreSimulator.SimRuntime.watchOS-26-2
visionOS 26.0 (26.0 - 23M336) - com.apple.CoreSimulator.SimRuntime.xrOS-26-0
visionOS 26.1 (26.1 - 23N47) - com.apple.CoreSimulator.SimRuntime.xrOS-26-1
watchOS 26.4 (26.4 - 23T240b) - com.apple.CoreSimulator.SimRuntime.watchOS-26-4
watchOS 26.5 (26.5 - 23T570) - com.apple.CoreSimulator.SimRuntime.watchOS-26-5
visionOS 26.2 (26.2 - 23N301) - com.apple.CoreSimulator.SimRuntime.xrOS-26-2
visionOS 26.4 (26.4.1 - 23O249a) - com.apple.CoreSimulator.SimRuntime.xrOS-26-4
visionOS 26.5 (26.5 - 23O470) - com.apple.CoreSimulator.SimRuntime.xrOS-26-5
+47
View File
@@ -0,0 +1,47 @@
#!/bin/bash
source ~/.zprofile
# Set shell options to enable fail-fast behavior
#
# * -e: fail the script when an error occurs or command fails
# * -u: fail the script when attempting to reference unset parameters
# * -o pipefail: by default an exit status of a pipeline is that of its
# last command, this fails the pipe early if an error in
# any of its commands occurs
#
set -euo pipefail
update_tcc_database() {
sudo sqlite3 "$1" <<-'EOF'
INSERT OR REPLACE
INTO access (
service,
client_type,
client,
auth_value,
auth_reason,
auth_version,
indirect_object_identifier_type,
indirect_object_identifier
) VALUES
-- Indirect osascript invocation via SSH
('kTCCServiceAccessibility', 1, '/usr/libexec/sshd-keygen-wrapper', 2, 0, 1, NULL, 'UNUSED'),
('kTCCServiceScreenCapture', 1, '/usr/libexec/sshd-keygen-wrapper', 2, 0, 1, NULL, 'UNUSED'),
('kTCCServicePostEvent', 1, '/usr/libexec/sshd-keygen-wrapper', 2, 0, 1, NULL, 'UNUSED'),
('kTCCServiceAppleEvents', 1, '/usr/libexec/sshd-keygen-wrapper', 2, 0, 1, 0, 'com.apple.systemevents'),
('kTCCServiceAppleEvents', 1, '/usr/libexec/sshd-keygen-wrapper', 2, 0, 1, 0, 'com.apple.Safari'),
-- Direct osascript invocation
('kTCCServiceAccessibility', 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'),
('kTCCServiceAppleEvents', 1, '/usr/bin/osascript', 2, 0, 1, 0, 'com.apple.systemevents'),
('kTCCServiceAppleEvents', 1, '/usr/bin/osascript', 2, 0, 1, 0, 'com.apple.Safari');
EOF
}
# Update TCC.db for all users
update_tcc_database "/Library/Application Support/com.apple.TCC/TCC.db"
# Update TCC.db for the current user
update_tcc_database "${HOME}/Library/Application Support/com.apple.TCC/TCC.db"
+10 -5
View File
@@ -7,13 +7,12 @@ packer {
}
}
variable "macos_version" {
variable "vm_name" {
type = string
}
source "tart-cli" "tart" {
vm_base_name = "ghcr.io/cirruslabs/macos-${var.macos_version}-vanilla:latest"
vm_name = "${var.macos_version}-base"
vm_name = "${var.vm_name}"
cpu_count = 4
memory_gb = 8
disk_size_gb = 50
@@ -65,6 +64,7 @@ build {
"brew --version",
"brew update",
"brew install wget unzip zip ca-certificates cmake gcc git-lfs jq yq gh gitlab-runner",
"brew install buildkite/buildkite/buildkite-agent",
"brew install equinix-labs/otel-cli/otel-cli",
"brew install curl || true", // doesn't work on Monterey
"brew install --cask git-credential-manager",
@@ -117,8 +117,8 @@ build {
provisioner "shell" {
inline = [
"source ~/.zprofile",
"brew install node@20",
"echo 'export PATH=\"/opt/homebrew/opt/node@20/bin:$PATH\"' >> ~/.zprofile",
"brew install node@24",
"echo 'export PATH=\"/opt/homebrew/opt/node@24/bin:$PATH\"' >> ~/.zprofile",
"source ~/.zprofile",
"node --version",
"npm install --global yarn",
@@ -177,4 +177,9 @@ build {
"sudo chmod 0644 /Library/LaunchAgents/org.cirruslabs.tart-guest-agent.plist",
]
}
# Update TCC.db and allow automation tools
provisioner "shell" {
script = "scripts/update-tcc-database.sh"
}
}
+3 -3
View File
@@ -1,7 +1,7 @@
packer {
required_plugins {
tart = {
version = ">= 1.12.0"
version = ">= 1.16.0"
source = "github.com/cirruslabs/tart"
}
ansible = {
@@ -12,7 +12,7 @@ packer {
}
source "tart-cli" "tart" {
// will be update to 15.7
// will be update to 15.7.2
from_ipsw = "https://updates.cdn-apple.com/2025SummerFCS/fullrestores/093-10809/CFD6DD38-DAF0-40DA-854F-31AAD1294C6F/UniversalMac_15.6.1_24G90_Restore.ipsw"
vm_name = "sequoia-vanilla"
cpu_count = 4
@@ -33,7 +33,7 @@ source "tart-cli" "tart" {
# [1]: should be named "English (US)", but oh well 🤷
"<wait30s>italiano<esc>english<enter>",
# Select Your Country or Region
"<wait30s>united states<leftShiftOn><tab><leftShiftOff><spacebar>",
"<wait30s><click 'Select Your Country or Region'><wait5s>united states<leftShiftOn><tab><leftShiftOff><spacebar>",
# Transfer Your Data to This Mac
"<wait10s><tab><tab><tab><spacebar><tab><tab><spacebar>",
# Written and Spoken Languages
+1 -1
View File
@@ -12,7 +12,7 @@ packer {
}
source "tart-cli" "tart" {
// will be update to 14.8
// will be update to 14.8.2
from_ipsw = "https://updates.cdn-apple.com/2024SummerFCS/fullrestores/062-52859/932E0A8F-6644-4759-82DA-F8FA8DEA806A/UniversalMac_14.6.1_23G93_Restore.ipsw"
vm_name = "sonoma-vanilla"
cpu_count = 4
+13 -4
View File
@@ -1,7 +1,7 @@
packer {
required_plugins {
tart = {
version = ">= 1.12.0"
version = ">= 1.16.0"
source = "github.com/cirruslabs/tart"
}
ansible = {
@@ -12,7 +12,7 @@ packer {
}
source "tart-cli" "tart" {
from_ipsw = "https://updates.cdn-apple.com/2025FallFCS/fullrestores/089-04148/791B6F00-A30B-4EB0-B2E3-257167F7715B/UniversalMac_26.1_25B78_Restore.ipsw"
from_ipsw = "https://updates.cdn-apple.com/2026SpringFCS/fullrestores/122-58869/DFB1CEEF-5619-4591-9924-E20DB2C8FED0/UniversalMac_26.5_25F71_Restore.ipsw"
vm_name = "tahoe-vanilla"
cpu_count = 4
memory_gb = 8
@@ -32,7 +32,7 @@ source "tart-cli" "tart" {
# [1]: should be named "English (US)", but oh well 🤷
"<wait30s>italiano<esc>english<enter>",
# Select Your Country or Region
"<wait60s>united states<leftShiftOn><tab><leftShiftOff><spacebar>",
"<wait60s><click 'Select Your Country or Region'><wait5s>united states<leftShiftOn><tab><leftShiftOff><spacebar>",
# Transfer Your Data to This Mac
"<wait10s><tab><tab><tab><spacebar><tab><tab><spacebar>",
# Written and Spoken Languages
@@ -46,13 +46,15 @@ source "tart-cli" "tart" {
# Enable Voice Over
"<wait120s><leftAltOn><f5><leftAltOff>",
# Sign In with Your Apple ID
"<wait10s><leftShiftOn><tab><leftShiftOff><spacebar>",
"<wait10s><leftShiftOn><tab><leftShiftOff><spacebar><up><spacebar>",
# Are you sure you want to skip signing in with an Apple ID?
"<wait10s><tab><spacebar>",
# Terms and Conditions
"<wait10s><leftShiftOn><tab><leftShiftOff><spacebar>",
# I have read and agree to the macOS Software License Agreement
"<wait10s><tab><spacebar>",
# Age Range -> Adult
"<wait10s><tab><tab><tab><spacebar>",
# Enable Location Services
"<wait10s><leftShiftOn><tab><leftShiftOff><spacebar>",
# Are you sure you don't want to use Location Services?
@@ -65,6 +67,10 @@ source "tart-cli" "tart" {
"<wait10s><tab><tab><spacebar>",
# Siri
"<wait10s><tab><spacebar><leftShiftOn><tab><leftShiftOff><spacebar>",
# You Mac is Ready for FileVault
"<wait10s><leftShiftOn><tab><tab><leftShiftOff><spacebar>",
# Mac Data Will Not Be Securely Encrypted
"<wait10s><tab><spacebar>",
# Choose Your Look
"<wait10s><leftShiftOn><tab><leftShiftOff><spacebar>",
# Update Mac Automatically
@@ -80,10 +86,13 @@ source "tart-cli" "tart" {
# Now that the installation is done, open "System Settings"
# On Tahoe opening System Settings through Spotlight is not very reliable, sometimes opens System information
"<wait10s>open '/System/Applications/System Settings.app'<enter>",
"<wait120s>",
# Navigate to "Sharing"
"<wait10s><leftCtrlOn><f2><leftCtrlOff><right><right><right><down>Sharing<enter>",
# Navigate to "Screen Sharing" and enable it
"<wait10s><tab><tab><tab><tab><tab><spacebar>",
# Type in the password to allow enabling Screen Sharing
"<wait10s>admin<enter>",
# Navigate to "Remote Login" and enable it
"<wait10s><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><spacebar>",
# Quit System Settings
+7 -4
View File
@@ -44,7 +44,7 @@ variable "tag" {
variable "disk_size" {
type = number
default = 120
default = 140
}
variable "disk_free_mb" {
@@ -54,7 +54,7 @@ variable "disk_free_mb" {
variable "android_sdk_tools_version" {
type = string
default = "11076708" # https://developer.android.com/studio#command-line-tools-only
default = "14742923" # https://developer.android.com/studio#command-line-tools-only
}
source "tart-cli" "tart" {
@@ -133,7 +133,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-35' 'build-tools;35.0.0' 'ndk;27.2.12479018'"
"yes | sdkmanager 'platform-tools' 'platforms;android-36' 'build-tools;36.0.0' 'ndk;28.2.13676358'"
]
}
@@ -231,7 +231,10 @@ build {
"source ~/.zprofile",
"brew install libimobiledevice ideviceinstaller ios-deploy carthage",
"brew install xcbeautify swiftformat swiftlint swiftgen licenseplist",
"brew install mint tuist/tuist/tuist",
"brew install mint",
"brew tap tuist/tuist",
"brew install --formula tuist",
"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 install fastlane",