# Desktop Release Packaging

WireShare desktop releases are built from the canonical `WireShare.jar`
produced by the root Gradle build. For Linux, the canonical hosted-builder
release contract is a source tarball, `WireShare.jar`, `SHA256SUMS`, and
`DEPENDENCY_INVENTORY.txt`; hosted builders are primary, while the locally
built Flatpak is a fallback GitHub Releases artifact.

For the general contributor guide covering build, run, jar, and package
commands, see [BUILDING.md](BUILDING.md). This document focuses on release
artifact identity, packaging inputs, and the split between hosted builders and
local fallback packaging.

## Product Identity

- App name: `WireShare`
- App id: `cx.hermes.WireShare`
- Legacy Linux ids kept only for migration compatibility: `org.teamhermes.WireShare`, `org.team_hermes.WireShare`
- Vendor: `Hermes`
- Version source: Gradle `releaseAppVersion`
- Release tag convention: `release/<version>`
- Upstream repository: `nmatavka/hermes-wireshare`
- Windows upgrade UUID: `5CAFE0D2-ABB3-4F01-8CFE-C564E00C09EC`

## Canonical Linux Release Inputs

Generate the Linux release inputs with:

```bash
./gradlew wireShareJar
./gradlew packageSourceTarball
./gradlew writeReleaseChecksums
./gradlew writeReleaseDependencyInventory
```

Or run the combined task:

```bash
./gradlew packageLinuxReleaseInputs
```

`packageSourceTarball` archives the current `HEAD` commit, so run the
release-input tasks from the committed release state you actually intend to
publish.

Canonical release-input outputs:

```text
WireShare.jar
build/release-artifacts/WireShare-<version>-source.tar.gz
build/release-artifacts/SHA256SUMS
build/release-artifacts/DEPENDENCY_INVENTORY.txt
```

These are the artifacts the checked-in Linux packaging recipes under
`packaging/` consume or reference through the rollout manifest.

## Hosted Builder Packaging

The repo now treats `packaging/` as the Linux packaging source of truth:

- `packaging/release_manifest.yaml` is the single user-editable release input
- `packaging/targets.yaml` describes the destination metadata, driver, submission mode, and headless capability for each ecosystem
- `packaging/common/` holds the canonical desktop entry, AppStream metainfo, icons, launcher scripts, and release-asset references
- `packaging/flathub/` and `packaging/snap/` hold the hosted app-bundle manifests for Flathub and Launchpad/Snap
- `packaging/aur/`, `packaging/obs/`, and `packaging/copr/` are the first-wave community-builder recipes
- the remaining distro and ports directories under `packaging/` hold the source-build-first wave for Debian, Fedora, openSUSE, PPA, Mageia, Gentoo, Nix, Guix, Alpine, Void, Solus, Homebrew, pkgsrc, SlackBuilds, FreeBSD, and OpenBSD

Use the orchestrator to prepare and render Linux rollout bundles:

```bash
scripts/release_linux_rollout.sh prepare
scripts/release_linux_rollout.sh validate
scripts/release_linux_rollout.sh doctor
scripts/release_linux_rollout.sh auth status
scripts/release_linux_rollout.sh config status
scripts/release_linux_rollout.sh install-tools --headless-only
scripts/release_linux_rollout.sh render
scripts/release_linux_rollout.sh submit --dry-run
scripts/release_linux_rollout.sh submit --headless-only --dry-run
```

Flathub is intentionally `human_gate`: the tool may generate the review packet
and PR-ready diff, but final submission remains human-reviewed and
human-authored. After review, use:

```bash
scripts/release_linux_rollout.sh resume --target flathub --acknowledge
```

That generates the final human submission dossier, including `PR_BODY.md`. The
orchestrator also prints the ready-to-run `gh pr create` command with the
resolved fork owner filled in, but still stops before executing that final PR
command.

Browser opening is opt-in. Add `--open` when you want guided/manual targets to
launch their downstream pages locally. `submit --headless-only` now restricts
the run to targets that have a terminal/API-first path in the current
orchestrator, including `full`, `conditional`, and `gated` targets. That means
Flathub now participates in headless-first runs, but it still stops at the
explicit human approval boundary before any final PR is authored. `install-tools`
provisions the supported local helper CLIs and target-specific managed runtimes;
the Python-backed `launchpadlib` runtime is only needed for Snap/PPA Launchpad
automation. `auth status` mirrors the live credential checks from `doctor`, while
`auth login --target snap` and `auth login --target ppa` create or refresh the
Launchpad OAuth cache that the Launchpad API adapter uses and populate the
local `accounts.launchpad_owner` override when it is blank. `auth login --target obs`
uses the authenticated `osc` session to populate `accounts.obs_owner` and the
derived `accounts.obs_project` in `~/.local/share/linux_rollout/config.yaml`.
Use `config set`, `config unset`, and `config status` for those local non-secret
override values. When those overrides are blank, the workspace auto-discovers
`accounts.pkgsrc_wip_user` from `ssh -G wip.pkgsrc.org` and derives the OBS
owner/project from `~/.oscrc` when an OBS login already exists.

The current promoted driver families are:

- `git_submit` for AUR, Homebrew, HaikuPorts, nixpkgs, Void, Solus, Gentoo, and Alpine
- `service_cli` for OBS and Copr
- `launchpad_api` for Snap and PPA
- `mail_submit` for Guix and OpenBSD
- `bugzilla_api` for Mageia and FreeBSD
- `conditional_git_submit` for pkgsrc-wip
- `human_gate` for Flathub

The mail driver keeps its own headless fallback path as well: Guix threaded
patch replies use `git send-email` when it is available, but fall back to the
managed `sendmail` transport when the host Git build does not ship that
subcommand.

## Local Packaging Tasks

```bash
./gradlew build --console=plain --warning-mode all
./gradlew wireShareJar
./gradlew packageDesktopRelease
```

`packageDesktopRelease` is host-specific:

- macOS builds `build/macos/dmg/WireShare-*.dmg`
- Windows x64 builds `build/windows/msi/WireShare-*.msi`
- Linux x86_64 builds `build/distributions/WireShare-<version>-linux-x64.flatpak`

On Linux, that Flatpak is the manual fallback artifact for GitHub Releases. It
is not the primary distribution path for Flathub or other hosted builders.

## Signing

Signing is optional for local packaging. If credentials are missing, Gradle
builds unsigned packages and logs a warning.

macOS:

- `macosCodesignIdentity` or `MACOS_CODESIGN_IDENTITY`
- `macosCodesignKeychain` or `MACOS_CODESIGN_KEYCHAIN`
- `macosNotaryProfile` or `MACOS_NOTARY_PROFILE`

Windows:

- `windowsCodesignCertificatePath` or `WINDOWS_CODESIGN_CERTIFICATE_PATH`
- `windowsCodesignCertificatePassword` or `WINDOWS_CODESIGN_CERTIFICATE_PASSWORD`
- `windowsCodesignCertificateThumbprint` or `WINDOWS_CODESIGN_CERTIFICATE_THUMBPRINT`
- `windowsSignToolPath` or `WINDOWS_SIGNTOOL_PATH`
- `windowsTimestampUrl` or `WINDOWS_TIMESTAMP_URL`

## Linux Flatpak Fallback

The local Flatpak fallback uses `org.freedesktop.Platform//25.08` and
`org.freedesktop.Sdk//25.08`.

Install local prerequisites:

```bash
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak install flathub org.freedesktop.Platform//25.08 org.freedesktop.Sdk//25.08
```

The fallback Flatpak bundles a Java 21 runtime image generated from the active
`JAVA_HOME` and the repo-tracked x86_64 Linux native libraries.
