Web - optimise initial loading and engine boot #2027
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build | |
| on: | |
| # Do it on every push or PR on these branches | |
| push: | |
| branches: [dev, stable] | |
| pull_request: | |
| branches: [dev, stable] | |
| # Do build on demand | |
| workflow_dispatch: | |
| jobs: | |
| # Build Sonic Pi | |
| build: | |
| name: "${{matrix.title}} (${{matrix.cc}}, ${{matrix.arch}}, ${{matrix.build_type}})" | |
| runs-on: ${{matrix.os}} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { | |
| title: "Linux", | |
| os: "ubuntu-latest", | |
| cc: "clang", | |
| arch: "x64", | |
| build_type: "Release", | |
| } | |
| - { | |
| title: "Linux", | |
| os: "ubuntu-latest", | |
| cc: "clang", | |
| arch: "x64", | |
| build_type: "Debug", | |
| } | |
| - { | |
| title: "Linux", | |
| os: "ubuntu-latest", | |
| cc: "gcc", | |
| arch: "x64", | |
| build_type: "Release", | |
| } | |
| - { | |
| title: "Linux", | |
| os: "ubuntu-latest", | |
| cc: "gcc", | |
| arch: "x64", | |
| build_type: "Debug", | |
| } | |
| - { | |
| title: "Windows", | |
| os: "windows-2022", | |
| cc: "vs2022", | |
| arch: "x64", | |
| build_type: "Release", | |
| } | |
| - { | |
| title: "Windows", | |
| os: "windows-2022", | |
| cc: "vs2022", | |
| arch: "x64", | |
| build_type: "Debug", | |
| } | |
| - { | |
| title: "Mac", | |
| os: "macos-latest", | |
| cc: "clang", | |
| arch: "x64", | |
| build_type: "Release", | |
| } | |
| - { | |
| title: "Mac", | |
| os: "macos-latest", | |
| cc: "clang", | |
| arch: "x64", | |
| build_type: "Debug", | |
| } | |
| - { | |
| title: "Mac", | |
| os: "macos-latest", | |
| cc: "clang", | |
| arch: "arm64", | |
| build_type: "Release", | |
| } | |
| - { | |
| title: "Mac", | |
| os: "macos-latest", | |
| cc: "clang", | |
| arch: "arm64", | |
| build_type: "Debug", | |
| } | |
| steps: | |
| # Get the code | |
| - uses: actions/checkout@v4 | |
| # Install Ruby for the windows build | |
| - uses: ruby/setup-ruby@v1 | |
| id: ruby-inst | |
| with: | |
| ruby-version: 3.4.4 | |
| if: startsWith(matrix.os, 'windows') | |
| - name: Set up CMake | |
| uses: lukka/get-cmake@v4.0.2 | |
| # Install gems Windows | |
| - name: Setup Ruby Windows | |
| working-directory: ${{github.workspace}}/app | |
| run: | | |
| gem install rugged | |
| gem install test-unit | |
| if: startsWith(matrix.os, 'windows') | |
| # Install gems Linux - needs sudo | |
| - name: Setup Ruby Gems | |
| working-directory: ${{github.workspace}}/app | |
| run: | | |
| sudo gem install rugged | |
| sudo gem install test-unit | |
| if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' | |
| # For windows we build a symlink in the bash shell because the windows method does not seem to work. | |
| - name: Add SymLink for Windows | |
| working-directory: ${{github.workspace}}/app/server/native | |
| run: | | |
| ln -s ${{steps.ruby-inst.outputs.ruby-prefix}} ruby | |
| if: startsWith(matrix.os, 'windows') | |
| # Get Qt | |
| - name: Install Qt 6 | |
| id: qt-inst | |
| uses: jurplel/install-qt-action@v4 | |
| with: | |
| modules: "qtpositioning qtwebchannel qtwebengine qtwebsockets" | |
| # Windows is pinned to the last pre-restructure Qt (6.9.x): Qt 6.10+ | |
| # split the Windows download tree into per-arch dirs and dropped the | |
| # old nested qt6_XXX/qt6_XXX/ wrapper, which aqtinstall 3.3.0 (used by | |
| # install-qt-action@v4) can't resolve -> "Failed to download checksum | |
| # for Updates.xml". Linux/macOS keep the nested layout, so they're | |
| # fine on 6.11.1. Revert once aqtinstall ships a fix (miurahr/aqtinstall#1007). | |
| version: ${{ startsWith(matrix.os, 'windows') && '6.9.3' || '6.11.1' }} | |
| # Prebuild on Ubuntu | |
| - name: Prebuild Linux | |
| working-directory: ${{github.workspace}}/app | |
| env: | |
| CC: ${{ matrix.cc }} | |
| QT_INSTALL_LOCATION: ${{steps.qt-inst.outputs.qtPath}} | |
| run: | | |
| sudo apt install -y pulseaudio dbus-x11 ruby-dev libssl-dev alsa-base alsa-utils libasound2-dev libjack-jackd2-dev libpipewire-0.3-dev libudev-dev autoconf automake libtool-bin gettext pkg-config m4 libaubio-dev libpng-dev libboost-dev libxrandr-dev libxinerama-dev libxcursor-dev libxcomposite-dev libxext-dev libxrender-dev libfreetype6-dev libfontconfig1-dev libglu1-mesa-dev | |
| ./linux-prebuild.sh | |
| if: matrix.os == 'ubuntu-latest' | |
| # Prebuild on Mac | |
| - name: Prebuild Mac | |
| working-directory: ${{github.workspace}}/app | |
| env: | |
| CC: ${{ matrix.cc }} | |
| QT_INSTALL_LOCATION: ${{steps.qt-inst.outputs.qtPath}} | |
| run: | | |
| ./mac-prebuild.sh | |
| if: matrix.os == 'macos-latest' | |
| # Hide every msys64 dir (system root + any bundled in setup-ruby's | |
| # tool-cache install) before vcpkg runs. Otherwise vcpkg's libflac port | |
| # picks up the mingw cmake.exe from msys64 and the MSVC-triplet build | |
| # blows up. The Ruby-tool-cache copy lives at e.g. | |
| # /c/hostedtoolcache/windows/Ruby/3.4.4/x64/msys64 | |
| # so the find walks the full hostedtoolcache tree (no depth limit). | |
| - name: Hide msys64 from PATH (Windows) | |
| shell: bash | |
| run: | | |
| set -x | |
| [ -d /c/msys64 ] && mv /c/msys64 /c/__msys64 || true | |
| find /c/hostedtoolcache -type d -name msys64 -print0 2>/dev/null \ | |
| | xargs -0 -I{} mv {} {}.__hidden || true | |
| where cmake || true | |
| if: startsWith(matrix.os, 'windows') | |
| - name: Prebuild Windows | |
| working-directory: ${{github.workspace}}/app | |
| shell: cmd | |
| env: | |
| CC: ${{ matrix.cc }} | |
| QT_INSTALL_LOCATION: ${{steps.qt-inst.outputs.qtPath}} | |
| run: | | |
| win-prebuild.bat | |
| if: startsWith(matrix.os, 'windows') | |
| #- name: Setup tmate session | |
| # uses: mxschmitt/action-tmate@v3 | |
| # Run Configuration Config on Ubuntu | |
| - name: Config Linux | |
| working-directory: ${{github.workspace}}/app | |
| env: | |
| CC: ${{ matrix.cc }} | |
| QT_INSTALL_LOCATION: ${{steps.qt-inst.outputs.qtPath}} | |
| run: | | |
| ./linux-config.sh --config ${{ matrix.build_type }} | |
| if: matrix.os == 'ubuntu-latest' | |
| # Run Configuration Config on Mac | |
| - name: Config Mac | |
| working-directory: ${{github.workspace}}/app | |
| env: | |
| CC: ${{ matrix.cc }} | |
| QT_INSTALL_LOCATION: ${{steps.qt-inst.outputs.qtPath}} | |
| run: | | |
| ./mac-config.sh --config ${{ matrix.build_type }} | |
| if: matrix.os == 'macos-latest' | |
| # Run Configuration Config on Windows | |
| - name: Config Windows | |
| working-directory: ${{github.workspace}}/app | |
| shell: cmd | |
| env: | |
| CC: ${{ matrix.cc }} | |
| QT_INSTALL_LOCATION: ${{steps.qt-inst.outputs.qtPath}} | |
| run: | | |
| win-config.bat ${{ matrix.build_type }} | |
| if: startsWith(matrix.os, 'windows') | |
| # Finally: Build | |
| - name: Build Linux | |
| working-directory: ${{github.workspace}}/app | |
| run: ./linux-build-gui.sh | |
| if: matrix.os == 'ubuntu-latest' | |
| - name: Build Mac | |
| working-directory: ${{github.workspace}}/app | |
| run: ./mac-build-gui.sh | |
| if: matrix.os == 'macos-latest' | |
| - name: Build Windows | |
| working-directory: ${{github.workspace}}/app | |
| shell: cmd | |
| run: win-build-gui.bat ${{ matrix.build_type }} | |
| if: startsWith(matrix.os, 'windows') | |
| - name: Ruby Tests (Mac/Linux) | |
| working-directory: ${{github.workspace}}/app/server/ruby | |
| run: rake test | |
| if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' | |
| - name: Ruby Tests (Windows) | |
| working-directory: ${{github.workspace}}/app/server/ruby | |
| run: rake test | |
| if: startsWith(matrix.os, 'windows') | |
| - name: API Tests - Mac | |
| working-directory: ${{github.workspace}}/app/build/api-tests | |
| env: | |
| SONIC_PI_ENV: test | |
| run: ctest --verbose | |
| if: matrix.os == 'macos-latest' | |
| - name: API Tests - Linux | |
| working-directory: ${{github.workspace}}/app/build/api-tests | |
| env: | |
| SONIC_PI_ENV: test | |
| run: | | |
| jackd -rd dummy & | |
| ctest --verbose | |
| if: matrix.os == 'ubuntu-latest' | |
| - name: Debug API Tests Directory (Windows) | |
| shell: cmd | |
| run: | | |
| echo Current directory is %CD% | |
| echo GITHUB_WORKSPACE is %GITHUB_WORKSPACE% | |
| echo Listing contents of %GITHUB_WORKSPACE%\app\build: | |
| dir "%GITHUB_WORKSPACE%\app\build" | |
| if not exist "%GITHUB_WORKSPACE%\app\build\api-tests" ( | |
| echo "Directory %GITHUB_WORKSPACE%\app\build\api-tests does not exist. Creating it now." | |
| mkdir "%GITHUB_WORKSPACE%\app\build\api-tests" | |
| ) else ( | |
| echo "Directory %GITHUB_WORKSPACE%\app\build\api-tests exists." | |
| ) | |
| if: startsWith(matrix.os, 'windows') | |
| # --- Windows API tests step --- | |
| - name: API Tests - Windows | |
| shell: cmd | |
| working-directory: ${{ github.workspace }}\app\build\api-tests | |
| env: | |
| SONIC_PI_ENV: test | |
| run: ctest --verbose | |
| if: startsWith(matrix.os, 'windows') | |
| # GUI tests: Catch2 + Qt Test, run headless via the offscreen platform. | |
| # (Windows offscreen path unverified — add a Windows step once confirmed.) | |
| - name: GUI Tests - Mac | |
| working-directory: ${{github.workspace}}/app/build/gui-tests | |
| env: | |
| QT_QPA_PLATFORM: offscreen | |
| run: ctest --verbose | |
| if: matrix.os == 'macos-latest' | |
| - name: GUI Tests - Linux | |
| working-directory: ${{github.workspace}}/app/build/gui-tests | |
| env: | |
| QT_QPA_PLATFORM: offscreen | |
| run: ctest --verbose | |
| if: matrix.os == 'ubuntu-latest' | |
| - name: Archive Logs | |
| uses: actions/upload-artifact@v4 | |
| if: ${{ always() }} | |
| with: | |
| name: Logs_${{matrix.title}}_${{matrix.cc}}_${{matrix.arch}}_${{matrix.build_type}} | |
| path: | | |
| ~/.sonic-pi/log/*.log | |
| # Build distributable AppImages for Linux x86_64 and aarch64. | |
| # (32-bit x86 can't share this job's shape — see package-linux-i386 below.) | |
| # | |
| # Each arch builds in the *oldest* container its Qt prebuilds tolerate, | |
| # because that container's glibc is the AppImage's runtime floor. | |
| # x86_64 → ubuntu:22.04 (glibc 2.35) + Qt 6.5.3 LTS | |
| # Runs on Ubuntu 22.04+, Debian 12+, Fedora 36+, Mint 21+, Arch. | |
| # aarch64 → ubuntu:24.04 (glibc 2.39) + Qt 6.9.0 | |
| # aqtinstall has no Linux ARM64 prebuilds before Qt 6.7, and | |
| # those need glibc ≥ 2.38, so 22.04 isn't an option here. | |
| # Runs on Ubuntu 24.04+, Debian 13+, Fedora 40+, Mint 22+, Arch. | |
| package-linux: | |
| name: "AppImage (${{matrix.arch}})" | |
| runs-on: ${{matrix.runner}} | |
| container: | |
| image: ${{matrix.container}} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - arch: x86_64 | |
| runner: ubuntu-22.04 | |
| container: ubuntu:22.04 | |
| qt_version: "6.5.3" | |
| image_os: ubuntu22 | |
| - arch: aarch64 | |
| runner: ubuntu-22.04-arm | |
| container: ubuntu:24.04 | |
| qt_version: "6.9.0" | |
| image_os: ubuntu24 | |
| env: | |
| RUBY_VERSION: 3.4.4 | |
| DEBIAN_FRONTEND: noninteractive | |
| SP_SKIP_RUBY_EXTS: "1" | |
| steps: | |
| - name: Install base build deps | |
| run: | | |
| apt-get update | |
| # Existing-CI Linux apt list (verbatim) plus extras the bare | |
| # ubuntu:22.04 container needs (build tools, archive tools), the | |
| # AppImage tooling needs (file/imagemagick/fuse), and the | |
| # source-build of Ruby needs (lib*-dev for ./configure). | |
| apt-get install -y \ | |
| pulseaudio dbus-x11 ruby-dev libssl-dev \ | |
| alsa-base alsa-utils libasound2-dev libjack-jackd2-dev \ | |
| libpipewire-0.3-dev \ | |
| libudev-dev autoconf automake libtool-bin gettext \ | |
| pkg-config m4 libaubio-dev libpng-dev libboost-dev \ | |
| libxrandr-dev libxinerama-dev libxcursor-dev libxcomposite-dev libxext-dev libxrender-dev \ | |
| libfreetype6-dev libfontconfig1-dev \ | |
| libglu1-mesa-dev \ | |
| build-essential ca-certificates curl git sudo \ | |
| unzip xz-utils p7zip-full \ | |
| file imagemagick fuse libfuse2 \ | |
| libyaml-dev libffi-dev libreadline-dev zlib1g-dev libgdbm-dev libgmp-dev | |
| - uses: actions/checkout@v4 | |
| # The container runs as root but the runner-mounted workspace is | |
| # owned by a different uid; without this, every `git` call inside | |
| # the build scripts (e.g. linux-prebuild.sh's submodule update) | |
| # fails with "fatal: detected dubious ownership in repository". | |
| - name: Trust workspace for git | |
| run: git config --global --add safe.directory '*' | |
| # Cache the bundled Ruby tree across runs — recompiling MRI takes ~3-5min. | |
| - name: Restore bundled Ruby cache | |
| id: ruby-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: ${{github.workspace}}/_bundled_ruby | |
| key: bundled-ruby-${{matrix.arch}}-${{env.RUBY_VERSION}}-${{matrix.image_os}} | |
| - name: Build Ruby ${{env.RUBY_VERSION}} (--enable-load-relative) | |
| if: steps.ruby-cache.outputs.cache-hit != 'true' | |
| # Force bash so set -o pipefail and ${VAR%.*} work — the | |
| # ubuntu:22.04 container's default /bin/sh is dash. | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| cd /tmp | |
| curl -fsSLO "https://cache.ruby-lang.org/pub/ruby/${RUBY_VERSION%.*}/ruby-${RUBY_VERSION}.tar.gz" | |
| tar xzf "ruby-${RUBY_VERSION}.tar.gz" | |
| cd "ruby-${RUBY_VERSION}" | |
| ./configure \ | |
| --prefix="${GITHUB_WORKSPACE}/_bundled_ruby" \ | |
| --enable-load-relative \ | |
| --disable-install-doc \ | |
| --disable-install-rdoc | |
| make -j"$(nproc)" | |
| make install | |
| - name: Set up CMake | |
| uses: lukka/get-cmake@v4.0.2 | |
| # The bare ubuntu containers ship no Rust; supersonic's native MIDI | |
| # subsystem (SUPERSONIC_ENABLE_MIDI) is a cargo-built staticlib, so | |
| # its CMake configure needs cargo on PATH. Hosted runners (the build | |
| # matrix) already have it pre-installed. | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install Qt 6 | |
| id: qt-inst | |
| uses: jurplel/install-qt-action@v4 | |
| # Per-arch Qt version, locked to what the container's glibc | |
| # supports (see the comment on `package-linux:` above). | |
| with: | |
| modules: "qtpositioning qtwebchannel qtwebengine qtwebsockets" | |
| version: "${{matrix.qt_version}}" | |
| - name: Put bundled Ruby first on PATH | |
| run: | | |
| echo "${GITHUB_WORKSPACE}/_bundled_ruby/bin" >> "$GITHUB_PATH" | |
| - name: Setup Ruby Gems | |
| working-directory: ${{github.workspace}}/app | |
| run: | | |
| gem install rugged | |
| gem install test-unit | |
| - name: Prebuild | |
| working-directory: ${{github.workspace}}/app | |
| env: | |
| QT_INSTALL_LOCATION: ${{steps.qt-inst.outputs.qtPath}} | |
| run: ./linux-prebuild.sh | |
| - name: Configure | |
| working-directory: ${{github.workspace}}/app | |
| env: | |
| QT_INSTALL_LOCATION: ${{steps.qt-inst.outputs.qtPath}} | |
| run: ./linux-config.sh --config Release | |
| - name: Build GUI | |
| working-directory: ${{github.workspace}}/app | |
| run: ./linux-build-gui.sh | |
| # The PipeWire backend is silently compiled out when libpipewire-0.3-dev | |
| # is missing from this container (CMake pkg_check gate) - which shipped | |
| # RC2 AppImages that fall back to ALSA and see no devices on | |
| # PipeWire-only systems (fresh RPi OS). The dlopen target string only | |
| # exists in the binary when the backend compiled in, so assert on it. | |
| - name: Verify PipeWire backend compiled in | |
| working-directory: ${{github.workspace}}/app | |
| run: | | |
| strings server/native/sonic-pi-supersonic | grep -q "libpipewire-0.3.so" \ | |
| || { echo "PipeWire backend missing from supersonic binary"; exit 1; } | |
| - name: Package AppImage | |
| working-directory: ${{github.workspace}}/app | |
| env: | |
| BUNDLED_RUBY_DIR: ${{github.workspace}}/_bundled_ruby | |
| run: ./linux-appimage.sh | |
| - name: Capture AppImage basename | |
| id: img | |
| shell: bash | |
| run: | | |
| f=$(ls "$GITHUB_WORKSPACE"/app/build/Sonic-Pi-*.AppImage | head -n1) | |
| echo "name=$(basename "$f" .AppImage)" >> "$GITHUB_OUTPUT" | |
| - name: Upload AppImage | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ steps.img.outputs.name }} | |
| path: ${{github.workspace}}/app/build/Sonic-Pi-*.AppImage | |
| if-no-files-found: error | |
| # Build, test and package 32-bit x86 (i686). | |
| # | |
| # This runs the same three suites the build matrix does (Spider, API, GUI), | |
| # so 32-bit gets real test coverage rather than a build-only smoke check. | |
| # The suites gate packaging: a failing test means no AppImage. | |
| # | |
| # This job is shaped differently from package-linux above, for two reasons: | |
| # | |
| # 1. No Qt prebuilds. aqtinstall carries linux_x64 and linux_arm64 only, so | |
| # Qt comes from Debian instead. bookworm is the oldest suite with a full | |
| # Qt 6 i386 stack; its glibc 2.36 is therefore the AppImage's runtime | |
| # floor, and its Qt 6.4 means the accessibility features gated on Qt 6.8+ | |
| # in app/gui/CMakeLists.txt compile out of this build. Moving to | |
| # i386/debian:trixie gets Qt 6.8 back at the cost of a glibc 2.41 floor. | |
| # | |
| # 2. No `container:`. The runner injects its own x86_64 Node to execute JS | |
| # actions, and an i386 rootfs has no ld-linux-x86-64.so.2, so checkout / | |
| # cache / upload-artifact would all fail. Instead the job runs on the | |
| # normal x86_64 host — actions included — and only the build itself is | |
| # put inside a 32-bit container. Nothing is emulated: x86_64 CPUs run | |
| # 32-bit code natively, so this costs roughly what the x86_64 job does. | |
| package-linux-i386: | |
| name: "Linux i686 (build, test, AppImage)" | |
| runs-on: ubuntu-22.04 | |
| env: | |
| RUBY_VERSION: 3.4.4 | |
| SP_I386_IMAGE: i386/debian:bookworm | |
| # The build prints its glibc floor (the highest GLIBC_ symbol any bundled | |
| # binary references), which is what actually decides distro coverage — | |
| # it can sit well below the container's own 2.36. Once the first run | |
| # reports it, pin it here as SP_MAX_GLIBC so a future dependency can't | |
| # quietly raise the floor and drop distros: | |
| # SP_MAX_GLIBC: "2.34" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # Cache the bundled Ruby tree across runs — recompiling MRI takes ~3-5min. | |
| - name: Restore bundled Ruby cache | |
| id: ruby-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: ${{github.workspace}}/_bundled_ruby | |
| key: bundled-ruby-i686-${{env.RUBY_VERSION}}-debian12 | |
| # One long-lived container for every phase below. Running each phase as | |
| # its own `docker exec` (rather than a single `docker run` doing the lot) | |
| # keeps the apt install shared while still giving each stage its own CI | |
| # step, so a failure names the stage that broke. | |
| - name: Start 32-bit container | |
| run: | | |
| docker run -d --name sp32 \ | |
| --platform linux/386 \ | |
| -v "${GITHUB_WORKSPACE}:/src" \ | |
| -w /src/app \ | |
| -e RUBY_VERSION \ | |
| -e SP_MAX_GLIBC \ | |
| "${SP_I386_IMAGE}" sleep infinity | |
| - name: Install dependencies | |
| run: docker exec sp32 ./linux-appimage-i386-container.sh deps | |
| - name: Build Ruby ${{env.RUBY_VERSION}} | |
| run: docker exec sp32 ./linux-appimage-i386-container.sh ruby | |
| - name: Setup Rust | |
| run: docker exec sp32 ./linux-appimage-i386-container.sh rust | |
| - name: Build | |
| run: docker exec sp32 ./linux-appimage-i386-container.sh build | |
| - name: Tests (Spider, API, GUI) | |
| run: docker exec sp32 ./linux-appimage-i386-container.sh test | |
| - name: Package AppImage | |
| run: docker exec sp32 ./linux-appimage-i386-container.sh package | |
| # Spider and API test failures are usually only diagnosable from the | |
| # Sonic Pi logs, which land in the container's root home rather than the | |
| # mounted workspace — copy them out before the container goes away. | |
| - name: Collect logs from container | |
| if: ${{ always() }} | |
| run: docker cp sp32:/root/.sonic-pi/log "${GITHUB_WORKSPACE}/i686-logs" || true | |
| - name: Stop 32-bit container | |
| if: ${{ always() }} | |
| run: docker rm -f sp32 || true | |
| - name: Archive Logs | |
| uses: actions/upload-artifact@v4 | |
| if: ${{ always() }} | |
| with: | |
| name: Logs_Linux_i686 | |
| path: ${{github.workspace}}/i686-logs/*.log | |
| if-no-files-found: ignore | |
| # The container builds as root, so everything it wrote is root-owned. | |
| # Hand it back before the cache and artifact actions (which run as the | |
| # unprivileged runner user) try to read it. | |
| - name: Reclaim ownership of container-written files | |
| if: ${{ always() }} | |
| run: sudo chown -R "$(id -u):$(id -g)" "${GITHUB_WORKSPACE}" | |
| - name: Capture AppImage basename | |
| id: img | |
| run: | | |
| f=$(ls "$GITHUB_WORKSPACE"/app/build/Sonic-Pi-*.AppImage | head -n1) | |
| echo "name=$(basename "$f" .AppImage)" >> "$GITHUB_OUTPUT" | |
| - name: Upload AppImage | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ steps.img.outputs.name }} | |
| path: ${{github.workspace}}/app/build/Sonic-Pi-*.AppImage | |
| if-no-files-found: error |