Skip to content

v1.0.5: fix X32/M32 and WING console connections #99

v1.0.5: fix X32/M32 and WING console connections

v1.0.5: fix X32/M32 and WING console connections #99

Workflow file for this run

name: Build
on:
push:
branches: [master]
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:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
# release tags must match project(VERSION) or artifacts ship with the
# wrong version baked in; failing here blocks the release+appcast jobs
- name: Check tag matches project version
if: startsWith(github.ref, 'refs/tags/v')
run: |
TAG="${GITHUB_REF_NAME#v}"
VER=$(sed -n 's/^ *VERSION \([0-9.]*\)$/\1/p' CMakeLists.txt | head -1)
if [ "$TAG" != "$VER" ]; then
echo "::error::Tag v${TAG} != project VERSION ${VER} in CMakeLists.txt"
exit 1
fi
- name: Install non-Qt dependencies
run: |
sudo apt-get update
sudo apt-get install -y libxkbcommon-dev liblo-dev libasound2-dev build-essential cmake rpm file
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: "6.11.0"
host: "linux"
target: "desktop"
arch: "linux_gcc_64"
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: ${{ runner.os }}-${{ hashFiles('**/CMakeLists.txt') }}
- name: Configure
run: cmake -B build -DCMAKE_BUILD_TYPE=Release
- name: Build
# cap parallelism: full -j OOM-kills cc1plus (heavy Qt PCH) on the runner
run: cmake --build build --config Release --parallel 2
- name: Test
run: ctest --test-dir build --output-on-failure
env:
QT_QPA_PLATFORM: offscreen
- name: Package (deb/rpm/tarball)
run: cd build && cpack
- name: Upload installers
uses: actions/upload-artifact@v7
with:
name: OpenMix-linux
path: |
build/*.deb
build/*.rpm
build/*.tar.gz
build-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v7
- name: Cache Qt
id: cache-qt
uses: actions/cache@v6
with:
path: C:\Qt\6.11.0\msvc2022_64
key: qt-6.11.0-msvc2022_64
- name: Download Qt
if: steps.cache-qt.outputs.cache-hit != 'true'
run: |
gh release download qt-deps --pattern "msvc2022_64.zip" --dir $env:TEMP
Expand-Archive -Path "$env:TEMP\msvc2022_64.zip" -DestinationPath C:\Qt\6.11.0
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install liblo via vcpkg
run: vcpkg install liblo:x64-windows
- name: Install NSIS
run: choco install nsis -y
- name: Set up MSVC
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: ${{ runner.os }}-${{ hashFiles('**/CMakeLists.txt') }}
- name: Configure
run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" -DCMAKE_PREFIX_PATH="C:\Qt\6.11.0\msvc2022_64"
- name: Build
run: cmake --build build --parallel
- name: Test
run: |
$env:PATH = "C:\Qt\6.11.0\msvc2022_64\bin;$env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\bin;$env:PATH"
ctest --test-dir build --output-on-failure
env:
QT_QPA_PLATFORM: offscreen
- name: Package (NSIS installer)
run: |
$env:PATH = "C:\Qt\6.11.0\msvc2022_64\bin;C:\Program Files (x86)\NSIS;$env:PATH"
cd build
cpack -G "NSIS;ZIP"
- name: Upload installer
uses: actions/upload-artifact@v7
with:
name: OpenMix-windows
path: |
build/OpenMix-*-win64.exe
build/OpenMix-*-win64.zip
build-macos:
runs-on: macos-15
steps:
- uses: actions/checkout@v7
- name: Remove untrusted brew taps
run: brew untap aws/tap 2>/dev/null || true
# official Qt macOS binaries are universal (arm64 + x86_64); brew's are
# arm64-only, which would make the DMG Apple-silicon-only
- name: Install Qt (universal)
uses: jurplel/install-qt-action@v4
with:
version: "6.11.0"
host: "mac"
target: "desktop"
arch: "clang_64"
# brew liblo is arm64-only too; build it universal from source
- name: Build liblo (universal)
run: |
curl -fsSL -o liblo.tar.gz https://downloads.sourceforge.net/liblo/liblo-0.31.tar.gz
tar xf liblo.tar.gz
cd liblo-0.31
./configure --prefix="$HOME/liblo-universal" \
--disable-tests --disable-examples --disable-tools \
CFLAGS="-arch arm64 -arch x86_64 -mmacosx-version-min=12.0"
make -j3 && make install
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2.23
with:
key: ${{ runner.os }}-universal-${{ hashFiles('**/CMakeLists.txt') }}
- name: Configure
run: |
export PKG_CONFIG_PATH="$HOME/liblo-universal/lib/pkgconfig:$PKG_CONFIG_PATH"
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
-DCMAKE_OSX_DEPLOYMENT_TARGET=12.0
- name: Build
run: cmake --build build --config Release --parallel 2
- name: Test
run: ctest --test-dir build --output-on-failure
env:
QT_QPA_PLATFORM: offscreen
- name: Verify universal binary
run: |
lipo -info build/OpenMix.app/Contents/MacOS/OpenMix
lipo -info build/OpenMix.app/Contents/MacOS/OpenMix | grep -q x86_64
lipo -info build/OpenMix.app/Contents/MacOS/OpenMix | grep -q arm64
# the app only uses SQLite; the Mimer driver's missing client library
# makes macdeployqt spew ERRORs, and ODBC/psql draw private-API warnings.
# Prune after configure/build: CMake's imported plugin targets error out
# if the dylibs disappear before configure
- name: Prune unused Qt SQL drivers
run: |
rm -f "$QT_ROOT_DIR/plugins/sqldrivers/"libqsqlmimer*.dylib \
"$QT_ROOT_DIR/plugins/sqldrivers/"libqsqlodbc*.dylib \
"$QT_ROOT_DIR/plugins/sqldrivers/"libqsqlpsql*.dylib
- name: Package (DMG)
run: cd build && cpack -G DragNDrop
- name: Upload installer
uses: actions/upload-artifact@v7
with:
name: OpenMix-macos
path: build/*.dmg
release:
if: startsWith(github.ref, 'refs/tags/v')
needs: [build-linux, build-windows, build-macos]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download artifacts
uses: actions/download-artifact@v8
- name: Create Release
uses: softprops/action-gh-release@v3
with:
files: |
OpenMix-linux/*
OpenMix-windows/*
OpenMix-macos/*
appcast:
if: startsWith(github.ref, 'refs/tags/v')
needs: [release]
runs-on: macos-15
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- name: Remove untrusted brew taps
run: brew untap aws/tap 2>/dev/null || true
# fetched from the pinned upstream release (same version CMake bundles);
# the homebrew sparkle cask is deprecated and disabled after 2026-09-01
- name: Install Sparkle tools
run: |
curl -fsSL -o /tmp/sparkle.tar.xz \
https://github.com/sparkle-project/Sparkle/releases/download/2.6.4/Sparkle-2.6.4.tar.xz
mkdir -p /tmp/sparkle
tar -xf /tmp/sparkle.tar.xz -C /tmp/sparkle
- name: Download artifacts
uses: actions/download-artifact@v8
- name: Build appcasts + installer tree
env:
SPARKLE_KEY: ${{ secrets.OPENMIX_SPARKLE_ED_PRIVATE_KEY }}
TAG: ${{ github.ref_name }}
run: |
VERSION="${TAG#v}"
BASE="https://openmix.dev/download/${TAG}"
mkdir -p site/download/${TAG}
cp OpenMix-macos/* OpenMix-windows/* OpenMix-linux/* site/download/${TAG}/ 2>/dev/null || true
SIGN=/tmp/sparkle/bin/sign_update
[ -x "$SIGN" ] || SIGN=""
DMG=$(ls OpenMix-macos/*.dmg | head -1)
if [ -n "$SPARKLE_KEY" ] && [ -n "$SIGN" ] && [ -n "$DMG" ]; then
echo "$SPARKLE_KEY" > /tmp/ed_key
SIG=$("$SIGN" -f /tmp/ed_key "$DMG") # prints sparkle:edSignature=... length=...
cat > site/appcast-macos.xml <<EOF
<?xml version="1.0"?>
<rss xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" version="2.0">
<channel>
<item>
<title>OpenMix ${VERSION}</title>
<sparkle:version>${VERSION}</sparkle:version>
<sparkle:shortVersionString>${VERSION}</sparkle:shortVersionString>
<enclosure url="${BASE}/$(basename "$DMG")" ${SIG} sparkle:version="${VERSION}" type="application/octet-stream"/>
</item>
</channel>
</rss>
EOF
else
echo "::warning::No Sparkle key/tool/DMG; skipping macOS appcast (updates will not verify)"
fi
# 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
<?xml version="1.0"?>
<rss xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" version="2.0">
<channel>
<item>
<title>OpenMix ${VERSION}</title>
<sparkle:version>${VERSION}</sparkle:version>
<enclosure url="${BASE}/$(basename "$EXE")" sparkle:version="${VERSION}" type="application/octet-stream"/>
</item>
</channel>
</rss>
EOF
fi
# 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
{
echo '<!doctype html><html lang="en"><head><meta charset="utf-8">'
echo '<meta name="viewport" content="width=device-width,initial-scale=1">'
echo "<title>Download OpenMix ${VERSION}</title>"
echo '<style>body{font-family:system-ui,sans-serif;max-width:40rem;margin:3rem auto;padding:0 1rem;line-height:1.7}a{color:#2563eb}</style>'
echo "</head><body><h1>Download OpenMix ${VERSION}</h1><ul>"
for f in site/download/${TAG}/*; do
[ -f "$f" ] || continue
n=$(basename "$f")
echo "<li><a href=\"${TAG}/${n}\">${n}</a></li>"
done
echo '</ul></body></html>'
} > site/download/index.html
- name: Deploy to VPS
env:
SSH_KEY: ${{ secrets.OPENMIX_DEPLOY_SSH_KEY }}
SSH_HOST: ${{ secrets.OPENMIX_DEPLOY_HOST }}
SSH_USER: ${{ secrets.OPENMIX_DEPLOY_USER }}
DEPLOY_PATH: ${{ secrets.OPENMIX_DEPLOY_PATH }}
run: |
if [ -z "$SSH_KEY" ] || [ -z "$SSH_HOST" ]; then
echo "::error::Missing OPENMIX_DEPLOY_* secrets; cannot publish to VPS"
exit 1
fi
mkdir -p ~/.ssh
echo "$SSH_KEY" > ~/.ssh/deploy && chmod 600 ~/.ssh/deploy
ssh-keyscan -H "$SSH_HOST" >> ~/.ssh/known_hosts 2>/dev/null
# keep old release dirs (keep_files-style); appcasts + latest.json overwrite
rsync -avz -e "ssh -i ~/.ssh/deploy" site/ "${SSH_USER}@${SSH_HOST}:${DEPLOY_PATH}/"
# prune download/ to the newest 5 release dirs (version-sorted)
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 --"
- name: Rebuild openmix.dev
env:
GH_TOKEN: ${{ secrets.OPENMIX_SITE_DISPATCH_TOKEN }}
run: |
if [ -z "$GH_TOKEN" ]; then
echo "::warning::OPENMIX_SITE_DISPATCH_TOKEN not set; site not rebuilt (downloads page stays on previous release)"
exit 0
fi
# --ref is required: the Actions-scoped PAT cannot resolve the
# default branch on its own
gh workflow run deploy.yml -R OpenMix-dev/openmix.dev --ref master || \
echo "::warning::site rebuild dispatch failed"