diff --git a/.travis.yml b/.travis.yml index b0a75f1..bc6af3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,17 @@ # Travis-CI Build for OpenRAModSDK # see travis-ci.org for details -dist: xenial language: csharp mono: 6.4.0 +jobs: + include: + - os: linux + dist: xenial + - os: osx + if: tag IS present + osx_image: xcode10 + addons: apt: packages: @@ -19,13 +26,13 @@ script: if [ "${TRAVIS_TEST_MOD}" == "True" ]; then make test || travis_terminate 1; fi; - if [ "${TRAVIS_TEST_PACKAGING}" == "True" ] || [ -n "${TRAVIS_TAG}" ]; then + if [ "$TRAVIS_OS_NAME" == "linux" ] && ( [ "${TRAVIS_TEST_PACKAGING}" == "True" ] || [ -n "${TRAVIS_TAG}" ] ); then wget http://mirrors.kernel.org/ubuntu/pool/universe/n/nsis/nsis-common_3.03-2_all.deb || travis_terminate 1; wget http://mirrors.kernel.org/ubuntu/pool/universe/n/nsis/nsis_3.03-2_amd64.deb || travis_terminate 1; sudo dpkg -i nsis-common_3.03-2_all.deb || travis_terminate 1; sudo dpkg -i nsis_3.03-2_amd64.deb || travis_terminate 1; fi - if [ "${TRAVIS_TEST_PACKAGING}" == "True" ] && [ -z "${TRAVIS_TAG}" ]; then + if [ "$TRAVIS_OS_NAME" == "linux" ] && [ "${TRAVIS_TEST_PACKAGING}" == "True" ] && [ -z "${TRAVIS_TAG}" ]; then make check-packaging-scripts && ./packaging/package-all.sh test-0 || travis_terminate 1; fi @@ -36,13 +43,8 @@ before_deploy: deploy: provider: releases api_key: ${GH_DEPLOY_API_KEY} - file: - - build/${PACKAGING_INSTALLER_NAME}-${TRAVIS_TAG}-x86.exe - - build/${PACKAGING_INSTALLER_NAME}-${TRAVIS_TAG}-x64.exe - - build/${PACKAGING_INSTALLER_NAME}-${TRAVIS_TAG}-x86-winportable.zip - - build/${PACKAGING_INSTALLER_NAME}-${TRAVIS_TAG}-x64-winportable.zip - - build/${PACKAGING_INSTALLER_NAME}-${TRAVIS_TAG}-macOS.zip - - build/${PACKAGING_INSTALLER_NAME}-${TRAVIS_TAG}-x86_64.AppImage + file_glob: true + file: build/* skip_cleanup: true on: tags: true diff --git a/Makefile b/Makefile index e7d0ada..e7ba025 100644 --- a/Makefile +++ b/Makefile @@ -67,7 +67,7 @@ check-sdk-scripts: fi check-packaging-scripts: - @if [ ! -x "packaging/package-all.sh" ] || [ ! -x "packaging/linux/buildpackage.sh" ] || [ ! -x "packaging/osx/buildpackage.sh" ] || [ ! -x "packaging/windows/buildpackage.sh" ]; then \ + @if [ ! -x "packaging/package-all.sh" ] || [ ! -x "packaging/linux/buildpackage.sh" ] || [ ! -x "packaging/macos/buildpackage.sh" ] || [ ! -x "packaging/windows/buildpackage.sh" ]; then \ echo "Required SDK scripts are not executable:"; \ if [ ! -x "packaging/package-all.sh" ]; then \ echo " packaging/package-all.sh"; \ @@ -75,8 +75,8 @@ check-packaging-scripts: if [ ! -x "packaging/linux/buildpackage.sh" ]; then \ echo " packaging/linux/buildpackage.sh"; \ fi; \ - if [ ! -x "packaging/osx/buildpackage.sh" ]; then \ - echo " packaging/osx/buildpackage.sh"; \ + if [ ! -x "packaging/macos/buildpackage.sh" ]; then \ + echo " packaging/macos/buildpackage.sh"; \ fi; \ if [ ! -x "packaging/windows/buildpackage.sh" ]; then \ echo " packaging/windows/buildpackage.sh"; \ diff --git a/mod.config b/mod.config index a665739..944666c 100644 --- a/mod.config +++ b/mod.config @@ -37,7 +37,7 @@ TRAVIS_TEST_PACKAGING="False" # The prefix used for the installer filenames. # - Windows installers will be named as {PACKAGING_INSTALLER_NAME}-{TAG}.exe -# - macOS installers will be named as {PACKAGING_INSTALLER_NAME}-{TAG}.zip +# - macOS installers will be named as {PACKAGING_INSTALLER_NAME}-{TAG}.dmg # - Linux .appimages will be named as {PACKAGING_INSTALLER_NAME}-${TAG}.AppImage PACKAGING_INSTALLER_NAME="ExampleMod" @@ -47,6 +47,7 @@ PACKAGING_INSTALLER_NAME="ExampleMod" # - macOS .app bundle name # - macOS menu bar # - macOS "About" window +# - macOS disk image title # - Windows installer # - Windows start menu # - Windows desktop shortcut @@ -68,7 +69,12 @@ PACKAGING_FAQ_URL="http://wiki.openra.net/FAQ" PACKAGING_AUTHORS="Example Mod authors" # The git tag to use for the macOS Launcher files. -PACKAGING_OSX_LAUNCHER_TAG="osx-launcher-20191007" +PACKAGING_OSX_LAUNCHER_TAG="osx-launcher-20200209" + +# The macOS disk image icon positions, matched to the background artwork +PACKAGING_OSX_DMG_MOD_ICON_POSITION="190, 210" +PACKAGING_OSX_DMG_APPLICATION_ICON_POSITION="410, 210" +PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION="190, 350" # Filename to use for the launcher executable on Windows. PACKAGING_WINDOWS_LAUNCHER_NAME="ExampleMod" diff --git a/packaging/artwork/icon_1024x1024.png b/packaging/artwork/icon_1024x1024.png new file mode 100644 index 0000000..a1fb514 Binary files /dev/null and b/packaging/artwork/icon_1024x1024.png differ diff --git a/packaging/artwork/icon_128x128.png b/packaging/artwork/icon_128x128.png new file mode 100644 index 0000000..ed1b458 Binary files /dev/null and b/packaging/artwork/icon_128x128.png differ diff --git a/packaging/artwork/icon_16x16.png b/packaging/artwork/icon_16x16.png new file mode 100644 index 0000000..c31b0fc Binary files /dev/null and b/packaging/artwork/icon_16x16.png differ diff --git a/packaging/artwork/icon_256x256.png b/packaging/artwork/icon_256x256.png new file mode 100644 index 0000000..e05a6f8 Binary files /dev/null and b/packaging/artwork/icon_256x256.png differ diff --git a/packaging/artwork/icon_32x32.png b/packaging/artwork/icon_32x32.png new file mode 100644 index 0000000..155dafd Binary files /dev/null and b/packaging/artwork/icon_32x32.png differ diff --git a/packaging/artwork/icon_48x48.png b/packaging/artwork/icon_48x48.png new file mode 100644 index 0000000..e5cc191 Binary files /dev/null and b/packaging/artwork/icon_48x48.png differ diff --git a/packaging/artwork/icon_512x512.png b/packaging/artwork/icon_512x512.png new file mode 100644 index 0000000..351150e Binary files /dev/null and b/packaging/artwork/icon_512x512.png differ diff --git a/packaging/artwork/icon_64x64.png b/packaging/artwork/icon_64x64.png new file mode 100644 index 0000000..d780c5a Binary files /dev/null and b/packaging/artwork/icon_64x64.png differ diff --git a/packaging/artwork/macos-background-2x.png b/packaging/artwork/macos-background-2x.png new file mode 100644 index 0000000..f4050f2 Binary files /dev/null and b/packaging/artwork/macos-background-2x.png differ diff --git a/packaging/artwork/macos-background.png b/packaging/artwork/macos-background.png new file mode 100644 index 0000000..d9b0b21 Binary files /dev/null and b/packaging/artwork/macos-background.png differ diff --git a/packaging/macos/buildpackage.sh b/packaging/macos/buildpackage.sh new file mode 100755 index 0000000..84008f4 --- /dev/null +++ b/packaging/macos/buildpackage.sh @@ -0,0 +1,271 @@ +#!/bin/bash +# OpenRA Mod SDK packaging script for macOS +# +# The application bundles will be signed if the following environment variable is defined: +# MACOS_DEVELOPER_IDENTITY: Certificate name, of the form `Developer\ ID\ Application:\ ` +# If the identity is not already in the default keychain, specify the following environment variables to import it: +# MACOS_DEVELOPER_CERTIFICATE_BASE64: base64 content of the exported .p12 developer ID certificate. +# Generate using `base64 certificate.p12 | pbcopy` +# MACOS_DEVELOPER_CERTIFICATE_PASSWORD: password to unlock the MACOS_DEVELOPER_CERTIFICATE_BASE64 certificate +# +# The applicaton bundles will be notarized if the following environment variables are defined: +# MACOS_DEVELOPER_USERNAME: Email address for the developer account +# MACOS_DEVELOPER_PASSWORD: App-specific password for the developer account +# +set -e + +if [[ "$OSTYPE" != "darwin"* ]]; then + echo >&2 "macOS packaging requires a macOS host" + exit 1 +fi + +command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires make."; exit 1; } +command -v python >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires python."; exit 1; } + +require_variables() { + missing="" + for i in "$@"; do + eval check="\$$i" + [ -z "${check}" ] && missing="${missing} ${i}\n" + done + if [ ! -z "${missing}" ]; then + echo "Required mod.config variables are missing:\n${missing}Repair your mod.config (or user.config) and try again." + exit 1 + fi +} + +if [ $# -eq "0" ]; then + echo "Usage: `basename $0` version [outputdir]" + exit 1 +fi + +PACKAGING_DIR=$(python -c "import os; print(os.path.dirname(os.path.realpath('$0')))") +TEMPLATE_ROOT="${PACKAGING_DIR}/../../" +ARTWORK_DIR="${PACKAGING_DIR}/../artwork/" + +# shellcheck source=mod.config +. "${TEMPLATE_ROOT}/mod.config" + +if [ -f "${TEMPLATE_ROOT}/user.config" ]; then + # shellcheck source=user.config + . "${TEMPLATE_ROOT}/user.config" +fi + +require_variables "MOD_ID" "ENGINE_DIRECTORY" "PACKAGING_DISPLAY_NAME" "PACKAGING_INSTALLER_NAME" \ + "PACKAGING_OSX_LAUNCHER_TAG" "PACKAGING_OSX_LAUNCHER_SOURCE" "PACKAGING_OSX_LAUNCHER_TEMP_ARCHIVE_NAME" \ + "PACKAGING_OSX_DMG_MOD_ICON_POSITION" "PACKAGING_OSX_DMG_APPLICATION_ICON_POSITION" "PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION" \ + "PACKAGING_FAQ_URL" "PACKAGING_OVERWRITE_MOD_VERSION" + +# Import code signing certificate +if [ -n "${MACOS_DEVELOPER_CERTIFICATE_BASE64}" ] && [ -n "${MACOS_DEVELOPER_CERTIFICATE_PASSWORD}" ] && [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then + echo "Importing signing certificate" + echo "${MACOS_DEVELOPER_CERTIFICATE_BASE64}" | base64 --decode > build.p12 + security create-keychain -p build build.keychain + security default-keychain -s build.keychain + security unlock-keychain -p build build.keychain + security import build.p12 -k build.keychain -P "${MACOS_DEVELOPER_CERTIFICATE_PASSWORD}" -T /usr/bin/codesign >/dev/null 2>&1 + security set-key-partition-list -S apple-tool:,apple: -s -k build build.keychain >/dev/null 2>&1 + rm -fr build.p12 +fi + +TAG="$1" +if [ $# -eq "1" ]; then + OUTPUTDIR=$(python -c "import os; print(os.path.realpath('.'))") +else + OUTPUTDIR=$(python -c "import os; print(os.path.realpath('$2'))") +fi + +BUILTDIR="${PACKAGING_DIR}/build" +PACKAGING_OSX_APP_NAME="OpenRA - ${PACKAGING_DISPLAY_NAME}.app" + +# Set the working dir to the location of this script +cd "${PACKAGING_DIR}" + +modify_plist() { + sed "s|$1|$2|g" "$3" > "$3.tmp" && mv "$3.tmp" "$3" +} + +echo "Building launcher" +curl -s -L -o "${PACKAGING_OSX_LAUNCHER_TEMP_ARCHIVE_NAME}" -O "${PACKAGING_OSX_LAUNCHER_SOURCE}" || exit 3 +unzip -qq -d "${BUILTDIR}" "${PACKAGING_OSX_LAUNCHER_TEMP_ARCHIVE_NAME}" +rm "${PACKAGING_OSX_LAUNCHER_TEMP_ARCHIVE_NAME}" + +modify_plist "{DEV_VERSION}" "${TAG}" "${BUILTDIR}/OpenRA.app/Contents/Info.plist" +modify_plist "{FAQ_URL}" "${PACKAGING_FAQ_URL}" "${BUILTDIR}/OpenRA.app/Contents/Info.plist" + +pushd "${TEMPLATE_ROOT}" > /dev/null + +if [ ! -f "${ENGINE_DIRECTORY}/Makefile" ]; then + echo "Required engine files not found." + echo "Run \`make\` in the mod directory to fetch and build the required files, then try again."; + exit 1 +fi + +if [ ! -d "${OUTPUTDIR}" ]; then + echo "Output directory '${OUTPUTDIR}' does not exist."; + exit 1 +fi + +MOD_VERSION=$(grep 'Version:' mods/${MOD_ID}/mod.yaml | awk '{print $2}') + +if [ "${PACKAGING_OVERWRITE_MOD_VERSION}" == "True" ]; then + make version VERSION="${TAG}" +else + echo "Mod version ${MOD_VERSION} will remain unchanged."; +fi + +pushd "${ENGINE_DIRECTORY}" > /dev/null +echo "Building core files" + +make clean +make osx-dependencies +make core +make version VERSION="${ENGINE_VERSION}" +make install-engine gameinstalldir="/Contents/Resources/" DESTDIR="${BUILTDIR}/OpenRA.app" +make install-common-mod-files gameinstalldir="/Contents/Resources/" DESTDIR="${BUILTDIR}/OpenRA.app" + +for f in ${PACKAGING_COPY_ENGINE_FILES}; do + mkdir -p "${BUILTDIR}/OpenRA.app/Contents/Resources/$(dirname "${f}")" + cp -r "${f}" "${BUILTDIR}/OpenRA.app/Contents/Resources/${f}" +done + +popd > /dev/null + +echo "Building mod files" +make core +cp -LR mods/* "${BUILTDIR}/OpenRA.app/Contents/Resources/mods" + +popd > /dev/null + +pushd "${BUILTDIR}" > /dev/null +mv "OpenRA.app" "${PACKAGING_OSX_APP_NAME}" + + +# Assemble multi-resolution icon +mkdir mod.iconset +cp "${ARTWORK_DIR}/icon_16x16.png" "mod.iconset/icon_16x16.png" +cp "${ARTWORK_DIR}/icon_32x32.png" "mod.iconset/icon_16x16@2.png" +cp "${ARTWORK_DIR}/icon_32x32.png" "mod.iconset/icon_32x32.png" +cp "${ARTWORK_DIR}/icon_64x64.png" "mod.iconset/icon_32x32@2x.png" +cp "${ARTWORK_DIR}/icon_128x128.png" "mod.iconset/icon_128x128.png" +cp "${ARTWORK_DIR}/icon_256x256.png" "mod.iconset/icon_128x128@2x.png" +cp "${ARTWORK_DIR}/icon_256x256.png" "mod.iconset/icon_256x256.png" +cp "${ARTWORK_DIR}/icon_512x512.png" "mod.iconset/icon_256x256@2x.png" +iconutil --convert icns "mod.iconset" -o "${PACKAGING_OSX_APP_NAME}/Contents/Resources/${MOD_ID}.icns" +rm -rf mod.iconset + +# Copy macOS specific files +modify_plist "{MOD_ID}" "${MOD_ID}" "${PACKAGING_OSX_APP_NAME}/Contents/Info.plist" +modify_plist "{MOD_NAME}" "${PACKAGING_DISPLAY_NAME}" "${PACKAGING_OSX_APP_NAME}/Contents/Info.plist" +modify_plist "{JOIN_SERVER_URL_SCHEME}" "openra-${MOD_ID}-${TAG}" "${PACKAGING_OSX_APP_NAME}/Contents/Info.plist" + +# Sign binaries with developer certificate +if [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then + codesign -s "${MACOS_DEVELOPER_IDENTITY}" --timestamp --options runtime -f --entitlements "${PACKAGING_DIR}/entitlements.plist" "${PACKAGING_OSX_APP_NAME}/Contents/Resources/"*.dylib + codesign -s "${MACOS_DEVELOPER_IDENTITY}" --timestamp --options runtime -f --entitlements "${PACKAGING_DIR}/entitlements.plist" --deep "${PACKAGING_OSX_APP_NAME}" +fi + +if [ -n "${MACOS_DEVELOPER_CERTIFICATE_BASE64}" ] && [ -n "${MACOS_DEVELOPER_CERTIFICATE_PASSWORD}" ] && [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then + security delete-keychain build.keychain +fi + +echo "Packaging disk image" +hdiutil create build.dmg -format UDRW -volname "${PACKAGING_DISPLAY_NAME}" -fs HFS+ -srcfolder "${BUILTDIR}" +DMG_DEVICE=$(hdiutil attach -readwrite -noverify -noautoopen "build.dmg" | egrep '^/dev/' | sed 1q | awk '{print $1}') +sleep 2 + +# Background image is created from source svg in artsrc repository +mkdir "/Volumes/${PACKAGING_DISPLAY_NAME}/.background/" +tiffutil -cathidpicheck "${ARTWORK_DIR}/macos-background.png" "${ARTWORK_DIR}/macos-background-2x.png" -out "/Volumes/${PACKAGING_DISPLAY_NAME}/.background/background.tiff" + +cp "${BUILTDIR}/${PACKAGING_OSX_APP_NAME}/Contents/Resources/${MOD_ID}.icns" "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns" + +echo ' + tell application "Finder" + tell disk "'${PACKAGING_DISPLAY_NAME}'" + open + set current view of container window to icon view + set toolbar visible of container window to false + set statusbar visible of container window to false + set the bounds of container window to {400, 100, 1000, 550} + set theViewOptions to the icon view options of container window + set arrangement of theViewOptions to not arranged + set icon size of theViewOptions to 72 + set background picture of theViewOptions to file ".background:background.tiff" + make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"} + set position of item "'${PACKAGING_OSX_APP_NAME}'" of container window to {'${PACKAGING_OSX_DMG_MOD_ICON_POSITION}'} + set position of item "Applications" of container window to {'${PACKAGING_OSX_DMG_APPLICATION_ICON_POSITION}'} + set position of item ".background" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'} + set position of item ".fseventsd" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'} + set position of item ".VolumeIcon.icns" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'} + update without registering applications + delay 5 + close + end tell + end tell +' | osascript + +# HACK: Copy the volume icon again - something in the previous step seems to delete it...? +cp "${BUILTDIR}/${PACKAGING_OSX_APP_NAME}/Contents/Resources/${MOD_ID}.icns" "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns" +SetFile -c icnC "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns" +SetFile -a C "/Volumes/${PACKAGING_DISPLAY_NAME}" + +chmod -Rf go-w "/Volumes/${PACKAGING_DISPLAY_NAME}" +sync +sync + +hdiutil detach "${DMG_DEVICE}" + +# Submit for notarization +if [ -n "${MACOS_DEVELOPER_USERNAME}" ] && [ -n "${MACOS_DEVELOPER_PASSWORD}" ]; then + echo "Submitting disk image for notarization" + + # Reset xcode search path to fix xcrun not finding altool + sudo xcode-select -r + + # Create a temporary read-only dmg for submission (notarization service rejects read/write images) + hdiutil convert build.dmg -format UDZO -imagekey zlib-level=9 -ov -o notarization.dmg + + NOTARIZATION_UUID=$(xcrun altool --notarize-app --primary-bundle-id "net.openra.modsdk" -u "${MACOS_DEVELOPER_USERNAME}" -p "${MACOS_DEVELOPER_PASSWORD}" --file notarization.dmg 2>&1 | awk -F' = ' '/RequestUUID/ { print $2; exit }') + if [ -z "${NOTARIZATION_UUID}" ]; then + echo "Submission failed" + exit 1 + fi + + echo "Submission UUID is ${NOTARIZATION_UUID}" + rm notarization.dmg + + while :; do + sleep 30 + NOTARIZATION_RESULT=$(xcrun altool --notarization-info "${NOTARIZATION_UUID}" -u "${MACOS_DEVELOPER_USERNAME}" -p "${MACOS_DEVELOPER_PASSWORD}" 2>&1 | awk -F': ' '/Status/ { print $2; exit }') + echo "Submission status: ${NOTARIZATION_RESULT}" + + if [ "${NOTARIZATION_RESULT}" == "invalid" ]; then + NOTARIZATION_LOG_URL=$(xcrun altool --notarization-info "${NOTARIZATION_UUID}" -u "${MACOS_DEVELOPER_USERNAME}" -p "${MACOS_DEVELOPER_PASSWORD}" 2>&1 | awk -F': ' '/LogFileURL/ { print $2; exit }') + echo "Notarization failed with error:" + curl -s "${NOTARIZATION_LOG_URL}" -w "\n" + exit 1 + fi + + if [ "${NOTARIZATION_RESULT}" == "success" ]; then + echo "Stapling notarization ticket" + DMG_DEVICE=$(hdiutil attach -readwrite -noverify -noautoopen "build.dmg" | egrep '^/dev/' | sed 1q | awk '{print $1}') + sleep 2 + + xcrun stapler staple "/Volumes/${PACKAGING_DISPLAY_NAME}/${PACKAGING_OSX_APP_NAME}" + + sync + sync + + hdiutil detach "${DMG_DEVICE}" + break + fi + done +fi + +hdiutil convert build.dmg -format UDZO -imagekey zlib-level=9 -ov -o "${OUTPUTDIR}/${PACKAGING_INSTALLER_NAME}-${TAG}.dmg" + +popd > /dev/null + +# Clean up +rm -rf "${BUILTDIR}" diff --git a/packaging/macos/entitlements.plist b/packaging/macos/entitlements.plist new file mode 100644 index 0000000..dcfe14c --- /dev/null +++ b/packaging/macos/entitlements.plist @@ -0,0 +1,16 @@ + + + + +com.apple.security.cs.allow-jit + +com.apple.security.cs.allow-unsigned-executable-memory + +com.apple.security.cs.disable-executable-page-protection + +com.apple.security.cs.disable-library-validation + +com.apple.security.cs.allow-dyld-environment-variables + + + diff --git a/packaging/osx/buildpackage.sh b/packaging/osx/buildpackage.sh deleted file mode 100755 index 6dc0c2b..0000000 --- a/packaging/osx/buildpackage.sh +++ /dev/null @@ -1,133 +0,0 @@ -#!/bin/bash -# OpenRA packaging script for macOS -set -e - -command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires make."; exit 1; } -command -v python >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires python."; exit 1; } -command -v curl >/dev/null 2>&1 || command -v wget > /dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires curl or wget."; exit 1; } - -require_variables() { - missing="" - for i in "$@"; do - eval check="\$$i" - [ -z "${check}" ] && missing="${missing} ${i}\n" - done - if [ ! -z "${missing}" ]; then - echo "Required mod.config variables are missing:\n${missing}Repair your mod.config (or user.config) and try again." - exit 1 - fi -} - -if [ $# -eq "0" ]; then - echo "Usage: `basename $0` version [outputdir]" - exit 1 -fi - -PACKAGING_DIR=$(python -c "import os; print(os.path.dirname(os.path.realpath('$0')))") -TEMPLATE_ROOT="${PACKAGING_DIR}/../../" - -# shellcheck source=mod.config -. "${TEMPLATE_ROOT}/mod.config" - -if [ -f "${TEMPLATE_ROOT}/user.config" ]; then - # shellcheck source=user.config - . "${TEMPLATE_ROOT}/user.config" -fi - -require_variables "MOD_ID" "ENGINE_DIRECTORY" "PACKAGING_DISPLAY_NAME" "PACKAGING_INSTALLER_NAME" \ - "PACKAGING_OSX_LAUNCHER_TAG" "PACKAGING_OSX_LAUNCHER_SOURCE" "PACKAGING_OSX_LAUNCHER_TEMP_ARCHIVE_NAME" \ - "PACKAGING_FAQ_URL" "PACKAGING_OVERWRITE_MOD_VERSION" - -TAG="$1" -if [ $# -eq "1" ]; then - OUTPUTDIR=$(python -c "import os; print(os.path.realpath('.'))") -else - OUTPUTDIR=$(python -c "import os; print(os.path.realpath('$2'))") -fi - -BUILTDIR="${PACKAGING_DIR}/build" -PACKAGING_OSX_APP_NAME="OpenRA - ${PACKAGING_DISPLAY_NAME}.app" - -# Set the working dir to the location of this script -cd "${PACKAGING_DIR}" - -modify_plist() { - sed "s|$1|$2|g" "$3" > "$3.tmp" && mv "$3.tmp" "$3" -} - -echo "Building launcher" - -if command -v curl >/dev/null 2>&1; then - curl -s -L -o "${PACKAGING_OSX_LAUNCHER_TEMP_ARCHIVE_NAME}" -O "${PACKAGING_OSX_LAUNCHER_SOURCE}" || exit 3 -else - wget -cq "${PACKAGING_OSX_LAUNCHER_SOURCE}" -O "${PACKAGING_OSX_LAUNCHER_TEMP_ARCHIVE_NAME}" || exit 3 -fi - -unzip -qq -d "${BUILTDIR}" "${PACKAGING_OSX_LAUNCHER_TEMP_ARCHIVE_NAME}" -rm "${PACKAGING_OSX_LAUNCHER_TEMP_ARCHIVE_NAME}" - -modify_plist "{DEV_VERSION}" "${TAG}" "${BUILTDIR}/OpenRA.app/Contents/Info.plist" -modify_plist "{FAQ_URL}" "${PACKAGING_FAQ_URL}" "${BUILTDIR}/OpenRA.app/Contents/Info.plist" - -pushd ${TEMPLATE_ROOT} > /dev/null - -if [ ! -f "${ENGINE_DIRECTORY}/Makefile" ]; then - echo "Required engine files not found." - echo "Run \`make\` in the mod directory to fetch and build the required files, then try again."; - exit 1 -fi - -if [ ! -d "${OUTPUTDIR}" ]; then - echo "Output directory '${OUTPUTDIR}' does not exist."; - exit 1 -fi - -MOD_VERSION=$(grep 'Version:' mods/${MOD_ID}/mod.yaml | awk '{print $2}') - -if [ "${PACKAGING_OVERWRITE_MOD_VERSION}" == "True" ]; then - make version VERSION="${TAG}" -else - echo "Mod version ${MOD_VERSION} will remain unchanged."; -fi - -pushd ${ENGINE_DIRECTORY} > /dev/null -echo "Building core files" - -make clean -make osx-dependencies -make core -make version VERSION="${ENGINE_VERSION}" -make install-engine gameinstalldir="/Contents/Resources/" DESTDIR="${BUILTDIR}/OpenRA.app" -make install-common-mod-files gameinstalldir="/Contents/Resources/" DESTDIR="${BUILTDIR}/OpenRA.app" - -for f in ${PACKAGING_COPY_ENGINE_FILES}; do - mkdir -p "${BUILTDIR}/OpenRA.app/Contents/Resources/$(dirname "${f}")" - cp -r "${f}" "${BUILTDIR}/OpenRA.app/Contents/Resources/${f}" -done - -popd > /dev/null - -echo "Building mod files" -make core -cp -Lr mods/* "${BUILTDIR}/OpenRA.app/Contents/Resources/mods" - -popd > /dev/null - -cp "mod.icns" "${BUILTDIR}/OpenRA.app/Contents/Resources/${MOD_ID}.icns" - -pushd "${BUILTDIR}" > /dev/null -mv "OpenRA.app" "${PACKAGING_OSX_APP_NAME}" - -# Copy macOS specific files -modify_plist "{MOD_ID}" "${MOD_ID}" "${PACKAGING_OSX_APP_NAME}/Contents/Info.plist" -modify_plist "{MOD_NAME}" "${PACKAGING_DISPLAY_NAME}" "${PACKAGING_OSX_APP_NAME}/Contents/Info.plist" -modify_plist "{JOIN_SERVER_URL_SCHEME}" "openra-${MOD_ID}-${TAG}" "${PACKAGING_OSX_APP_NAME}/Contents/Info.plist" - -echo "Packaging zip archive" - -zip "${PACKAGING_INSTALLER_NAME}-${TAG}-macOS.zip" -r -9 "${PACKAGING_OSX_APP_NAME}" --quiet -mv "${PACKAGING_INSTALLER_NAME}-${TAG}-macOS.zip" "${OUTPUTDIR}" -popd > /dev/null - -# Clean up -rm -rf "${BUILTDIR}" diff --git a/packaging/osx/mod.icns b/packaging/osx/mod.icns deleted file mode 100644 index 68e41c8..0000000 Binary files a/packaging/osx/mod.icns and /dev/null differ diff --git a/packaging/package-all.sh b/packaging/package-all.sh index 7458609..32c3c39 100755 --- a/packaging/package-all.sh +++ b/packaging/package-all.sh @@ -15,31 +15,36 @@ fi command -v python >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires python."; exit 1; } command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires make."; exit 1; } -command -v curl >/dev/null 2>&1 || command -v wget > /dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires curl or wget."; exit 1; } -command -v makensis >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires makensis."; exit 1; } + +if [[ "$OSTYPE" != "darwin"* ]]; then + command -v curl >/dev/null 2>&1 || command -v wget > /dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires curl or wget."; exit 1; } + command -v makensis >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires makensis."; exit 1; } +fi PACKAGING_DIR=$(python -c "import os; print(os.path.dirname(os.path.realpath('$0')))") -echo "Building Windows package" -${PACKAGING_DIR}/windows/buildpackage.sh "${TAG}" "${OUTPUTDIR}" -if [ $? -ne 0 ]; then - echo "Windows package build failed." -fi - -echo "Building macOS package" -${PACKAGING_DIR}/osx/buildpackage.sh "${TAG}" "${OUTPUTDIR}" -if [ $? -ne 0 ]; then - echo "macOS package build failed." -fi - if [[ "$OSTYPE" == "darwin"* ]]; then + echo "Windows packaging requires a Linux host." echo "Linux AppImage packaging requires a Linux host." + echo "Building macOS package" + ${PACKAGING_DIR}/macos/buildpackage.sh "${TAG}" "${OUTPUTDIR}" + if [ $? -ne 0 ]; then + echo "macOS package build failed." + fi else + echo "Building Windows package" + ${PACKAGING_DIR}/windows/buildpackage.sh "${TAG}" "${OUTPUTDIR}" + if [ $? -ne 0 ]; then + echo "Windows package build failed." + fi + echo "Building Linux AppImage package" ${PACKAGING_DIR}/linux/buildpackage.sh "${TAG}" "${OUTPUTDIR}" if [ $? -ne 0 ]; then echo "Linux AppImage package build failed." fi + + echo "macOS packaging requires a macOS host." fi echo "Package build done."