Files
Local Admin 1c53e698aa
Build macOS Packages / Build macOS (Intel) (push) Failing after 15s
Build macOS Packages / Build macOS (Apple Silicon) (push) Failing after 29s
Build macOS Packages / Build macOS (Universal) (push) Skipped
build fixes
2026-09-07 06:11:55 -07:00

321 lines
12 KiB
YAML

name: Build macOS Packages
# Produces, per architecture (x86_64, arm64, universal):
# TargetPrint_<tag>-<sha>-macos-<arch>.app.zip — vendored into ICCery
# TargetPrint_<tag>-<sha>-macos-<arch>.dmg — installable disk image
# plus TargetPrint_<tag>-<sha>-vendor-iccery.zip — macos-x86_64 / macos-aarch64 / macos-universal layout
on:
push:
tags:
- "v*"
branches:
- main
pull_request:
workflow_dispatch:
jobs:
build-arch:
name: Build macOS (${{ matrix.platform.name }})
runs-on: ${{ matrix.platform.os }}
env:
XDG_CONFIG_HOME: ${{ runner.temp }}/.config
strategy:
fail-fast: false
matrix:
platform:
- name: Intel
os: macos
arch: x86_64
vendor_dir: macos-x86_64
- name: Apple Silicon
os: macos
arch: arm64
vendor_dir: macos-aarch64
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Ensure workspace and git permissions
run: |
mkdir -p "${{ runner.temp }}/.config/git"
touch "${{ runner.temp }}/.config/git/ignore"
mkdir -p .git/info
touch .git/info/exclude
chmod -R u+rwX .git || true
git config --local core.excludesFile "${{ runner.temp }}/.config/git/ignore" || true
- name: Enter project root
run: |
if [ -f macos/TargetPrint.xcodeproj/project.pbxproj ]; then
echo "PROJECT_ROOT=macos" >> "$GITHUB_ENV"
else
echo "PROJECT_ROOT=." >> "$GITHUB_ENV"
fi
- name: Select Xcode
env:
XCODE_APP: ${{ vars.XCODE_APP }}
run: |
ROOT="${PROJECT_ROOT:-.}"
chmod +x "$ROOT/Scripts/select_xcode.sh"
"$ROOT/Scripts/select_xcode.sh"
- name: Show toolchain
run: |
echo "HAS_FULL_XCODE=${HAS_FULL_XCODE:-unset}"
echo "DEVELOPER_DIR=${DEVELOPER_DIR:-unset}"
echo "SDKROOT=${SDKROOT:-unset}"
echo "SWIFT=${SWIFT:-unset}"
echo "xcode-select -p: $(xcode-select -p 2>/dev/null || echo unknown)"
if [ "${HAS_FULL_XCODE:-0}" = "1" ]; then
XB="${XCODEBUILD:-xcodebuild}"
"$XB" -version
else
echo "Full Xcode.app not installed; will compile with swiftc."
"${SWIFT:-$(xcrun --find swiftc)}" --version
fi
sw_vers
uname -m
- name: Set release names
id: set_env
shell: bash
run: |
if [[ "${GITHUB_REF:-}" == refs/tags/* ]]; then
TAG="${GITHUB_REF_NAME}"
else
TAG="dev"
fi
SHORT_SHA="$(git rev-parse --short HEAD)"
PREFIX="TargetPrint_${TAG}-${SHORT_SHA}-macos-${{ matrix.platform.arch }}"
echo "TAG=${TAG}" >> "$GITHUB_ENV"
echo "SHORT_SHA=${SHORT_SHA}" >> "$GITHUB_ENV"
echo "PREFIX=${PREFIX}" >> "$GITHUB_ENV"
echo "prefix=${PREFIX}" >> "$GITHUB_OUTPUT"
- name: Make scripts executable
working-directory: ${{ env.PROJECT_ROOT }}
run: chmod +x Scripts/*.sh
- name: Run unit tests
working-directory: ${{ env.PROJECT_ROOT }}
run: |
if [ "${HAS_FULL_XCODE:-0}" != "1" ]; then
echo "Skipping XCTest — no Xcode.app (XCTest.framework is not part of CLT)."
exit 0
fi
XB="${XCODEBUILD:-xcodebuild}"
"$XB" test \
-project TargetPrint.xcodeproj \
-scheme TargetPrint \
-destination "platform=macOS" \
-only-testing:TargetPrintTests \
-jobs "$(sysctl -n hw.ncpu 2>/dev/null || echo 4)" \
-parallelizeTargets \
CODE_SIGNING_ALLOWED=NO \
ONLY_ACTIVE_ARCH=YES
- name: Build ${{ matrix.platform.arch }} .app
working-directory: ${{ env.PROJECT_ROOT }}
env:
MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
run: |
IDENTITY="${MACOS_CODESIGN_IDENTITY:--}"
export MACOS_CODESIGN_IDENTITY="$IDENTITY"
./Scripts/build_macos.sh "${{ matrix.platform.arch }}" Release
- name: Package .app.zip and .dmg
working-directory: ${{ env.PROJECT_ROOT }}
env:
MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
run: |
export MACOS_CODESIGN_IDENTITY="${MACOS_CODESIGN_IDENTITY:--}"
./Scripts/package_release.sh "${{ matrix.platform.arch }}" "${PREFIX}"
(cd build/release-assets && shasum -a 256 "${PREFIX}.app.zip" "${PREFIX}.dmg" | tee "${PREFIX}.SHA256.txt")
- name: Upload ${{ matrix.platform.arch }} .app (for universal lipo)
uses: actions/upload-artifact@v3
with:
name: app-${{ matrix.platform.arch }}
path: ${{ env.PROJECT_ROOT }}/build/apps/${{ matrix.platform.arch }}/TargetPrint.app
- name: Upload ${{ matrix.platform.arch }} packages
uses: actions/upload-artifact@v3
with:
name: ${{ env.PREFIX }}
path: ${{ env.PROJECT_ROOT }}/build/release-assets/${{ env.PREFIX }}.*
- name: Upload Release Assets to Gitea
if: ${{ startsWith(github.ref, 'refs/tags/') && !cancelled() }}
env:
GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SERVER_URL: ${{ github.server_url }}
REPO: ${{ github.repository }}
working-directory: ${{ env.PROJECT_ROOT }}
run: |
echo "Finding release for tag ${TAG}..."
RELEASE_RESP=$(curl -s -H "Authorization: token ${GITEA_TOKEN}" \
"${SERVER_URL}/api/v1/repos/${REPO}/releases/tags/${TAG}")
RELEASE_ID=$(echo "${RELEASE_RESP}" | grep -o '"id":[0-9]*' | head -n 1 | cut -d: -f2)
if [ -n "${RELEASE_ID}" ]; then
echo "Found Release ID: ${RELEASE_ID}. Uploading ${PREFIX} assets..."
for f in build/release-assets/${PREFIX}.app.zip \
build/release-assets/${PREFIX}.dmg \
build/release-assets/${PREFIX}.SHA256.txt; do
if [ -f "$f" ]; then
FILENAME=$(basename "$f")
echo "Uploading $FILENAME..."
curl -s -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: multipart/form-data" \
-F "attachment=@$f" \
"${SERVER_URL}/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets?name=${FILENAME}"
fi
done
else
echo "No existing release found for tag ${TAG}. Skipping asset upload."
fi
build-universal:
name: Build macOS (Universal)
needs: build-arch
runs-on: macos
env:
XDG_CONFIG_HOME: ${{ runner.temp }}/.config
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Enter project root
run: |
if [ -f macos/TargetPrint.xcodeproj/project.pbxproj ]; then
echo "PROJECT_ROOT=macos" >> "$GITHUB_ENV"
else
echo "PROJECT_ROOT=." >> "$GITHUB_ENV"
fi
- name: Select Xcode
env:
XCODE_APP: ${{ vars.XCODE_APP }}
run: |
ROOT="${PROJECT_ROOT:-.}"
chmod +x "$ROOT/Scripts/select_xcode.sh"
"$ROOT/Scripts/select_xcode.sh"
- name: Set release names
shell: bash
run: |
if [[ "${GITHUB_REF:-}" == refs/tags/* ]]; then
TAG="${GITHUB_REF_NAME}"
else
TAG="dev"
fi
SHORT_SHA="$(git rev-parse --short HEAD)"
PREFIX="TargetPrint_${TAG}-${SHORT_SHA}-macos-universal"
echo "TAG=${TAG}" >> "$GITHUB_ENV"
echo "SHORT_SHA=${SHORT_SHA}" >> "$GITHUB_ENV"
echo "PREFIX=${PREFIX}" >> "$GITHUB_ENV"
echo "VENDOR_PREFIX=TargetPrint_${TAG}-${SHORT_SHA}-vendor-iccery" >> "$GITHUB_ENV"
- name: Download Intel .app
uses: actions/download-artifact@v3
with:
name: app-x86_64
path: ${{ env.PROJECT_ROOT }}/build/apps/x86_64
- name: Download Apple Silicon .app
uses: actions/download-artifact@v3
with:
name: app-arm64
path: ${{ env.PROJECT_ROOT }}/build/apps/arm64
- name: Make scripts executable
working-directory: ${{ env.PROJECT_ROOT }}
run: chmod +x Scripts/*.sh
- name: Lipo Universal 2 .app
working-directory: ${{ env.PROJECT_ROOT }}
env:
MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
run: |
export MACOS_CODESIGN_IDENTITY="${MACOS_CODESIGN_IDENTITY:--}"
# upload-artifact may nest as TargetPrint.app/ or as Contents/ at the root
for arch in x86_64 arm64; do
base="build/apps/${arch}"
if [ ! -x "${base}/TargetPrint.app/Contents/MacOS/TargetPrint" ] \
&& [ -x "${base}/Contents/MacOS/TargetPrint" ]; then
mkdir -p "${base}/TargetPrint.app"
# Move bundle contents into TargetPrint.app
shopt -s dotglob
mv "${base}/Contents" "${base}/PkgInfo" "${base}/Resources" "${base}/Info.plist" \
"${base}/_CodeSignature" "${base}/TargetPrint.app/" 2>/dev/null || true
shopt -u dotglob
fi
test -x "${base}/TargetPrint.app/Contents/MacOS/TargetPrint"
lipo -info "${base}/TargetPrint.app/Contents/MacOS/TargetPrint"
done
./Scripts/make_universal.sh
lipo -info build/apps/universal/TargetPrint.app/Contents/MacOS/TargetPrint
- name: Package universal .app.zip, .dmg, and ICCery vendor zip
working-directory: ${{ env.PROJECT_ROOT }}
env:
MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
run: |
export MACOS_CODESIGN_IDENTITY="${MACOS_CODESIGN_IDENTITY:--}"
./Scripts/package_release.sh x86_64 "TargetPrint_${TAG}-${SHORT_SHA}-macos-x86_64"
./Scripts/package_release.sh arm64 "TargetPrint_${TAG}-${SHORT_SHA}-macos-arm64"
./Scripts/package_release.sh universal "${PREFIX}"
./Scripts/vendor_bundle.sh "${VENDOR_PREFIX}"
(cd build/release-assets && shasum -a 256 \
"${PREFIX}.app.zip" "${PREFIX}.dmg" "${VENDOR_PREFIX}.zip" \
| tee "${PREFIX}.SHA256.txt")
- name: Upload universal packages
uses: actions/upload-artifact@v3
with:
name: ${{ env.PREFIX }}
path: |
${{ env.PROJECT_ROOT }}/build/release-assets/${{ env.PREFIX }}.*
${{ env.PROJECT_ROOT }}/build/release-assets/${{ env.VENDOR_PREFIX }}.zip
- name: Upload ICCery vendor tree
uses: actions/upload-artifact@v3
with:
name: ${{ env.VENDOR_PREFIX }}
path: ${{ env.PROJECT_ROOT }}/build/release-assets/vendor-iccery
- name: Upload Release Assets to Gitea
if: ${{ startsWith(github.ref, 'refs/tags/') && !cancelled() }}
env:
GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SERVER_URL: ${{ github.server_url }}
REPO: ${{ github.repository }}
working-directory: ${{ env.PROJECT_ROOT }}
run: |
echo "Finding release for tag ${TAG}..."
RELEASE_RESP=$(curl -s -H "Authorization: token ${GITEA_TOKEN}" \
"${SERVER_URL}/api/v1/repos/${REPO}/releases/tags/${TAG}")
RELEASE_ID=$(echo "${RELEASE_RESP}" | grep -o '"id":[0-9]*' | head -n 1 | cut -d: -f2)
if [ -n "${RELEASE_ID}" ]; then
echo "Found Release ID: ${RELEASE_ID}. Uploading universal + vendor assets..."
for f in build/release-assets/${PREFIX}.app.zip \
build/release-assets/${PREFIX}.dmg \
build/release-assets/${PREFIX}.SHA256.txt \
build/release-assets/${VENDOR_PREFIX}.zip; do
if [ -f "$f" ]; then
FILENAME=$(basename "$f")
echo "Uploading $FILENAME..."
curl -s -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: multipart/form-data" \
-F "attachment=@$f" \
"${SERVER_URL}/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets?name=${FILENAME}"
fi
done
else
echo "No existing release found for tag ${TAG}. Skipping asset upload."
fi