Workflow and helper-script entrypoints:
.github/workflows/release-gui.yml.github/workflows/verify-gui-packaging.yml.github/scripts/release_gui_prepare.py.github/scripts/release_gui_collect.py
release-gui.yml supports two source modes:
release_tag: package from an existing stable tag/version.current_ref: package from the current commit for verification; publish job is skipped and packaging metadata is derived from the workspace semver (stable or prerelease).
Manual workflow_dispatch defaults to the safe verification path:
source_mode: current_refdry_run: true
To publish from a manual run, the operator must explicitly choose release_tag,
provide a stable release tag/version (vX.Y.Z or X.Y.Z), and set dry_run
to false.
verify-gui-packaging.yml follows the same split:
- explicit
taginput remains stable-only, - empty
tagderives packaging metadata from[workspace.package].version, including prerelease workspace versions used for smoke/verification branches.
When packaging metadata comes from a prerelease workspace version, artifact
names and manifests keep the full prerelease tag. Windows packager config uses
the numeric major.minor.patch core only, because WiX/MSI product versions do
not accept prerelease/build metadata.
release_tag publishes on tag-triggered runs and on manual runs where
dry_run is false.
release_tag gates:
- tag format/existence validation,
- workspace version == tag version,
- server+CLI smoke test including restart persistence (docs/dev/devlog.md#runtime-smoke-test-server-cli),
- packaging/build jobs check out the resolved source ref directly (full-tree tag fidelity in
release_tagmode).
Published release assets (when produced) follow:
localpaste-<tag>-windows-x86_64.msilocalpaste-<tag>-windows-x86_64.ziplocalpaste-<tag>-linux-x86_64.AppImagelocalpaste-<tag>-linux-x86_64.tar.gzlocalpaste-<tag>-macos-aarch64.dmglocalpaste-<tag>-macos-aarch64.app.tar.gzchecksums.sha256
Windows and Linux artifacts are always expected for successful release runs.
Packaging verification checks include:
- Windows: MSI presence + non-empty payload + administrative extraction contains
localpaste.exe. - Linux: AppImage presence + non-empty payload + runtime metadata check via
--appimage-version. - macOS: DMG integrity/format validation, plus signed-bundle verification inside mounted DMG when notarization secrets are present.
Release/packaging workflows enforce these baseline controls:
- Least privilege by default: workflow-level
permissions: contents: read, with publish-only elevation tocontents: write. - Immutable action pinning (
uses:entries pinned to commit SHAs) for release-critical jobs. - Deterministic source checkout for packaging jobs via resolved
SOURCE_REF(no selective tree overlay from a different ref). - Windows WiX toolchain pinning (
3.14.1) plus major-version assertion inrelease_gui_prepare.py.
Signing/notarization runs only when Apple secrets are present
(APPLE_SIGNING_*, APPLE_ID, APPLE_APP_SPECIFIC_PASSWORD, APPLE_TEAM_ID).
Behavior when secrets are missing:
release_tag: macOS artifacts are still built/published in permissive mode as unsigned/unnotarized.current_ref: unsigned macOS packaging build is allowed for verification runs.
Behavior when secrets are present:
release_tagandcurrent_ref: workflow signs, notarizes, and staples macOS artifacts.
When a .dmg is present in published assets, the workflow appends this one-line macOS note to the release body (idempotent):
macOS note: this release may include unsigned/unnotarized LocalPaste macOS artifacts. If Gatekeeper blocks LocalPaste, use Open Anyway in System Settings > Privacy & Security or run \xattr -cr /Applications/LocalPaste.app`.`