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
173 changes: 173 additions & 0 deletions .github/workflows/ci-alpine.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
---
name: CI-Alpine
permissions: {}

on:
workflow_call:
inputs:
release_commit:
required: true
type: string
release_version:
required: true
type: string

jobs:
build_alpine:
name: ${{ matrix.arch }}
env:
ALPINE_PACKAGE_DIR: cmake-build-alpine-package
BRANCH: ${{ github.head_ref || github.ref_name }}
BUILD_VERSION: ${{ inputs.release_version }}
CLONE_URL: >-
${{
github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.clone_url ||
github.event.repository.clone_url
}}
COMMIT: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || inputs.release_commit }}
permissions:
contents: read
runs-on: ${{ matrix.runner }}
container:
image: alpine:${{ matrix.alpine_version }}
strategy:
fail-fast: false
matrix:
alpine_version:
- '3.24'
arch:
- x86_64
- aarch64
include:
- arch: x86_64
runner: ubuntu-latest
- arch: aarch64
runner: ubuntu-24.04-arm
steps:
- name: Fix arm64 Alpine container
if: runner.arch == 'ARM64'
uses: laverdet/alpine-arm64@7f0f72ee2f71eb2324e5888e8b6e42b1b53e6160 # v1.0.0

- name: Install packaging tools
run: |
set -eux
apk add --no-cache \
alpine-sdk \
atools \
bash \
cmake \
file \
git \
libcap-utils \
pax-utils \
sudo
apk update

- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
submodules: recursive

- name: Setup builder user
run: |
set -eux
adduser -D builder
addgroup builder abuild
mkdir -p /etc/sudoers.d
echo 'builder ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/builder
chmod 440 /etc/sudoers.d/builder
chown -R builder:abuild "${GITHUB_WORKSPACE}"
sudo -u builder abuild-keygen -a -i -n

- name: Configure APKBUILD
run: |
set -eux
sub_version=""
if [ "${BRANCH}" != "master" ]; then
# Alpine development-version suffixes accept a numeric component,
# while hexadecimal commit IDs are rejected by abuild.
sub_version="_git${GITHUB_RUN_NUMBER}"
fi

cmake -S . -B "${ALPINE_PACKAGE_DIR}" \
-DSUNSHINE_CONFIGURE_ONLY=ON \
-DSUNSHINE_CONFIGURE_APKBUILD=ON \
-DSUNSHINE_SUB_VERSION="${sub_version}"

mkdir -p apk
mv "${ALPINE_PACKAGE_DIR}/APKBUILD" apk/
mv "${ALPINE_PACKAGE_DIR}/sunshine.post-install" apk/
mv "${ALPINE_PACKAGE_DIR}/sunshine.post-upgrade" apk/
chown -R builder:abuild apk

cd apk
sh -n sunshine.post-install
sh -n sunshine.post-upgrade
sudo -u builder apkbuild-lint APKBUILD

- name: Build Alpine package
id: build
working-directory: apk
run: |
set -eux
echo "::add-matcher::.github/matchers/gcc.json"
sudo -u builder env \
_coverage_dir="${GITHUB_WORKSPACE}/coverage" \
_run_unit_tests=true \
_source_dir="${GITHUB_WORKSPACE}" \
abuild -r
echo "::remove-matcher owner=gcc::"

- name: Install and verify package
id: package
run: |
set -eux
package_file="$(find /home/builder/packages -type f -name 'sunshine-*.apk' -print -quit)"
test -n "${package_file}"

apk add --allow-untrusted "${package_file}"

file /usr/bin/sunshine | tee sunshine-file.txt
grep -Fq 'dynamically linked' sunshine-file.txt
ldd /usr/bin/sunshine | tee sunshine-ldd.txt
grep -Eq 'libc\.musl|ld-musl' sunshine-ldd.txt
scanelf -n /usr/bin/sunshine
/usr/bin/sunshine --version

rule_file="$(find /lib /usr/lib -path '*/udev/rules.d/60-sunshine.rules' -print -quit)"
test -n "${rule_file}"
grep -Fq 'IMPORT{parent}="HID_*"' "${rule_file}"
grep -Fq 'ENV{HID_PHYS}=="libvirtualhid/uhid/*"' "${rule_file}"
test -e /sys/class/mem/null
if ! udevadm test --action=add /sys/class/mem/null > udevadm-test.txt 2>&1; then
cat udevadm-test.txt
exit 1
fi
test -f /etc/modules-load.d/60-sunshine.conf
grep -Fxq 'uhid' /etc/modules-load.d/60-sunshine.conf
getcap /usr/bin/sunshine | grep -Eq 'cap_sys_admin,cap_sys_nice[=+]p'

mkdir -p artifacts
cp "${package_file}" \
"artifacts/sunshine_${BUILD_VERSION}_alpine${{ matrix.alpine_version }}_${{ matrix.arch }}.apk"

- name: Upload coverage artifact
if: >-
always() &&
(steps.build.outcome == 'success' || steps.build.outcome == 'failure')
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: coverage-Alpine-${{ matrix.arch }}
path: |
coverage/coverage.xml
coverage/tests/test_results.xml
if-no-files-found: error

- name: Upload artifacts
if: steps.package.outcome == 'success'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: build-Alpine-${{ matrix.arch }}
path: artifacts/
if-no-files-found: error
3 changes: 2 additions & 1 deletion .github/workflows/ci-cloudsmith.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
workflow_call:
inputs:
release_tag:
description: GitHub release tag containing the DEB assets.
description: GitHub release tag containing the package assets.
required: true
type: string
repository:
Expand All @@ -33,6 +33,7 @@ jobs:
mkdir -p artifacts/packages
gh release download "${RELEASE_TAG}" \
--dir artifacts/packages \
--pattern '*.apk' \
--pattern '*.deb' \
--pattern '*.rpm'

Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,16 @@ jobs:
release_commit: ${{ needs.release-setup.outputs.release_commit }}
release_version: ${{ needs.release-setup.outputs.release_version }}

build-alpine:
name: Alpine
needs: release-setup
permissions:
contents: read
uses: ./.github/workflows/ci-alpine.yml
with:
release_commit: ${{ needs.release-setup.outputs.release_commit }}
release_version: ${{ needs.release-setup.outputs.release_version }}

build-linux-copr:
name: Linux Copr
if: github.event_name != 'push' # releases are handled directly in ci-release.yml
Expand Down Expand Up @@ -189,6 +199,7 @@ jobs:
- build-freebsd
- build-linux
- build-archlinux
- build-alpine
- build-linux-flatpak
- build-macos
- build-homebrew
Expand All @@ -208,6 +219,10 @@ jobs:
coverage: true
- name: Archlinux
coverage: true
- name: Alpine-x86_64
coverage: true
- name: Alpine-aarch64
coverage: true
- name: macOS-arm64
coverage: true
- name: macOS-x86_64
Expand Down Expand Up @@ -268,6 +283,7 @@ jobs:
needs:
- release-setup
- build-archlinux
- build-alpine
- build-docker
- build-freebsd
- build-homebrew
Expand Down
6 changes: 5 additions & 1 deletion cmake/dependencies/ffmpeg.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ if(NOT DEFINED FFMPEG_PREPARED_BINARIES)
set(FFMPEG_PREPARED_BINARIES "${FFMPEG_EXTRACT_DIR}/ffmpeg")

# Set the archive filename based on architecture
set(FFMPEG_ARCHIVE_NAME "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}-ffmpeg.tar.gz")
if(NOT DEFINED FFMPEG_RELEASE_ASSET_NAME)
set(FFMPEG_ARCHIVE_NAME "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}-ffmpeg.tar.gz")
else()
set(FFMPEG_ARCHIVE_NAME "${FFMPEG_RELEASE_ASSET_NAME}")
endif()
set(FFMPEG_ARCHIVE_PATH "${FFMPEG_VERSION_DIR}/${FFMPEG_ARCHIVE_NAME}")
set(FFMPEG_DOWNLOAD_URL "${FFMPEG_RELEASE_URL}/${FFMPEG_ARCHIVE_NAME}")

Expand Down
2 changes: 2 additions & 0 deletions cmake/prep/options.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ elseif(UNIX) # Linux
"Enable a Flatpak build." OFF)
option(SUNSHINE_CONFIGURE_PKGBUILD
"Configure files required for AUR. Recommended to use with SUNSHINE_CONFIGURE_ONLY" OFF)
option(SUNSHINE_CONFIGURE_APKBUILD
"Configure files required for an Alpine Linux package. Recommended to use with SUNSHINE_CONFIGURE_ONLY" OFF)
option(SUNSHINE_CONFIGURE_FLATPAK_MAN
"Configure manifest file required for Flatpak build. Recommended to use with SUNSHINE_CONFIGURE_ONLY" OFF)

Expand Down
7 changes: 7 additions & 0 deletions cmake/prep/special_package_configuration.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ elseif(UNIX)
configure_file(packaging/linux/Arch/sunshine.install sunshine.install @ONLY)
endif()

# configure the Alpine Linux APKBUILD
if(${SUNSHINE_CONFIGURE_APKBUILD})
configure_file(packaging/linux/Alpine/APKBUILD APKBUILD @ONLY)
configure_file(packaging/linux/Alpine/sunshine.post-install sunshine.post-install COPYONLY)
configure_file(packaging/linux/Alpine/sunshine.post-install sunshine.post-upgrade COPYONLY)
endif()

# configure the flatpak manifest
if(${SUNSHINE_CONFIGURE_FLATPAK_MAN})
configure_file(packaging/linux/flatpak/${PROJECT_FQDN}.yml ${PROJECT_FQDN}.yml @ONLY)
Expand Down
21 changes: 21 additions & 0 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,27 @@ CUDA is used for NVFBC capture.
</tr>
</table>

#### Alpine Linux

> [!IMPORTANT]
> The Alpine package is dynamically linked against Alpine 3.24 libraries. CUDA and NVFBC capture are not available in
> this package, but the other capture and encoding backends supported by the system remain enabled.

##### Install

1. Download `sunshine_{version}_alpine{distro-version}_{arch}.apk` from the [latest release][latest-release].
2. Install the package as root. Release APKs use a per-build signing key, so explicitly allow the downloaded package.

```sh
apk add --allow-untrusted ./sunshine_{version}_alpine{distro-version}_{arch}.apk
```

##### Uninstall

```sh
apk del sunshine
```

#### AppImage

> [!CAUTION]
Expand Down
Loading
Loading