Nixerus/pkgs/apps/sunshine/updater.sh

126 lines
4.7 KiB
Bash
Raw Normal View History

2026-06-18 17:27:06 +02:00
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p gnugrep gnused coreutils curl jq nix-update nix-prefetch-git
# shellcheck shell=bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
package_nix="$script_dir/sunshine.nix"
nixerus_root="$(cd "$script_dir/../../.." && pwd)"
cd "$nixerus_root"
log() {
printf '\n==> %s\n' "$*" >&2
}
api() {
curl ${GITHUB_TOKEN:+-u ":$GITHUB_TOKEN"} --silent --location "$@"
}
log "Querying latest Sunshine release from GitHub"
version=$(api https://api.github.com/repos/LizardByte/Sunshine/releases/latest | jq --raw-output .tag_name | grep -oP "^v\K.*")
log "Latest version: $version"
if [[ "${UPDATE_NIX_OLD_VERSION:-}" == "$version" ]]; then
log "Already up to date!"
exit 0
fi
log "Updating sunshine version (src hash refreshed separately, see below)"
# --no-src: nix-update can't fetch submodules, so we refresh the src hash
# ourselves via nix-prefetch-git below.
nix-update sunshine --version "$version" --no-src
log "Prefetching sunshine src with submodules (this can take several minutes)"
# nix-prefetch-git outputs SRI under .hash on recent versions. The submodule
# tree NAR-hashes identically on Linux and Darwin, so one hash serves both.
src_hash=$(nix-prefetch-git \
--quiet \
--fetch-submodules \
--url "https://github.com/LizardByte/Sunshine" \
--rev "v$version" \
| jq --raw-output .hash)
if [[ -z "$src_hash" || "$src_hash" == "null" ]]; then
echo "ERROR: failed to prefetch sunshine src hash" >&2
exit 1
fi
log "src hash: $src_hash"
log "Patching src hash in $package_nix"
# The src fetchFromGitHub is the only one with fetchSubmodules; anchor on it so
# we don't touch the ffmpeg or npmDepsHash entries. sed -z spans newlines.
sed -i -zE "s#hash = \"sha256-[A-Za-z0-9+/=]+\"(\\s*fetchSubmodules = true;)#hash = \"$src_hash\"\\1#" "$package_nix"
if ! grep -q "$src_hash" "$package_nix"; then
echo "ERROR: failed to write src hash into $package_nix" >&2
exit 1
fi
log "Regenerating sunshine.ui package-lock.json"
# `--generate-lockfile` only regenerates package-lock.json; it skips the npmDepsHash
# refresh (see nix-update's dependency_hashes.py). Run a second pass to update the hash.
# `--no-src` avoids re-fetching the (already-pinned) sunshine src on each pass.
nix-update sunshine --version=skip --no-src --generate-lockfile --subpackage ui
log "Refreshing sunshine.ui npmDepsHash"
nix-update sunshine --version=skip --no-src --subpackage ui
# Update the LizardByte/build-deps tag and pinned ffmpeg tarball hashes.
# Sunshine pins build-deps via a git submodule at third-party/build-deps; the
# tag we need is whichever build-deps release tag points at that submodule's
# commit.
log "Resolving LizardByte/build-deps submodule commit and tag"
build_deps_sha=$(api "https://api.github.com/repos/LizardByte/Sunshine/contents/third-party?ref=v$version" \
| jq --raw-output '.[] | select(.name=="build-deps") | .sha')
log "build-deps submodule commit: $build_deps_sha"
build_deps_tag=$(api "https://api.github.com/repos/LizardByte/build-deps/tags?per_page=100" \
| jq --raw-output --arg sha "$build_deps_sha" '.[] | select(.commit.sha==$sha) | .name' \
| head -n1)
if [[ -z "$build_deps_tag" ]]; then
echo "ERROR: no LizardByte/build-deps tag points at submodule commit $build_deps_sha" >&2
exit 1
fi
log "build-deps tag: $build_deps_tag"
# Compute the SRI hash of a `fetchzip` (default stripRoot=true) for a URL.
# `nix-prefetch-url --unpack` produces the same NAR hash AND caches by URL
# (whereas the empty-hash + fetchzip trick re-downloads every invocation).
prefetch_unpacked_sri() {
local raw
raw=$(nix-prefetch-url --unpack --type sha256 "$1")
nix --extra-experimental-features nix-command hash convert --hash-algo sha256 --to sri "$raw"
}
ffmpeg_url() {
echo "https://github.com/LizardByte/build-deps/releases/download/$build_deps_tag/$1-ffmpeg.tar.gz"
}
# Map nix system → upstream tarball arch token. Keep this in sync with the
# `ffmpegArch` attrset in package.nix.
declare -A ffmpeg_arch=(
[x86_64-linux]=Linux-x86_64
)
declare -A ffmpeg_hash
for system in "${!ffmpeg_arch[@]}"; do
log "Prefetching ffmpeg tarball for $system (${ffmpeg_arch[$system]})"
h=$(prefetch_unpacked_sri "$(ffmpeg_url "${ffmpeg_arch[$system]}")")
if [[ -z "$h" ]]; then
echo "ERROR: failed to prefetch ffmpeg tarball for $system" >&2
exit 1
fi
log " $system -> $h"
ffmpeg_hash[$system]=$h
done
log "Patching $package_nix"
sed_args=(-E -e "s#buildDepsTag = \"v[^\"]*\";#buildDepsTag = \"$build_deps_tag\";#")
for system in "${!ffmpeg_hash[@]}"; do
sed_args+=(-e "s#$system = (lib\\.fakeHash|\"sha256-[A-Za-z0-9+/=]+\");#$system = \"${ffmpeg_hash[$system]}\";#")
done
sed -i "${sed_args[@]}" "$package_nix"
log "Done."