ci(desktop): build macOS, and publish every desktop artifact to the release page

Three desktop targets, three different states, one destination.

macOS did not build at all. There was no workflow, only Cake's from-source
scripts and an Xcode project. It turns out most of the work was already done:
monero_c ships aarch64-apple-darwin and x86_64-apple-darwin, and
Runner.xcodeproj already references both dylibs with CodeSignOnCopy. So this
fetches the same prebuilt bundle the iOS and Android legs use, lipos the two
slices into universal libraries, and builds. One download serves Apple Silicon
and Intel, because a single-arch build looks correct on the machine that made
it and fails on half of everyone else's.

It signs with a Developer ID Application certificate, which is NOT the Apple
Distribution certificate the TestFlight workflow uses. They are not
interchangeable: an App Store cert on a directly downloaded app is refused by
Gatekeeper. Signing is inside-out by hand rather than --deep, which Apple
deprecated and which skips nested code it does not recognise. Then notarytool
with the App Store Connect key this repository already has, then stapler, so
Gatekeeper clears the app without a network round trip.

Every credential is optional and the preflight says, before spending forty
minutes, exactly which stages the run can reach and what the user will see if
it cannot reach them. Absent secrets downgrade the build loudly; they do not
fail it and they do not pass silently.

Windows and Linux already built. Windows already Authenticode-signs through the
Fleet broker. What both lacked was a way to get the artifact to anybody:
upload-artifact is the only publication and Gitea Actions artifacts here upload
and then list as zero, so the signed Windows zip has never been reachable. Both
now publish to the GitHub release, on the smirk pattern: tag-triggered, the
release must already exist so a half-populated one never goes public, and a
same-named asset from an earlier attempt is replaced rather than duplicated.
Windows does its API work in PowerShell because git-bash there has neither
python nor node guaranteed and ConvertFrom-Json is native.

Tags now build automatically on all three. A tag is the thing a release is cut
from, and the artifact that gets signed should come from it rather than from
whatever was dispatched by hand.

scripts/release/sign-release.sh detach-signs the collected artifacts and signs
SHA256SUMS, which is the signature that matters when a download reaches someone
from a mirror without its .asc. It verifies even immediately after signing: a
signature written but never checked invites trust it has not earned.

Not done here, and both need a human: GH_RELEASE_TOKEN does not exist in this
repository's Gitea secrets, and the release key's user ID still says Smirk.
This commit is contained in:
jwinterm
2026-09-23 08:13:10 -04:00
parent c11c79b0c5
commit c1f618176c
5 changed files with 610 additions and 7 deletions
+11 -1
View File
@@ -1,4 +1,14 @@
lib*_wallet2_api_c.so
# embedded Wownero node daemon (provisioned at build time, like the wallet libs)
# Embedded Wownero node daemon. NOT provisioned by any build step: no script
# here and no CI job stages it, so a CI-built APK does not contain it. It is
# built by hand and kept out of the tree entirely, at
# ~/Build/hash-wallet/embedded-node/<abi>/libwownerod.so.
#
# Binaries do not belong in src even when ignored. Everything else in this
# directory is staging output that build_monero_all.sh or the Android workflow
# regenerates; this one had no generator, which is why it sat here for weeks.
# When the UI toggle and foreground service land, it needs a provisioning step
# beside the monero_c one, and shipping it before then would put 20 MB of
# unreachable executable in front of a store reviewer for no reason.
libwownerod.so