name: macos build (gitea self-hosted) # Runs ONLY on the Gitea mac runner (GitHub ignores .gitea/workflows). # Dispatch-only: the mac runner has capacity 1 and also serves the Hash Bags # iOS lane, so macOS wowlet builds are an explicit button, not a push hook. # All build state lands under the runner's work dir, which lives on # /Volumes/DataSSD (never backed up: the fleet backup pulls an allowlist of # gitea data only). # # Signing/notarization uses the SAME seven secrets as the smirk-monorepo # desktop lane, set by ~/keys/suchsoftware/set-gitea-desktop-secrets.sh: # APPLE_CERTIFICATE (b64 Developer ID Application .p12), # APPLE_CERTIFICATE_PASSWORD, APPLE_SIGNING_IDENTITY, APPLE_TEAM_ID, # APPLE_API_ISSUER, APPLE_API_KEY, APPLE_API_KEY_P8_BASE64 (notarytool). # If APPLE_CERTIFICATE is unset the build ships unsigned instead of failing. on: [workflow_dispatch] jobs: build-macos: name: "macOS (brew, native)" runs-on: macos-latest env: APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} APPLE_API_KEY_P8_BASE64: ${{ secrets.APPLE_API_KEY_P8_BASE64 }} steps: - uses: actions/checkout@v4 with: submodules: recursive - name: install dependencies (brew) run: | export PATH="/opt/homebrew/bin:$PATH" brew install --quiet qt libsodium libzip qrencode unbound cmake boost hidapi openssl expat protobuf pkgconfig zxing-cpp - name: fetch wownerod to embed run: | set -e ARCH=$(uname -m) case "$ARCH" in arm64) WOWTAR=wownero-aarch64-apple-darwin11-v0.11.4.0.tar.bz2 ;; *) WOWTAR=wownero-x86_64-apple-darwin11-v0.11.4.0.tar.bz2 ;; esac mkdir -p /tmp/wownerod-embed curl -L -o /tmp/wownero.tar.bz2 \ "https://github.com/wownero/wownero-codeberg-mirror/releases/download/v0.11.4.0/$WOWTAR" tar xjf /tmp/wownero.tar.bz2 -C /tmp find /tmp -name wownerod -type f -exec cp {} /tmp/wownerod-embed/ \; chmod +x /tmp/wownerod-embed/wownerod ls -la /tmp/wownerod-embed - name: build run: | export PATH="/opt/homebrew/bin:$PATH" mkdir -p build && cd build cmake -DWITH_SCANNER=OFF -DWOWNEROD_DIR=/tmp/wownerod-embed .. cmake --build . -j "$(sysctl -n hw.ncpu)" - name: package app bundle run: | set -e cd build APP=$(find . -maxdepth 3 -name "*.app" -type d | head -1) [ -n "$APP" ] || { echo "no .app bundle produced"; ls -la bin/; exit 1; } mkdir -p dist cp -R "$APP" dist/Wowlet.app # bundle Qt frameworks/plugins so the app runs off-machine /opt/homebrew/opt/qt/bin/macdeployqt dist/Wowlet.app ls -la dist/ - name: sign and notarize (skipped when secrets absent) run: | set -e cd build if [ -z "$APPLE_CERTIFICATE" ]; then echo "APPLE_CERTIFICATE not set — shipping UNSIGNED build" exit 0 fi KC=/tmp/wowlet-ci.keychain-db KCPW=$(/usr/bin/uuidgen) echo "$KCPW" > /tmp/wowlet-ci-kcpw # for the cleanup step only security create-keychain -p "$KCPW" "$KC" security set-keychain-settings -lut 3600 "$KC" security unlock-keychain -p "$KCPW" "$KC" printf '%s' "$APPLE_CERTIFICATE" | base64 -d > /tmp/dev_id.p12 security import /tmp/dev_id.p12 -k "$KC" -P "$APPLE_CERTIFICATE_PASSWORD" \ -T /usr/bin/codesign security set-key-partition-list -S apple-tool:,apple: -s -k "$KCPW" "$KC" >/dev/null security list-keychains -d user -s "$KC" login.keychain-db # sign nested Mach-O executables first (embedded wownerod etc.), # then frameworks, then the bundle — all hardened-runtime + timestamp SIGN() { codesign --force --options runtime --timestamp --keychain "$KC" \ --sign "$APPLE_SIGNING_IDENTITY" "$@"; } find dist/Wowlet.app -type f -perm +111 ! -path "*/Frameworks/*" \ | while read -r f; do file "$f" | grep -q Mach-O && SIGN "$f" || true; done find dist/Wowlet.app/Contents/Frameworks -maxdepth 1 \( -name "*.framework" -o -name "*.dylib" \) 2>/dev/null \ | while read -r fw; do SIGN "$fw"; done SIGN dist/Wowlet.app codesign --verify --deep --strict dist/Wowlet.app printf '%s' "$APPLE_API_KEY_P8_BASE64" | base64 -d > /tmp/notary.p8 ditto -c -k --keepParent dist/Wowlet.app /tmp/wowlet-notarize.zip xcrun notarytool submit /tmp/wowlet-notarize.zip \ --key /tmp/notary.p8 --key-id "$APPLE_API_KEY" --issuer "$APPLE_API_ISSUER" \ --wait --timeout 30m xcrun stapler staple dist/Wowlet.app echo "signed + notarized + stapled" - name: zip artifact run: | set -e cd build/dist ditto -c -k --keepParent Wowlet.app ../wowlet-macos-$(uname -m).zip ls -la ../wowlet-macos-*.zip - name: cleanup signing material if: always() run: | if [ -f /tmp/wowlet-ci-kcpw ]; then security delete-keychain /tmp/wowlet-ci.keychain-db || true fi rm -f /tmp/dev_id.p12 /tmp/notary.p8 /tmp/wowlet-ci-kcpw /tmp/wowlet-notarize.zip - name: upload artifact uses: actions/upload-artifact@v3 with: name: wowlet-macos path: build/wowlet-macos-*.zip retention-days: 14