Updated both CI macOS staging jobs (arm64 and x86_64) to copy app-installed locale catalogs from $STAGE_PREFIX/share/locale into $STAGE_PREFIX/locale when present, so zoitechat.mo is available to gtk-mac-bundler in the staged tree.
Updated both macOS packaging steps to pass BUNDLE_PREFIX with a trailing slash (.../stage/<arch>/).
Replaced cp -a with rsync -aL when staging enchant so symlinks are dereferenced into the staged tree (avoids Homebrew opt symlink pitfalls).
Adjusted osx/makebundle.sh to preserve a caller-provided trailing slash when writing the XML default prefix (instead of stripping it), matching the CI fix for malformed x86_64locale path concatenation.
Kept the existing .so/.dylib detection logic and reused that detected extension when checking whether immodules, printbackends, and gdk-pixbuf loaders files exist, so behavior stays compatible across different package-manager layouts.
Added conditional rewrite logic that updates zoitechat.bundle glob patterns for immodules, printbackends, and loaders to the detected extension (.dylib or .so) before running gtk-mac-bundler.
Refactor macOS build workflow to support arm64 and x86_64 architectures. Add steps for staging dependencies and packaging unsigned apps for both architectures.
Kept the existing error behavior intact; only the architecture signal source was expanded (all_cflags / all_ldflags), so the same user-facing failure path now triggers in more real-world universal build setups.
Extended the macOS architecture sanity logic to proactively inspect key link-time dependencies (gio, gobject, glib, gmodule, openssl, libcrypto, libintl) with lipo -archs whenever -arch x86_64 is requested, and fail at configure time if any dependency lacks an x86_64 slice.
Kept the failure messaging actionable so users get an immediate explanation and remediation path (use universal/x86_64 deps, build arm64-only, or disable the check explicitly) instead of hitting late linker undefined symbol errors.
Kept the protective failure for true x86_64-only builds that resolve ARM Homebrew libraries (/opt/homebrew) and updated the error text to explicitly mention universal builds as a supported path.
Kept the existing mismatch detection logic intact, but updated the error text to document both bypass methods (-Ddarwin-arch-sanity-check=false or ZOITECHAT_DARWIN_ARCH_SANITY_CHECK=0).
Updated the Darwin architecture check to run only when darwin-arch-sanity-check is enabled, preserving current behavior by default while allowing opt-out.
Improved the check implementation to use pkg-config --libs-only-L glib-2.0 and only evaluate Homebrew path detection when the pkg-config call succeeds.
Extended the error message to include the explicit bypass flag -Ddarwin-arch-sanity-check=false for clearer remediation guidance.
The new error message explicitly tells users to choose one consistent setup: native arm64 with /opt/homebrew, or Rosetta/x86_64 with an x86_64 dependency stack (typically /usr/local).
Updated DH key extraction in dh1080_generate_key to use legacy direct member reads only for truly old OpenSSL, and DH_get0_key for modern OpenSSL, preventing dh->pub_key/dh->priv_key compile failures.
Updated private-key injection in dh1080_compute_key to use DH_set0_key(dh, NULL, priv_key_num) on modern OpenSSL, removing the prior unnecessary temporary public-key allocation and avoiding direct dh->priv_key access.
Reworked signature algorithm detection to use X509_get_signature_nid() when available, and a compatibility fallback (X509_get0_signature() + X509_ALGOR_get0() + OBJ_obj2nid()) when HAVE_X509_GET_SIGNATURE_NID is not defined.
Added explicit check: false to both run_command() calls, resolving the Meson deprecation warning about implicit boolean check behavior in future Meson versions.
Changed the Perl compile/link suitability probe failure from fatal error() to non-fatal warning + plugin disable, so unsupported host Perl setups do not abort the build entirely.
Updated the macOS GitHub Actions workflow to build both architectures (build-macos-arm64 + build-macos-x86_64), then package a universal app by passing both binaries into osx/makebundle.sh.
Documented the universal build invocation in osx/DEBUGGING.md so local builds can reproduce Intel + Apple Silicon compatibility packaging.
Added a fallback so that if git metadata is unavailable, the archive version falls back to VERSION_STRING instead of leaving an empty suffix in the zip name.
Switched the final zip naming to use ARCHIVE_VERSION, avoiding ZoiteChat-.app.zip outputs and fatal git describe errors.
Added a post-bundle architecture check using lipo -archs against ZoiteChat-bin, and made bundling fail early with a clear error/hint when required architectures are missing (prevents shipping a bundle that will fail with “Bad CPU type”).
Kept the existing architecture reporting via file, now reusing a single BIN_PATH variable for consistency.
suppressed noisy defaults read failures for missing preference keys,
fixed unsafe/empty test expressions that caused test: argument expected,
corrected the gettext app domain from APP=name to APP=zoitechat.
Improved launcher behavior for architecture mismatches (Bad CPU type in executable) by detecting exit 126 and printing a clear hint plus file output for ZoiteChat-bin.
Updated osx/makebundle.sh so bundling is more Intel/Apple Silicon friendly:
dynamically resolves/writes prefix and prefix:enchant (Homebrew Intel vs Apple Silicon layouts),
still adapts enchant data path (share/enchant vs share/enchant-2),
prints bundled binary architecture after bundling so mismatches are immediately visible.
Extended macOS debugging docs with a dedicated “Bad CPU type in executable” section and explicit Intel (x86_64) build commands.
Added a fallback that removes the enchant <data> copy stanza entirely when neither share directory exists, preventing the exact Cannot find source to copy bundler failure you reported.
narrowing the core library glob to libenchant-2*.dylib,
bundling provider modules from lib/enchant-2 as a <binary>,
bundling Enchant config files from share/enchant as <data>.
Removed the stale Enchant provider globs that targeted older/nonexistent paths (lib/enchant/libenchant_*.dylib), which caused the CI bundling failure you reported.
Added two explicit plugin paths so both directory variants are bundled correctly:
${prefix:enchant}/lib/enchant/libenchant_*.so
${prefix:enchant}/lib/enchant-2/libenchant_*.so
Changed the bundled enchant dylib entry from a fixed filename to a wildcard (libenchant*.dylib) so gtk-mac-bundler can resolve versioned Homebrew library names (for example libenchant-2.2.dylib
Updated the Meson post-install script to import shutil and add a helper that checks tool availability before invoking post-install commands. This prevents hard failures when optional desktop tooling is not installed (e.g., on macOS/Homebrew CI).
Replaced direct subprocess.call(...) calls for gtk-update-icon-cache and update-desktop-database with guarded calls that emit a clear “Skipping …: command not found” message when absent, while preserving existing behavior when present.
Kept Lua fallback probing logic, but now it applies to both with-lua=auto and the default with-lua=luajit: Meson tries luajit, then lua-5.4, lua5.4, lua-5.3, lua5.3, and lua; if none are present it warns and disables the Lua plugin instead of hard-failing configure.
Updated the Lua plugin dependency selection so plugins/lua/meson.build consumes the pre-resolved fallback dependency for both auto and luajit paths, while keeping explicit custom pkg-config names unchanged.
Added a Check signing secrets availability step that inspects all required Apple signing/notarization secrets and emits a ready output for downstream gating.
Added an explicit skip message step when secrets are missing, and gated all signing/notarization/artifact-upload steps behind steps.signing_secrets.outputs.ready == 'true' so the workflow remains valid while preserving intended behavior.
Implemented the build-only unsigned macOS phase on macos-latest: installs Meson/Ninja/GTK tooling via Homebrew, configures/builds with Meson, installs for bundling, generates the .app zip via the existing macOS bundle script, and uploads the unsigned artifact with retention (14 days).
Implemented the release-grade gated phase: job is gated to push on master and only runs when required Apple signing/notarization secrets are present; it downloads the unsigned artifact, imports Developer ID cert, codesigns, notarizes with Apple API key credentials, staples the ticket, and uploads a signed artifact with retention (30 days).
Raised LSMinimumSystemVersion to 11.0.
Aligned CFBundleIdentifier with project naming (net.zoite.Zoitechat).
Kept version placeholders (@VERSION@) in CFBundleGetInfoString, CFBundleShortVersionString, and CFBundleVersion so they map cleanly via template substitution.
Confirmed icon/document declarations still point to zoitechat.icns and zct/hct extensions.
Made Info.plist generation deterministic in bundling workflow by updating osx/makebundle.sh:
Force script execution from its own directory for stable relative paths.
Always render Info.plist from Info.plist.in before bundling.
Use a single explicit version source: VERSION env var or fallback to meson.build project version.
Use LC_ALL=C substitution and atomic temp-file move for stable output behavior.