# Builds Frame Studio for every computer it runs on, and the Frame Home installer, on every push (any branch or tag), # every pull request, and by hand (Actions > build > Run workflow). Each build is a downloadable artifact of the run. # A push to main also replaces the "latest" pre-release with them (one place to download the newest of everything); # a tag "v*" publishes them as that version's release. name: build on: push: pull_request: workflow_dispatch: # A newer push to the same branch replaces a run still going (its builds would be out of date anyway). concurrency: group: build-${{ github.ref }} cancel-in-progress: true jobs: linux: name: Linux ${{ matrix.arch }} strategy: fail-fast: false matrix: include: - { arch: x64, runner: ubuntu-24.04, extra: "" } - { arch: x86, runner: ubuntu-24.04, extra: "gcc-multilib g++-multilib" } - { arch: arm64, runner: ubuntu-24.04-arm, extra: "" } runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@v4 - name: Tools and X11 headers run: | sudo apt-get update sudo apt-get install -y ninja-build cmake libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxkbcommon-dev ${{ matrix.extra }} - name: Build run: sh scripts/build-studio.sh linux-${{ matrix.arch }} - uses: actions/upload-artifact@v4 with: name: FrameStudio-linux-${{ matrix.arch }} path: dist/FrameStudio-linux-${{ matrix.arch }}.tar.gz # Frame Home for SteamVR on a Windows PC (frame-home.exe, frame-switcher.exe and the PC installer), cross-built with # llvm-mingw as it's developed: the pc/ folder of the Windows x64 Studio, and a download of its own. pc-home-windows: name: Frame Home for Windows PCs runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: llvm-mingw run: | sudo apt-get update && sudo apt-get install -y ninja-build cmake url=$(curl -s https://api.github.com/repos/mstorsjo/llvm-mingw/releases/latest | grep -o 'https://[^"]*ucrt-ubuntu-[0-9.]*-x86_64\.tar\.xz' | head -1) curl -sL "$url" | tar -xJ -C "$HOME" && mv "$HOME"/llvm-mingw-* "$HOME/llvm-mingw" - name: Build run: | export PATH="$HOME/llvm-mingw/bin:$PATH" cmake -S . -B build/pc-win64 -G Ninja -DCMAKE_BUILD_TYPE=Release -DFRAME_HOME_PC=ON -DCMAKE_TOOLCHAIN_FILE=cmake/llvm-mingw.cmake -DWINDOWS_ARCH=x86_64 -DLLVM_MINGW="$HOME/llvm-mingw" cmake --build build/pc-win64 --target frame-home frame-switcher d3d11.dll --parallel mkdir -p "build/stage/FrameHome-PC-windows-x64" dist cp build/pc-win64/frame-home.exe build/pc-win64/frame-switcher.exe build/pc-win64/d3d11.dll frame/pc/install-frame-home-pc.ps1 \ "frame/pc/Install Frame Home on this PC.bat" "frame/pc/Remove Frame Home from this PC.bat" "build/stage/FrameHome-PC-windows-x64/" cp LICENSE build/stage/FrameHome-PC-windows-x64/LICENSE.txt (cd build/stage && zip -qr ../../dist/FrameHome-PC-windows-x64.zip FrameHome-PC-windows-x64) - uses: actions/upload-artifact@v4 with: name: FrameHome-PC-windows-x64 path: dist/FrameHome-PC-windows-x64.zip windows: name: Windows ${{ matrix.arch }} needs: [pc-home-windows] strategy: fail-fast: false matrix: arch: [x64, x86, arm64] runs-on: windows-latest steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 if: matrix.arch == 'x64' with: name: FrameHome-PC-windows-x64 path: pc - name: Build (MSVC) shell: cmd run: studio\build_windows.bat ${{ matrix.arch }} "%GITHUB_WORKSPACE%\build\windows-${{ matrix.arch }}" - name: Package shell: pwsh run: | $name = "FrameStudio-windows-${{ matrix.arch }}" $stage = "build/stage/$name" New-Item -ItemType Directory -Force $stage | Out-Null Copy-Item "build/windows-${{ matrix.arch }}/Frame Studio.exe" $stage Copy-Item -Recurse "build/windows-${{ matrix.arch }}/frame" "$stage/frame" Copy-Item LICENSE "$stage/LICENSE.txt" if ("${{ matrix.arch }}" -eq "x64") { # Frame Home for this PC's SteamVR, beside Studio Expand-Archive "pc/FrameHome-PC-windows-x64.zip" -DestinationPath build/pc Copy-Item -Recurse "build/pc/FrameHome-PC-windows-x64" "$stage/pc" Remove-Item "$stage/pc/LICENSE.txt" } New-Item -ItemType Directory -Force dist | Out-Null Compress-Archive -Path $stage -DestinationPath "dist/$name.zip" -Force - uses: actions/upload-artifact@v4 with: name: FrameStudio-windows-${{ matrix.arch }} path: dist/FrameStudio-windows-${{ matrix.arch }}.zip macos: name: macOS ${{ matrix.arch }} strategy: fail-fast: false matrix: include: - { arch: arm64, runner: macos-14 } - { arch: x64, runner: macos-13 } runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@v4 - name: Tools and MoltenVK (Vulkan on Metal, bundled into the app) run: brew install ninja molten-vk - name: Build run: sh scripts/build-studio.sh macos-${{ matrix.arch }} - uses: actions/upload-artifact@v4 with: name: FrameStudio-macos-${{ matrix.arch }} path: dist/FrameStudio-macos-${{ matrix.arch }}.zip frame-home: name: Frame Home installer runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Package run: sh scripts/build-studio.sh frame-home - uses: actions/upload-artifact@v4 with: name: FrameHome-installer path: dist/FrameHome-installer.zip release: name: Publish # (also when a platform failed: "latest" gets every build that worked; a version release needs them all) if: ${{ !cancelled() && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') }} needs: [linux, windows, macos, frame-home, pc-home-windows] runs-on: ubuntu-24.04 permissions: contents: write env: GH_TOKEN: ${{ github.token }} REPO: ${{ github.repository }} steps: - uses: actions/download-artifact@v4 with: path: dist merge-multiple: true - name: Version release (tag v*) if: ${{ startsWith(github.ref, 'refs/tags/v') && !contains(needs.*.result, 'failure') }} run: gh release create "${{ github.ref_name }}" dist/* --repo "$REPO" --title "Frame Studio ${{ github.ref_name }}" --generate-notes - name: Latest build (push to main) if: github.ref == 'refs/heads/main' run: | gh release delete latest --repo "$REPO" --yes --cleanup-tag 2>/dev/null || true gh release create latest dist/* --repo "$REPO" --prerelease --target "${{ github.sha }}" \ --title "Latest build (${GITHUB_SHA::7})" \ --notes "Built automatically from ${{ github.sha }} on $(date -u '+%Y-%m-%d %H:%M UTC'). Replaced by every push to main."