Skip to content

Briefcase Installer#4629

Draft
andrewsanchez wants to merge 22 commits intomainfrom
briefcase
Draft

Briefcase Installer#4629
andrewsanchez wants to merge 22 commits intomainfrom
briefcase

Conversation

@andrewsanchez
Copy link
Copy Markdown
Contributor

@andrewsanchez andrewsanchez commented Mar 24, 2026

Summary

Feature branch that migrates Anki Desktop packaging from the legacy NSIS/uv-based installer to BeeWare Briefcase. This branch integrates work from many related issues and PRs to deliver cross-platform native installers (MSI on Windows, .app on macOS, PyInstaller on Linux) with code signing, notarization, and file association support.

Integrated PRs

Related Issues

Related PRs

abdnh added 8 commits March 6, 2026 20:38
* Set up a Briefcase project

* Replace pip-system-certs with truststore

It doesn't play nicely with Briefcase and triggers RecursionError

* Pass --adhoc-sign

MacOS signing is deferred to a later PR.

* Fix lint errors

* Set `supportd = false` for mobile/web deployments

* Fix `qt` extra

* Use Briefcase 0.4.0

Released yesterday
* Add Briefcase icons

* Generate scaled PNG icons

* Generate CHANGELOG

Required for .deb packages
* Add permissions

* Add macOS entitlements

* Add the audio-input entitlement

permission.microphone maps to "com.apple.security.device.microphone" but the Briefcase docs claim otherwise.
It doesn't seem to be required with the microphone entitlement in place, but adding it just in case.

https://stackoverflow.com/a/57060745
* Move Briefcase app to subdir

* Use our custom Windows template

* Update Windows template
* Pass --identity to briefcase

* Write Briefcase logs

Can be found under out/installer/logs
* Use sys.executable

* Refactor installer action into a BuildAction impl

Also pass version as an arg

* Use argparse

* Build a universal macOS wheel

* Move universal_wheel action to installer group

So that the build-x64-mac script doesn't need to be run first every time the wheels group is run.

* Add build-installer scripts

* Fix mypy error

* Replace cp39 tag

We bumped the minimum Python version earlier

* Fix Windows build
Comment thread tools/build-installer Outdated
Comment on lines +5 to +7
if [[ "$(uname -s)" == "Darwin" ]]; then
./tools/build-x64-mac
fi
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A different Rust toolchain is required for macos so we call this prior to running the installer.

@abdnh

This comment was marked as resolved.

abdnh added 9 commits March 25, 2026 13:32
* Use our Linux template

* Update template

* Fix mypy error

* Update template

* Update template
## Changes

This changes the new installer to use PyInstaller instead of Briefcase
on Linux. The main benefit is that PyInstaller bundles all dependencies
with the app (including Python), while Briefcase relies on the system's
Python matching the one linked to the app, which makes distribution and
support for multiple distros really hard. See #4622 for some details.

## How to test

- Build the installer: `./ninja installer`.
- Run the executable under `./out/installer/dist/anki`.
- If you have access to another (newer) Linux distro, move the compiled
dist folder there and try running it. I did some tests on Ubuntu 22 and
Debian 13.

## Comments

One approach I considered is to use PyInstaller on all platforms for
bundling dependencies, then pass the output to Briefcase as an [external
app](https://briefcase.beeware.org/en/stable/how-to/building/external-apps/)
so we have less platform differences to worry about. This worked well,
especially on Windows, except that macOS universal binary support is
[complicated](https://pyinstaller.org/en/stable/feature-notes.html#macos-multi-arch-support)
(it requires all dependencies to have universal2 builds).
Add a small section about the Briefcase/PyInstaller installer to
docs/development.md.
## Changes

This reworks packaging on Linux to produce a zip with custom
install/uninstall scripts based on the ones under `qt/launcher/lin`.

## How to test

- Build the package: `./ninja installer`.
- Extract the zip under `out/installer/dist`:
```bash
cd out/installer/dist
tar xaf anki-25.09.2-linux-x86_64.tar.zst
```
- cd into the extracted dir and run Anki:
```bash
cd anki-25.09.2-linux
./anki
```
- Test the install script (`sudo ./install.sh`) and confirm Anki is
integrated into the system (i.e., icon displayed and file associations
work).
- Test the uninstall script (`sudo /usr/local/share/anki/uninstall.sh`)
----

See #4622
## Changes

This disables Briefcase's universal builds for macOS and removes
universal wheel handling. Briefcase now needs to be run natively on
Intel to produce a separate .dmg package. This has the advantage of
smaller packages and installations:
#4632 (comment)

Compare release sizes:
- Universal builds: https://github.com/abdnh/anki/releases/tag/26.03
- Native builds: https://github.com/abdnh/anki/releases/tag/26.04

## How to test

Build installer on ARM/Intel Mac and confirm package still works on the
same system: `tools/build-installer`.
@read-the-docs-community
Copy link
Copy Markdown

read-the-docs-community bot commented Apr 1, 2026

Documentation build overview

📚 Anki | 🛠️ Build #32256268 | 📁 Comparing 91b18e3 against latest (81eefc5)

  🔍 Preview build  

203 files changed · ± 203 modified

± Modified

Copy link
Copy Markdown
Contributor

@Luc-Mcgrady Luc-Mcgrady left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested it on linux and windows and it all LGTM. It seems to fix #4144 as well.

Comment thread qt/installer/linux-scripts/install.sh Outdated

rm -rf "$PREFIX"/share/anki "$PREFIX"/bin/anki
mkdir -p "$PREFIX"/share/anki
cp -av --no-preserve=owner,context -- * "$PREFIX"/share/anki/
Copy link
Copy Markdown
Contributor

@Luc-Mcgrady Luc-Mcgrady Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm being super picky, it might be worth not using "*" here and manually listing the top level files and _internal in case the user copies some files into the folder which would then be copied into their system files.

Comment thread qt/installer/linux-scripts/README.md Outdated
To install system wide, run 'sudo ./install.sh'

To remove in the future, run 'sudo /usr/local/share/anki/uninstall.sh'. You should
do this before installing a newer version.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe uninstalling before a re-install should be automatic?

mkdir -p "$PREFIX"/share/applications
mkdir -p "$PREFIX"/share/man/man1
cd "$PREFIX"/share/anki && (\
mv -Z anki.xpm anki.png "$PREFIX"/share/pixmaps/;\
Copy link
Copy Markdown
Contributor

@Luc-Mcgrady Luc-Mcgrady Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also picky but maybe "$PREFIX" should be made absolute because the cd will break the script if it is relative here I think.

mv: target '../share/pixmaps/': No such file or directory

abdnh added 3 commits April 8, 2026 17:15
## Linked issue

Closes #4670

## Summary

- Silently uninstall existing non-elevated NSIS-based installations.
- If an elevated install is detected (Anki versions before 2.1.64 - see
#2497), abort installation with an error message (for simplicity).

See changes to the WiX template:
https://github.com/ankitects/briefcase-windows-app-template/compare/806816f1a4ed376a7f1441184644d146f5e0dade..1c01b4cc29122280c7a03127db9410b95d5a749a


## Steps to reproduce (before)

1. Install the latest stable release.
2. Build the new MSI installer (`./tools/ninja installer`) and install
it on top of the existing version.
3. Notice two entries in the system's app list (Settings > Apps >
Installed apps on Windows 11): "Anki" and "Anki Launcher".

## How to test (after)

1. Repeat the process with the latest stable release: The existing
installation should be silently uninstalled.
2. Repeat the process with [Anki
2.1.64](github.com/ankitects/anki/releases/tag/2.1.64): Installer should
fail with an error message.

### Checklist

- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.

## UI evidence

Installation on top of an elevated installation:

<img width="398" height="189" alt="image"
src="https://github.com/user-attachments/assets/2cb1a0db-37be-43e7-b36a-24110b745f2f"
/>

## Scope

- [x] This PR is focused on one change (no unrelated edits).
## Linked issue

Closes #4675

## Summary

Remove duplicate icons created by Briefcase for Anki file types (the
`document_type` options in pyproject.toml.template). See Briefcase
template changes here:
1.
ankitects/briefcase-windows-app-template@56bfc07
2.
ankitects/briefcase-macOS-app-template@8ef2200

## Steps to reproduce (before)

1. Build and install Anki on Windows or macOS.
3. Notice several anki-\*.ico icons in the installation folder on
Windows. On macOS, right-click the app icon and click Show Package
Contents then go to the Resources folder and confirm you see several
anki-\*.icns icons.

## How to test (after)

Build and install the app and confirm the duplicate icons are removed.

### Checklist

- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.


## Scope

- [x] This PR is focused on one change (no unrelated edits).
## Linked issue

#4679

## Summary

Add anki-console.bat to Briefcase's Windows package to launch Anki in a
new terminal.

## How to test

- Build the installer: `./tools/ninja installer`.
- Install the package at `./out/dist/`.
- Confirm anki-console.bat exists in the installation folder.

## Notes

Console output won't show up yet. That depends on an upstream fix:
beeware/briefcase-windows-VisualStudio-template#88
@andrewsanchez andrewsanchez added this to the Improve the Installer milestone Apr 14, 2026
@andrewsanchez andrewsanchez mentioned this pull request Apr 14, 2026
Copy link
Copy Markdown
Contributor

@iamllama iamllama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall it LGTM!


if __name__ == "__main__":
import sys
from pathlib import Path
Copy link
Copy Markdown
Contributor

@iamllama iamllama Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For console output, instead of modifying the wix template to reopen the console handles, we can do it within the interpreter itself (https://github.com/iamllama/anki/blob/3e0e5914ebf9208dba65cd4e24b93b15fe5592d1/qt/launcher/src/platform/mod.rs#L139) (tested on win10/11)

Suggested change
from pathlib import Path
from pathlib import Path
sys.stdout = sys.stderr = open("CONOUT$", "w")
sys.stdin = open("CONIN$", "r")

EDIT: within the try block as opening the handles will fail when run normally as a gui app

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That works. I submitted a PR to upstream anyway: beeware/briefcase-windows-VisualStudio-template#88

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.

4 participants