Deadlock Mod Manager
Developer Documentation

APT Repository

How the Ubuntu/Debian APT repository is built, signed, and published

APT Repository

Ubuntu and Debian users can install Deadlock Mod Manager from the APT repository at https://apt.deadlockmods.app. See the installation guide for the user-facing setup.

How It Works

The publish-apt.yml workflow rebuilds the whole repository on every run:

  1. Downloads the regular *_amd64.deb and CEF *_amd64-cef.deb assets from the latest stable GitHub releases (5 by default). Nightly releases are excluded.
  2. Puts regular builds in the main component and CEF builds in the cef component, repacks packages whose metadata is out of date, names each one <package>_<version>_<arch>_<sha256 prefix>.deb, and generates the Packages indexes and Release file with apt-ftparchive.
  3. Signs Release as InRelease and Release.gpg, and exports the public key as key.gpg and key.asc.
  4. Runs apt-get update against the local repository to verify the signature and indexes.
  5. Syncs the result to the deadlock-apt Cloudflare R2 bucket, which is served at apt.deadlockmods.app.

The release workflow calls it after the GitHub release is published. Because the repository is regenerated from releases each time, re-running the workflow is always safe. To republish manually, run Publish APT Repository from the Actions tab; the keep-releases input controls how many stable releases are included.

Uploads are ordered so clients never see an index that points at a missing file: new packages first, then the package indexes, then the signed Release files, and finally removal of old packages. Packages are cached as immutable, and dists/ is served with no-cache.

Repository Layout

key.gpg                                  # Public signing key (binary)
key.asc                                  # Public signing key (armored)
dists/stable/InRelease
dists/stable/Release
dists/stable/Release.gpg
dists/stable/main/binary-amd64/Packages(.gz)
dists/stable/cef/binary-amd64/Packages(.gz)
pool/main/d/deadlock-mod-manager/deadlock-mod-manager_<version>_amd64_<hash>.deb
pool/cef/d/deadlock-mod-manager/deadlock-mod-manager_<version>_amd64_<hash>.deb

Pool files are named by a prefix of their SHA-256 because they're cached as immutable. A package that gets repacked never reuses the URL of an earlier copy, so a stale cache can't cause Hash Sum mismatch errors.

CEF Component

Both components ship a package named deadlock-mod-manager, because the in-app updater installs updates with dpkg -i using that package name. A renamed CEF package that conflicts with deadlock-mod-manager would make those updates fail. Users enable one component in their source line.

Repacked Packages

Release assets are published unchanged unless their metadata is wrong. The workflow then rewrites DEBIAN/control and rebuilds the package; the installed files are untouched:

  • Version. CEF builds in the v1.0.0 and v1.1.0 releases were stamped with nightly versions (for example 1.2.0-nightly.20260801.a633e8e), which apt would rank above the next stable release. CEF packages are published under their release tag's version.
  • Depends. Any entry from bundle.linux.deb.depends in tauri.conf.json (for main) or tauri.cef.conf.json (for cef) that a package doesn't declare is appended. Older CEF builds predate the CEF dependency list and fail to start without libnss3/libnspr4, and builds before desktop-file-utils and xdg-utils were added can't register deep links on minimal installs.

Repacking pins timestamps with SOURCE_DATE_EPOCH, so each run produces byte-identical packages and unchanged files aren't re-uploaded.

Secrets

SecretPurpose
APT_GPG_PRIVATE_KEYArmored private key used to sign the repository (no passphrase)
APT_R2_ACCESS_KEY_IDR2 API token access key with read/write access to deadlock-apt
APT_R2_SECRET_ACCESS_KEYR2 API token secret
APT_R2_ENDPOINTR2 S3 endpoint, without the bucket name

Signing Key

The repository is signed with an ed25519 key:

Deadlock Mod Manager APT Repository <apt@deadlockmods.app>
FEB3B67A5727ED8F0A1C71CB8535BB5119FFD1A0

Rotating the key

Every user has imported the public key, so replacing it breaks apt update until users import the new key. If the key is compromised, publish the revocation certificate, generate a new key, update APT_GPG_PRIVATE_KEY, re-run the workflow, and announce the new key import command.

Limitations

  • Only stable x86_64 builds are published, in the main (system webview) and cef components.
  • Packages are built on Ubuntu 24.04 and do not declare a minimum glibc version, so older distributions such as Ubuntu 22.04 or Debian 12 can install them but may fail to start.

On this page