From f64361fc11818b3d3a90054eec0110fb43c7620b Mon Sep 17 00:00:00 2001 From: Sami Ahmed Date: Sun, 15 Mar 2026 02:59:33 -0700 Subject: [PATCH] Add macOS CI build, RPM, and Nix packaging - GitHub Actions workflow builds DMGs for both Intel and Apple Silicon - Update .pro file: macOS 11+ target, Homebrew paths instead of MacPorts - Add RPM spec + build script for Fedora/RHEL/openSUSE - Add Nix derivation with autoPatchelfHook - Update Homebrew formula to support macOS (Intel + ARM64) Co-Authored-By: Claude Opus 4.6 --- .github/workflows/build-macos.yml | 136 +++++++++++++++++++++++++++++ packaging/homebrew/triangles.rb | 24 ++++- packaging/nix/default.nix | 90 +++++++++++++++++++ packaging/rpm/build-rpm.sh | 28 ++++++ packaging/rpm/triangles-qt.desktop | 11 +++ packaging/rpm/triangles.spec | 44 ++++++++++ triangles-qt.pro | 15 ++-- 7 files changed, 338 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/build-macos.yml create mode 100644 packaging/nix/default.nix create mode 100644 packaging/rpm/build-rpm.sh create mode 100644 packaging/rpm/triangles-qt.desktop create mode 100644 packaging/rpm/triangles.spec diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml new file mode 100644 index 0000000..20f1d01 --- /dev/null +++ b/.github/workflows/build-macos.yml @@ -0,0 +1,136 @@ +name: Build macOS + +on: + push: + tags: + - 'v*' + workflow_dispatch: + +jobs: + build-macos: + runs-on: macos-13 # Intel runner (x86_64) + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: | + brew install qt@5 openssl@3 boost berkeley-db@5 leveldb libevent miniupnpc + + - name: Build LevelDB + run: | + cd src/leveldb + make clean || true + CC=clang CXX=clang++ make OPT="-O2" libleveldb.a libmemenv.a + + - name: Run qmake + run: | + export PATH="/usr/local/opt/qt@5/bin:$PATH" + qmake triangles-qt.pro -spec macx-clang \ + "BOOST_INCLUDE_PATH=/usr/local/opt/boost/include" \ + "BOOST_LIB_PATH=/usr/local/opt/boost/lib" \ + "BDB_INCLUDE_PATH=/usr/local/opt/berkeley-db@5/include" \ + "BDB_LIB_PATH=/usr/local/opt/berkeley-db@5/lib" \ + "BDB_LIB_SUFFIX=" \ + "OPENSSL_INCLUDE_PATH=/usr/local/opt/openssl@3/include" \ + "OPENSSL_LIB_PATH=/usr/local/opt/openssl@3/lib" \ + "MINIUPNPC_INCLUDE_PATH=/usr/local/opt/miniupnpc/include" \ + "MINIUPNPC_LIB_PATH=/usr/local/opt/miniupnpc/lib" \ + "EVENT_INCLUDE_PATH=/usr/local/opt/libevent/include" \ + "EVENT_LIB_PATH=/usr/local/opt/libevent/lib" \ + "RELEASE=1" + + - name: Build + run: | + export PATH="/usr/local/opt/qt@5/bin:$PATH" + make -j$(sysctl -n hw.ncpu) + + - name: Create .app bundle + run: | + export PATH="/usr/local/opt/qt@5/bin:$PATH" + macdeployqt Triangles-Qt.app -verbose=1 + + - 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${{ github.ref_name }}-macos-x64.dmg" + + - name: Upload DMG + uses: actions/upload-artifact@v4 + with: + name: macos-dmg + path: "*.dmg" + + - name: Upload to Release + if: startsWith(github.ref, 'refs/tags/') + uses: softprops/action-gh-release@v2 + with: + files: "*.dmg" + + build-macos-arm: + runs-on: macos-14 # Apple Silicon runner (ARM64) + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: | + brew install qt@5 openssl@3 boost berkeley-db@5 leveldb libevent miniupnpc + + - name: Build LevelDB + run: | + cd src/leveldb + 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: 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${{ github.ref_name }}-macos-arm64.dmg" + + - name: Upload DMG + uses: actions/upload-artifact@v4 + with: + name: macos-arm64-dmg + path: "*.dmg" + + - name: Upload to Release + if: startsWith(github.ref, 'refs/tags/') + uses: softprops/action-gh-release@v2 + with: + files: "*.dmg" diff --git a/packaging/homebrew/triangles.rb b/packaging/homebrew/triangles.rb index ca17221..d194565 100644 --- a/packaging/homebrew/triangles.rb +++ b/packaging/homebrew/triangles.rb @@ -4,16 +4,30 @@ class Triangles < Formula license "MIT" version "5.1.4" + on_macos do + if Hardware::CPU.intel? + url "https://github.com/SamiAhmed7777/triangles_v5/releases/download/v5.1.4/Cryptographic-Triangles-v5.1.4-macos-x64.dmg" + sha256 "PLACEHOLDER_X64_HASH" + else + url "https://github.com/SamiAhmed7777/triangles_v5/releases/download/v5.1.4/Cryptographic-Triangles-v5.1.4-macos-arm64.dmg" + sha256 "PLACEHOLDER_ARM64_HASH" + end + end + on_linux do url "https://github.com/SamiAhmed7777/triangles_v5/releases/download/v5.1.4/trianglesd-linux" sha256 "6f5c19d34a2e1f6cdadee095d9e11b25d18b41a0d1602a163ffca7ec80b3da37" end depends_on "openssl@3" - depends_on :linux def install - bin.install "trianglesd-linux" => "trianglesd" + if OS.mac? + prefix.install "Triangles-Qt.app" + bin.write_exec_script prefix/"Triangles-Qt.app/Contents/MacOS/Triangles-Qt" + else + bin.install "trianglesd-linux" => "trianglesd" + end end service do @@ -23,6 +37,10 @@ class Triangles < Formula end test do - system "#{bin}/trianglesd", "-version" + if OS.mac? + assert_predicate prefix/"Triangles-Qt.app", :exist? + else + system "#{bin}/trianglesd", "-version" + end end end diff --git a/packaging/nix/default.nix b/packaging/nix/default.nix new file mode 100644 index 0000000..62ebaef --- /dev/null +++ b/packaging/nix/default.nix @@ -0,0 +1,90 @@ +{ lib +, stdenv +, fetchurl +, autoPatchelfHook +, qt5 +, openssl +, boost +, db +, leveldb +, libevent +, miniupnpc +, makeWrapper +, makeDesktopItem +}: + +let + version = "5.1.4"; + + desktopItem = makeDesktopItem { + name = "triangles-qt"; + desktopName = "Cryptographic Triangles"; + genericName = "TRI Wallet"; + comment = "Cryptographic Triangles cryptocurrency wallet"; + exec = "triangles-qt %u"; + icon = "triangles"; + categories = [ "Finance" "Network" "P2P" "Qt" ]; + mimeTypes = [ "x-scheme-handler/triangles" ]; + startupNotify = true; + }; +in +stdenv.mkDerivation { + pname = "triangles"; + inherit version; + + srcs = [ + (fetchurl { + url = "https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${version}/triangles-qt-linux"; + sha256 = "19eaadfdf18b899ce8434fe714e690e2db0546597e36037de37a29854fc23aeb"; + name = "triangles-qt-linux"; + }) + (fetchurl { + url = "https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${version}/trianglesd-linux"; + sha256 = "6f5c19d34a2e1f6cdadee095d9e11b25d18b41a0d1602a163ffca7ec80b3da37"; + name = "trianglesd-linux"; + }) + ]; + + sourceRoot = "."; + dontUnpack = true; + + nativeBuildInputs = [ + autoPatchelfHook + makeWrapper + qt5.wrapQtAppsHook + ]; + + buildInputs = [ + qt5.qtbase + openssl + boost + db + leveldb + libevent + miniupnpc + ]; + + installPhase = '' + runHook preInstall + + install -Dm755 ${builtins.elemAt srcs 0} $out/bin/triangles-qt + install -Dm755 ${builtins.elemAt srcs 1} $out/bin/trianglesd + install -Dm644 ${desktopItem}/share/applications/* $out/share/applications/ + + runHook postInstall + ''; + + meta = with lib; { + description = "Cryptographic Triangles (TRI) cryptocurrency wallet"; + longDescription = '' + Privacy-focused cryptocurrency featuring Proof-of-Stake consensus + with 33% annual staking rewards, Tor v3 onion routing, and built-in + encrypted peer-to-peer messaging. Originally launched in July 2014, + featuring the unique Hash9 algorithm (13-step hash cascade). + ''; + homepage = "https://cryptographic-triangles.org"; + license = licenses.mit; + platforms = [ "x86_64-linux" ]; + mainProgram = "triangles-qt"; + }; +} diff --git a/packaging/rpm/build-rpm.sh b/packaging/rpm/build-rpm.sh new file mode 100644 index 0000000..8d2c4b8 --- /dev/null +++ b/packaging/rpm/build-rpm.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# Build RPM package for Cryptographic Triangles +# Run on a Fedora/RHEL/openSUSE system with rpmbuild installed +# Install build tools: sudo dnf install rpm-build rpmdevtools +set -e + +VERSION="5.1.4" +RELEASE_URL="https://github.com/SamiAhmed7777/triangles_v5/releases/download/v${VERSION}" + +echo "Building RPM for Triangles v${VERSION}..." + +# Set up rpmbuild directory structure +rpmdev-setuptree + +# Download sources into SOURCES +echo "Downloading binaries..." +curl -L -o ~/rpmbuild/SOURCES/triangles-qt-linux "${RELEASE_URL}/triangles-qt-linux" +curl -L -o ~/rpmbuild/SOURCES/trianglesd-linux "${RELEASE_URL}/trianglesd-linux" +cp triangles-qt.desktop ~/rpmbuild/SOURCES/ + +# Copy spec file +cp triangles.spec ~/rpmbuild/SPECS/ + +# Build the RPM (binary only, no source compilation needed) +rpmbuild -bb ~/rpmbuild/SPECS/triangles.spec + +echo "RPM built in ~/rpmbuild/RPMS/x86_64/" +echo "Install with: sudo dnf install ~/rpmbuild/RPMS/x86_64/triangles-${VERSION}-1.*.x86_64.rpm" diff --git a/packaging/rpm/triangles-qt.desktop b/packaging/rpm/triangles-qt.desktop new file mode 100644 index 0000000..f167763 --- /dev/null +++ b/packaging/rpm/triangles-qt.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=Cryptographic Triangles +GenericName=TRI Wallet +Comment=Cryptographic Triangles cryptocurrency wallet +Exec=triangles-qt %u +Terminal=false +Type=Application +Icon=triangles +MimeType=x-scheme-handler/triangles; +Categories=Finance;Network;P2P;Qt; +StartupNotify=true diff --git a/packaging/rpm/triangles.spec b/packaging/rpm/triangles.spec new file mode 100644 index 0000000..7ae674c --- /dev/null +++ b/packaging/rpm/triangles.spec @@ -0,0 +1,44 @@ +Name: triangles +Version: 5.1.4 +Release: 1%{?dist} +Summary: Cryptographic Triangles (TRI) cryptocurrency wallet +License: MIT +URL: https://cryptographic-triangles.org +Source0: https://github.com/SamiAhmed7777/triangles_v5/releases/download/v%{version}/triangles-qt-linux +Source1: https://github.com/SamiAhmed7777/triangles_v5/releases/download/v%{version}/trianglesd-linux +Source2: triangles-qt.desktop + +BuildArch: x86_64 +ExclusiveArch: x86_64 + +Requires: qt5-qtbase +Requires: qt5-qtbase-gui +Requires: openssl-libs +Requires: boost-system +Requires: boost-filesystem +Requires: boost-program-options +Requires: boost-thread +Requires: boost-chrono +Requires: libevent +Requires: miniupnpc-libs +Requires: libdb-cxx +Recommends: tor + +%description +Privacy-focused cryptocurrency featuring Proof-of-Stake consensus +with 33% annual staking rewards, Tor v3 onion routing, and built-in +encrypted peer-to-peer messaging. Originally launched in July 2014, +featuring the unique Hash9 algorithm (13-step hash cascade). + +This package contains the Qt GUI wallet (triangles-qt) and the +headless daemon (trianglesd). + +%install +install -Dm755 %{SOURCE0} %{buildroot}%{_bindir}/triangles-qt +install -Dm755 %{SOURCE1} %{buildroot}%{_bindir}/trianglesd +install -Dm644 %{SOURCE2} %{buildroot}%{_datadir}/applications/triangles-qt.desktop + +%files +%{_bindir}/triangles-qt +%{_bindir}/trianglesd +%{_datadir}/applications/triangles-qt.desktop diff --git a/triangles-qt.pro b/triangles-qt.pro index ada3887..d804a3e 100644 --- a/triangles-qt.pro +++ b/triangles-qt.pro @@ -47,8 +47,9 @@ UI_DIR = build # use: qmake "RELEASE=1" contains(RELEASE, 1) { - # Mac: compile for maximum compatibility (10.5, 32-bit) - macx:QMAKE_CXXFLAGS += -mmacosx-version-min=10.5 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.5.sdk + # Mac: compile for compatibility (macOS 11+) + macx:QMAKE_CXXFLAGS += -mmacosx-version-min=11.0 + macx:QMAKE_LFLAGS += -mmacosx-version-min=11.0 !windows:!macx { # Linux: static link @@ -455,23 +456,23 @@ isEmpty(BOOST_THREAD_LIB_SUFFIX) { } isEmpty(BDB_LIB_PATH) { - macx:BDB_LIB_PATH = /opt/local/lib/db48 + macx:BDB_LIB_PATH = /opt/homebrew/opt/berkeley-db@5/lib } isEmpty(BDB_LIB_SUFFIX) { - macx:BDB_LIB_SUFFIX = -4.8 + macx:BDB_LIB_SUFFIX = } isEmpty(BDB_INCLUDE_PATH) { - macx:BDB_INCLUDE_PATH = /opt/local/include/db48 + macx:BDB_INCLUDE_PATH = /opt/homebrew/opt/berkeley-db@5/include } isEmpty(BOOST_LIB_PATH) { - macx:BOOST_LIB_PATH = /opt/local/lib + macx:BOOST_LIB_PATH = /opt/homebrew/opt/boost/lib } isEmpty(BOOST_INCLUDE_PATH) { - macx:BOOST_INCLUDE_PATH = /opt/local/include + macx:BOOST_INCLUDE_PATH = /opt/homebrew/opt/boost/include } windows:DEFINES += WIN32