Skip to content

macOS

macOS #5737

Workflow file for this run

name: macOS
on:
push:
branches-ignore:
- 'l10n_**' # Push events to translation service branches (that begin with "l10n_")
pull_request:
# Match all pull requests...
paths-ignore:
# Except some text-only files / documentation
- 'ChangeLog'
# Except those that only include changes to stats
- 'data/base/stats/**'
- 'data/mp/stats/**'
- 'data/mp/multiplay/script/functions/camTechEnabler.js'
# Linux-specific example scripts
- 'doc/hosting/linux_scripts/**'
# Support running after "Draft Tag Release" workflow completes, as part of automated release process
workflow_run:
workflows: ["Draft Tag Release"]
push:
tags:
- '*'
types:
- completed
jobs:
macos-build:
strategy:
matrix:
include:
- name: "Xcode 14.3 (x64)"
image: "macos-13"
osx_target_arch: "x86_64"
vcpkg_triplet: "x64-osx"
xcode_dev_dir: "/Applications/Xcode_14.3.1.app"
include_videos: false
artifact_suffix: "x64"
publish_artifact: true
- name: "Xcode 14.3 (ARM64)"
image: "macos-13"
osx_target_arch: "arm64"
vcpkg_triplet: "arm64-osx"
xcode_dev_dir: "/Applications/Xcode_14.3.1.app"
include_videos: true
artifact_suffix: "arm64"
publish_artifact: true
fail-fast: false
name: '${{ matrix.name }}'
permissions:
contents: read
runs-on: '${{ matrix.image }}'
if: "!contains(github.event.head_commit.message, '[ci skip]')"
env:
MACOSX_DEPLOYMENT_TARGET: '10.13'
VSCMD_SKIP_SENDTELEMETRY: 1
DESIRED_XCODE_DEV_DIR: '${{ matrix.xcode_dev_dir }}'
WZ_INCLUDE_VIDEOS: '${{ matrix.include_videos }}'
WZ_OSX_TARGET_ARCH: '${{ matrix.osx_target_arch }}'
VCPKG_DEFAULT_TRIPLET: '${{ matrix.vcpkg_triplet }}'
ARCHS: '${{ matrix.osx_target_arch }}'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
path: 'src'
- name: Configure Repo Checkout
id: checkout-config
working-directory: ./src
env:
WORKFLOW_RUN_CONCLUSION: ${{ github.event.workflow_run.conclusion }}
WORKFLOW_RUN_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
run: |
. .ci/githubactions/checkout_config.sh
- name: Prepare Git Repo for autorevision
working-directory: ./src
run: cmake -P .ci/githubactions/prepare_git_repo.cmake
- name: Init Git Submodules
working-directory: ./src
run: git submodule update --init --recursive
- name: Install Pre-reqs
env:
HOMEBREW_NO_AUTO_UPDATE: 1
HOMEBREW_NO_INSTALL_UPGRADE: 1
run: |
echo "::group::brew install"
brew install --quiet automake gettext pkg-config xcbeautify
echo "::endgroup::"
# NOTE: Specify an explicit Asciidoctor version to help ensure reproducible builds
echo "::group::gem install asciidoctor"
gem install asciidoctor -v 2.0.23 --no-document
echo "::endgroup::"
#if (brew outdated | grep cmake > /dev/null); then echo "upgrading CMake"; brew upgrade cmake; fi
cmake --version
- name: Prep Environment
run: |
mkdir build
mkdir output
echo "OUTPUT_DIR=output" >> $GITHUB_ENV
WZ_DISTRIBUTOR="UNKNOWN"
if [ "${GITHUB_REPOSITORY}" == "Warzone2100/warzone2100" ]; then
WZ_DISTRIBUTOR="wz2100.net"
fi
echo "WZ_DISTRIBUTOR=${WZ_DISTRIBUTOR}"
echo "WZ_DISTRIBUTOR=${WZ_DISTRIBUTOR}" >> $GITHUB_ENV
echo "Setting Xcode: ${DESIRED_XCODE_DEV_DIR}"
sudo xcode-select -s "${DESIRED_XCODE_DEV_DIR}"
echo "MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET}"
echo "VCPKG_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET}" >> $GITHUB_ENV
echo "VCPKG_KEEP_ENV_VARS=VCPKG_OSX_DEPLOYMENT_TARGET;MACOSX_DEPLOYMENT_TARGET" >> $GITHUB_ENV
- name: configure_mac.cmake
working-directory: ./build
env:
SENTRY_IO_DSN: '${{ secrets.CRASHREPORTING_SENTRY_IO_DSN }}'
DISCORD_RPC_APPID: '${{ secrets.DISCORD_RPC_APPID }}'
run: |
ADDITIONAL_CMAKE_ARGUMENTS="-DCMAKE_OSX_ARCHITECTURES=${WZ_OSX_TARGET_ARCH};-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY=-;-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO;-DENABLE_DISCORD:BOOL=ON"
echo "WZ_INCLUDE_VIDEOS=${WZ_INCLUDE_VIDEOS}"
if [ "${WZ_INCLUDE_VIDEOS}" == "true" ]; then
ADDITIONAL_CMAKE_ARGUMENTS="${ADDITIONAL_CMAKE_ARGUMENTS};-DWZ_INCLUDE_VIDEOS:BOOL=ON"
else
ADDITIONAL_CMAKE_ARGUMENTS="${ADDITIONAL_CMAKE_ARGUMENTS};-DWZ_INCLUDE_VIDEOS:BOOL=OFF"
fi
echo "ADDITIONAL_CMAKE_ARGUMENTS=${ADDITIONAL_CMAKE_ARGUMENTS}"
WZ_ENABLE_SENTRY="false"
if [[ "${GITHUB_EVENT_NAME}" == "push" ]] && [[ "${GITHUB_REF}" == "refs/heads/master" ]]; then
WZ_ENABLE_SENTRY="true"
fi
if [[ "${GITHUB_EVENT_NAME}" == "workflow_run" ]]; then
WZ_ENABLE_SENTRY="true"
fi
# Always build Sentry anyway, even if we don't pass the configuration to actually enable it
ADDITIONAL_CMAKE_ARGUMENTS="${ADDITIONAL_CMAKE_ARGUMENTS};-DWZ_BUILD_SENTRY:BOOL=ON"
if [[ "${WZ_ENABLE_SENTRY}" == "true" ]] && [[ ! -z "${SENTRY_IO_DSN}" ]]; then
# Pass the configuration to enable it
ADDITIONAL_CMAKE_ARGUMENTS="${ADDITIONAL_CMAKE_ARGUMENTS};-DSENTRY_IO_DSN:STRING=${SENTRY_IO_DSN}"
fi
if [[ ! -z "${DISCORD_RPC_APPID}" ]]; then
ADDITIONAL_CMAKE_ARGUMENTS="${ADDITIONAL_CMAKE_ARGUMENTS};-DDISCORD_RPC_APPID:STRING=${DISCORD_RPC_APPID}"
fi
#cmake -DVCPKG_BUILD_TYPE=release -DWZ_DISTRIBUTOR:STRING="${WZ_DISTRIBUTOR}" -DADDITIONAL_CMAKE_ARGUMENTS="${ADDITIONAL_CMAKE_ARGUMENTS}" -P ../src/configure_mac.cmake
cmake -DADDITIONAL_VCPKG_FLAGS=--no-binarycaching -DVCPKG_BUILD_TYPE=release -DWZ_DISTRIBUTOR:STRING="${WZ_DISTRIBUTOR}" -DADDITIONAL_CMAKE_ARGUMENTS="${ADDITIONAL_CMAKE_ARGUMENTS}" -P ../src/configure_mac.cmake
result=${?}
if [ $result -ne 0 ]; then
echo "ERROR: configure_mac.cmake failed"
exit ${result}
fi
- name: Build Xcode project
working-directory: ./build
run: |
# Build Xcode project, and package "warzone2100.zip"
set -o pipefail && \
xcodebuild \
-project warzone2100.xcodeproj \
-target "package" \
-configuration "Release" \
-destination "platform=macOS" \
-PBXBuildsContinueAfterErrors=NO \
| tee "xcodebuild.log" | xcbeautify --renderer github-actions
result=${?}
if [ $result -ne 0 ]; then
echo "ERROR: xcodebuild failed"
exit ${result}
fi
- name: Output Build Info
shell: sh {0}
run: |
echo "OUTPUT_DIR=${OUTPUT_DIR}"
echo "[autorevision.h]:"
cat "build/build_tools/autorevision.h"
echo "==============================="
echo "[netplay_config.h]:"
cat "build/lib/netplay/netplay_config.h"
echo "==============================="
# Verify "warzone2100.zip" was created
BUILT_WARZONE_ZIP="build/warzone2100.zip"
src/platforms/macos/BuildBot/check_warzone2100_zip.sh "${BUILT_WARZONE_ZIP}" "build/tmp/"
# Move warzone2100.zip to the output directory, renaming it
DESIRED_ZIP_NAME="warzone2100_macOS_${{ matrix.artifact_suffix }}.zip"
mv "$BUILT_WARZONE_ZIP" "${OUTPUT_DIR}/${DESIRED_ZIP_NAME}"
result=${?}
if [ $result -ne 0 ]; then
echo "ERROR: Failed to move zip file"
exit ${result}
fi
echo "Generated warzone2100.zip: \"${OUTPUT_DIR}/${DESIRED_ZIP_NAME}\""
ZIP_HASH="$(shasum -a 512 "${OUTPUT_DIR}/${DESIRED_ZIP_NAME}")"
ZIP_SIZE="$(stat -f '%z' "${OUTPUT_DIR}/${DESIRED_ZIP_NAME}")"
echo " -> SHA512: ${ZIP_HASH}"
echo " -> Size (bytes): ${ZIP_SIZE}"
echo "WZ_FULL_OUTPUT_ZIP_PATH=${OUTPUT_DIR}/${DESIRED_ZIP_NAME}" >> $GITHUB_ENV
exit 0
- uses: actions/upload-artifact@v4
if: success() && (matrix.publish_artifact == true)
with:
name: "warzone2100_macOS_${{ matrix.artifact_suffix }}"
path: ${{ env.OUTPUT_DIR }}
if-no-files-found: 'error'
macos_universal_combine:
name: 'Package Universal Binary'
permissions:
contents: write # Needed to upload to releases
# needed to generate artifact attestations, see: https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds
id-token: write
attestations: write
needs: macos-build
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
path: 'src'
- name: Configure Repo Checkout
id: checkout-config
working-directory: ./src
env:
WORKFLOW_RUN_CONCLUSION: ${{ github.event.workflow_run.conclusion }}
WORKFLOW_RUN_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
run: |
. .ci/githubactions/checkout_config.sh
- name: Prep Environment
run: |
mkdir dl-artifacts
mkdir build
mkdir output
echo "OUTPUT_DIR=output" >> $GITHUB_ENV
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
path: ./dl-artifacts
- name: Display structure of downloaded files
working-directory: ./dl-artifacts
run: ls -R
- name: Extract each .zip
working-directory: ./dl-artifacts
run: |
for i in ./*/*.zip; do
folder=${i%.zip}
folder="$(dirname $folder)"
unzip -o "$i" -d "$folder" && rm "$i"
done
- name: Create Universal Binary
working-directory: ./dl-artifacts
run: |
BASE_APP_BUNDLE="warzone2100_macOS_arm64/Warzone 2100.app"
# extract entitlements plist from the "base" app bundle binary
echo "Extract entitlements.plist"
codesign -d --entitlements :- "${BASE_APP_BUNDLE}/Contents/MacOS/Warzone 2100" > "entitlements.plist"
cat "entitlements.plist"
echo "-----------------------------------"
echo "Make universal binary + app package"
../src/platforms/macos/BuildBot/make_universal.sh "${BASE_APP_BUNDLE}" "warzone2100_macOS_x64/Warzone 2100.app"
# Rename the "base" app package directory
mv "warzone2100_macOS_arm64" "warzone2100_macOS_universal"
echo "Re-code-sign"
codesign --force --options runtime --entitlements "entitlements.plist" -s - "warzone2100_macOS_universal/Warzone 2100.app"
# Zip and copy to build dir
echo "Compress .zip"
cd "warzone2100_macOS_universal"
zip -vr --symlinks "../../build/warzone2100.zip" "Warzone 2100.app/"
- name: Output Build Info (Full)
shell: sh {0}
run: |
echo "OUTPUT_DIR=${OUTPUT_DIR}"
# Verify "warzone2100.zip" was created
BUILT_WARZONE_ZIP="build/warzone2100.zip"
src/platforms/macos/BuildBot/check_warzone2100_zip.sh "${BUILT_WARZONE_ZIP}" "build/tmp/"
# Move warzone2100.zip to the output directory, renaming it
DESIRED_ZIP_NAME="warzone2100_macOS_universal.zip"
mv "$BUILT_WARZONE_ZIP" "${OUTPUT_DIR}/${DESIRED_ZIP_NAME}"
result=${?}
if [ $result -ne 0 ]; then
echo "ERROR: Failed to move zip file"
exit ${result}
fi
echo "Generated warzone2100.zip: \"${OUTPUT_DIR}/${DESIRED_ZIP_NAME}\""
ZIP_HASH="$(shasum -a 512 "${OUTPUT_DIR}/${DESIRED_ZIP_NAME}")"
ZIP_SIZE="$(stat -f '%z' "${OUTPUT_DIR}/${DESIRED_ZIP_NAME}")"
echo " -> SHA512: ${ZIP_HASH}"
echo " -> Size (bytes): ${ZIP_SIZE}"
echo "WZ_FULL_OUTPUT_ZIP_PATH=${OUTPUT_DIR}/${DESIRED_ZIP_NAME}" >> $GITHUB_ENV
exit 0
- uses: actions/upload-artifact@v4
with:
name: "warzone2100_macOS_universal"
path: ${{ env.WZ_FULL_OUTPUT_ZIP_PATH }}
if-no-files-found: 'error'
- name: 'Generate artifact attestation - (full)'
# Run on push to master branch (development build), or tag release automation build
if: success() && ((github.event_name == 'push' && github.ref == 'refs/heads/master') || (github.event_name == 'workflow_run' && github.event.workflow_run.name == 'Draft Tag Release'))
uses: actions/attest-build-provenance@v1
continue-on-error: true
with:
subject-path: '${{ env.WZ_FULL_OUTPUT_ZIP_PATH }}'
- name: Upload "universal" to release
if: success() && (github.event_name == 'workflow_run' && github.event.workflow_run.name == 'Draft Tag Release') && (github.repository == 'Warzone2100/warzone2100')
run: |
SOURCE_TAG="${WZ_GITHUB_REF#refs/tags/}"
echo "Uploading: ${WZ_FULL_OUTPUT_ZIP_PATH}"
gh release upload "${SOURCE_TAG}" "${WZ_FULL_OUTPUT_ZIP_PATH}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
WZ_GITHUB_REF: ${{ steps.checkout-config.outputs.WZ_GITHUB_REF }}
- name: Clear OUTPUT_DIR
run: |
echo "OUTPUT_DIR=${OUTPUT_DIR}"
rm -rf "${OUTPUT_DIR}"
mkdir -p "${OUTPUT_DIR}"
- name: Create Universal Binary (no videos)
working-directory: ./dl-artifacts
run: |
# Remove the videos from the universal app bundle
rm "warzone2100_macOS_universal/Warzone 2100.app/Contents/Resources/data/sequences.wz"
# Re-code-sign
echo "Re-code-sign no-videos package"
codesign --force --options runtime --entitlements "entitlements.plist" -s - "warzone2100_macOS_universal/Warzone 2100.app"
# Zip and copy to build dir
echo "Compress no videos .zip"
cd "warzone2100_macOS_universal"
zip -vr --symlinks "../../build/warzone2100_novideos.zip" "Warzone 2100.app/"
- name: Output Build Info (No-Videos)
shell: sh {0}
run: |
echo "OUTPUT_DIR=${OUTPUT_DIR}"
# Verify "warzone2100_novideos.zip" was created
BUILT_WARZONE_ZIP="build/warzone2100_novideos.zip"
src/platforms/macos/BuildBot/check_warzone2100_zip.sh "${BUILT_WARZONE_ZIP}" "build/tmp/"
# Move warzone2100.zip to the output directory, renaming it
DESIRED_ZIP_NAME="warzone2100_macOS_universal_novideos.zip"
mv "$BUILT_WARZONE_ZIP" "${OUTPUT_DIR}/${DESIRED_ZIP_NAME}"
result=${?}
if [ $result -ne 0 ]; then
echo "ERROR: Failed to move zip file"
exit ${result}
fi
echo "Generated warzone2100_novideos.zip: \"${OUTPUT_DIR}/${DESIRED_ZIP_NAME}\""
ZIP_HASH="$(shasum -a 512 "${OUTPUT_DIR}/${DESIRED_ZIP_NAME}")"
ZIP_SIZE="$(stat -f '%z' "${OUTPUT_DIR}/${DESIRED_ZIP_NAME}")"
echo " -> SHA512: ${ZIP_HASH}"
echo " -> Size (bytes): ${ZIP_SIZE}"
echo "WZ_FULL_OUTPUT_ZIP_PATH=${OUTPUT_DIR}/${DESIRED_ZIP_NAME}" >> $GITHUB_ENV
exit 0
- uses: actions/upload-artifact@v4
with:
name: "warzone2100_macOS_universal_novideos"
path: ${{ env.WZ_FULL_OUTPUT_ZIP_PATH }}
if-no-files-found: 'error'
- name: 'Generate artifact attestation - (novideos)'
# Run on push to master branch (development build), or tag release automation build
if: success() && ((github.event_name == 'push' && github.ref == 'refs/heads/master') || (github.event_name == 'workflow_run' && github.event.workflow_run.name == 'Draft Tag Release'))
uses: actions/attest-build-provenance@v1
continue-on-error: true
with:
subject-path: '${{ env.WZ_FULL_OUTPUT_ZIP_PATH }}'
- name: Upload "universal_novideos" to release
if: success() && (github.event_name == 'workflow_run' && github.event.workflow_run.name == 'Draft Tag Release') && (github.repository == 'Warzone2100/warzone2100')
run: |
SOURCE_TAG="${WZ_GITHUB_REF#refs/tags/}"
echo "Uploading: ${WZ_FULL_OUTPUT_ZIP_PATH}"
gh release upload "${SOURCE_TAG}" "${WZ_FULL_OUTPUT_ZIP_PATH}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
WZ_GITHUB_REF: ${{ steps.checkout-config.outputs.WZ_GITHUB_REF }}
upload-debug-symbols:
name: 'Upload Debug Symbols'
permissions:
contents: read
runs-on: ubuntu-latest
# Run on push to master branch (development build), or tag release automation build
if: (github.repository == 'Warzone2100/warzone2100') && ((github.event_name == 'push' && github.ref == 'refs/heads/master') || (github.event_name == 'workflow_run' && github.event.workflow_run.name == 'Draft Tag Release'))
needs: macos_universal_combine
environment: upload_symbols
# For this job to work, the following secrets must be set in the 'upload_symbols' environment:
# SENTRY_AUTH_TOKEN
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
path: 'src'
- name: Prep Environment
run: |
mkdir dl-archive
echo "WZ_REPO_PATH=$(pwd)/src" >> $GITHUB_ENV
- name: Download Artifacts
uses: actions/download-artifact@v4
with:
name: 'warzone2100_macOS_universal_novideos'
path: ./dl-archive
- name: Extract archive
id: extract
run: |
OUTPUTDIR="wz-macOS"
ZIPFILE="./dl-archive/warzone2100_macOS_universal_novideos.zip"
unzip -o "${ZIPFILE}" -d "${OUTPUTDIR}" && rm "${ZIPFILE}"
echo "ARCHIVEDIR=${OUTPUTDIR}" >> $GITHUB_OUTPUT
- name: 'Upload debug symbols'
env:
SENTRY_AUTH_TOKEN: '${{ secrets.SENTRY_AUTH_TOKEN }}'
WZ_ARCHIVE_DIR: '${{ steps.extract.outputs.ARCHIVEDIR }}'
run: |
if [[ -z "${SENTRY_AUTH_TOKEN}" ]]; then
echo "No SENTRY_AUTH_TOKEN - skipping"
exit 0
fi
# Download sentry-cli
echo "::group::Downloading sentry-cli ..."
cmake -P "${WZ_REPO_PATH}/.ci/githubactions/FetchSentryCLI.cmake"
echo "Downloading sentry-cli ... Done"
echo "::endgroup::"
# Upload symbols
echo "::group::sentry-cli debug-files upload"
./sentry-cli/sentry-cli debug-files upload --no-zips -o warzone2100 -p warzone2100 "${WZ_ARCHIVE_DIR}"
echo "::endgroup::"