mirror of
https://github.com/cirruslabs/macos-image-templates.git
synced 2026-09-30 11:51:13 +02:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85b6aae17f |
@@ -1,19 +0,0 @@
|
|||||||
task:
|
|
||||||
name: "Update Base Images ($MACOS_VERSION)"
|
|
||||||
alias: update-base
|
|
||||||
matrix:
|
|
||||||
- env:
|
|
||||||
MACOS_VERSION: sonoma
|
|
||||||
- env:
|
|
||||||
MACOS_VERSION: sequoia
|
|
||||||
<<: *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
|
|
||||||
push_base_script:
|
|
||||||
- tart push $MACOS_VERSION-base ghcr.io/cirruslabs/macos-$MACOS_VERSION-base:latest
|
|
||||||
always:
|
|
||||||
cleanup_script:
|
|
||||||
- tart delete $MACOS_VERSION-base
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
task:
|
|
||||||
name: "Release Xcode $CIRRUS_TAG ($MACOS_VERSION)"
|
|
||||||
matrix:
|
|
||||||
- env:
|
|
||||||
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\"]" 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
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
task:
|
|
||||||
name: "Update Runner Image ($MACOS_VERSION)"
|
|
||||||
execution_lock: runner-image-update
|
|
||||||
env:
|
|
||||||
matrix:
|
|
||||||
- MACOS_VERSION: sonoma
|
|
||||||
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.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=$DISK_SIZE \
|
|
||||||
-var disk_free_mb=100000 \
|
|
||||||
-var macos_version="$MACOS_VERSION" \
|
|
||||||
-var xcode_version="[$XCODE_VERSIONS]" \
|
|
||||||
-var additional_runtimes="[$ADDITIONAL_RUNTIMES]" \
|
|
||||||
templates/xcode.pkr.hcl
|
|
||||||
push_script: |
|
|
||||||
tart push "$MACOS_VERSION-xcode:runner" ghcr.io/cirruslabs/macos-runner:$MACOS_VERSION
|
|
||||||
always:
|
|
||||||
cleanup_script:
|
|
||||||
- tart delete "$MACOS_VERSION-xcode:runner"
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
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 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-$MACOS_VERSION.pkr.hcl
|
|
||||||
- packer build templates/vanilla-$MACOS_VERSION.pkr.hcl
|
|
||||||
disable_sip_script:
|
|
||||||
- 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 $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
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
task:
|
|
||||||
name: "Update Xcode Images ($MACOS_VERSION $XCODE_VERSION)"
|
|
||||||
depends_on: update-base
|
|
||||||
env:
|
|
||||||
matrix:
|
|
||||||
- MACOS_VERSION: sequoia
|
|
||||||
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
|
|
||||||
- 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
|
|
||||||
build_xcode_script:
|
|
||||||
- packer init templates/xcode.pkr.hcl
|
|
||||||
- packer build -var macos_version="$MACOS_VERSION" -var xcode_version="[\"$XCODE_VERSION\"]" 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"
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
load("cirrus", "env", "http", "fs")
|
|
||||||
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")
|
|
||||||
if env.get("CIRRUS_CRON") == "weekly":
|
|
||||||
result += fs.read(".ci/cirrus.runner.yml")
|
|
||||||
return result
|
|
||||||
+75
-17
@@ -1,21 +1,79 @@
|
|||||||
persistent_worker:
|
task:
|
||||||
labels:
|
name: "Update Images"
|
||||||
name: dev-mini
|
only_if: $CIRRUS_CRON != ""
|
||||||
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
|
timeout_in: 3h
|
||||||
update_script:
|
persistent_worker:
|
||||||
- brew update || true
|
labels:
|
||||||
- brew upgrade || true
|
name: dev-mini
|
||||||
|
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]
|
||||||
|
update_script: brew update && brew upgrade
|
||||||
info_script:
|
info_script:
|
||||||
- tart --version
|
- tart --version
|
||||||
- packer --version
|
- packer --version
|
||||||
|
env_script:
|
||||||
|
- echo "XCODE_VERSION=$(cat variables.pkrvars.hcl | grep xcode_version | awk '{print $(NF)}' | tr -d '\"')" >> $CIRRUS_ENV
|
||||||
|
build_base_script:
|
||||||
|
- packer init templates/base.pkr.hcl
|
||||||
|
- packer build -var-file="variables.pkrvars.hcl" templates/base.pkr.hcl
|
||||||
|
build_xcode_script:
|
||||||
|
- packer init templates/xcode.pkr.hcl
|
||||||
|
- packer build -var-file="variables.pkrvars.hcl" templates/xcode.pkr.hcl
|
||||||
|
push_base_script:
|
||||||
|
- tart push sonoma-base ghcr.io/cirruslabs/macos-sonoma-base:latest
|
||||||
|
push_xcode_script:
|
||||||
|
- tart push sonoma-xcode:$XCODE_VERSION ghcr.io/cirruslabs/macos-sonoma-xcode:$XCODE_VERSION ghcr.io/cirruslabs/macos-sonoma-xcode:latest
|
||||||
|
push_base_ecr_script:
|
||||||
|
- tart push --chunk-size=5 sonoma-base public.ecr.aws/cirruslabs/macos:sonoma-base
|
||||||
|
push_xcode_ecr_script:
|
||||||
|
- tart push --chunk-size=5 sonoma-xcode:$XCODE_VERSION public.ecr.aws/cirruslabs/macos:sonoma-xcode-$XCODE_VERSION public.ecr.aws/cirruslabs/macos:sonoma-xcode
|
||||||
|
always:
|
||||||
|
cleanup_script:
|
||||||
|
- tart delete sonoma-base || true
|
||||||
|
- tart delete sonoma-xcode:$XCODE_VERSION || true
|
||||||
|
|
||||||
|
task:
|
||||||
|
name: "Release Xcode $CIRRUS_TAG"
|
||||||
|
only_if: $CIRRUS_TAG != ""
|
||||||
|
timeout_in: 3h
|
||||||
|
persistent_worker:
|
||||||
|
labels:
|
||||||
|
name: dev-mini
|
||||||
|
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]
|
||||||
|
update_script: brew update && brew upgrade
|
||||||
|
info_script:
|
||||||
|
- tart --version
|
||||||
|
- packer --version
|
||||||
|
pull_base_script:
|
||||||
|
- tart pull ghcr.io/cirruslabs/macos-sonoma-base:latest
|
||||||
|
- tart clone ghcr.io/cirruslabs/macos-sonoma-base:latest sonoma-base
|
||||||
|
build_script:
|
||||||
|
- packer init templates/xcode.pkr.hcl
|
||||||
|
- packer build -var-file="variables.pkrvars.hcl" -var xcode_version="$CIRRUS_TAG" templates/xcode.pkr.hcl
|
||||||
|
push_script: |
|
||||||
|
if [[ $CIRRUS_TAG == *"beta"* ]]
|
||||||
|
then
|
||||||
|
tart push sonoma-xcode:$CIRRUS_TAG ghcr.io/cirruslabs/macos-sonoma-xcode:$CIRRUS_TAG
|
||||||
|
else
|
||||||
|
tart push sonoma-xcode:$CIRRUS_TAG ghcr.io/cirruslabs/macos-sonoma-xcode:$CIRRUS_TAG ghcr.io/cirruslabs/macos-sonoma-xcode:latest
|
||||||
|
fi
|
||||||
|
push_ecr_script: |
|
||||||
|
if [[ $CIRRUS_TAG == *"beta"* ]]
|
||||||
|
then
|
||||||
|
tart push --chunk-size=5 sonoma-xcode:$CIRRUS_TAG public.ecr.aws/cirruslabs/macos:sonoma-xcode-$CIRRUS_TAG
|
||||||
|
else
|
||||||
|
tart push --chunk-size=5 sonoma-xcode:$CIRRUS_TAG public.ecr.aws/cirruslabs/macos:sonoma-xcode-$CIRRUS_TAG public.ecr.aws/cirruslabs/macos:sonoma-xcode
|
||||||
|
fi
|
||||||
|
always:
|
||||||
|
cleanup_script:
|
||||||
|
- tart delete sonoma-base || true
|
||||||
|
- tart delete sonoma-xcode:$CIRRUS_TAG || true
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
## Building Vanilla Image
|
|
||||||
|
|
||||||
To build `macos-sonoma-vanilla`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
packer build templates/vanilla-sonoma.pkr.hcl
|
|
||||||
```
|
|
||||||
|
|
||||||
Optionally, SIP can be disabled for each image by running the following commands:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
## Building Xcode Image
|
|
||||||
|
|
||||||
```bash
|
|
||||||
packer build -var macos_version=sonoma -var xcode_version="[15.4]" templates/xcode.pkr.hcl
|
|
||||||
```
|
|
||||||
@@ -1,32 +1,35 @@
|
|||||||
## macOS Packer Templates for Tart
|
## 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/),
|
Repository with Packer templates to build [Tart VMs](https://github.com/cirruslabs/tart) to use with [Cirrus Runners](https://tart.run/integrations/github-actions/) and [Cirrus CI](https://cirrus-ci.org/guide/macOS/).
|
||||||
[Cirrus CI](https://cirrus-ci.org/guide/macOS/) or [any other automation](https://tart.run/integrations/cirrus-cli/).
|
|
||||||
|
|
||||||
The following image variants are currently available:
|
* `macos-{monterey,ventura,sonoma}-vanilla` image has nothing pre-installed
|
||||||
|
* `macos-{monterey,ventura,sonoma}-base` image has only `brew` pre-installed
|
||||||
* `macos-{sequoia,sonoma}-base` image has only `brew` pre-installed and the latest version of `macOS` available
|
* `macos-{monterey,ventura,sonoma}-xcode:N` image is based on `macos-{monterey,ventura}-base` image and has `Xcode N` with [`Flutter`](https://flutter.dev/) pre-installed
|
||||||
* `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:{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-).
|
See a full list of VMs available [here](https://github.com/orgs/cirruslabs/packages?tab=packages&q=macos-).
|
||||||
|
|
||||||
## Release Cadence
|
## Building Vanilla Image
|
||||||
|
|
||||||
Once a new version of Xcode is released, we will initiate a GitHub release which will automatically build and push
|
To build `macos-sonoma-vanilla`:
|
||||||
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.
|
```bash
|
||||||
|
packer build templates/vanilla-sonoma.pkr.hcl
|
||||||
|
```
|
||||||
|
|
||||||
## Update Cadence
|
Optionally, SIP can be disabled for each image by running the following commands:
|
||||||
|
|
||||||
Some of the images are regularly getting rebuild in order to update the pre-installed packages. The following images are updated
|
```bash
|
||||||
monthly on the first Saturday of the month:
|
packer build -var vm_name=sonoma-vanilla templates/disable-sip.pkr.hcl
|
||||||
|
```
|
||||||
|
|
||||||
* `ghcr.io/cirruslabs/macos-{sequoia,sonoma}-base`
|
## Building Base Image
|
||||||
* `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:{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/)
|
```bash
|
||||||
on Cirrus Runners and Cirrus CI services.
|
packer build -var-file="variables.pkrvars.hcl" templates/base.pkr.hcl
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building Xcode Image
|
||||||
|
|
||||||
|
```bash
|
||||||
|
packer build -var-file="variables.pkrvars.hcl" templates/xcode.pkr.hcl
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
- hosts: default
|
|
||||||
roles:
|
|
||||||
- system-updater
|
|
||||||
vars:
|
|
||||||
ansible_password: admin
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
- 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]"
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
- 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
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
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=
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#!/usr/bin/expect -f
|
|
||||||
|
|
||||||
spawn automationmodetool enable-automationmode-without-authentication
|
|
||||||
expect "Enter the password for user 'admin':"
|
|
||||||
send "admin\n"
|
|
||||||
expect "Setting up machine to allow Automation Mode without requiring user authentication... succeeded."
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
source ~/.zprofile
|
|
||||||
brew install jq
|
|
||||||
|
|
||||||
DOWNLOAD_URL=$(curl -sS 'https://api.github.com/repos/actions/runner/releases/latest' | jq --raw-output '.assets[] | select(.name | test("actions-runner-osx-arm64-[0-9.]+.tar.gz")) | .browser_download_url')
|
|
||||||
|
|
||||||
rm -rf actions-runner && mkdir actions-runner && cd actions-runner
|
|
||||||
|
|
||||||
wget -O - "${DOWNLOAD_URL}" | tar xz
|
|
||||||
+17
-57
@@ -1,7 +1,7 @@
|
|||||||
packer {
|
packer {
|
||||||
required_plugins {
|
required_plugins {
|
||||||
tart = {
|
tart = {
|
||||||
version = ">= 1.12.0"
|
version = ">= 1.2.0"
|
||||||
source = "github.com/cirruslabs/tart"
|
source = "github.com/cirruslabs/tart"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,10 @@ variable "macos_version" {
|
|||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "gha_version" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
source "tart-cli" "tart" {
|
source "tart-cli" "tart" {
|
||||||
vm_base_name = "ghcr.io/cirruslabs/macos-${var.macos_version}-vanilla:latest"
|
vm_base_name = "ghcr.io/cirruslabs/macos-${var.macos_version}-vanilla:latest"
|
||||||
vm_name = "${var.macos_version}-base"
|
vm_name = "${var.macos_version}-base"
|
||||||
@@ -49,6 +53,15 @@ build {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
provisioner "shell" {
|
||||||
|
inline = [
|
||||||
|
"cd $HOME",
|
||||||
|
"mkdir actions-runner && cd actions-runner",
|
||||||
|
"curl -O -L https://github.com/actions/runner/releases/download/v${var.gha_version}/actions-runner-osx-arm64-${var.gha_version}.tar.gz",
|
||||||
|
"tar xzf ./actions-runner-osx-arm64-${var.gha_version}.tar.gz",
|
||||||
|
"rm actions-runner-osx-arm64-${var.gha_version}.tar.gz",
|
||||||
|
]
|
||||||
|
}
|
||||||
provisioner "shell" {
|
provisioner "shell" {
|
||||||
inline = [
|
inline = [
|
||||||
"/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"",
|
"/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"",
|
||||||
@@ -56,49 +69,13 @@ build {
|
|||||||
"echo 'eval \"$(/opt/homebrew/bin/brew shellenv)\"' >> ~/.zprofile",
|
"echo 'eval \"$(/opt/homebrew/bin/brew shellenv)\"' >> ~/.zprofile",
|
||||||
"echo \"export HOMEBREW_NO_AUTO_UPDATE=1\" >> ~/.zprofile",
|
"echo \"export HOMEBREW_NO_AUTO_UPDATE=1\" >> ~/.zprofile",
|
||||||
"echo \"export HOMEBREW_NO_INSTALL_CLEANUP=1\" >> ~/.zprofile",
|
"echo \"export HOMEBREW_NO_INSTALL_CLEANUP=1\" >> ~/.zprofile",
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
provisioner "shell" {
|
|
||||||
inline = [
|
|
||||||
"source ~/.zprofile",
|
"source ~/.zprofile",
|
||||||
"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 cmake gcc git-lfs jq gh gitlab-runner",
|
||||||
"brew install curl || true", // doesn't work on Monterey
|
|
||||||
"brew install --cask git-credential-manager",
|
|
||||||
"git lfs install",
|
"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"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a /Users/runner → /Users/admin symlink to support certain GitHub Actions
|
|
||||||
// like ruby/setup-ruby that hard-code the "/Users/runner/hostedtoolcache" path[1]
|
|
||||||
//
|
|
||||||
// [1]: https://github.com/ruby/setup-ruby/blob/6bd3d993c602f6b675728ebaecb2b569ff86e99b/common.js#L268
|
|
||||||
provisioner "shell" {
|
|
||||||
inline = [
|
|
||||||
"sudo ln -s /Users/admin /Users/runner"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
provisioner "shell" {
|
provisioner "shell" {
|
||||||
inline = [
|
inline = [
|
||||||
"source ~/.zprofile",
|
"source ~/.zprofile",
|
||||||
@@ -107,7 +84,7 @@ build {
|
|||||||
"echo 'if which rbenv > /dev/null; then eval \"$(rbenv init -)\"; fi' >> ~/.zprofile",
|
"echo 'if which rbenv > /dev/null; then eval \"$(rbenv init -)\"; fi' >> ~/.zprofile",
|
||||||
"source ~/.zprofile",
|
"source ~/.zprofile",
|
||||||
"rbenv install 2.7.8", // latest 2.x.x before EOL
|
"rbenv install 2.7.8", // latest 2.x.x before EOL
|
||||||
"rbenv install -l | grep -v - | tail -2 | xargs -L1 rbenv install",
|
"rbenv install $(rbenv install -l | grep -v - | tail -1)",
|
||||||
"rbenv global $(rbenv install -l | grep -v - | tail -1)",
|
"rbenv global $(rbenv install -l | grep -v - | tail -1)",
|
||||||
"gem install bundler",
|
"gem install bundler",
|
||||||
]
|
]
|
||||||
@@ -115,9 +92,7 @@ build {
|
|||||||
provisioner "shell" {
|
provisioner "shell" {
|
||||||
inline = [
|
inline = [
|
||||||
"source ~/.zprofile",
|
"source ~/.zprofile",
|
||||||
"brew install node@20",
|
"brew install node",
|
||||||
"echo 'export PATH=\"/opt/homebrew/opt/node@20/bin:$PATH\"' >> ~/.zprofile",
|
|
||||||
"source ~/.zprofile",
|
|
||||||
"node --version",
|
"node --version",
|
||||||
"npm install --global yarn",
|
"npm install --global yarn",
|
||||||
"yarn --version",
|
"yarn --version",
|
||||||
@@ -134,19 +109,4 @@ build {
|
|||||||
"brew install awscli"
|
"brew install awscli"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
# Enable UI automation, see https://github.com/cirruslabs/macos-image-templates/issues/136
|
|
||||||
provisioner "shell" {
|
|
||||||
script = "scripts/automationmodetool.expect"
|
|
||||||
}
|
|
||||||
|
|
||||||
// some other health checks
|
|
||||||
provisioner "shell" {
|
|
||||||
inline = [
|
|
||||||
"source ~/.zprofile",
|
|
||||||
"test -d /Users/runner",
|
|
||||||
"test -f ~/.ssh/known_hosts",
|
|
||||||
"brew doctor"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
packer {
|
packer {
|
||||||
required_plugins {
|
required_plugins {
|
||||||
tart = {
|
tart = {
|
||||||
version = ">= 1.12.0"
|
version = ">= 1.2.0"
|
||||||
source = "github.com/cirruslabs/tart"
|
source = "github.com/cirruslabs/tart"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,8 +22,11 @@ source "tart-cli" "tart" {
|
|||||||
# Skip over "Macintosh" and select "Options"
|
# Skip over "Macintosh" and select "Options"
|
||||||
# to boot into macOS Recovery
|
# to boot into macOS Recovery
|
||||||
"<wait60s><right><right><enter>",
|
"<wait60s><right><right><enter>",
|
||||||
|
# Select default language
|
||||||
|
"<wait10s><enter>",
|
||||||
# Open Terminal
|
# Open Terminal
|
||||||
"<wait10s><leftAltOn>T<leftAltOff>",
|
"<wait10s><leftCtrlOn><f2><leftCtrlOff>",
|
||||||
|
"<right><right><right><right><down><down><down><enter>",
|
||||||
# Disable SIP
|
# Disable SIP
|
||||||
"<wait10s>csrutil disable<enter>",
|
"<wait10s>csrutil disable<enter>",
|
||||||
"<wait10s>y<enter>",
|
"<wait10s>y<enter>",
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,16 +4,13 @@ packer {
|
|||||||
version = ">= 1.2.0"
|
version = ">= 1.2.0"
|
||||||
source = "github.com/cirruslabs/tart"
|
source = "github.com/cirruslabs/tart"
|
||||||
}
|
}
|
||||||
ansible = {
|
|
||||||
version = "~> 1"
|
|
||||||
source = "github.com/hashicorp/ansible"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
source "tart-cli" "tart" {
|
source "tart-cli" "tart" {
|
||||||
# You can find macOS IPSW URLs on various websites like https://ipsw.me/
|
# 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"
|
# and https://www.theiphonewiki.com/wiki/Beta_Firmware/Mac/13.x
|
||||||
|
from_ipsw = "https://updates.cdn-apple.com/2022FallFCS/fullrestores/012-40537/0EC7C669-13E9-49FB-BD64-9EECC1D174B2/UniversalMac_12.6_21G115_Restore.ipsw"
|
||||||
vm_name = "monterey-vanilla"
|
vm_name = "monterey-vanilla"
|
||||||
cpu_count = 4
|
cpu_count = 4
|
||||||
memory_gb = 8
|
memory_gb = 8
|
||||||
@@ -24,14 +21,8 @@ source "tart-cli" "tart" {
|
|||||||
boot_command = [
|
boot_command = [
|
||||||
# hello, hola, bonjour, etc.
|
# hello, hola, bonjour, etc.
|
||||||
"<wait60s><spacebar>",
|
"<wait60s><spacebar>",
|
||||||
# Language: most of the times we have a list of "English"[1], "English (UK)", etc. with
|
# Language
|
||||||
# "English" language already selected. If we type "english", it'll cause us to switch
|
"<wait30s><enter>",
|
||||||
# to the "English (UK)", which is not what we want. To solve this, we switch to some other
|
|
||||||
# language first, e.g. "Italiano" and then switch back to "English". We'll then jump to the
|
|
||||||
# first entry in a list of "english"-prefixed items, which will be "English".
|
|
||||||
#
|
|
||||||
# [1]: should be named "English (US)", but oh well 🤷
|
|
||||||
"<wait30s>italiano<esc>english<enter>",
|
|
||||||
# Select Your Country and Region
|
# Select Your Country and Region
|
||||||
"<wait30s>united states<leftShiftOn><tab><leftShiftOff><spacebar>",
|
"<wait30s>united states<leftShiftOn><tab><leftShiftOff><spacebar>",
|
||||||
# Written and Spoken Languages
|
# Written and Spoken Languages
|
||||||
@@ -83,9 +74,6 @@ source "tart-cli" "tart" {
|
|||||||
// A (hopefully) temporary workaround for Virtualization.Framework's
|
// A (hopefully) temporary workaround for Virtualization.Framework's
|
||||||
// installation process not fully finishing in a timely manner
|
// installation process not fully finishing in a timely manner
|
||||||
create_grace_time = "30s"
|
create_grace_time = "30s"
|
||||||
|
|
||||||
// Keep the recovery partition, otherwise it's not possible to "softwareupdate"
|
|
||||||
recovery_partition = "keep"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build {
|
build {
|
||||||
@@ -114,8 +102,10 @@ build {
|
|||||||
"disown",
|
"disown",
|
||||||
"sleep 30",
|
"sleep 30",
|
||||||
"kill -9 $SAFARI_PID",
|
"kill -9 $SAFARI_PID",
|
||||||
// Enable Safari's remote automation
|
// Enable Safari's remote automation and "Develop" menu
|
||||||
"sudo safaridriver --enable",
|
"sudo safaridriver --enable",
|
||||||
|
"defaults write com.apple.Safari.SandboxBroker ShowDevelopMenu -bool true",
|
||||||
|
"defaults write com.apple.Safari IncludeDevelopMenu -bool true",
|
||||||
// Disable screen lock
|
// Disable screen lock
|
||||||
//
|
//
|
||||||
// Note that this only works if the user is logged-in,
|
// Note that this only works if the user is logged-in,
|
||||||
@@ -123,25 +113,4 @@ build {
|
|||||||
"sysadminctl -screenLock off -password admin",
|
"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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,146 +0,0 @@
|
|||||||
packer {
|
|
||||||
required_plugins {
|
|
||||||
tart = {
|
|
||||||
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/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
|
|
||||||
disk_size_gb = 40
|
|
||||||
ssh_password = "admin"
|
|
||||||
ssh_username = "admin"
|
|
||||||
ssh_timeout = "300s"
|
|
||||||
boot_command = [
|
|
||||||
# hello, hola, bonjour, etc.
|
|
||||||
"<wait60s><spacebar>",
|
|
||||||
# Language: most of the times we have a list of "English"[1], "English (UK)", etc. with
|
|
||||||
# "English" language already selected. If we type "english", it'll cause us to switch
|
|
||||||
# to the "English (UK)", which is not what we want. To solve this, we switch to some other
|
|
||||||
# language first, e.g. "Italiano" and then switch back to "English". We'll then jump to the
|
|
||||||
# first entry in a list of "english"-prefixed items, which will be "English".
|
|
||||||
#
|
|
||||||
# [1]: should be named "English (US)", but oh well 🤷
|
|
||||||
"<wait30s>italiano<esc>english<enter>",
|
|
||||||
# Select Your Country and Region
|
|
||||||
"<wait30s>united states<leftShiftOn><tab><leftShiftOff><spacebar>",
|
|
||||||
# Written and Spoken Languages
|
|
||||||
"<wait10s><leftShiftOn><tab><leftShiftOff><spacebar>",
|
|
||||||
# Accessibility
|
|
||||||
"<wait10s><leftShiftOn><tab><leftShiftOff><spacebar>",
|
|
||||||
# Data & Privacy
|
|
||||||
"<wait10s><leftShiftOn><tab><leftShiftOff><spacebar>",
|
|
||||||
# Migration Assistant
|
|
||||||
"<wait10s><tab><tab><tab><spacebar>",
|
|
||||||
# Sign In with Your Apple ID
|
|
||||||
"<wait10s><leftShiftOn><tab><leftShiftOff><leftShiftOn><tab><leftShiftOff><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>",
|
|
||||||
# Create a Computer Account
|
|
||||||
"<wait10s>admin<tab><tab>admin<tab>admin<tab><tab><tab><spacebar>",
|
|
||||||
# Enable Location Services
|
|
||||||
"<wait120s><leftShiftOn><tab><leftShiftOff><spacebar>",
|
|
||||||
# Are you sure you don't want to use Location Services?
|
|
||||||
"<wait10s><tab><spacebar>",
|
|
||||||
# Select Your Time Zone
|
|
||||||
"<wait10s><tab><tab>UTC<enter><leftShiftOn><tab><tab><leftShiftOff><spacebar>",
|
|
||||||
# Analytics
|
|
||||||
"<wait10s><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>",
|
|
||||||
# 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>",
|
|
||||||
]
|
|
||||||
|
|
||||||
// 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 auto-login
|
|
||||||
//
|
|
||||||
// See https://github.com/xfreebird/kcpassword for details.
|
|
||||||
"echo '00000000: 1ced 3f4a bcbc ba2c caca 4e82' | sudo xxd -r - /etc/kcpassword",
|
|
||||||
"sudo defaults write /Library/Preferences/com.apple.loginwindow autoLoginUser admin",
|
|
||||||
// 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 = [
|
|
||||||
# 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,14 @@
|
|||||||
packer {
|
packer {
|
||||||
required_plugins {
|
required_plugins {
|
||||||
tart = {
|
tart = {
|
||||||
version = ">= 1.12.0"
|
version = ">= 1.2.0"
|
||||||
source = "github.com/cirruslabs/tart"
|
source = "github.com/cirruslabs/tart"
|
||||||
}
|
}
|
||||||
ansible = {
|
|
||||||
version = "~> 1"
|
|
||||||
source = "github.com/hashicorp/ansible"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
source "tart-cli" "tart" {
|
source "tart-cli" "tart" {
|
||||||
from_ipsw = "https://updates.cdn-apple.com/2024SummerFCS/fullrestores/052-69922/F5DA2B64-25EB-4370-9E89-FA5689859796/UniversalMac_14.6_23G80_Restore.ipsw"
|
from_ipsw = "https://updates.cdn-apple.com/2023FallFCS/fullrestores/042-86430/DBE44960-58A6-4715-948B-D64F33F769BD/UniversalMac_14.1_23B74_Restore.ipsw"
|
||||||
vm_name = "sonoma-vanilla"
|
vm_name = "sonoma-vanilla"
|
||||||
cpu_count = 4
|
cpu_count = 4
|
||||||
memory_gb = 8
|
memory_gb = 8
|
||||||
@@ -23,14 +19,8 @@ source "tart-cli" "tart" {
|
|||||||
boot_command = [
|
boot_command = [
|
||||||
# hello, hola, bonjour, etc.
|
# hello, hola, bonjour, etc.
|
||||||
"<wait60s><spacebar>",
|
"<wait60s><spacebar>",
|
||||||
# Language: most of the times we have a list of "English"[1], "English (UK)", etc. with
|
# Language
|
||||||
# "English" language already selected. If we type "english", it'll cause us to switch
|
"<wait30s>english<enter>",
|
||||||
# to the "English (UK)", which is not what we want. To solve this, we switch to some other
|
|
||||||
# language first, e.g. "Italiano" and then switch back to "English". We'll then jump to the
|
|
||||||
# first entry in a list of "english"-prefixed items, which will be "English".
|
|
||||||
#
|
|
||||||
# [1]: should be named "English (US)", but oh well 🤷
|
|
||||||
"<wait30s>italiano<esc>english<enter>",
|
|
||||||
# Select Your Country and Region
|
# Select Your Country and Region
|
||||||
"<wait30s>united states<leftShiftOn><tab><leftShiftOff><spacebar>",
|
"<wait30s>united states<leftShiftOn><tab><leftShiftOff><spacebar>",
|
||||||
# Written and Spoken Languages
|
# Written and Spoken Languages
|
||||||
@@ -75,6 +65,12 @@ source "tart-cli" "tart" {
|
|||||||
"<wait10s><tab><tab><tab><tab><tab><spacebar>",
|
"<wait10s><tab><tab><tab><tab><tab><spacebar>",
|
||||||
# Navigate to "Remote Login" and enable it
|
# Navigate to "Remote Login" and enable it
|
||||||
"<wait10s><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><spacebar>",
|
"<wait10s><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><spacebar>",
|
||||||
|
# Open "Remote Login" details
|
||||||
|
"<wait10s><tab><spacebar>",
|
||||||
|
# Enable "Full Disk Access"
|
||||||
|
"<wait10s><tab><spacebar>",
|
||||||
|
# Click "Done"
|
||||||
|
"<wait10s><leftShiftOn><tab><leftShiftOff><leftShiftOn><tab><leftShiftOff><spacebar>",
|
||||||
# Disable Voice Over
|
# Disable Voice Over
|
||||||
"<leftAltOn><f5><leftAltOff>",
|
"<leftAltOn><f5><leftAltOff>",
|
||||||
]
|
]
|
||||||
@@ -82,9 +78,6 @@ source "tart-cli" "tart" {
|
|||||||
// A (hopefully) temporary workaround for Virtualization.Framework's
|
// A (hopefully) temporary workaround for Virtualization.Framework's
|
||||||
// installation process not fully finishing in a timely manner
|
// installation process not fully finishing in a timely manner
|
||||||
create_grace_time = "30s"
|
create_grace_time = "30s"
|
||||||
|
|
||||||
// Keep the recovery partition, otherwise it's not possible to "softwareupdate"
|
|
||||||
recovery_partition = "keep"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build {
|
build {
|
||||||
@@ -113,8 +106,10 @@ build {
|
|||||||
"disown",
|
"disown",
|
||||||
"sleep 30",
|
"sleep 30",
|
||||||
"kill -9 $SAFARI_PID",
|
"kill -9 $SAFARI_PID",
|
||||||
// Enable Safari's remote automation
|
// Enable Safari's remote automation and "Develop" menu
|
||||||
"sudo safaridriver --enable",
|
"sudo safaridriver --enable",
|
||||||
|
"defaults write com.apple.Safari.SandboxBroker ShowDevelopMenu -bool true",
|
||||||
|
"defaults write com.apple.Safari IncludeDevelopMenu -bool true",
|
||||||
// Disable screen lock
|
// Disable screen lock
|
||||||
//
|
//
|
||||||
// Note that this only works if the user is logged-in,
|
// Note that this only works if the user is logged-in,
|
||||||
@@ -122,22 +117,4 @@ build {
|
|||||||
"sysadminctl -screenLock off -password admin",
|
"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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
packer {
|
packer {
|
||||||
required_plugins {
|
required_plugins {
|
||||||
tart = {
|
tart = {
|
||||||
version = ">= 1.12.0"
|
version = ">= 1.2.0"
|
||||||
source = "github.com/cirruslabs/tart"
|
source = "github.com/cirruslabs/tart"
|
||||||
}
|
}
|
||||||
ansible = {
|
|
||||||
version = "~> 1"
|
|
||||||
source = "github.com/hashicorp/ansible"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
source "tart-cli" "tart" {
|
source "tart-cli" "tart" {
|
||||||
# You can find macOS IPSW URLs on various websites like https://ipsw.me/
|
# You can find macOS IPSW URLs on various websites like https://ipsw.me/
|
||||||
# and https://www.theiphonewiki.com/wiki/Beta_Firmware/Mac/13.x
|
# and https://www.theiphonewiki.com/wiki/Beta_Firmware/Mac/13.x
|
||||||
from_ipsw = "https://updates.cdn-apple.com/2023FallFCS/fullrestores/042-55833/C0830847-A2F8-458F-B680-967991820931/UniversalMac_13.6_22G120_Restore.ipsw"
|
from_ipsw = "https://updates.cdn-apple.com/2023SummerFCS/fullrestores/042-43686/945D434B-DA5D-48DB-A558-F6D18D11AD69/UniversalMac_13.5.2_22G91_Restore.ipsw"
|
||||||
vm_name = "ventura-vanilla"
|
vm_name = "ventura-vanilla"
|
||||||
cpu_count = 4
|
cpu_count = 4
|
||||||
memory_gb = 8
|
memory_gb = 8
|
||||||
@@ -25,14 +21,8 @@ source "tart-cli" "tart" {
|
|||||||
boot_command = [
|
boot_command = [
|
||||||
# hello, hola, bonjour, etc.
|
# hello, hola, bonjour, etc.
|
||||||
"<wait60s><spacebar>",
|
"<wait60s><spacebar>",
|
||||||
# Language: most of the times we have a list of "English"[1], "English (UK)", etc. with
|
# Language
|
||||||
# "English" language already selected. If we type "english", it'll cause us to switch
|
"<wait30s>english<enter>",
|
||||||
# to the "English (UK)", which is not what we want. To solve this, we switch to some other
|
|
||||||
# language first, e.g. "Italiano" and then switch back to "English". We'll then jump to the
|
|
||||||
# first entry in a list of "english"-prefixed items, which will be "English".
|
|
||||||
#
|
|
||||||
# [1]: should be named "English (US)", but oh well 🤷
|
|
||||||
"<wait30s>italiano<esc>english<enter>",
|
|
||||||
# Select Your Country and Region
|
# Select Your Country and Region
|
||||||
"<wait30s>united states<leftShiftOn><tab><leftShiftOff><spacebar>",
|
"<wait30s>united states<leftShiftOn><tab><leftShiftOff><spacebar>",
|
||||||
# Written and Spoken Languages
|
# Written and Spoken Languages
|
||||||
@@ -90,9 +80,6 @@ source "tart-cli" "tart" {
|
|||||||
// A (hopefully) temporary workaround for Virtualization.Framework's
|
// A (hopefully) temporary workaround for Virtualization.Framework's
|
||||||
// installation process not fully finishing in a timely manner
|
// installation process not fully finishing in a timely manner
|
||||||
create_grace_time = "30s"
|
create_grace_time = "30s"
|
||||||
|
|
||||||
// Keep the recovery partition, otherwise it's not possible to "softwareupdate"
|
|
||||||
recovery_partition = "keep"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build {
|
build {
|
||||||
@@ -121,8 +108,10 @@ build {
|
|||||||
"disown",
|
"disown",
|
||||||
"sleep 30",
|
"sleep 30",
|
||||||
"kill -9 $SAFARI_PID",
|
"kill -9 $SAFARI_PID",
|
||||||
// Enable Safari's remote automation
|
// Enable Safari's remote automation and "Develop" menu
|
||||||
"sudo safaridriver --enable",
|
"sudo safaridriver --enable",
|
||||||
|
"defaults write com.apple.Safari.SandboxBroker ShowDevelopMenu -bool true",
|
||||||
|
"defaults write com.apple.Safari IncludeDevelopMenu -bool true",
|
||||||
// Disable screen lock
|
// Disable screen lock
|
||||||
//
|
//
|
||||||
// Note that this only works if the user is logged-in,
|
// Note that this only works if the user is logged-in,
|
||||||
@@ -131,22 +120,4 @@ build {
|
|||||||
"defaults -currentHost write com.apple.screensaver idleTime 0"
|
"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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-154
@@ -1,7 +1,7 @@
|
|||||||
packer {
|
packer {
|
||||||
required_plugins {
|
required_plugins {
|
||||||
tart = {
|
tart = {
|
||||||
version = ">= 1.12.0"
|
version = ">= 1.2.0"
|
||||||
source = "github.com/cirruslabs/tart"
|
source = "github.com/cirruslabs/tart"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,96 +12,60 @@ variable "macos_version" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
variable "xcode_version" {
|
variable "xcode_version" {
|
||||||
type = list(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "additional_runtimes" {
|
|
||||||
type = list(string)
|
|
||||||
default = []
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "tag" {
|
|
||||||
type = string
|
type = string
|
||||||
default = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "disk_size" {
|
variable "gha_version" {
|
||||||
type = number
|
type = string
|
||||||
default = 100
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "disk_free_mb" {
|
|
||||||
type = number
|
|
||||||
default = 15000
|
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "android_sdk_tools_version" {
|
variable "android_sdk_tools_version" {
|
||||||
type = string
|
type = string
|
||||||
default = "11076708" # https://developer.android.com/studio#command-line-tools-only
|
default = "9477386" # https://developer.android.com/studio/#command-tools
|
||||||
}
|
}
|
||||||
|
|
||||||
source "tart-cli" "tart" {
|
source "tart-cli" "tart" {
|
||||||
vm_base_name = "ghcr.io/cirruslabs/macos-${var.macos_version}-base:latest"
|
vm_base_name = "${var.macos_version}-base"
|
||||||
// use tag or the last element of the xcode_version list
|
vm_name = "${var.macos_version}-xcode:${var.xcode_version}"
|
||||||
vm_name = "${var.macos_version}-xcode:${var.tag != "" ? var.tag : var.xcode_version[0]}"
|
|
||||||
cpu_count = 4
|
cpu_count = 4
|
||||||
memory_gb = 8
|
memory_gb = 8
|
||||||
disk_size_gb = var.disk_size
|
disk_size_gb = 90
|
||||||
headless = true
|
headless = true
|
||||||
ssh_password = "admin"
|
ssh_password = "admin"
|
||||||
ssh_username = "admin"
|
ssh_username = "admin"
|
||||||
ssh_timeout = "120s"
|
ssh_timeout = "120s"
|
||||||
}
|
}
|
||||||
|
|
||||||
locals {
|
|
||||||
xcode_install_provisioners = [
|
|
||||||
for version in reverse(sort(var.xcode_version)) : {
|
|
||||||
type = "shell"
|
|
||||||
inline = [
|
|
||||||
"source ~/.zprofile",
|
|
||||||
"sudo xcodes install ${version} --experimental-unxip --path /Users/admin/Downloads/Xcode_${version}.xip --select --empty-trash",
|
|
||||||
// get selected xcode path, strip /Contents/Developer and move to GitHub compatible locations
|
|
||||||
"INSTALLED_PATH=$(xcodes select -p)",
|
|
||||||
"CONTENTS_DIR=$(dirname $INSTALLED_PATH)",
|
|
||||||
"APP_DIR=$(dirname $CONTENTS_DIR)",
|
|
||||||
"sudo mv $APP_DIR /Applications/Xcode_${version}.app",
|
|
||||||
"sudo xcode-select -s /Applications/Xcode_${version}.app",
|
|
||||||
"xcodebuild -downloadAllPlatforms",
|
|
||||||
"xcodebuild -runFirstLaunch",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
build {
|
build {
|
||||||
sources = ["source.tart-cli.tart"]
|
sources = ["source.tart-cli.tart"]
|
||||||
|
|
||||||
|
// re-install the actions runner
|
||||||
|
provisioner "shell" {
|
||||||
|
inline = [
|
||||||
|
"cd $HOME",
|
||||||
|
"rm -rf actions-runner",
|
||||||
|
"mkdir actions-runner && cd actions-runner",
|
||||||
|
"curl -O -L https://github.com/actions/runner/releases/download/v${var.gha_version}/actions-runner-osx-arm64-${var.gha_version}.tar.gz",
|
||||||
|
"tar xzf ./actions-runner-osx-arm64-${var.gha_version}.tar.gz",
|
||||||
|
"rm actions-runner-osx-arm64-${var.gha_version}.tar.gz",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
provisioner "shell" {
|
provisioner "shell" {
|
||||||
inline = [
|
inline = [
|
||||||
"source ~/.zprofile",
|
"source ~/.zprofile",
|
||||||
"brew --version",
|
"brew --version",
|
||||||
"brew update",
|
"brew update",
|
||||||
"brew upgrade",
|
"brew upgrade",
|
||||||
]
|
"brew install curl wget unzip zip ca-certificates",
|
||||||
}
|
"sudo softwareupdate --install-rosetta --agree-to-license"
|
||||||
|
|
||||||
// Re-install the GitHub Actions runner
|
|
||||||
provisioner "shell" {
|
|
||||||
script = "scripts/install-actions-runner.sh"
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure our workaround from base is still valid
|
|
||||||
provisioner "shell" {
|
|
||||||
inline = [
|
|
||||||
"sudo ln -s /Users/admin /Users/runner || true"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
provisioner "shell" {
|
provisioner "shell" {
|
||||||
inline = [
|
inline = [
|
||||||
"source ~/.zprofile",
|
"source ~/.zprofile",
|
||||||
"brew install openjdk@17",
|
"brew install homebrew/cask-versions/temurin17",
|
||||||
"echo 'export PATH=\"/opt/homebrew/opt/openjdk@17/bin:$PATH\"' >> ~/.zprofile",
|
|
||||||
"echo 'export ANDROID_HOME=$HOME/android-sdk' >> ~/.zprofile",
|
"echo 'export ANDROID_HOME=$HOME/android-sdk' >> ~/.zprofile",
|
||||||
"echo 'export ANDROID_SDK_ROOT=$ANDROID_HOME' >> ~/.zprofile",
|
"echo 'export ANDROID_SDK_ROOT=$ANDROID_HOME' >> ~/.zprofile",
|
||||||
"echo 'export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator' >> ~/.zprofile",
|
"echo 'export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator' >> ~/.zprofile",
|
||||||
@@ -112,49 +76,28 @@ build {
|
|||||||
"rm android-sdk-tools.zip",
|
"rm android-sdk-tools.zip",
|
||||||
"mv $ANDROID_HOME/cmdline-tools/cmdline-tools $ANDROID_HOME/cmdline-tools/latest",
|
"mv $ANDROID_HOME/cmdline-tools/cmdline-tools $ANDROID_HOME/cmdline-tools/latest",
|
||||||
"yes | sdkmanager --licenses",
|
"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-33' 'build-tools;34.0.0' 'ndk;25.2.9519653'"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
provisioner "shell" {
|
provisioner "shell" {
|
||||||
inline = [
|
inline = [
|
||||||
|
"echo 'export PATH=/usr/local/bin/:$PATH' >> ~/.zprofile",
|
||||||
"source ~/.zprofile",
|
"source ~/.zprofile",
|
||||||
"brew install xcodesorg/made/xcodes",
|
"wget --quiet https://github.com/RobotsAndPencils/xcodes/releases/latest/download/xcodes.zip",
|
||||||
|
"unzip xcodes.zip",
|
||||||
|
"rm xcodes.zip",
|
||||||
|
"chmod +x xcodes",
|
||||||
|
"sudo mkdir -p /usr/local/bin/",
|
||||||
|
"sudo mv xcodes /usr/local/bin/xcodes",
|
||||||
"xcodes version",
|
"xcodes version",
|
||||||
|
"wget --quiet https://storage.googleapis.com/xcodes-cache/Xcode_${var.xcode_version}.xip",
|
||||||
|
"xcodes install ${var.xcode_version} --experimental-unxip --path $PWD/Xcode_${var.xcode_version}.xip",
|
||||||
|
"sudo rm -rf ~/.Trash/*",
|
||||||
|
"xcodes select ${var.xcode_version}",
|
||||||
|
"xcodebuild -downloadAllPlatforms",
|
||||||
|
"xcodebuild -runFirstLaunch",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
provisioner "file" {
|
|
||||||
sources = [ for version in var.xcode_version : pathexpand("~/XcodesCache/Xcode_${version}.xip")]
|
|
||||||
destination = "/Users/admin/Downloads/"
|
|
||||||
}
|
|
||||||
|
|
||||||
// iterate over all Xcode versions and install them
|
|
||||||
// select the latest one as the default
|
|
||||||
dynamic "provisioner" {
|
|
||||||
for_each = local.xcode_install_provisioners
|
|
||||||
labels = ["shell"]
|
|
||||||
content {
|
|
||||||
inline = provisioner.value.inline
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
provisioner "shell" {
|
|
||||||
inline = [
|
|
||||||
"source ~/.zprofile",
|
|
||||||
"sudo xcodes select '${var.xcode_version[0]}'",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
provisioner "shell" {
|
|
||||||
inline = concat(
|
|
||||||
["source ~/.zprofile"],
|
|
||||||
[
|
|
||||||
for runtime in var.additional_runtimes : "sudo xcodes runtimes install ${runtime}"
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
provisioner "shell" {
|
provisioner "shell" {
|
||||||
inline = [
|
inline = [
|
||||||
"source ~/.zprofile",
|
"source ~/.zprofile",
|
||||||
@@ -173,11 +116,9 @@ build {
|
|||||||
inline = [
|
inline = [
|
||||||
"source ~/.zprofile",
|
"source ~/.zprofile",
|
||||||
"brew install libimobiledevice ideviceinstaller ios-deploy fastlane carthage",
|
"brew install libimobiledevice ideviceinstaller ios-deploy fastlane carthage",
|
||||||
"brew install xcbeautify",
|
"sudo gem update",
|
||||||
"gem update",
|
"sudo gem install cocoapods",
|
||||||
"gem install cocoapods",
|
"sudo gem uninstall --ignore-dependencies ffi && sudo gem install ffi -- --enable-libffi-alloc"
|
||||||
"gem install xcpretty",
|
|
||||||
"gem uninstall --ignore-dependencies ffi && gem install ffi -- --enable-libffi-alloc"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,8 +127,7 @@ build {
|
|||||||
inline = [
|
inline = [
|
||||||
"source ~/.zprofile",
|
"source ~/.zprofile",
|
||||||
"brew install graphicsmagick imagemagick",
|
"brew install graphicsmagick imagemagick",
|
||||||
"brew install wix/brew/applesimutils",
|
"brew install wix/brew/applesimutils"
|
||||||
"brew install gnupg"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,12 +135,14 @@ build {
|
|||||||
provisioner "shell" {
|
provisioner "shell" {
|
||||||
inline = [
|
inline = [
|
||||||
"source ~/.zprofile",
|
"source ~/.zprofile",
|
||||||
|
"sudo security delete-certificate -Z FF6797793A3CD798DC5B2ABEF56F73EDC9F83A64 /Library/Keychains/System.keychain",
|
||||||
|
"curl -o add-certificate.swift https://raw.githubusercontent.com/actions/runner-images/fb3b6fd69957772c1596848e2daaec69eabca1bb/images/macos/provision/configuration/add-certificate.swift",
|
||||||
|
"swiftc add-certificate.swift",
|
||||||
|
"sudo mv ./add-certificate /usr/local/bin/add-certificate",
|
||||||
"curl -o AppleWWDRCAG3.cer https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer",
|
"curl -o AppleWWDRCAG3.cer https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer",
|
||||||
"curl -o DeveloperIDG2CA.cer https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer",
|
"curl -o DeveloperIDG2CA.cer https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer",
|
||||||
"curl -o add-certificate.swift https://raw.githubusercontent.com/actions/runner-images/fb3b6fd69957772c1596848e2daaec69eabca1bb/images/macos/provision/configuration/add-certificate.swift",
|
"sudo add-certificate AppleWWDRCAG3.cer",
|
||||||
"swiftc -suppress-warnings add-certificate.swift",
|
"sudo add-certificate DeveloperIDG2CA.cer",
|
||||||
"sudo ./add-certificate AppleWWDRCAG3.cer",
|
|
||||||
"sudo ./add-certificate DeveloperIDG2CA.cer",
|
|
||||||
"rm add-certificate* *.cer"
|
"rm add-certificate* *.cer"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -211,54 +153,4 @@ build {
|
|||||||
"flutter doctor"
|
"flutter doctor"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
// check there is at least 15GB of free space and fail if not
|
|
||||||
provisioner "shell" {
|
|
||||||
inline = [
|
|
||||||
"source ~/.zprofile",
|
|
||||||
"df -h",
|
|
||||||
"export FREE_MB=$(df -m | awk '{print $4}' | head -n 2 | tail -n 1)",
|
|
||||||
"[[ $FREE_MB -gt ${var.disk_free_mb} ]] && echo OK || exit 1"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// some other health checks
|
|
||||||
provisioner "shell" {
|
|
||||||
inline = [
|
|
||||||
"source ~/.zprofile",
|
|
||||||
"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"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
macos_version = "sonoma"
|
||||||
|
gha_version = "2.311.0"
|
||||||
|
xcode_version = "15.1"
|
||||||
Reference in New Issue
Block a user