Commit Graph
7 Commits
Author SHA1 Message Date
jwinterm f4bbfd49ad fix(ci): publish the signed Windows zips to the tag's release
The Linux and macOS jobs already attach their tag-build output to the release,
because this Gitea reports zero artifacts for every run through its REST API and
its web download route answers "Not found." under every auth style. The Windows
job was left out, so even a green signed build produced an exe nobody could
fetch back.

The step runs after the Authenticode, RFC 3161 timestamp and signer checks, so
an unsigned or untimestamped binary can never reach a release. Both archives go
up: the signed one users should download, and the unsigned one that stays
byte-reproducible for verifiers.

curl.exe rather than Invoke-WebRequest, because `shell: powershell` is Windows
PowerShell 5.1 and its Invoke-WebRequest has no -Form for multipart uploads.
Fail-safe like the others: no token, no resolvable release or a non-201 upload
reports itself and exits 0 rather than reddening a build that produced a
correctly signed binary.
2026-09-13 18:09:17 -04:00
jwinterm ce84b1d062 fix(ci): scope the embed extracts to the run, not to a shared /tmp
ubuntu-latest and windows-latest both resolve to the same host in host mode,
and both jobs began with `rm -rf /tmp/wownerod-embed`. Dispatched together for
5.1.4, the Windows fetch deleted the Linux job's binary in the eight seconds
between its own `ls` showing the file present and cmake configuring, so the
Linux build died on "WOWNEROD_DIR was specified but the wownerod binary could
not be found" while the identical workflow had passed minutes earlier when it
ran alone.

Both jobs now extract under /tmp/wowlet-$GITHUB_RUN_ID, so concurrent runs stop
sharing state. macOS is left alone: it runs on its own host, it never rm -rf's
the directory, and it is the one platform currently building green.
2026-09-13 13:13:35 -04:00
jwinterm ea9c73826b fix(build): ship the binary as wowlet, not feather
The CMake target keeps its upstream name so the twenty-odd target_* calls stay
put, but OUTPUT_NAME now produces build/bin/wowlet, and on macOS a wowlet.app
whose CFBundleExecutable matches it.

Linux and Windows already renamed the artifact as they copied it, so their cp
lines just move to the new path. macOS copied the whole bundle instead, so it
shipped Contents/MacOS/feather with a Feather name in the Info.plist, which is
what anyone installing it actually saw. The Linux install rules had the same
problem one level down: they installed feather.desktop, which sets Exec=feather
and Name=Feather Wallet, while the correct wowlet.desktop sat unused beside it.

CFBundleIdentifier moves to org.wownero.wowlet. Nothing in signing or
notarization reads it, but macOS keys per-app state by bundle id, so an existing
install starts with fresh window state.
2026-09-13 10:49:00 -04:00
jwinterm b200d997b0 fix(ci): write ZIP entry names with forward slashes
Compress-Archive on Windows PowerShell writes the OS path separator into entry
names, so the archives came out with "tor\tor.exe". The ZIP format mandates
forward slashes, and 5.1.0 shipped "tor/tor.exe" from `zip -X` on Linux -- this
was a regression introduced when the packaging moved to the signing host.

It is not cosmetic for this application. Extractors that take the backslash
literally produce a file named "tor\tor.exe" in the archive root rather than a
tor directory, which puts the bundled Tor somewhere wowlet does not look. The
daemon is given an exclusive --tx-proxy, so a wallet that cannot find its Tor
cannot relay a transaction at all.

Archives are now built through System.IO.Compression with entry names
normalised explicitly, and the job asserts the result: a backslash in any entry
name, or a missing tor/tor.exe, fails the build rather than shipping.

Caught by extracting the artifact and diffing it against the 5.1.0 release
before publishing.
2026-09-01 10:23:07 -04:00
jwinterm 11e8e3241c ci(gitea): move the Linux AppImage off GitHub, and ship both Windows archives
Linux: the x86_64 AppImage now builds on the Gitea runner. Unlike the Windows
lane, which builds a static toolchain of its own through contrib/depends, it
links against the host's Qt6 -- so those dependencies are owned by such-fleet
(roles/wowlet_build_host) and the job asserts them rather than apt-installing.
A workflow that installs needs sudo on a shared runner and makes the build
host's contents a property of whichever job ran last.

Windows: the lane now publishes two archives instead of one. Authenticode
mutates the exe, so a signed binary can never byte-match a build someone
reproduces from source. Shipping only the signed one quietly costs the project
its reproducibility story; shipping only the unsigned one costs every normal
user a SmartScreen warning. Both, with both hashes in the PGP-signed
hashes.txt, costs neither -- and keeps one canonical download page rather than
splitting the project across a fork.

The AppImage lane carries the packaging knowledge that a plain linuxdeploy run
does not: qmlimportscanner does not follow a module's own qmldir dependency
chain, so the QtQuick and QtQml trees are copied wholesale and each copied
plugin's Qt libraries resolved by hand, and a guard fails the build if
mining.qml ever imports QtQuick.Controls again rather than shipping a white
mining tab.
2026-08-31 18:23:46 -04:00
jwinterm f5e40ab5b2 ci(gitea): pin the artifact actions to v3
The first Gitea run built cleanly all the way through -- depends, wowlet.exe,
staging -- and then died on the last step:

  ::error::@actions/artifact v2.0.0+, upload-artifact@v4+ and
  download-artifact@v4+ are not currently supported on GHES.

Gitea Actions implements the older artifact protocol, so the v4 actions (which
use @actions/artifact v2) refuse to talk to it. Hash Bags' Windows lane already
uses v3 for the same reason.

Pinned with a comment so nobody upgrades it back and loses a 22 minute build to
the same error.
2026-08-31 18:15:46 -04:00
jwinterm 0ce230de3c ci(gitea): move the Windows build and signing off GitHub
Gitea is master and GitHub is a mirror, but the Windows and Linux jobs still
only existed in .github/workflows, so GitHub was doing real build work. This
moves Windows.

Two jobs on two machines, which is the point rather than an accident:

  build  runs on `deb` (windows-latest:host — it carries the MinGW
         cross-compiler) and produces an unsigned wowlet.exe.
  sign   runs on desktop-iim2fs2 (windows:host), the machine with the EV
         code-signing token physically in it.

The signing job does not itself sign. Its runner is NT SERVICE\act_runner,
which cannot use the token: SafeNet holds the login per user and the login is
established interactively by an operator. So the job queues the binary for the
Fleet-installed broker (roles/windows_code_signing) and waits. CI never holds
the key and never holds the token password, so it cannot spend one of the
token's three password attempts.

Differences from the GitHub lane, all because this is a real fleet host rather
than a disposable hosted runner:

- No apt install and no sudo. Every dependency is already present on deb, and a
  first step asserts the toolchain — including that mingw is the posix
  threading variant — and fails pointing at such-fleet rather than half
  building.
- No disk-freeing or fallocated swap. Those existed to survive a hosted
  runner's 16G/14G budget; deb has 30G and 3.1T free.
- depends builds at -j4 and wowlet at -j6 rather than -j2 for the same reason.

The exe is staged unzipped between the jobs because the broker signs one PE at
a time; the published zip is assembled after signing, so the archive contains
the signed binary. The signature, its RFC 3161 timestamp and the expected
signer are all re-verified on the artifact that actually ships.

Dispatch-only: both runners are capacity 1 and shared with other lanes.
2026-08-31 17:54:02 -04:00