Thanks for helping. This file covers how to set up, what a good change looks like and how releases work.
- For a bug, open an issue with the steps to reproduce it, unless the fix is small and obvious.
- For a new feature, open an issue first and describe what you want to do. Each one gets agreed on in the issue before code.
- Read ARCHITECTURE.md. Changes to the locked stack need agreement in an issue first.
You need:
- Rust stable (
rustuppicks the toolchain fromrust-toolchain.toml) - Node.js 22.13 or newer
dbus-daemonfor the daemon's integration tests- GNOME Shell 46 to try the extension
cargo test
cd extension
npm ci
npm run check
npm run lint
npm testThe Windows app in desktop/ builds on Windows only (npx tauri build
there); on any system its page and pure modules can be checked:
cargo test -p nokta-desktop
cd desktop
npm ci
npm run check
npm run lint
npm test
npm run shots -- /tmp/nokta-shotsdocs/testing.md explains the test layers and how to run the extension in a headless GNOME Shell that cannot touch your own session.
-
Write a test that fails without your change, then make it pass.
-
Keep the D-Bus contract in
contracts/as the source of truth. If you change it, update both sides in the same pull request. -
Run what CI runs before you push:
tools/precheck.sh
It runs CI's steps one at a time and stops at the first failure: format, lint and tests of the daemon and the extension, the shell scripts, the installer, the dependency audit (with
cargo-auditinstalled), the smoke test here and, with podman installed, the smoke test in the containers of every GNOME version CI tests.--quickskips those containers. The Rust version is pinned inrust-toolchain.toml, so clippy here says what clippy in CI says. -
For changes to what the notch shows or how it moves, go through the matching part of the checklist in docs/testing.md and add a screenshot to the pull request.
The extension's text lives in extension/po/: nokta@nokta.io.pot is the
template and each language has a .po file named after its code. Every
string the user reads goes through _('…') in the source, or N_('…') in a
table built when a module loads, and numbers go in with format() and %s
or %d, so a translation can put them where its grammar wants.
- After changing text in
extension/src/, runnpm run i18ninextension/to update the template, then translate the new entries. - To add a language, copy the template to
extension/po/<code>.po, fill in everymsgstr, and add the code toextension/po/LINGUAS. npm run checkfails while a language misses an entry, keeps one marked fuzzy, or drops a placeholder.
Nokta uses Conventional Commits. The changelog and version numbers are generated from them, so write the message for someone reading the changelog:
feat(lyrics): show plain lyrics when no synced version exists
fix(media): stop the progress bar from jumping back after a seek
docs: explain the Just Perfection clock setting
Types: feat, fix, perf, refactor, test, docs, build, ci,
chore. Scopes: media, lyrics, settings, osd, devices, timer,
activities, weather, calendar, shelf, clipboard, downloads, system, updates, tour, screenshots, privacy, themes, panel, i18n, app, contracts, extension, desktop, plugins, cli, packaging, core. A breaking change gets a ! after the
scope and a BREAKING CHANGE: footer.
Releases are automated with
release-please. It keeps a
release pull request open that collects the changes on main. When a
maintainer merges it, it tags the version, writes CHANGELOG.md, and CI
builds and attaches the daemon archive, the extension zip, the Windows
installer (built on windows-latest) and their SHA256SUMS to the GitHub
release. Version numbers follow SemVer; the daemon,
the extension and the Windows app always share one version.
Everyone taking part follows the Code of Conduct.