name: Build All Platforms on: push: branches: [master] tags: ['v*'] pull_request: branches: [master] workflow_dispatch: jobs: test-linux-unit: runs-on: ubuntu-22.04 continue-on-error: true steps: - uses: actions/checkout@v4 - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y build-essential libboost-all-dev \ libssl-dev libdb++-dev libleveldb-dev libevent-dev libminiupnpc-dev - name: Build LevelDB run: | cd src/leveldb chmod +x build_detect_platform make clean || true make OPT="-O2" libleveldb.a libmemenv.a - name: Build and run unit tests run: | cd src make -f makefile.unix test -j$(nproc) ./test_triangles --log_level=test_suite 2>&1 || true build-windows-qt: runs-on: windows-latest defaults: run: shell: msys2 {0} steps: - uses: actions/checkout@v4 - uses: msys2/setup-msys2@v2 with: msystem: MINGW64 update: true install: >- mingw-w64-x86_64-gcc mingw-w64-x86_64-qt5-base mingw-w64-x86_64-qt5-tools mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-db mingw-w64-x86_64-libevent mingw-w64-x86_64-miniupnpc make - name: Create Qt5 tool symlinks run: | ln -sf /mingw64/bin/qmake-qt5.exe /mingw64/bin/qmake.exe 2>/dev/null || true ln -sf /mingw64/bin/lrelease-qt5.exe /mingw64/bin/lrelease.exe 2>/dev/null || true ln -sf /mingw64/bin/windeployqt-qt5.exe /mingw64/bin/windeployqt.exe 2>/dev/null || true - name: Set VERSION from source run: | MAJOR=$(grep 'CLIENT_VERSION_MAJOR' src/clientversion.h | awk '{print $3}') MINOR=$(grep 'CLIENT_VERSION_MINOR' src/clientversion.h | awk '{print $3}') REV=$(grep 'CLIENT_VERSION_REVISION' src/clientversion.h | awk '{print $3}') echo "VERSION=${MAJOR}.${MINOR}.${REV}" >> $GITHUB_ENV - name: Clean stale build artifacts run: rm -rf build/*.o build/*.h - name: Build LevelDB run: | cd src/leveldb make clean || true CC=gcc CXX=g++ TARGET_OS=OS_WINDOWS_CROSSCOMPILE make OPT="-fno-keep-inline-dllexport -march=nocona -msahf -mtune=generic -Wa,-mbig-obj -O2" libleveldb.a libmemenv.a - name: Run qmake run: qmake triangles-qt.pro "RELEASE=1" - name: Build run: make -j$(nproc) - name: Package run: | mkdir -p dist cp release/triangles-qt.exe dist/ windeployqt dist/triangles-qt.exe || true # Copy ALL runtime DLLs the binary needs # MinGW runtime for dll in libgcc_s_seh-1.dll libstdc++-6.dll libwinpthread-1.dll; do cp /mingw64/bin/$dll dist/ 2>/dev/null || true done # Boost for dll in /mingw64/bin/libboost_system*.dll /mingw64/bin/libboost_filesystem*.dll \ /mingw64/bin/libboost_thread*.dll /mingw64/bin/libboost_program_options*.dll \ /mingw64/bin/libboost_chrono*.dll; do cp $dll dist/ 2>/dev/null || true done # OpenSSL for dll in /mingw64/bin/libssl*.dll /mingw64/bin/libcrypto*.dll; do cp $dll dist/ 2>/dev/null || true done # BerkeleyDB, libevent, miniupnpc, zlib for dll in /mingw64/bin/libdb*.dll /mingw64/bin/libevent*.dll \ /mingw64/bin/libminiupnpc*.dll /mingw64/bin/zlib1.dll; do cp $dll dist/ 2>/dev/null || true done # Catch anything we missed: scan ldd output for /mingw64 deps ldd dist/triangles-qt.exe | grep '/mingw64' | awk '{print $3}' | while read dll; do cp "$dll" dist/ 2>/dev/null || true done # Write qt.conf so the exe finds plugins relative to itself printf '[Paths]\nPlugins = .\n' > dist/qt.conf # Ensure Qt platform plugins are present (windeployqt sometimes misses them in MSYS2) if [ ! -f dist/platforms/qwindows.dll ]; then echo "WARNING: windeployqt did not copy platform plugins, copying manually..." mkdir -p dist/platforms cp /mingw64/share/qt5/plugins/platforms/qwindows.dll dist/platforms/ 2>/dev/null || \ cp /mingw64/lib/qt5/plugins/platforms/qwindows.dll dist/platforms/ 2>/dev/null || \ find /mingw64 -name 'qwindows.dll' -exec cp {} dist/platforms/ \; 2>/dev/null fi # Also copy styles and imageformats for good measure for plugdir in styles imageformats; do if [ ! -d "dist/$plugdir" ]; then srcdir=$(find /mingw64 -type d -name "$plugdir" -path "*/plugins/*" 2>/dev/null | head -1) if [ -n "$srcdir" ]; then cp -r "$srcdir" dist/ fi fi done strip --strip-all dist/triangles-qt.exe echo "=== dist/ contents ===" find dist/ -type f | head -50 - name: Download Tor shell: powershell run: | $TOR_VERSION = "15.0.8" $TOR_URL = "https://dist.torproject.org/torbrowser/${TOR_VERSION}/tor-expert-bundle-windows-x86_64-${TOR_VERSION}.tar.gz" Invoke-WebRequest -Uri $TOR_URL -OutFile tor-bundle.tar.gz New-Item -ItemType Directory -Path tor-extract -Force tar -xzf tor-bundle.tar.gz -C tor-extract New-Item -ItemType Directory -Path tor-files -Force Copy-Item tor-extract/tor/tor.exe tor-files/ Copy-Item tor-extract/tor/tor-gencert.exe tor-files/ -ErrorAction SilentlyContinue if (Test-Path tor-extract/tor/pluggable_transports) { Copy-Item -Recurse tor-extract/tor/pluggable_transports tor-files/ } if (Test-Path tor-extract/data) { Copy-Item -Recurse tor-extract/data tor-files/data } - name: Install NSIS via MSYS2 run: pacman -S --noconfirm mingw-w64-x86_64-nsis - name: Install NSIS inetc plugin run: | pacman -S --noconfirm unzip NSIS_DIR="/mingw64/share/nsis" cd /tmp curl -L -o Inetc.zip "https://nsis.sourceforge.io/mediawiki/images/c/c9/Inetc.zip" unzip -o Inetc.zip -d inetc_extract # MSYS2 mingw64 NSIS is 64-bit, needs amd64-unicode plugin in Plugins/unicode/ mkdir -p "$NSIS_DIR/Plugins/unicode" cp inetc_extract/Plugins/amd64-unicode/INetC.dll "$NSIS_DIR/Plugins/unicode/" echo "Installed 64-bit INetC.dll to $NSIS_DIR/Plugins/unicode/" - name: Build NSIS installer run: makensis //DVERSION=$VERSION contrib/nsis/setup.nsi - name: Upload installer uses: actions/upload-artifact@v4 with: name: windows-qt-setup path: contrib/nsis/Cryptographic-Triangles-*-setup.exe build-windows-daemon: runs-on: windows-latest defaults: run: shell: msys2 {0} steps: - uses: actions/checkout@v4 - uses: msys2/setup-msys2@v2 with: msystem: MINGW64 update: true install: >- mingw-w64-x86_64-gcc mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-db mingw-w64-x86_64-libevent mingw-w64-x86_64-miniupnpc make - name: Build LevelDB run: | cd src/leveldb make clean || true CC=gcc CXX=g++ TARGET_OS=OS_WINDOWS_CROSSCOMPILE make OPT="-fno-keep-inline-dllexport -march=nocona -msahf -mtune=generic -Wa,-mbig-obj -O2" libleveldb.a libmemenv.a - name: Build daemon run: | set -eo pipefail cd src mkdir -p obj make -f makefile.mingw DEPSDIR=/mingw64 all -j$(nproc) 2>&1 strip --strip-all trianglesd.exe - name: Package daemon with DLLs run: | mkdir -p daemon-dist/tor cp src/trianglesd.exe daemon-dist/ # Copy all linked DLLs from MSYS2 ldd src/trianglesd.exe | grep '/mingw64' | awk '{print $3}' | while read dll; do cp "$dll" daemon-dist/ 2>/dev/null || true done - name: Bundle Tor for daemon shell: powershell run: | $TOR_VERSION = "15.0.8" Invoke-WebRequest -Uri "https://dist.torproject.org/torbrowser/${TOR_VERSION}/tor-expert-bundle-windows-x86_64-${TOR_VERSION}.tar.gz" -OutFile tor-bundle.tar.gz New-Item -ItemType Directory -Path tor-extract -Force tar -xzf tor-bundle.tar.gz -C tor-extract Copy-Item tor-extract/tor/tor.exe daemon-dist/tor/ if (Test-Path tor-extract/data) { Copy-Item -Recurse tor-extract/data daemon-dist/tor/data } - name: Upload artifact uses: actions/upload-artifact@v4 with: name: windows-daemon path: daemon-dist/ build-linux-qt: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Set VERSION from source run: | MAJOR=$(grep 'CLIENT_VERSION_MAJOR' src/clientversion.h | awk '{print $3}') MINOR=$(grep 'CLIENT_VERSION_MINOR' src/clientversion.h | awk '{print $3}') REV=$(grep 'CLIENT_VERSION_REVISION' src/clientversion.h | awk '{print $3}') echo "VERSION=${MAJOR}.${MINOR}.${REV}" >> $GITHUB_ENV - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y build-essential qt5-qmake qtbase5-dev \ qttools5-dev-tools libboost-all-dev libssl-dev libdb++-dev \ libleveldb-dev libevent-dev libminiupnpc-dev - name: Build LevelDB run: | cd src/leveldb chmod +x build_detect_platform make clean || true make OPT="-O2" libleveldb.a libmemenv.a - name: Clean stale build artifacts run: rm -rf build/*.o - name: Run qmake run: qmake triangles-qt.pro "RELEASE=1" - name: Build run: make -j$(nproc) - name: Strip binary run: strip --strip-all triangles-qt - name: Build .deb package (fully self-contained) run: | TOR_VERSION="15.0.8" curl -sL "https://dist.torproject.org/torbrowser/${TOR_VERSION}/tor-expert-bundle-linux-x86_64-${TOR_VERSION}.tar.gz" -o tor-bundle.tar.gz mkdir -p tor-extract && tar -xzf tor-bundle.tar.gz -C tor-extract PKG="cryptographic-triangles_${VERSION}_amd64" mkdir -p ${PKG}/DEBIAN mkdir -p ${PKG}/usr/lib/cryptographic-triangles/lib mkdir -p ${PKG}/usr/lib/cryptographic-triangles/tor mkdir -p ${PKG}/usr/bin mkdir -p ${PKG}/usr/share/applications mkdir -p ${PKG}/usr/share/pixmaps cp triangles-qt ${PKG}/usr/lib/cryptographic-triangles/ cp tor-extract/tor/tor ${PKG}/usr/lib/cryptographic-triangles/tor/ chmod +x ${PKG}/usr/lib/cryptographic-triangles/tor/tor [ -d tor-extract/data ] && cp -r tor-extract/data ${PKG}/usr/lib/cryptographic-triangles/tor/data # Bundle ALL shared library dependencies (except glibc/kernel) ldd triangles-qt | grep '=> /' | awk '{print $3}' | while read lib; do case "$lib" in /lib/x86_64-linux-gnu/libc.so*|/lib/x86_64-linux-gnu/libm.so*|/lib/x86_64-linux-gnu/libpthread.so*|/lib/x86_64-linux-gnu/libdl.so*|/lib/x86_64-linux-gnu/librt.so*|/lib/x86_64-linux-gnu/ld-linux*|/lib64/ld-linux*) ;; # Skip glibc core — always present *) cp -L "$lib" ${PKG}/usr/lib/cryptographic-triangles/lib/ 2>/dev/null || true ;; esac done echo "=== Bundled libs ===" ls ${PKG}/usr/lib/cryptographic-triangles/lib/ | wc -l ls ${PKG}/usr/lib/cryptographic-triangles/lib/ # Launcher with LD_LIBRARY_PATH cat > ${PKG}/usr/bin/cryptographic-triangles << 'LAUNCHER' #!/bin/bash INSTALL_DIR=/usr/lib/cryptographic-triangles export LD_LIBRARY_PATH="${INSTALL_DIR}/lib:${LD_LIBRARY_PATH}" exec "${INSTALL_DIR}/triangles-qt" "$@" LAUNCHER sed -i 's/^ //' ${PKG}/usr/bin/cryptographic-triangles chmod +x ${PKG}/usr/bin/cryptographic-triangles cat > ${PKG}/usr/share/applications/cryptographic-triangles.desktop << 'DESKTOP' [Desktop Entry] Name=Cryptographic Triangles Comment=Triangles Cryptocurrency Wallet Exec=cryptographic-triangles Terminal=false Type=Application Icon=cryptographic-triangles Categories=Finance;Network; DESKTOP sed -i 's/^ //' ${PKG}/usr/share/applications/cryptographic-triangles.desktop cp src/qt/res/icons/triangles.ico ${PKG}/usr/share/pixmaps/cryptographic-triangles.ico 2>/dev/null || true cat > ${PKG}/DEBIAN/control << CTRL Package: cryptographic-triangles Version: ${VERSION} Architecture: amd64 Maintainer: Cryptographic Triangles Description: Cryptographic Triangles wallet with integrated Tor Fully self-contained wallet with all libraries and Tor bundled. No external dependencies required — runs on any x86_64 Linux. Section: finance Priority: optional CTRL sed -i 's/^ //' ${PKG}/DEBIAN/control dpkg-deb --build ${PKG} - name: Upload .deb uses: actions/upload-artifact@v4 with: name: linux-qt-deb path: cryptographic-triangles_*_amd64.deb build-linux-daemon: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Set VERSION from source run: | MAJOR=$(grep 'CLIENT_VERSION_MAJOR' src/clientversion.h | awk '{print $3}') MINOR=$(grep 'CLIENT_VERSION_MINOR' src/clientversion.h | awk '{print $3}') REV=$(grep 'CLIENT_VERSION_REVISION' src/clientversion.h | awk '{print $3}') echo "VERSION=${MAJOR}.${MINOR}.${REV}" >> $GITHUB_ENV - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y build-essential libboost-all-dev \ libssl-dev libdb++-dev libleveldb-dev libevent-dev libminiupnpc-dev - name: Build LevelDB run: | cd src/leveldb chmod +x build_detect_platform make clean || true make OPT="-O2" libleveldb.a libmemenv.a - name: Build daemon run: | cd src mkdir -p obj make -f makefile.unix trianglesd -j$(nproc) - name: Strip binary run: strip --strip-all src/trianglesd - name: Build .deb package (fully self-contained) run: | TOR_VERSION="15.0.8" curl -sL "https://dist.torproject.org/torbrowser/${TOR_VERSION}/tor-expert-bundle-linux-x86_64-${TOR_VERSION}.tar.gz" -o tor-bundle.tar.gz mkdir -p tor-extract && tar -xzf tor-bundle.tar.gz -C tor-extract PKG="cryptographic-triangles-daemon_${VERSION}_amd64" mkdir -p ${PKG}/DEBIAN mkdir -p ${PKG}/usr/lib/cryptographic-triangles/lib mkdir -p ${PKG}/usr/lib/cryptographic-triangles/tor mkdir -p ${PKG}/usr/bin mkdir -p ${PKG}/etc/systemd/system cp src/trianglesd ${PKG}/usr/lib/cryptographic-triangles/ cp tor-extract/tor/tor ${PKG}/usr/lib/cryptographic-triangles/tor/ chmod +x ${PKG}/usr/lib/cryptographic-triangles/tor/tor [ -d tor-extract/data ] && cp -r tor-extract/data ${PKG}/usr/lib/cryptographic-triangles/tor/data # Bundle ALL shared library dependencies (except glibc/kernel) ldd src/trianglesd | grep '=> /' | awk '{print $3}' | while read lib; do case "$lib" in /lib/x86_64-linux-gnu/libc.so*|/lib/x86_64-linux-gnu/libm.so*|/lib/x86_64-linux-gnu/libpthread.so*|/lib/x86_64-linux-gnu/libdl.so*|/lib/x86_64-linux-gnu/librt.so*|/lib/x86_64-linux-gnu/ld-linux*|/lib64/ld-linux*) ;; # Skip glibc core — always present *) cp -L "$lib" ${PKG}/usr/lib/cryptographic-triangles/lib/ 2>/dev/null || true ;; esac done echo "=== Bundled libs ===" ls ${PKG}/usr/lib/cryptographic-triangles/lib/ | wc -l ls ${PKG}/usr/lib/cryptographic-triangles/lib/ # Launcher with LD_LIBRARY_PATH cat > ${PKG}/usr/bin/trianglesd << 'LAUNCHER' #!/bin/bash INSTALL_DIR=/usr/lib/cryptographic-triangles export LD_LIBRARY_PATH="${INSTALL_DIR}/lib:${LD_LIBRARY_PATH}" exec "${INSTALL_DIR}/trianglesd" "$@" LAUNCHER sed -i 's/^ //' ${PKG}/usr/bin/trianglesd chmod +x ${PKG}/usr/bin/trianglesd cat > ${PKG}/etc/systemd/system/trianglesd.service << 'SVC' [Unit] Description=Cryptographic Triangles Daemon After=network-online.target Wants=network-online.target [Service] Type=simple Environment=LD_LIBRARY_PATH=/usr/lib/cryptographic-triangles/lib ExecStart=/usr/lib/cryptographic-triangles/trianglesd Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target SVC sed -i 's/^ //' ${PKG}/etc/systemd/system/trianglesd.service cat > ${PKG}/DEBIAN/control << CTRL Package: cryptographic-triangles-daemon Version: ${VERSION} Architecture: amd64 Maintainer: Cryptographic Triangles Description: Cryptographic Triangles daemon with integrated Tor Fully self-contained headless node with all libraries, Tor, and systemd service. No external dependencies required — runs on any x86_64 Linux. Section: finance Priority: optional CTRL sed -i 's/^ //' ${PKG}/DEBIAN/control cat > ${PKG}/DEBIAN/postinst << 'POST' #!/bin/bash systemctl daemon-reload echo "" echo "Cryptographic Triangles daemon installed." echo " Start: sudo systemctl start trianglesd" echo " On boot: sudo systemctl enable trianglesd" echo "" POST chmod +x ${PKG}/DEBIAN/postinst dpkg-deb --build ${PKG} - name: Upload .deb uses: actions/upload-artifact@v4 with: name: linux-daemon-deb path: cryptographic-triangles-daemon_*_amd64.deb build-macos: runs-on: macos-15 steps: - uses: actions/checkout@v4 - name: Set VERSION from source run: | MAJOR=$(grep 'CLIENT_VERSION_MAJOR' src/clientversion.h | awk '{print $3}') MINOR=$(grep 'CLIENT_VERSION_MINOR' src/clientversion.h | awk '{print $3}') REV=$(grep 'CLIENT_VERSION_REVISION' src/clientversion.h | awk '{print $3}') echo "VERSION=${MAJOR}.${MINOR}.${REV}" >> $GITHUB_ENV - name: Install dependencies run: | brew install qt@5 openssl@3 boost berkeley-db@5 leveldb libevent miniupnpc - name: Clean stale build artifacts run: rm -rf build/*.o build/*.h - name: Build LevelDB run: | cd src/leveldb chmod +x build_detect_platform make clean || true CC=clang CXX=clang++ make OPT="-O2" libleveldb.a libmemenv.a - name: Run qmake run: | export PATH="/opt/homebrew/opt/qt@5/bin:$PATH" qmake triangles-qt.pro -spec macx-clang \ "BOOST_INCLUDE_PATH=/opt/homebrew/opt/boost/include" \ "BOOST_LIB_PATH=/opt/homebrew/opt/boost/lib" \ "BDB_INCLUDE_PATH=/opt/homebrew/opt/berkeley-db@5/include" \ "BDB_LIB_PATH=/opt/homebrew/opt/berkeley-db@5/lib" \ "BDB_LIB_SUFFIX=" \ "OPENSSL_INCLUDE_PATH=/opt/homebrew/opt/openssl@3/include" \ "OPENSSL_LIB_PATH=/opt/homebrew/opt/openssl@3/lib" \ "MINIUPNPC_INCLUDE_PATH=/opt/homebrew/opt/miniupnpc/include" \ "MINIUPNPC_LIB_PATH=/opt/homebrew/opt/miniupnpc/lib" \ "EVENT_INCLUDE_PATH=/opt/homebrew/opt/libevent/include" \ "EVENT_LIB_PATH=/opt/homebrew/opt/libevent/lib" \ "RELEASE=1" - name: Build run: | export PATH="/opt/homebrew/opt/qt@5/bin:$PATH" make -j$(sysctl -n hw.ncpu) - name: Create .app bundle run: | export PATH="/opt/homebrew/opt/qt@5/bin:$PATH" macdeployqt Triangles-Qt.app -verbose=1 - name: Bundle non-Qt dylibs into app run: | FRAMEWORKS="Triangles-Qt.app/Contents/Frameworks" MACOS="Triangles-Qt.app/Contents/MacOS" BINARY="$MACOS/Triangles-Qt" # Copy Homebrew dylibs that macdeployqt doesn't handle for lib in boost_system boost_filesystem boost_thread boost_program_options boost_chrono; do DYLIB=$(otool -L "$BINARY" | grep "$lib" | awk '{print $1}') if [ -n "$DYLIB" ] && [ -f "$DYLIB" ]; then cp "$DYLIB" "$FRAMEWORKS/" BASENAME=$(basename "$DYLIB") install_name_tool -change "$DYLIB" "@executable_path/../Frameworks/$BASENAME" "$BINARY" fi done for lib in libssl libcrypto libevent libdb_cxx libminiupnpc libsodium; do DYLIB=$(otool -L "$BINARY" | grep "$lib" | awk '{print $1}') if [ -n "$DYLIB" ] && [ -f "$DYLIB" ]; then cp "$DYLIB" "$FRAMEWORKS/" BASENAME=$(basename "$DYLIB") install_name_tool -change "$DYLIB" "@executable_path/../Frameworks/$BASENAME" "$BINARY" fi done echo "=== Final dylib dependencies ===" otool -L "$BINARY" | head -30 - name: Bundle Tor into app run: | TOR_VERSION="15.0.8" curl -sL "https://dist.torproject.org/torbrowser/${TOR_VERSION}/tor-expert-bundle-macos-aarch64-${TOR_VERSION}.tar.gz" -o tor-bundle.tar.gz mkdir -p tor-extract && tar -xzf tor-bundle.tar.gz -C tor-extract mkdir -p Triangles-Qt.app/Contents/MacOS/tor cp tor-extract/tor/tor Triangles-Qt.app/Contents/MacOS/tor/ chmod +x Triangles-Qt.app/Contents/MacOS/tor/tor [ -d tor-extract/data ] && cp -r tor-extract/data Triangles-Qt.app/Contents/MacOS/tor/data - name: Create DMG run: | mkdir -p dmg_contents cp -R Triangles-Qt.app dmg_contents/ ln -s /Applications dmg_contents/Applications hdiutil create -volname "Cryptographic Triangles" \ -srcfolder dmg_contents \ -ov -format UDZO \ "Cryptographic-Triangles-v${VERSION}-macos-arm64.dmg" - name: Upload DMG uses: actions/upload-artifact@v4 with: name: macos-arm64-dmg path: "*.dmg" release: if: startsWith(github.ref, 'refs/tags/v') needs: [build-windows-qt, build-windows-daemon, build-linux-qt, build-linux-daemon, build-macos] runs-on: ubuntu-latest permissions: contents: write steps: - name: Set VERSION from tag run: echo "VERSION=${GITHUB_REF_NAME#v}" >> $GITHUB_ENV - name: Download all artifacts uses: actions/download-artifact@v4 with: path: artifacts - name: Prepare release assets run: | mkdir -p release # Windows Qt installer (setup.exe — includes Tor, Start Menu shortcuts, uninstaller) cp artifacts/windows-qt-setup/*.exe release/ # Windows daemon (zip with DLLs + Tor) cd artifacts/windows-daemon && zip -r "../../release/Cryptographic-Triangles-${VERSION}-win-x64-daemon.zip" . && cd ../.. # Linux Qt .deb (dpkg -i to install — includes Tor, desktop entry, icon) cp artifacts/linux-qt-deb/*.deb release/ # Linux daemon .deb (dpkg -i to install — includes Tor, systemd service) cp artifacts/linux-daemon-deb/*.deb release/ # macOS DMG (drag to Applications — Tor inside .app bundle) cp artifacts/macos-arm64-dmg/*.dmg release/ ls -la release/ - name: Create Release uses: softprops/action-gh-release@v2 with: files: release/* generate_release_notes: true trigger-tripi: name: Trigger TRI-PI ARM64 Build if: startsWith(github.ref, 'refs/tags/v') needs: release runs-on: ubuntu-latest steps: - name: Dispatch tri-pi ARM64 build run: | curl -f -X POST \ -H "Accept: application/vnd.github.v3+json" \ -H "Authorization: token ${{ secrets.TRIPI_BUILD_TOKEN }}" \ https://api.github.com/repos/SamiAhmed7777/tri-pi/actions/workflows/build-arm64.yml/dispatches \ -d '{"ref":"main","inputs":{"version":"${{ github.ref_name }}"}}' echo "Triggered tri-pi build for ${{ github.ref_name }}"