mirror of
https://github.com/Toastconcern/FrameStudio.git
synced 2026-10-29 04:02:56 +01:00
CI stamps every Studio build with its commit (FRAME_BUILD) and the release gets latest.json: the commit, Frame Home's identity (a hash of the headset programs in frame/payload) and the files in the release. Frame Studio (studio/updater.h): checks a few seconds after start and every 6 hours (Help > Check for Updates any time). A newer build shows "Update Available" in the top bar; Download and Install fetches this computer's build with the system's curl, unpacks it with tar, and swaps each item in (the old one renamed aside first, so the running copy keeps working and a failure rolls everything back). Restart Now closes through the normal unsaved-changes prompt, then starts the new copy; the next start deletes what was set aside. Local builds never update. New platform calls: systemTool (System32's curl/tar on Windows) and launch. Frame Home (src/switcher.cpp): on the Steam Frame the Environments panel checks a minute after it starts and every 6 hours. When the installed programs' hash isn't the release's, "Update Frame Home" shows beside Restart Frame Home; it downloads FrameHome-installer.zip and runs its install.sh in its own session (which restarts Frame Home and the panel), and the new panel says "Frame Home is updated". Also frame-switcher --check-update / --update from a terminal. frame/payload: frame-switcher rebuilt on the Steam Frame with this. Tested: Studio's full cycle (check, download, unpack, swap, relaunch, cleanup) and its rollback against a local fake release on Windows; the headset's check and update against a fake release on the Frame (old panel and Frame Home replaced, then up to date); Linux compile of Studio; Studio --selftest unchanged (98 passed, same 6 known fails). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
156 lines
6.7 KiB
YAML
156 lines
6.7 KiB
YAML
# 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
|
|
|
|
# Every Studio build knows the commit it's from (studio/updater.h compares it with the latest release's).
|
|
env:
|
|
FRAME_BUILD: ${{ github.sha }}
|
|
|
|
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, i386: true,
|
|
extra: "gcc-multilib g++-multilib libx11-dev:i386 libxrandr-dev:i386 libxinerama-dev:i386 libxcursor-dev:i386 libxi-dev:i386" }
|
|
- { arch: arm64, runner: ubuntu-24.04-arm, extra: "" }
|
|
runs-on: ${{ matrix.runner }}
|
|
timeout-minutes: 45
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Tools and X11 headers
|
|
run: |
|
|
# x86 links against 32-bit X11, so apt needs the i386 packages too
|
|
if [ "${{ matrix.i386 }}" = "true" ]; then sudo dpkg --add-architecture i386; fi
|
|
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
|
|
|
|
windows:
|
|
name: Windows ${{ matrix.arch }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
arch: [x64, x86, arm64]
|
|
runs-on: windows-latest
|
|
timeout-minutes: 45
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- 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"
|
|
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 }
|
|
# Intel: macos-13 was retired (Dec 2025); macos-15-intel is GitHub's last Intel Mac runner (until Aug 2027).
|
|
# Not cross-built on an ARM Mac because Homebrew's MoltenVK, bundled into the app, is the runner's own arch.
|
|
- { arch: x64, runner: macos-15-intel }
|
|
runs-on: ${{ matrix.runner }}
|
|
timeout-minutes: 45
|
|
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
|
|
timeout-minutes: 30
|
|
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
|
|
# "latest" gets every build that finished (a failed or still-slow platform just isn't in it); a version release
|
|
# needs them all. We don't wait on macOS: its runners can sit in GitHub's queue for hours, and since a push
|
|
# cancels the previous run, waiting meant no run ever reached this job. Both Mac builds still upload and are
|
|
# attached whenever they finish in time.
|
|
if: ${{ !cancelled() && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') }}
|
|
needs: [linux, windows, frame-home]
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 20
|
|
permissions:
|
|
contents: write
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
REPO: ${{ github.repository }}
|
|
steps:
|
|
- uses: actions/download-artifact@v4
|
|
with:
|
|
path: dist
|
|
merge-multiple: true
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
path: src
|
|
# What Frame Studio (studio/updater.h) and the headset's Environments panel check for updates: this commit,
|
|
# Frame Home's identity (a hash of the headset programs, the same one the panel works out for what's installed)
|
|
# and the files in this release.
|
|
- name: latest.json
|
|
run: |
|
|
home=$(cd src/frame/payload && sha256sum bin/frame-home bin/frame-switcher bin/fenv-tool layer/libframe_home_layer.so layer/env_ps.spv | cut -c1-64 | sha256sum | cut -c1-64)
|
|
files=$(ls dist | python3 -c 'import json, sys; print(json.dumps([l.strip() for l in sys.stdin if l.strip()]))')
|
|
printf '{"build": "%s", "home": "%s", "date": "%s", "files": %s}\n' "$GITHUB_SHA" "$home" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$files" > dist/latest.json
|
|
cat dist/latest.json
|
|
- 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."
|