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
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @johnqherman
64 changes: 64 additions & 0 deletions .github/workflows/auto-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Auto Release

# Merging a branch named vX.Y.Z into master tags the merge commit and kicks
# off the tag-gated release pipeline in build.yml. The Build run is dispatched
# explicitly because tags pushed with GITHUB_TOKEN never trigger on-push
# workflows.

on:
pull_request:
types: [closed]
branches: [master]

jobs:
tag-and-release:
if: github.event.pull_request.merged == true &&
startsWith(github.event.pull_request.head.ref, 'v')
runs-on: ubuntu-24.04
permissions:
contents: write
actions: write
env:
TAG: ${{ github.event.pull_request.head.ref }}
MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha }}
steps:
- name: Validate release branch name
id: check
run: |
if [[ "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "release=true" >> "$GITHUB_OUTPUT"
else
echo "Branch '$TAG' is not vX.Y.Z; skipping release"
fi

- uses: actions/checkout@v7
if: steps.check.outputs.release == 'true'
with:
ref: ${{ env.MERGE_SHA }}

# same guard as build.yml: a tag that disagrees with project(VERSION)
# would bake the wrong version into every artifact
- name: Check branch matches project version
if: steps.check.outputs.release == 'true'
run: |
VER=$(sed -n 's/^ *VERSION \([0-9.]*\)$/\1/p' CMakeLists.txt | head -1)
if [ "${TAG#v}" != "$VER" ]; then
echo "::error::Branch ${TAG} != project VERSION ${VER} in CMakeLists.txt"
exit 1
fi

- name: Create and push tag
if: steps.check.outputs.release == 'true'
run: |
if git ls-remote --tags origin "refs/tags/${TAG}" | grep -q .; then
echo "::error::Tag ${TAG} already exists"
exit 1
fi
git tag "$TAG" "$MERGE_SHA"
git push origin "refs/tags/${TAG}"

- name: Dispatch release build
if: steps.check.outputs.release == 'true'
env:
GH_TOKEN: ${{ github.token }}
run: gh workflow run build.yml --ref "refs/tags/${TAG}" -R "$GITHUB_REPOSITORY"
39 changes: 15 additions & 24 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
tags: ["v*"]
pull_request:
branches: [master]
# auto-release.yml dispatches this on the tag it creates (GITHUB_TOKEN tag
# pushes never fire the on-push trigger)
workflow_dispatch:

jobs:
build-linux:
Expand Down Expand Up @@ -94,8 +97,6 @@ jobs:
run: choco install nsis -y

- name: Set up MSVC
# still node20 upstream (no node24 release as of v1.13.0); the runner
# force-runs it on node24, which works but logs a deprecation warning
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
Expand Down Expand Up @@ -128,20 +129,14 @@ jobs:
uses: actions/upload-artifact@v7
with:
name: OpenMix-windows
# explicit patterns so the raw build/OpenMix.exe binary isn't shipped
path: |
build/OpenMix-*-win64.exe
build/OpenMix-*-win64.zip

build-macos:
# pinned: macos-latest is migrating to macOS 26 (June 2026); keep the
# known-good image for the universal Qt build until 26 is validated
runs-on: macos-15
steps:
- uses: actions/checkout@v7

# runner image ships untrusted third-party taps (aws/tap) that make
# every brew call (incl. ccache-action's) log a tap-trust warning
- name: Remove untrusted brew taps
run: brew untap aws/tap 2>/dev/null || true

Expand Down Expand Up @@ -180,8 +175,6 @@ jobs:
-DCMAKE_OSX_DEPLOYMENT_TARGET=12.0

- name: Build
# cap parallelism: full -j exhausts the 7GB arm64 runner on Qt PCH
# (cc1plus), starving/killing the runner ("lost communication")
run: cmake --build build --config Release --parallel 2

- name: Test
Expand Down Expand Up @@ -222,10 +215,6 @@ jobs:
OpenMix-windows/*
OpenMix-macos/*

# generate the Sparkle/WinSparkle appcasts + installer tree and rsync them to
# the openmix.dev VPS. Requires a Sparkle EdDSA private key in
# OPENMIX_SPARKLE_ED_PRIVATE_KEY and OPENMIX_DEPLOY_* SSH secrets
# (see docs/AUTOUPDATE.md).
appcast:
if: startsWith(github.ref, 'refs/tags/v')
needs: [release]
Expand Down Expand Up @@ -254,7 +243,6 @@ jobs:
mkdir -p site/download/${TAG}
cp OpenMix-macos/* OpenMix-windows/* OpenMix-linux/* site/download/${TAG}/ 2>/dev/null || true

# macOS: sign the DMG with Sparkle's EdDSA key and emit a full appcast
SIGN=$(find /opt/homebrew /usr/local -name sign_update -type f 2>/dev/null | head -1)
DMG=$(ls OpenMix-macos/*.dmg | head -1)
if [ -n "$SPARKLE_KEY" ] && [ -n "$SIGN" ] && [ -n "$DMG" ]; then
Expand All @@ -277,7 +265,8 @@ jobs:
echo "::warning::No Sparkle key/tool/DMG; skipping macOS appcast (updates will not verify)"
fi

# Windows: WinSparkle RSS appcast
# legacy feed: pre-1.0.1 clients still run WinSparkle and need this
# appcast to reach the first WinSparkle-free build
EXE=$(ls OpenMix-windows/*.exe | head -1)
if [ -n "$EXE" ]; then
cat > site/appcast-windows.xml <<EOF
Expand All @@ -294,13 +283,19 @@ jobs:
EOF
fi

# Linux notify-fallback: tiny JSON polled by UpdateChecker
cat > site/latest.json <<EOF
# the in-app updater (UpdateChecker) reads latest.json; the installer
# url + sha256 drive the Windows download-and-install flow
if [ -n "$EXE" ]; then
EXE_SHA256=$(shasum -a 256 "$EXE" | cut -d' ' -f1)
cat > site/latest.json <<EOF
{"tag_name": "${TAG}", "html_url": "https://openmix.dev/download", "windows_installer_url": "${BASE}/$(basename "$EXE")", "windows_installer_sha256": "${EXE_SHA256}"}
EOF
else
cat > site/latest.json <<EOF
{"tag_name": "${TAG}", "html_url": "https://openmix.dev/download"}
EOF
fi

# download landing page: nginx autoindex is off, so /download/
# 403s without an index.html. list the current release's files.
{
echo '<!doctype html><html lang="en"><head><meta charset="utf-8">'
echo '<meta name="viewport" content="width=device-width,initial-scale=1">'
Expand Down Expand Up @@ -335,10 +330,6 @@ jobs:
ssh -i ~/.ssh/deploy "${SSH_USER}@${SSH_HOST}" \
"cd '${DEPLOY_PATH}/download' && ls -1d v*/ 2>/dev/null | sed 's:/*\$::' | sort -V | head -n -5 | xargs -r rm -rf --"

# the site bakes release data (downloads table, past releases) at build
# time, so rebuild it whenever a release ships. Needs a fine-grained PAT
# with Actions write on openmix.dev in OPENMIX_SITE_DISPATCH_TOKEN;
# non-fatal so a missing token never blocks a release.
- name: Rebuild openmix.dev
env:
GH_TOKEN: ${{ secrets.OPENMIX_SITE_DISPATCH_TOKEN }}
Expand Down
41 changes: 6 additions & 35 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.16)

project(OpenMix
VERSION 1.0.0
VERSION 1.0.1
DESCRIPTION "Stage mixing software for live theatre that lets engineers program, automate, and run cues seamlessly across 30+ digital mixing consoles"
LANGUAGES CXX
)
Expand Down Expand Up @@ -157,6 +157,7 @@ set(SOURCES
src/ui/ActiveCueInfoPanel.cpp
src/ui/FxSetupDialog.cpp
src/ui/WelcomeDialog.cpp
src/ui/UpdateDialog.cpp
src/ui/HelpDialog.cpp
src/ui/MarkerNotesDialog.cpp
src/ui/PopOutWindow.cpp
Expand Down Expand Up @@ -370,40 +371,10 @@ target_link_libraries(${PROJECT_NAME} PRIVATE openmix_liblo)

target_link_libraries(${PROJECT_NAME} PRIVATE RtMidi)

# --- auto-update frameworks (Windows = WinSparkle, macOS = Sparkle) ----------
# Linux has no silent-update framework; AutoUpdater falls back to the notify-and
# -link checker there, so nothing extra is linked.
if(WIN32)
FetchContent_Declare(winsparkle
URL https://github.com/vslavik/winsparkle/releases/download/v0.8.1/WinSparkle-0.8.1.zip)
FetchContent_MakeAvailable(winsparkle)
# the 0.8.1 zip layout (nesting, x64/Release/ subdir) is fragile; glob for the
# header, x64 lib, and x64 dll so the exact structure can't break the build
file(GLOB_RECURSE _ws_hdrs "${winsparkle_SOURCE_DIR}/*winsparkle.h")
file(GLOB_RECURSE _ws_libs "${winsparkle_SOURCE_DIR}/*WinSparkle.lib")
file(GLOB_RECURSE _ws_dlls "${winsparkle_SOURCE_DIR}/*WinSparkle.dll")
list(GET _ws_hdrs 0 _ws_hdr)
get_filename_component(WINSPARKLE_INCLUDE ${_ws_hdr} DIRECTORY)
foreach(f ${_ws_libs})
if(f MATCHES "x64")
set(WINSPARKLE_LIB ${f})
endif()
endforeach()
foreach(f ${_ws_dlls})
if(f MATCHES "x64")
set(WINSPARKLE_DLL ${f})
endif()
endforeach()
if(NOT WINSPARKLE_INCLUDE OR NOT WINSPARKLE_LIB OR NOT WINSPARKLE_DLL)
message(FATAL_ERROR "WinSparkle header/x64 lib/dll not found under ${winsparkle_SOURCE_DIR}")
endif()
target_include_directories(${PROJECT_NAME} PRIVATE ${WINSPARKLE_INCLUDE})
target_link_libraries(${PROJECT_NAME} PRIVATE ${WINSPARKLE_LIB})
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${WINSPARKLE_DLL} $<TARGET_FILE_DIR:${PROJECT_NAME}>)
install(FILES ${WINSPARKLE_DLL} DESTINATION ${CMAKE_INSTALL_BINDIR})
elseif(APPLE)
# --- auto-update framework (macOS = Sparkle) ---------------------------------
# Windows and Linux use the in-app updater (UpdateChecker + UpdateDialog), so
# nothing extra is linked there.
if(APPLE)
FetchContent_Declare(sparkle
URL https://github.com/sparkle-project/Sparkle/releases/download/2.6.4/Sparkle-2.6.4.tar.xz)
FetchContent_MakeAvailable(sparkle)
Expand Down
93 changes: 0 additions & 93 deletions docs/AUTOUPDATE.md

This file was deleted.

2 changes: 0 additions & 2 deletions packaging/Info.plist.in
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
<true/>
<key>SUAutomaticallyUpdate</key>
<true/>
<!-- EdDSA public key; must match the OPENMIX_SPARKLE_ED_PRIVATE_KEY signing
secret used by CI (see docs/AUTOUPDATE.md). -->
<key>SUPublicEDKey</key>
<string>Th9esMBuKy6nRfgTeOA7eeUr5Ms3fBaGtLZFI5hyH7c=</string>
</dict>
Expand Down
Loading
Loading