Skip to content

feat: cross-platform support (Windows, macOS scaffolding)#1

Merged
Matbe34 merged 18 commits into
masterfrom
feature/windows-support
May 4, 2026
Merged

feat: cross-platform support (Windows, macOS scaffolding)#1
Matbe34 merged 18 commits into
masterfrom
feature/windows-support

Conversation

@Matbe34

@Matbe34 Matbe34 commented May 4, 2026

Copy link
Copy Markdown
Owner

Summary

Splits the Linux-only signature/PDF code into per-OS implementations via Go build tags, introduces two new packages (internal/signature/{certstore,platform}), wires Windows certificate-store signing through github/smimesign/certstore, and adds CI verification on windows-latest.

All Go code is now portable across Linux / Windows / macOS. Linux behavior is unchanged. macOS Keychain is stubbed (returns "not implemented"); Windows certificate store is functional via the new certstore abstraction.

Notable changes

  • Per-OS code split with *_linux.go / *_windows.go / *_darwin.go build tags across internal/signature/{certificates,signing,nss}, internal/signature/platform/, and internal/pdf/render_suppress_*.
  • New internal/signature/certstore package abstracts platform certificate stores behind a single `CertificateStore` interface (`ListCertificates`, `GetSigner` returning both signer and `*x509.Certificate`, `Close`). Linux backend wraps NSS; Windows backend wraps smimesign.
  • New `internal/signature/platform` package centralizes per-OS path constants (PKCS#11 module locations, allowed cert-store prefixes, system/user cert dirs). Windows variant filters empty env-var prefixes at init so unset `USERPROFILE` etc. don't make path validation permissive.
  • Cross-platform config dir via `os.UserConfigDir()`.
  • Stderr save/restore for MuPDF warning suppression — fixes a regression where the per-OS split lost the `dup`/`dup2` round-trip; suppress was permanent until process exit. Includes `fflush(stderr)` before fd swaps so buffered C writes don't leak across the boundary.
  • `smimesign` replace directive points at `nikwo/smimesign-fork` (commit `0956e442`) which adds `unsafe.Pointer` cast to `HLOCAL` — required for cgo type-strictness on any modern Go + Windows toolchain.
  • `task vet-cross` runs `go vet` for linux/windows/darwin to catch build-tag mistakes.
  • `task build-windows` for local mingw cross-compile (note: blocked on MSVC-vs-mingw ABI for the bundled MuPDF static lib — works for everything except the MuPDF link step; CI handles the real Windows build).
  • `.github/workflows/windows.yml` runs a real `windows-latest` build via MSVC (`ilammy/msvc-dev-cmd@v1`) and uploads the binary as an artifact.

Test plan

  • `go build ./...` clean on Linux
  • `go test -count=1 ./...` green on Linux
  • `task vet-cross` confirms Linux package vets cleanly with build tags (Windows/Darwin vet failures are external CGO chains, expected without that toolchain)
  • Windows CI workflow lands a working `lankir.exe` artifact — verifies on this PR
  • Manual: verify on a real Windows machine that `lankir cert list` enumerates Windows Certificate Store certificates
  • Manual: sign a PDF on Windows using a cert from the Windows store

Follow-ups (out of scope, worth tracking)

  • Replace the personal smimesign fork with either an upstreamed PR or a fork under your own GitHub org — depending on a 2022-static personal repo is fragile.
  • Pre-existing flakiness in `internal/pdf` test suite (`TestConcurrentOperations` race-y under MuPDF C calls) — independent of this branch.
  • macOS Keychain integration (currently stubbed).
  • Native Wails Windows app packaging (this PR builds the Go binary; full Wails desktop app needs WebView2 + NSIS).

@Matbe34
Matbe34 force-pushed the feature/windows-support branch from 37d5ab2 to 63f096d Compare May 4, 2026 19:24
@Matbe34
Matbe34 merged commit 1a2a70c into master May 4, 2026
3 checks passed
@Matbe34
Matbe34 deleted the feature/windows-support branch May 4, 2026 20:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant