Technical Manifest¶
Flatpak Automatic is a secure, systemd-native automation wrapper for Flatpak updates. It features Snapper-integrated atomic rollbacks, multi-channel alerting (Apprise, Mail, Webhooks, Desktop), and supports both system-wide and rootless user-level execution. Designed for reliability and ease of use, it ensures your Flatpak environment remains current and resilient.
🏗 Architectural Overview¶
The project is structured as a single RPM/DEB package providing the following components:
1. Automation Core (src/flatpak-automatic.py)¶
- Update Logic: Handles the
flatpak updateprocess with dry-run checks via D-Bus and CLI to avoid unnecessary operations. - Snapshot Integration: Automatically creates Snapper pre/post snapshots if Btrfs and Snapper are detected.
- Notification System: Multi-channel support. Uses
string.Templateformatting with context-aware templates (config/templates/) to format outputs for Apprise, Webhooks, Desktop notifications, and local mail (s-nail/mailx).
2. Systemd Integration (config/systemd/)¶
- Timer: Manages the daily execution schedule with randomized delays to prevent server congestion (
flatpak-automatic.timer/flatpak-automatic-user.timer). - Service: A
oneshotservice that executes the automation script with proper environment configuration.
3. Configuration (config/)¶
- Sysconfig (
config/sysconfig/flatpak-automatic): Holds environment-based configuration for snapshot behavior and Snapper settings. - YAML Configs: Stores structured settings (e.g.,
config.default.yaml,config.user.default.yaml,config.example.yaml). - Python Packaging (
pyproject.toml): Defines the project metadata, dependencies, and entry points following PEP 621.
🛠 Project Standards¶
- Exclusion Management: Supports surgical updates by allowing users to exclude specific Flatpak App IDs via the
exclusionsconfiguration key. - Dual-Default Configuration: Employs a context-aware loading strategy that switches between system (
config.default.yaml) and user (config.user.default.yaml) default profiles based on process UID. - XDG Scaffolding: Automatically initializes a user's local configuration at
~/.config/flatpak-automatic/config.yamlusing the user default profile (config.user.default.yaml) upon first rootless execution. - Idempotency: The update script handles "No updates available" gracefully by cleaning up its own pre-update snapshots.
- Atomic Operations: Every update attempt is preceded by a Snapper
presnapshot and followed by apostsnapshot only if changes occurred. - Configuration Persistence: The
/etc/sysconfig/flatpak-automaticfile is marked asnoreplaceto preserve user overrides during package updates. - Automated RPM Spec: The RPM changelog is generated from
CHANGELOG.mdusingscripts/build/update-package-metadata.pyand injected directly into the%changelogsection of the.specfile. - Markdown Linting: All changes to Markdown files (
.md) must adhere to the project's Markdown linting rules (enforced via.markdownlint.jsonc), especially MD013 to prevent line length overflows. - Language Standard: Always use English when editing any project files, including code, comments, and documentation.
🚀 Deployment Workflow¶
To deploy changes locally for testing:
- Build the RPM:
make rpm(For Debian, utilizescripts/build/build-deb-local.sh). - Generate Repo:
make rpm-repo CHANNEL=testing - Update Local Repo:
cp -r repo/ ../dnf-repos/flatpak-automatic/ - Install/Reinstall:
sudo dnf reinstall -Cy ../dnf-repos/flatpak-automatic/latest/testing/*.rpm - Manage Timer:
sudo flatpak-automatic --enable-timer(or--disable-timer)
🤖 AI & CLI Guidelines¶
-
Self-Correction: After modifying this
AGENT.md(orAGENTS.md), immediately re-read it to ensure the active context reflects the latest project guidelines. -
Professionalism: Maintain high engineering standards. Write clean, idiomatic Python 3 (PEP 8 with type hints), communicate clearly, and verify all changes before completion.
-
Branching Strategy (Mandatory): All features, bug fixes, and other changes must be developed in a new branch. Never commit directly to
main. Branch protection rules MUST be configured onmainto require status checks and mandatory Pull Requests.
Branch names must follow: <type>/v<version>-<short-description> Where <type>: feat | fix | chore | refactor | docs | ci | style | test | revert | perf | build | format | deps | sec Where <version>: target release version
-
Conventional Commits (Mandatory): Because
CHANGELOG.mdis automatically generated from commit history, you MUST use Conventional Commits (e.g.,feat: Add webhook support,fix: Resolve DBus timeout). Commit messages must be professional, descriptive, and "customer-ready." -
Pull Request Workflow:
- Standard feature/fix PRs MUST be created using the GitOps PR CLI tool provided in this repository (
scripts/maintainer/gitops-pr-cli-tool.sh). -
These standard PRs target existing versions and do not bump version numbers.
-
CI & Quality Requirements: All Pull Requests must pass CI checks before merging. This includes:
pre-commithooksmarkdownlint&rpmlintshellcheck&shfmtlint-python(Ruff, Mypy, Bandit for security)- Pytest suite (
tests/) -
RPM/DEB build and smoke tests
-
Testing (
tests/): Thoroughly test all changes before committing: - Write or update unit/integration tests in the
tests/directory (e.g.,test_notifications.py,integration_test_dbus.py). - Run
pytestlocally. -
Verify systemd integration and timer scheduling.
-
Verification: After modifying the RPM spec (
rpm/flatpak-automatic.spec.in), Debian controls (debian/), orMakefile: - Verify file paths and installation logic.
-
Ensure resulting packages behave as expected.
-
Documentation: Keep documentation consistent and up to date:
- Update
docs/development.mdfor build steps. - Update
docs/testing.mdfor testing requirements. -
Update
README.mdand man pages (docs/flatpak-automatic.1) for user-facing changes. -
Versioning & Release Process (
tbump): Do NOT manually editCHANGELOG.mdduring feature development. - For a new release, you MUST use tbump in no-push mode:
tbump <version> --no-push --non-interactive. tbumpwill automatically trigger the hook to sync/generate theCHANGELOG.mdbased on commit history, bump the version inMakefileand metadata files, and bundle it into a single commit.-
This commit is then pushed manually to open the final "Release PR". Once merged, the version tag is manually pushed to trigger the CI release.
-
Script Requirements: All scripts (
scripts/maintainer/,scripts/build/) must be idempotent, failure-tolerant (usingset -euo pipefailfor bash), and safe to re-run.
🛠 Agent Troubleshooting Guide¶
When investigating failures as an AI agent:
- Verify Config Layering: Use
flatpak-automatic --check-configto see the merged result of system defaults and user overrides. - Inspect State: Read the state JSON files to understand the last run context.
- Simulate Notifications: Use
--test-notifyto ensure the template rendering and dispatch logic are functional. - Environment Context: Always check
os.geteuid()behavior to determine if the service is operating in system or user scope. - Dry-Run Validation: For any logic changes to the update process, validate with
--dry-runto prevent accidental system modifications.
📦 Reference Docs¶
- README.md: Installation and usage guide.
- CONTRIBUTING.md: Guidelines for contributors.
- DEVELOPMENT.md: Build instructions and technical notes.
- TESTING.md: Testing instructions and requirements.
- CHANGELOG.md: Record of notable changes and versions (Auto-generated on release).
- MAINTAINERS.md: Project maintenance guide.
- LICENSE: GPL-3.0-or-later.
Note: All changes made to this instruction file must also be reflected in AGENTS.md and GEMINI.md.
Architecture & Execution Flow¶
graph TD
A[Systemd Timer] -->|Triggers| B(Systemd Service)
B --> C{Dry Run Check}
C -->|Updates Available| D[Pre-Snapshot]
C -->|No Updates| Z[Exit 0]
D --> E[Flatpak Update]
E --> F[Post-Snapshot]
F --> G{Alerting Enabled?}
G -->|Yes| H[Format Jinja Template]
H --> I[Send Apprise/Mail/Desktop Alert]
G -->|No| J[Exit 0]
I --> J