From f631933e6050c8db965c0d63b6dbea5971c3d685 Mon Sep 17 00:00:00 2001
From: siegmund-heiss-ich
 <119589995+siegmund-heiss-ich@users.noreply.github.com>
Date: Tue, 5 Sep 2023 01:28:44 +0200
Subject: [PATCH] Add macOS Headless release workflow (#5272)

* Add macOS Headless release workflow

* Add MACH-O check before applying signature

* Rename script for consistency

* Remove redundant compiler flag

* Fix release.yml arguments + names

* Update headless.sh to include changes of pr #5398
---
 .github/workflows/build.yml                   |  15 ++-
 .github/workflows/release.yml                 |  10 +-
 ...cos_build.sh => create_macos_build_ava.sh} |   0
 .../macos/create_macos_build_headless.sh      | 111 ++++++++++++++++++
 4 files changed, 131 insertions(+), 5 deletions(-)
 rename distribution/macos/{create_macos_build.sh => create_macos_build_ava.sh} (100%)
 create mode 100755 distribution/macos/create_macos_build_headless.sh

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 3f0d02c747..16058d9f88 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -135,9 +135,13 @@ jobs:
         id: git_short_hash
         run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
 
-      - name: Publish macOS
+      - name: Publish macOS Ryujinx.Ava
         run: |
-          ./distribution/macos/create_macos_build.sh . publish_tmp publish_ava ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
+          ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
+
+      - name: Publish macOS Ryujinx.Headless.SDL2
+        run: |
+          ./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
 
       - name: Upload Ryujinx.Ava artifact
         uses: actions/upload-artifact@v3
@@ -145,3 +149,10 @@ jobs:
           name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
           path: "publish_ava/*.tar.gz"
         if: github.event_name == 'pull_request'
+
+      - name: Upload Ryujinx.Headless.SDL2 artifact
+        uses: actions/upload-artifact@v3
+        with:
+          name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
+          path: "publish_headless/*.tar.gz"
+        if: github.event_name == 'pull_request'
\ No newline at end of file
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 2aed3aa7cf..988264a312 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -188,15 +188,19 @@ jobs:
           sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
         shell: bash
 
-      - name: Publish macOS
+      - name: Publish macOS Ryujinx.Ava
         run: |
-          ./distribution/macos/create_macos_build.sh . publish_tmp publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
+          ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
+          
+      - name: Publish macOS Ryujinx.Headless.SDL2
+        run: |
+          ./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
 
       - name: Pushing new release
         uses: ncipollo/release-action@v1
         with:
           name: ${{ steps.version_info.outputs.build_version }}
-          artifacts: "publish_ava/*.tar.gz"
+          artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz"
           tag: ${{ steps.version_info.outputs.build_version }}
           body: "For more information about this release please check out the official [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog)."
           omitBodyDuringUpdate: true
diff --git a/distribution/macos/create_macos_build.sh b/distribution/macos/create_macos_build_ava.sh
similarity index 100%
rename from distribution/macos/create_macos_build.sh
rename to distribution/macos/create_macos_build_ava.sh
diff --git a/distribution/macos/create_macos_build_headless.sh b/distribution/macos/create_macos_build_headless.sh
new file mode 100755
index 0000000000..a439aef45b
--- /dev/null
+++ b/distribution/macos/create_macos_build_headless.sh
@@ -0,0 +1,111 @@
+#!/bin/bash
+
+set -e
+
+if [ "$#" -lt 7 ]; then
+    echo "usage <BASE_DIR> <TEMP_DIRECTORY> <OUTPUT_DIRECTORY> <ENTITLEMENTS_FILE_PATH> <VERSION> <SOURCE_REVISION_ID> <CONFIGURATION> <EXTRA_ARGS>"
+    exit 1
+fi
+
+mkdir -p "$1"
+mkdir -p "$2"
+mkdir -p "$3"
+
+BASE_DIR=$(readlink -f "$1")
+TEMP_DIRECTORY=$(readlink -f "$2")
+OUTPUT_DIRECTORY=$(readlink -f "$3")
+ENTITLEMENTS_FILE_PATH=$(readlink -f "$4")
+VERSION=$5
+SOURCE_REVISION_ID=$6
+CONFIGURATION=$7
+EXTRA_ARGS=$8
+
+if [ "$VERSION" == "1.1.0" ];
+then
+  RELEASE_TAR_FILE_NAME=sdl2-ryujinx-headless-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.tar
+else
+  RELEASE_TAR_FILE_NAME=sdl2-ryujinx-headless-$VERSION-macos_universal.tar
+fi
+
+ARM64_OUTPUT="$TEMP_DIRECTORY/publish_arm64"
+X64_OUTPUT="$TEMP_DIRECTORY/publish_x64"
+UNIVERSAL_OUTPUT="$OUTPUT_DIRECTORY/publish"
+EXECUTABLE_SUB_PATH=Ryujinx.Headless.SDL2
+
+rm -rf "$TEMP_DIRECTORY"
+mkdir -p "$TEMP_DIRECTORY"
+
+DOTNET_COMMON_ARGS=(-p:DebugType=embedded -p:Version="$VERSION" -p:SourceRevisionId="$SOURCE_REVISION_ID" --self-contained true $EXTRA_ARGS)
+
+dotnet restore
+dotnet build -c "$CONFIGURATION" src/Ryujinx.Headless.SDL2
+dotnet publish -c "$CONFIGURATION" -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Headless.SDL2
+dotnet publish -c "$CONFIGURATION" -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Headless.SDL2
+
+# Get rid of the support library for ARMeilleure for x64 (that's only for arm64)
+rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib"
+
+# Get rid of libsoundio from arm64 builds as we don't have a arm64 variant
+# TODO: remove this once done
+rm -rf "$TEMP_DIRECTORY/publish_arm64/libsoundio.dylib"
+
+rm -rf "$OUTPUT_DIRECTORY"
+mkdir -p "$OUTPUT_DIRECTORY"
+
+# Let's copy one of the two different outputs and remove the executable
+cp -R "$ARM64_OUTPUT/" "$UNIVERSAL_OUTPUT"
+rm "$UNIVERSAL_OUTPUT/$EXECUTABLE_SUB_PATH"
+
+# Make it libraries universal
+python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_OUTPUT" "$X64_OUTPUT" "$UNIVERSAL_OUTPUT" "**/*.dylib"
+
+if ! [ -x "$(command -v lipo)" ];
+then
+    if ! [ -x "$(command -v llvm-lipo-14)" ];
+    then
+        LIPO=llvm-lipo
+    else
+        LIPO=llvm-lipo-14
+    fi
+else
+    LIPO=lipo
+fi
+
+# Make the executable universal
+$LIPO "$ARM64_OUTPUT/$EXECUTABLE_SUB_PATH" "$X64_OUTPUT/$EXECUTABLE_SUB_PATH" -output "$UNIVERSAL_OUTPUT/$EXECUTABLE_SUB_PATH" -create
+
+# Now sign it
+if ! [ -x "$(command -v codesign)" ];
+then
+    if ! [ -x "$(command -v rcodesign)" ];
+    then
+        echo "Cannot find rcodesign on your system, please install rcodesign."
+        exit 1
+    fi
+
+    # NOTE: Currently require https://github.com/indygreg/apple-platform-rs/pull/44 to work on other OSes.
+    # cargo install --git "https://github.com/marysaka/apple-platform-rs" --branch "fix/adhoc-app-bundle" apple-codesign --bin "rcodesign"
+    echo "Using rcodesign for ad-hoc signing"
+    for FILE in "$UNIVERSAL_OUTPUT"/*; do
+        if [[ $(file "$FILE") == *"Mach-O"* ]]; then
+            rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$FILE"
+        fi
+    done  
+else
+    echo "Using codesign for ad-hoc signing"
+    for FILE in "$UNIVERSAL_OUTPUT"/*; do
+        if [[ $(file "$FILE") == *"Mach-O"* ]]; then
+            codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f --deep -s - "$FILE"
+        fi
+    done    
+fi
+
+echo "Creating archive"
+pushd "$OUTPUT_DIRECTORY"
+tar --exclude "publish/Ryujinx.Headless.SDL2" -cvf "$RELEASE_TAR_FILE_NAME" publish 1> /dev/null
+python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" "$RELEASE_TAR_FILE_NAME" "publish/Ryujinx.Headless.SDL2" "publish/Ryujinx.Headless.SDL2"
+gzip -9 < "$RELEASE_TAR_FILE_NAME" > "$RELEASE_TAR_FILE_NAME.gz"
+rm "$RELEASE_TAR_FILE_NAME"
+popd
+
+echo "Done"
\ No newline at end of file