Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ body:
- Linux - pkg.tar.zst
- Linux - solus (Third Party)
- Linux - Unraid (Third Party)
- macOS - dmg
- macOS - Homebrew
- Windows - Chocolatey (Third Party)
- Windows - exe installer
Expand Down
146 changes: 124 additions & 22 deletions .github/workflows/ci-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,19 @@ jobs:
permissions:
contents: read
runs-on: ${{ matrix.os }}
outputs:
notarytool_submission_id_arm64: ${{ steps.notarize_submit.outputs.submission_id_arm64 }}
notarytool_submission_id_x86_64: ${{ steps.notarize_submit.outputs.submission_id_x86_64 }}
strategy:
fail-fast: false
matrix:
include:
- os: "macos-14"
name: "macOS-arm64"
arch: "arm64"
- os: "macos-15-intel"
name: "macOS-x86_64"
arch: "x86_64"
steps:
- name: Install Apple certificate
uses: apple-actions/import-codesign-certs@b610f78488812c1e56b20e6df63ec42d833f2d14 # v6.0.0
Expand Down Expand Up @@ -99,14 +104,15 @@ jobs:
-DAPPLE_CODESIGN_IDENTITY="${APPLE_CODESIGN_IDENTITY}"

- name: Build
run: cmake --build build -j "$(sysctl -n hw.ncpu)"
run: |
echo "::add-matcher::.github/matchers/gcc.json"
cmake --build build -j "$(sysctl -n hw.ncpu)"
echo "::remove-matcher owner=gcc::"

- name: Package DMG
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_NOTARYTOOL_PASSWORD: ${{ secrets.APPLE_NOTARYTOOL_PASSWORD }}
APPLE_CODESIGN_IDENTITY: ${{ secrets.APPLE_CODESIGN_IDENTITY }}
MATRIX_NAME: ${{ matrix.name }}
SHOULD_SIGN: ${{ inputs.publish_release }}
run: |
# build DMG and sign everything (see cmake/packaging/macos.cmake)
Expand All @@ -120,25 +126,31 @@ jobs:
fi
fi

# Notarize
if [[ "${SHOULD_SIGN}" == "true" && -n "${APPLE_NOTARYTOOL_PASSWORD}" ]]; then
# Notarizing allows the signed .app to run on any Mac with no prompts.
# If you don't notarize, users must jump through the "Open Anyway" hoop as well as run
# `xattr -cr /Applications/Sunshine.app` to remove quarantine.
if [[ -n "${APPLE_NOTARYTOOL_PASSWORD}" ]]; then
xcrun notarytool submit build/cpack_artifacts/Sunshine.dmg \
--apple-id "${APPLE_ID}" \
--team-id "${APPLE_TEAM_ID}" \
--password "${APPLE_NOTARYTOOL_PASSWORD}" \
--wait \
--timeout 15m
xcrun stapler staple -v build/cpack_artifacts/Sunshine.dmg
fi
fi

mkdir -p artifacts
mv build/cpack_artifacts/Sunshine.dmg \
artifacts/Sunshine-${{ matrix.name }}.dmg
cp "build/cpack_artifacts/Sunshine.dmg" "artifacts/Sunshine-${MATRIX_NAME}.dmg"

- name: Submit for notarization
id: notarize_submit
if: inputs.publish_release == 'true'
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_NOTARYTOOL_PASSWORD: ${{ secrets.APPLE_NOTARYTOOL_PASSWORD }}
MATRIX_ARCH: ${{ matrix.arch }}
run: |
# Notarizing allows the signed .app to run on any Mac with no prompts.
# If you don't notarize, users must jump through the "Open Anyway" hoop as well as run
# `xattr -cr /Applications/Sunshine.app` to remove quarantine.
if [[ -n "${APPLE_NOTARYTOOL_PASSWORD}" ]]; then
submission_id=$(xcrun notarytool submit build/cpack_artifacts/Sunshine.dmg \
--apple-id "${APPLE_ID}" \
--team-id "${APPLE_TEAM_ID}" \
--password "${APPLE_NOTARYTOOL_PASSWORD}" \
--output-format json \
| jq -r '.id')
echo "Submission ID: ${submission_id}"
echo "submission_id_${MATRIX_ARCH}=${submission_id}" >> "${GITHUB_OUTPUT}"
fi

- name: Test
id: test
Expand Down Expand Up @@ -174,7 +186,97 @@ jobs:
build/tests/test_results.xml
if-no-files-found: error

- name: Set artifact prefix
id: artifact_prefix
env:
INPUTS_PUBLISH_RELEASE: ${{ inputs.publish_release }}
run: |
if [[ "${INPUTS_PUBLISH_RELEASE}" == "true" ]]; then
echo "prefix=unsigned" >> "${GITHUB_OUTPUT}"
else
echo "prefix=build" >> "${GITHUB_OUTPUT}"
fi

- name: Upload Artifacts
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: ${{ steps.artifact_prefix.outputs.prefix }}-${{ matrix.name }}
path: artifacts/
if-no-files-found: error

notarize_dmg:
name: Notarize ${{ matrix.name }}
needs: build_dmg
if: inputs.publish_release == 'true'
permissions:
contents: read
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: "macos-14"
name: "macOS-arm64"
arch: "arm64"
- os: "macos-15-intel"
name: "macOS-x86_64"
arch: "x86_64"
steps:
- name: Install Apple certificate
uses: apple-actions/import-codesign-certs@b610f78488812c1e56b20e6df63ec42d833f2d14 # v6.0.0
with:
p12-file-base64: ${{ secrets.APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE_BASE64 }}
p12-password: ${{ secrets.APPLE_DEVELOPER_ID_APPLICATION_CERTIFICATE_P12_PASSWORD }}

- name: Download DMG artifact
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
with:
name: unsigned-${{ matrix.name }}
path: artifacts

- name: Wait for notarization and staple
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_NOTARYTOOL_PASSWORD: ${{ secrets.APPLE_NOTARYTOOL_PASSWORD }}
MATRIX_NAME: ${{ matrix.name }}
SUBMISSION_ID: ${{ matrix.arch == 'arm64'
&& needs.build_dmg.outputs.notarytool_submission_id_arm64
|| needs.build_dmg.outputs.notarytool_submission_id_x86_64 }}
run: |
if [[ -z "${SUBMISSION_ID}" ]]; then
echo "No submission ID found; skipping notarization wait."
exit 0
fi

echo "Polling notarization status for submission: ${SUBMISSION_ID}"
while true; do
status=$(xcrun notarytool info "${SUBMISSION_ID}" \
--apple-id "${APPLE_ID}" \
--team-id "${APPLE_TEAM_ID}" \
--password "${APPLE_NOTARYTOOL_PASSWORD}" \
--output-format json \
| jq -r '.status')
echo "Current status: ${status}"
if [[ "${status}" == "Accepted" ]]; then
echo "Notarization accepted."
break
elif [[ "${status}" == "Invalid" || "${status}" == "Rejected" ]]; then
echo "Notarization failed with status: ${status}"
# Print the full log for debugging
xcrun notarytool log "${SUBMISSION_ID}" \
--apple-id "${APPLE_ID}" \
--team-id "${APPLE_TEAM_ID}" \
--password "${APPLE_NOTARYTOOL_PASSWORD}"
exit 1
fi
echo "Status is '${status}', waiting 30 seconds before retrying..."
sleep 30
done

xcrun stapler staple -v "artifacts/Sunshine-${MATRIX_NAME}.dmg"

- name: Upload stapled artifact
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: build-${{ matrix.name }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ jobs:
- build-homebrew
- build-linux
- build-linux-flatpak
- build-macos
- build-windows
permissions:
contents: read
Expand Down
19 changes: 19 additions & 0 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,25 @@ brew uninstall sunshine
> [!IMPORTANT]
> Sunshine on macOS is experimental. Gamepads do not work.

#### DMG

##### Install

1. Download and install based on your architecture:

| Architecture | Package |
|-----------------------|------------------------------------------------------------------------------------------------------------------------|
| arm64 (Apple Silicon) | [Sunshine-macOS-arm64.dmg](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-macOS-arm64.dmg) |
| x86_64 (Intel) | [Sunshine-macOS-x86_64.dmg](https://github.com/LizardByte/Sunshine/releases/latest/download/Sunshine-macOS-x86_64.dmg) |

2. Open the downloaded `.dmg` file.
3. Drag `Sunshine.app` into the `Applications` folder.
4. Eject the disk image.

##### Uninstall
1. Quit Sunshine if it is running.
2. Open `Finder`, navigate to `Applications`, and drag `Sunshine.app` to the Trash.

#### Homebrew
This package requires that you have [Homebrew](https://docs.brew.sh/Installation) installed.

Expand Down
Loading