Contributing to ProtonPlus
August 9, 2026 · View on GitHub
Thank you for contributing to ProtonPlus. The project is a Linux GTK4 and libadwaita application written primarily in Vala, built with Meson, and distributed as a Flatpak and native Linux packages.
Please read this guide, the README, and the Code of Conduct before starting. For security issues, follow SECURITY.md instead of opening a public issue.
Before you start
Search existing issues and pull requests before opening a new one. For a substantial feature or architectural change, open or comment on an issue first so the scope can be agreed before implementation. Small fixes, documentation improvements, tests, and translations are welcome without prior approval.
The default integration branch is main; the required CI workflow runs for pull requests targeting main. There is no enforced branch-name or commit-message convention, but short-lived branches such as fix/... or feat/... and concise imperative commit subjects make reviews easier.
Set up a checkout
Fork the repository, then clone your fork and create a topic branch:
git clone https://github.com/YOUR_USERNAME/ProtonPlus.git
cd ProtonPlus
git switch -c fix/short-description
Native build dependencies
For a native build, install the development packages provided by your distribution for:
- Git, a C compiler, pkg-config, Meson 1.0 or newer, Ninja, and Vala
- GLib, including glib-compile-schemas, GTK4, and libadwaita 1.6 or newer
- json-glib, libsoup 3, libgee, libarchive, libnotify, Cairo, AppStream, and SDL 3.2 or newer
- gettext and desktop-file-utils
- Python 3 for the maintenance-script tests
scripts/get-dependencies.sh installs the native packages used by the project on Arch-based systems. It is not a portable dependency installer and must not be run unchanged on other distributions.
Flatpak build dependencies
For the sandboxed build, install Flatpak, configure a Flathub remote, and have network access. The build helper installs the GNOME 50 SDK and runtime, the Vala SDK extension, and Flatpak Builder when needed.
Use com.vysp3r.ProtonPlus.local.yml for development. It builds the current checkout. The other manifest, com.vysp3r.ProtonPlus.yml, builds a tagged Git source and is primarily used for release packaging.
Build and run
The project helper is the easiest way to build a development checkout:
# Build natively into build-native/
./scripts/build.sh native
# Build and run the native application
./scripts/build.sh native run
The native helper configures Meson with /usr as the install prefix and sets the data and locale paths needed when running from the checkout. To install a native build system-wide, use the normal privilege boundary explicitly:
sudo meson install -C build-native
For a native debug build, use either of these commands:
./scripts/build.sh native debug # build and run under GDB
./scripts/build.sh native-debug # build /tmp/protonplus-build-debug
The debug modes require GDB. The VS Code configuration uses the latter build directory.
To check native build tools and development libraries without creating a project build directory:
./scripts/build.sh native-deps
This performs a temporary Meson configuration with dependency downloads disabled. It reports the exact missing tool or library while leaving the working tree unchanged.
To build and install the local Flatpak for the current user:
./scripts/build.sh local
./scripts/build.sh local run
The Flatpak build runs in a sandbox and uses the permissions declared in the local manifest. It is useful for checking packaging, runtime integration, and launcher detection in the same general environment as the distributed app.
The Makefile provides shortcuts for common operations, including make build, make build-run, make build-debug, make local, make flathub, and make clean.
Test changes
For a fresh test build, configure it once, then compile and run the complete suite:
meson setup build-tests
meson compile -C build-tests
meson test -C build-tests --print-errorlogs
If build-tests/ already exists, reconfigure it with:
meson setup build-tests --reconfigure
make tests is a verbose shortcut that configures build-tests/ when needed, reconfigures an existing build, then compiles and runs the complete suite.
The test suite includes Vala unit tests, maintenance-script tests, and—when the corresponding host tools are available—desktop-file, AppStream, and GSettings schema validation. Add a focused regression test for behavior that could otherwise regress, especially for provider parsing, release identity, cache state, filesystem transactions, launcher layouts, VDF parsing, and asynchronous UI state.
Useful commands for a targeted run are:
meson test -C build-tests --list
meson test -C build-tests --print-errorlogs "ProtonPlus unit tests"
When testing installation or launcher behavior manually, use a disposable profile or test fixture. Do not point a development build at data you cannot restore, and close games before testing compatibility-tool updates or removal.
Code quality and maintenance commands
Run these checks before opening a pull request:
git diff --check
pre-commit run --all-files
meson compile -C build-tests
meson test -C build-tests --print-errorlogs
Install the pre-commit package with your distribution or Python tooling, then install the hook locally if desired:
pre-commit install
The repository configures vala-lint through .pre-commit-config.yaml and .vala-lint.conf. There is no separate formatter or static-analysis workflow; the compiler, Meson validation tests, Vala lint, and Flatpak linters are the authoritative checks currently configured in the repository. CI runs the local Flatpak build and its tests on x86_64 and aarch64. Its Flatpak lint step is advisory.
Additional helper commands:
make translations
./scripts/build.sh linter
./scripts/build.sh icons
./scripts/build.sh clean
make translations regenerates po/POTFILES and updates .po files. ./scripts/build.sh linter runs flatpak-builder-lint on the local manifest. ./scripts/build.sh icons regenerates tracked PNG icons from the SVG source. ./scripts/build.sh clean removes ignored build and distribution directories.
The linter and icon commands require Flatpak tooling and rsvg-convert, respectively. Do not commit generated build directories. Generated icon PNGs are tracked and should only be regenerated when the source icon changes.
Project layout and architecture
- src/cli/ — command-line handling and output.
- src/models/ — launcher, game, tool, release, asset, and provider models.
- src/models/launchers/ — supported launcher integrations and their installation capabilities.
- src/models/providers/ — provider definitions, validation, and catalog composition.
- src/providers/sources/ — GitHub, GitHub Actions, GitLab, and Forgejo release-source adapters and parsers.
- src/services/ — installation jobs, transactional workflows, and migrations.
- src/utils/ — filesystem, archive, network, cache, system, translation, and VDF helpers.
- src/widgets/ — GTK4/libadwaita application, window, preferences, tools, games, and MangoHud UI.
- data/ — resources, icons, CSS, desktop metadata, AppStream metadata, GSettings schema, and systemd units.
- po/ — gettext catalogs and the generated source-file list.
- tests/ — Vala regression tests, fixtures, and maintenance-script tests.
- scripts/ — build, dependency, translation, icon, AppImage, and version maintenance helpers.
- docs/codebase-guide.md — the whole-system runtime map, ownership boundaries, persistence contracts, and change-location guide.
- docs/provider-architecture.md — the provider and release-source extension model.
- docs/testing.md — focused test paths, fixture rules, safety constraints, and manual-validation expectations.
Adding a provider
Read docs/provider-architecture.md first. Ordinary providers are definition-driven; they do not require a provider subclass, widget branch, or installation-service branch.
- Add or update the relevant definition in src/models/providers/definitions/ and include it through the existing built-in definition collection.
- Reuse an existing release source and installation layout whenever their semantics match. Keep provider identity, variants, asset selection, and launcher-specific layouts explicit.
- Add or update focused tests and fixtures under tests/, especially for filtering, canonical asset URLs, variants, identity, and cache behavior.
- Add a new source adapter only when the upstream API semantics require one; register it in src/providers/sources/release-source-registry.vala and test malformed responses, pagination, failures, identity, and asset selection.
Adding launcher or installation behavior
Launcher integrations belong under src/models/launchers/. Installation transactions belong under src/services/. The installation service selects a workflow from the job's capabilities: ordinary archive providers use the standard workflow, while materially different behavior such as Steam Tinker Launch has a dedicated workflow. Do not add branches keyed only to a provider ID when a capability or launcher context expresses the requirement more accurately.
Any new .vala file must be added to the appropriate meson.build file. Update tests, documentation, and translations when the change affects them.
Coding and UI guidelines
- Use four spaces for Vala and Python. Use tabs for Makefile recipes and follow .editorconfig for Meson, YAML, JSON, and other files.
- Follow the existing Vala and GLib conventions. Keep changes focused and avoid unrelated formatting or architectural rewrites.
- Keep network, filesystem, archive, and other blocking work out of GTK filter, sort, and rendering callbacks. Use the existing asynchronous services and pass cancellation through the whole operation.
- After an asynchronous yield, verify that the requested object and current operation still match before updating UI or cache state.
- Preserve transactional installation and update behavior: stage privately, promote atomically, roll back on failure, and clean up only paths owned by the current operation.
- Wrap user-visible strings with gettext helpers (_() or ngettext()), use clear accessible labels and tooltips, and keep controls keyboard reachable. Check UI changes in both light and dark themes and at narrow window sizes.
- Avoid duplicating information in compact GTK controls and preserve layout allocation when a conditional control is temporarily unavailable.
Translations and metadata
User-facing text is translated with gettext and coordinated through Weblate. When adding or removing translatable source files, regenerate the source list and translation catalogs:
make translations
Do not hand-edit generated translation output unless you are intentionally updating a catalog. Changes to icons, desktop metadata, AppStream metadata, GSettings, or resources should be tested through the Meson build and relevant validation tests.
Issues and pull requests
Bug reports
Use the bug report form after checking existing issues and the latest release. Include:
- a clear description of the actual and expected behavior;
- reproducible steps, input, and relevant upstream provider or release;
- distribution, desktop environment, ProtonPlus version, installation type, and launcher setup;
- logs, screenshots, or a stack trace when useful; and
- whether the issue occurs in both native and Flatpak builds, if relevant.
Never include secrets such as API tokens or private paths containing sensitive information. Report vulnerabilities privately using SECURITY.md.
Feature requests
Use the feature request form. Explain the user problem, the proposed behavior, alternatives considered, and why the change benefits ProtonPlus users generally.
Pull requests
Open pull requests against main and complete .github/pull_request_template.md. A good pull request:
- contains one coherent change and links the relevant issue when one exists;
- explains motivation, design decisions, new dependencies, and configuration changes;
- includes focused tests or explains why tests are not practical;
- updates documentation, metadata, and translations when applicable;
- includes screenshots or a recording for meaningful UI changes; and
- reports the exact build, test, lint, or manual verification performed.
Reviewers prioritize correctness, data safety, regressions, accessibility, performance, maintainability, and consistency with the existing architecture. Passing CI is necessary but does not replace manual review of behavior and UI.
Release and versioning notes
Release work is maintainer-led. The project version is declared in meson.build; scripts/set-version.py VERSION updates the Meson version and the tagged source reference in the Flathub manifest. Release notes in data/com.vysp3r.ProtonPlus.metainfo.xml.in and the Git tag (vVERSION) are updated separately. Publishing a GitHub release triggers the AppImage workflow.
Contributors should not change the project version or release metadata unless the pull request is specifically part of a release. If a version-related change is requested, use --dry-run first and verify every generated and manual update before committing.
Final checklist
Before requesting review:
git diff --check
meson compile -C build-tests
meson test -C build-tests --print-errorlogs
pre-commit run --all-files
Then run the application or the relevant Flatpak build, inspect the diff for unrelated changes, and describe the verification in the pull request.