Thank you for your interest in addict. Bug reports, ideas and pull requests are welcome.
Open an issue on GitHub. Say what you did, what you expected and what happened, and add:
- your distribution and its version, and your desktop (GNOME, KDE Plasma) with its version;
- how you installed addict: from source (with the commit) or from a package;
- what addict printed on the terminal, if you started it from one.
Do not paste your DeepL key, and check that a screenshot does not show it.
For anything larger than a small fix, open an issue first, so we can agree on the change before you spend time on it. Then:
- Fork the repository and make a branch from
main. - Make the change, with tests for new behaviour.
- Run the checks below.
- Open a pull request that says what the change does and why.
Commit messages follow Conventional Commits:
feat(window): …, fix(ocr): …, docs: …, ci: …, with a short subject
in the imperative.
The messages also drive the releases. On every push to main,
release-please keeps a release
pull request open: fix raises the patch version, feat the minor version,
and, before 1.0, a breaking change (feat!:) the minor version too. The pull
request sets the version in Cargo.toml, Cargo.lock and the MetaInfo, and
writes CHANGELOG.md, so do not edit those by hand. Merging it tags the release
and publishes it on GitHub. The tag then starts the release workflow, which
runs the CI checks and, only when they pass, attaches these assets to that
release (<version> is the version without the v; the names and checks are
in docs/release.md):
Addict-<version>-x86_64.flatpakand its.sha256: the Flatpak bundle;Addict-<version>-x86_64.AppImageand its.sha256, with the build files.build.txt,.inputs.lock.json,.rpms.txt,.layout.txt,.notices.jsonand.components.sha256, and the corresponding sources of the AppImage's components as.sources.tar.00,.sources.tar.01, ... with.sources.tar.sha256;addict-<version>-vendored.tar.xzand its.sha256: the tagged tree with its crates vendored, for building offline.
The README's install steps use these names, so change them together.
Code, docs or other content written with an AI tool are welcome, if you
disclose it: add a Co-Authored-By trailer that names the tool or model to
each commit with such content, for example
Co-Authored-By: Claude <noreply@anthropic.com>
You are responsible for what you submit: read it, test it and be ready to explain it. The project's own use of AI is described in AI-DISCLOSURE.md, and Flathub requires it to stay accurate.
Build addict as the README says. Before you open a pull request, run:
scripts/check.shIt runs cargo fmt --check, cargo clippy with warnings as errors, a build
of the product without the test features, all the tests, and a guard that
keeps GTK out of every crate but addict-app. Some tests run Tesseract, so
install it with its English data. The portal and forwarded-launch tests also
need dbus-run-session and dbus-daemon (sudo dnf install dbus-daemon on
Fedora). They create isolated session buses and do not use your desktop portal.
CI on GitHub runs the format and lint checks, the tests, reuse lint, a
secret scan of the whole history, the tests of the release trigger and upload
script (scripts/release-tests.sh), and builds the Flatpak and checks it with
flatpak-builder-lint, but not the build without the test features or the
GTK guard, so run scripts/check.sh yourself. CI runs once for each commit
of a pull request and for each commit on main; a push to another branch
without a pull request starts no run, but "Run workflow" on the CI workflow's
Actions page tests any branch.
To lint the Flatpak locally as CI and Flathub do, use the lint build and the
flatpak-builder-lint commands in the header of
packaging/flatpak/io.github.doqhu.Addict.yml, not its --install build.
The lint build uses --mirror-screenshots-url and
--compose-url-policy=full, as Flathub's build does; without them, the
builddir and repo lints fail on appstream-external-screenshot-url and
appstream-remote-icon-not-mirrored.
The Flatpak build has no network, so it takes the crates from
packaging/flatpak/cargo-sources.json. If your change touches Cargo.lock,
regenerate that file with scripts/flatpak-sources.sh (it needs
flatpak-cargo-generator from flatpak-builder-tools) and commit it too.
Regenerate the list of the crates' licenses the same way, with
scripts/crate-licenses.sh (it needs cargo-about 0.9.3), and commit
packaging/licenses/crate-licenses.txt. CI regenerates both files and fails
when either differs from the committed one.
Before you try a Flatpak you built from packaging/flatpak, run
addict uninstall and quit the running addict, as the
README says.
The experimental x86_64 AppImage has a separate pinned build and packaging checks. See AppImage build and isolated desktop acceptance. Its download and typed-translation desktop checks are required before claiming that an artifact works on a target distribution.
crates/addict-core-- the product identity and the domain types.crates/addict-platform-- the desktop adapters: portals, screen capture and Tesseract recognition.crates/addict-dictionary-- the dictionary index format, its reader and the importers of each dictionary source.crates/addict-deepl-- the DeepL client and its key file.crates/addict-engine-- the logic of the program without its widgets: the texts of the window, the manual path, lookups, online requests, downloads, the cache, the history and the evidence. It must not depend on GTK, GDK, gio or glib;scripts/check.shguards it, so a second frontend can reuse it.crates/addict-app-- theaddictprogram: the resident process, the window and the commands.
Only addict-app may depend on GTK.
addict is licensed under the MIT License. By contributing, you agree that
your contribution is licensed under it too. REUSE.toml covers every file,
so a new file needs no license header. Data from another source needs its own
entry in crates/addict-dictionary/src/sources.rs, which CREDITS is
generated from. Any other file with third-party content, such as a screenshot
that shows dictionary text, needs its own annotation in REUSE.toml; so does
a file whose format asks for another license, such as the MetaInfo
(CC0-1.0).