208 lines
9.6 KiB
YAML
208 lines
9.6 KiB
YAML
name: Build Full Installer ISO/DMG image
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
macos_version:
|
|
description: "Choose a macOS version to build."
|
|
required: true
|
|
type: choice
|
|
options:
|
|
- ''
|
|
- 'Tahoe'
|
|
- 'Sequoia'
|
|
- 'Sonoma'
|
|
- 'Ventura'
|
|
- 'Monterey'
|
|
- 'Big Sur'
|
|
- 'Catalina'
|
|
- 'Mojave'
|
|
- 'High Sierra'
|
|
- 'Sierra'
|
|
- 'El Capitan'
|
|
- 'Yosemite'
|
|
- 'Mavericks'
|
|
- 'Mountain Lion'
|
|
- 'Lion'
|
|
image_format:
|
|
description: "Choose 'iso' for virtual machines, 'dmg' for flash to USB drive."
|
|
required: true
|
|
type: choice
|
|
options:
|
|
- ''
|
|
- 'iso'
|
|
- 'dmg'
|
|
|
|
jobs:
|
|
preflight:
|
|
if: ${{ inputs.macos_version != '' && inputs.image_format != '' }}
|
|
runs-on: ubuntu-slim
|
|
timeout-minutes: 5
|
|
outputs:
|
|
_build: ${{ steps.check.outputs._build }}
|
|
|
|
steps:
|
|
- name: Preflight
|
|
id: check
|
|
run: |
|
|
# Third time's the charm
|
|
if [ ${{ github.run_attempt }} -ge 3 ]; then
|
|
echo "_build=true" >> $GITHUB_OUTPUT
|
|
exit 0
|
|
fi
|
|
|
|
FOUND=false
|
|
PAGE=1
|
|
while [ $PAGE -le 50 ]; do
|
|
DATA=$(curl -s \
|
|
-H "Accept: application/vnd.github+json" \
|
|
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
|
|
"https://api.github.com/repos/LongQT-sea/macos-iso-builder/stargazers?per_page=100&page=${PAGE}")
|
|
echo "$DATA" | jq -e --arg user "$GITHUB_ACTOR" 'any(.[]; .login == $user)' > /dev/null && FOUND=true && break
|
|
[ "$(echo "$DATA" | grep -c '"login"')" -lt 100 ] && break
|
|
PAGE=$((PAGE + 1))
|
|
done
|
|
|
|
if [ "$FOUND" = "false" ]; then
|
|
if [ ${{ github.run_attempt }} -eq 1 ]; then
|
|
echo "## Before you build — check if someone already did it for you :point_down:" >> $GITHUB_STEP_SUMMARY
|
|
echo "Browse the **[Recent Forks List](https://github.com/LongQT-sea/macos-iso-builder/releases/latest)** — someone may have already built the macOS version you need." >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "> [!TIP]" >> $GITHUB_STEP_SUMMARY
|
|
echo "> Too lazy to browse? Click **Re-run all jobs** and I'll search recent forks for you automatically. :mag:" >> $GITHUB_STEP_SUMMARY
|
|
echo "> Otherwise, star :star: [LongQT-sea/macos-iso-builder](https://github.com/LongQT-sea/macos-iso-builder) to go straight to build next time." >> $GITHUB_STEP_SUMMARY
|
|
echo "> <br>" >> $GITHUB_STEP_SUMMARY
|
|
else
|
|
VERSION_NORMALIZED=$(echo "${{ inputs.macos_version }}" | tr ' ' '_')
|
|
FORMAT="${{ inputs.image_format }}"
|
|
FOUND_RUN_URL=""
|
|
FOUND_ARTIFACT_NAME=""
|
|
PAST_15_DAYS=$(date -u -d '15 days ago' +%Y-%m-%dT%H:%M:%SZ)
|
|
PAGE=1
|
|
|
|
while true; do
|
|
FORKS=$(curl -s \
|
|
-H "Accept: application/vnd.github+json" \
|
|
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
|
|
"https://api.github.com/repos/LongQT-sea/macos-iso-builder/forks?sort=newest&per_page=100&page=${PAGE}")
|
|
[ "$(echo "$FORKS" | jq 'length')" -eq 0 ] && break
|
|
RECENT=$(echo "$FORKS" | jq -r --arg date "$PAST_15_DAYS" \
|
|
'.[] | select(.created_at > $date) | .full_name')
|
|
[ -z "$RECENT" ] && break
|
|
while IFS= read -r fork_full_name; do
|
|
[ -z "$fork_full_name" ] && continue
|
|
RUN_ID=$(curl -s \
|
|
-H "Accept: application/vnd.github+json" \
|
|
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
|
|
"https://api.github.com/repos/${fork_full_name}/actions/runs?status=success&per_page=10" \
|
|
| jq -r --arg date "$PAST_15_DAYS" '
|
|
.workflow_runs[]
|
|
| select(.name == "Build Full Installer ISO/DMG image")
|
|
| select(.created_at > $date)
|
|
| .id' | head -1)
|
|
[ -z "$RUN_ID" ] || [ "$RUN_ID" = "null" ] && continue
|
|
MATCH=$(curl -s \
|
|
-H "Accept: application/vnd.github+json" \
|
|
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
|
|
"https://api.github.com/repos/${fork_full_name}/actions/runs/${RUN_ID}/artifacts" \
|
|
| jq -r --arg v "macOS_${VERSION_NORMALIZED}" --arg f "$FORMAT" '
|
|
.artifacts[]
|
|
| select(.name | startswith($v) and (endswith($f) or endswith($f + ".img")))
|
|
| select(.expired == false)
|
|
| .name' | head -1)
|
|
if [ -n "$MATCH" ] && [ "$MATCH" != "null" ]; then
|
|
FOUND_RUN_URL="https://github.com/${fork_full_name}/actions/runs/${RUN_ID}"
|
|
FOUND_ARTIFACT_NAME="$MATCH"
|
|
break 2
|
|
fi
|
|
done < <(echo "$RECENT")
|
|
PAGE=$((PAGE + 1))
|
|
done
|
|
|
|
if [ -n "$FOUND_RUN_URL" ]; then
|
|
echo "## Found **${FOUND_ARTIFACT_NAME}** in a recent fork" >> $GITHUB_STEP_SUMMARY
|
|
echo "**[${FOUND_RUN_URL}](${FOUND_RUN_URL})**" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "1. Open the link above" >> $GITHUB_STEP_SUMMARY
|
|
echo "2. Scroll down to the **Artifacts** section" >> $GITHUB_STEP_SUMMARY
|
|
echo "3. Click **${FOUND_ARTIFACT_NAME}** to download" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "> [!TIP]" >> $GITHUB_STEP_SUMMARY
|
|
echo "> Want to build your own latest version? Star :star: [LongQT-sea/macos-iso-builder](https://github.com/LongQT-sea/macos-iso-builder) to skip this search and go straight to build next time." >> $GITHUB_STEP_SUMMARY
|
|
echo "> <br>" >> $GITHUB_STEP_SUMMARY
|
|
else
|
|
echo "## No recent builds found in forks." >> $GITHUB_STEP_SUMMARY
|
|
echo "Star :star: [LongQT-sea/macos-iso-builder](https://github.com/LongQT-sea/macos-iso-builder) to skip this search and go straight to build next time." >> $GITHUB_STEP_SUMMARY
|
|
echo "<br>" >> $GITHUB_STEP_SUMMARY
|
|
echo "_build=true" >> $GITHUB_OUTPUT
|
|
fi
|
|
fi
|
|
exit 0
|
|
fi
|
|
|
|
echo "_build=true" >> $GITHUB_OUTPUT
|
|
|
|
build-macos-image:
|
|
needs: preflight
|
|
if: needs.preflight.outputs._build == 'true'
|
|
runs-on: macos-15-intel
|
|
timeout-minutes: 80
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v6
|
|
|
|
- name: System Information
|
|
run: |
|
|
echo "Runner OS: $(sw_vers -productName) $(sw_vers -productVersion)"
|
|
echo "Architecture: $(uname -m)"
|
|
echo ""
|
|
df -h $(mktemp)
|
|
echo ""
|
|
echo "RAM: $(top -l 1 | grep PhysMem)"
|
|
echo ""
|
|
echo "CPU: $(sysctl -n machdep.cpu.brand_string)"
|
|
|
|
- name: Create macOS image
|
|
id: create_image
|
|
run: |
|
|
./mkmaciso "${{ inputs.macos_version }}" "${{ inputs.image_format }}"
|
|
if [ "${{ inputs.image_format }}" == "iso" ]; then
|
|
echo "image_name=$(basename *.iso)" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "image_name=$(basename *.dmg.img)" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
- name: Upload artifact
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
path: ${{ steps.create_image.outputs.image_name }}
|
|
compression-level: 0
|
|
retention-days: 15
|
|
archive: false
|
|
|
|
- name: Summary
|
|
if: always()
|
|
run: |
|
|
if [ "${{ steps.create_image.outcome }}" == "failure" ]; then
|
|
echo "## Download macOS failed" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY
|
|
echo "> This runner may have network issues. Please **re-run the workflow** to try a different runner." >> $GITHUB_STEP_SUMMARY
|
|
elif [ "${{ job.status }}" == "success" ]; then
|
|
if [ "${{ inputs.image_format }}" == "iso" ]; then
|
|
echo "## Successfully built $(basename *.iso)" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "> [!Important]" >> $GITHUB_STEP_SUMMARY
|
|
echo "> This ISO image is intended for creating macOS virtual machines on Proxmox VE, QEMU, VMware, and VirtualBox." >> $GITHUB_STEP_SUMMARY
|
|
else
|
|
echo "## Successfully built $(basename *.dmg.img)" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "> [!Important]" >> $GITHUB_STEP_SUMMARY
|
|
echo '> This DMG image is intended for flashing to USB drive using [Rufus](https://rufus.ie/en/#download) *(Windows)* or `dd` *(Linux)*.' >> $GITHUB_STEP_SUMMARY
|
|
fi
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "> [!TIP]" >> $GITHUB_STEP_SUMMARY
|
|
echo "> Enable [Cloudflare WARP](https://one.one.one.one/) for faster download from GitHub artifact." >> $GITHUB_STEP_SUMMARY
|
|
fi
|