Thank you for your interest in contributing to draphyOS! This document provides guidelines and instructions for contributing to this project.
By participating in this project, you agree to be respectful and create a harassment-free experience for everyone.
We follow a structured workflow for all contributions. Here's the process:
- Before making any changes, start by creating an issue in the GitHub issue tracker
- Clearly describe the bug, feature, or improvement you want to address
- Wait for a DRO issue number to be assigned in the comments
Note: Small fixes (typos, minor docs) can skip this step — just open a PR directly.
Create a branch with the following naming format:
username/dro-<issue-number>-<issue-title>
Example:
johndoe/dro-123-fix-battery-detection
janedoe/dro-45-add-bluetooth-module
- Fork the repository to your GitHub account
- Clone your fork to your local machine
- Add the upstream repository as a remote
git clone https://github.com/YOUR_USERNAME/draphyOS.git
cd draphyOS
git remote add upstream https://github.com/draphy/draphyOS.git# Ensure you have shellcheck installed
sudo dnf install ShellCheck
# Validate all scripts
shellcheck install.sh uninstall.sh update.sh
shellcheck migrations/*.sh
# Check bash syntax
bash -n install.sh
bash -n uninstall.sh
bash -n update.sh
bash -n migrations/common.sh- Create a new branch with the proper naming convention
- Make your changes following the coding conventions
- Update documentation if necessary
What you can modify:
- Configs: Edit files in
configs/ - Scripts: Modify
install.sh,uninstall.sh,update.sh - Migrations: Add migration scripts in
migrations/ - Docs: Update
README.md,CONTRIBUTING.md - Manifests: Update
VERSION,PACKAGES(maintainers only)
We use Conventional Commits for clear and meaningful commit messages.
Format:
<type>: <description>
Where type is one of:
| Type | Description |
|---|---|
feat |
A new feature |
fix |
A bug fix |
docs |
Documentation changes |
style |
Formatting, no code change |
refactor |
Code refactoring |
perf |
Performance improvements |
test |
Adding or updating tests |
build |
Build system changes |
ci |
CI configuration changes |
chore |
Maintenance tasks |
revert |
Reverting changes |
Example:
git commit -m "feat: add network speed display to polybar"
git commit -m "fix: correct battery detection on desktops"
git commit -m "docs: update installation instructions"-
Before pushing, run the full local check to ensure CI will pass:
# Lint shell scripts shellcheck install.sh uninstall.sh update.sh shellcheck migrations/*.sh 2>/dev/null || true # Check bash syntax bash -n install.sh bash -n uninstall.sh bash -n update.sh bash -n migrations/common.sh
-
Push your changes to your fork
-
Create a pull request against the
latestbranch -
Use this format for the PR title:
<type>: <Description starting with capital letter>Example:
feat: Add network speed display to polybar fix: Correct battery detection on desktops docs: Update installation instructions -
Provide a detailed description in the PR
-
Link the PR to the relevant issue
-
Ensure all status checks pass
-
Request a review from maintainers
Pull requests require approval before they can be merged.
PR Title Examples:
| ✅ Valid | ❌ Invalid |
|---|---|
feat: Add network speed display to polybar |
Added new feature |
fix: Correct battery detection on desktops |
fix - battery bug |
docs: Update installation instructions |
updated docs |
Your PR will automatically run these checks:
| Check | What It Does |
|---|---|
| PR Title Check | Validates conventional commit format |
| ShellCheck | Lints shell scripts for errors |
| Conflict Check | Detects merge conflicts with latest |
All checks must pass before merging.
Shell Scripts:
- Run
shellcheckbefore committing - Quote variables:
"$variable"not$variable - Use
[[ ]]for conditionals (not[ ]) - Add comments for complex logic
- Follow Google Shell Style Guide
Config Files:
- Keep configs well-commented
- Use consistent indentation
- Document hardware-specific settings
⚠️ WARNING: Always test in a VM or disposable system!Never test draphyOS changes on your main/production system. The installer modifies system configs, installs packages, and changes shell settings. Bugs in your code could:
- Break your desktop environment
- Corrupt config files
- Leave your system in an inconsistent state
Recommended testing environments:
- VirtualBox / VMware / QEMU with Fedora i3 Spin
- A separate Fedora installation on another partition
- Fedora in a container (for script logic testing only)
- A spare laptop/PC
For full testing, run the installer on a test Fedora system:
# Fresh install
./install.sh
# Test update functionality
./update.sh -d
# Test uninstall
./uninstall.sh./update.sh # Interactive menu
./update.sh -u # System update (dnf upgrade)
./update.sh -s # Security updates only
./update.sh -c # Check for updates (no install)
./update.sh -f # Full maintenance
./update.sh -v # Fedora version upgrade
./update.sh -d # draphyOS config update
./update.sh -h # Show helpIf testing in VirtualBox/VMware/QEMU:
- The installer auto-detects VMs and switches picom to
xrenderbackend - Test that VM detection works:
systemd-detect-virt - Verify picom settings are correct for VM environment
- Update documentation to reflect any changes
- Use clear and concise language
- Follow the existing documentation style
Good First Issues:
- Fix typos in docs or comments
- Improve error messages in scripts
- Add missing keybindings to cheatsheet
- Better hardware detection
Feature Ideas:
- New polybar modules
- Additional rofi themes
- More cheatsheets (vim, tmux, etc.)
- Improved install/uninstall scripts
If you need help with the contribution process or have questions, feel free to:
- Comment on the relevant issue
- Ask questions in pull requests
- Open a discussion for general questions
This section is for project maintainers who manage releases and version updates.
draphyOS/
├── configs/ # User configuration files
│ ├── i3/
│ │ ├── config # i3 window manager config
│ │ ├── lock.sh # Lock screen script
│ │ └── scripts/
│ │ ├── cheatsheet.sh
│ │ └── cheatsheets/ # Cheatsheet text files
│ ├── polybar/
│ │ ├── config.ini # Polybar configuration
│ │ └── launch.sh # Polybar launcher
│ ├── rofi/
│ │ ├── config.rasi # Rofi configuration
│ │ └── mint-y-dark.rasi # Rofi theme
│ ├── dunst/dunstrc # Notification daemon
│ ├── picom/picom.conf # Compositor
│ ├── fish/config.fish # Fish shell
│ ├── gtk-3.0/settings.ini # GTK theme settings
│ ├── redshift/redshift.conf
│ ├── xprofile # X session startup
│ └── alacritty/alacritty.toml # Alacritty terminal config
├── migrations/ # Version migration scripts
│ ├── common.sh # Shared migration utilities
│ ├── TEMPLATE.sh # Template for new migrations
│ └── v1_to_v2.sh # Example: migration from v1 to v2
├── assets/ # Images, wallpapers
│ ├── logo.png
│ └── wallpaper.png
├── install.sh # Installation script
├── uninstall.sh # Uninstallation script
├── update.sh # System update tool
├── VERSION # Current version number (integer)
├── PACKAGES # Package manifest with version ranges
├── README.md
└── CONTRIBUTING.md
How configs are installed (symlinks unless noted):
| Source | Destination | Notes |
|---|---|---|
configs/i3/config |
~/.config/i3/config |
Symlink |
configs/i3/lock.sh |
~/.config/i3/lock.sh |
Symlink |
configs/i3/scripts/cheatsheet.sh |
~/.config/i3/scripts/cheatsheet.sh |
Symlink |
configs/i3/scripts/cheatsheets/ |
~/.config/i3/scripts/cheatsheets/ |
Copied (not symlinked) |
configs/polybar/config.ini |
~/.config/polybar/config.ini |
Symlink → Real file if hardware detected |
configs/polybar/launch.sh |
~/.config/polybar/launch.sh |
Symlink |
configs/rofi/* |
~/.config/rofi/* |
Symlink |
configs/dunst/dunstrc |
~/.config/dunst/dunstrc |
Symlink |
configs/picom/picom.conf |
~/.config/picom/picom.conf |
Symlink → Real file if VM detected |
configs/fish/config.fish |
~/.config/fish/config.fish |
Symlink |
configs/gtk-3.0/settings.ini |
~/.config/gtk-3.0/settings.ini |
Symlink |
configs/redshift/redshift.conf |
~/.config/redshift/redshift.conf |
Symlink |
configs/xprofile |
~/.xprofile |
Symlink |
configs/alacritty/alacritty.toml |
~/.config/alacritty/alacritty.toml |
Symlink |
assets/wallpaper.png |
~/.config/wallpaper.png |
Copied |
Important:
polybar/config.iniandpicom/picom.confare converted from symlinks to real files when hardware-specific modifications are needed (battery detection, VM mode). Contributors modifying these should be aware of this behavior.
Understanding how install.sh works:
1. Pre-flight checks
├── Verify Fedora Linux
├── Check not running as root
├── Acquire sudo (with background keeper)
└── Check network connectivity
2. Backup existing configs
└── ~/.config-backup-YYYYMMDD-HHMMSS/
3. Save package state (for clean uninstall)
└── ~/.draphyOS-packages-before
4. Clone/update repository
└── ~/.draphyOS/
5. Install packages
└── dnf install polybar picom fish ...
6. Create config symlinks
└── ~/.config/* → ~/.draphyOS/configs/*
7. Hardware detection & configuration
├── Battery detection → Update polybar config
├── Network interface detection → Update polybar config
├── VM detection → Switch picom to xrender
└── Battery charge limit (optional)
8. Shell setup
├── Add fish to /etc/shells
└── Change default shell to fish (optional)
9. Save installation state
├── ~/.draphyOS-installed (marker file)
├── ~/.draphyOS-config-checksums (for updates)
└── /usr/local/bin/update-draphyOS
10. LightDM customization
└── /etc/lightdm/lightdm-gtk-greeter.conf
The installer performs automatic hardware detection:
# Location: install.sh → configure_hardware()
# Searches: /sys/class/power_supply/BAT*/type
# Updates: polybar config with correct battery name# Location: install.sh → configure_hardware()
# WiFi: Looks for wl* interfaces
# Ethernet: Looks for enp*/eth* interfaces
# Updates: polybar config, stored in marker file# Location: install.sh → configure_vm_settings()
# Method: systemd-detect-virt
# Detects: oracle (VirtualBox), vmware, qemu, kvm, microsoft (Hyper-V)
# Action: Converts picom config to xrender backendWhen users run update-draphyOS -d, the system uses three-way merge:
USER_FILE = User's current config (may have modifications)
ORIGINAL_FILE = Config checksum from last install/update
NEW_FILE = Latest config from GitHub
If USER_FILE unchanged from ORIGINAL → Replace with NEW_FILE
If NEW_FILE unchanged from ORIGINAL → Keep USER_FILE
If both changed → Attempt diff3 merge, prompt on conflicts
The checksum file (~/.draphyOS-config-checksums) tracks original states.
For users who installed before version tracking:
| Missing File | Behavior |
|---|---|
No DRAPHYOS_VERSION in marker |
Treated as version "0" |
No ~/.draphyOS-config-checksums |
Created on first update |
No ~/.draphyOS-packages-before |
Falls back to legacy package lists |
Code must handle these gracefully. See get_draphyos_version() in update.sh.
The ~/.draphyOS-installed file tracks installation state:
Installed: Mon Jan 20 10:30:00 UTC 2025
DRAPHYOS_VERSION=1
BASE_SYSTEM=fedora-i3 # or "fedora-other"
BASE_VARIANT=i3 # i3, workstation, kde, xfce, etc.
VM_MODE=true # Only if VM detected
WIFI_IFACE=wlan0 # Detected WiFi interface
ETH_IFACE=enp0s3 # Detected Ethernet interfaceThe ~/.xprofile runs at X session start and handles:
# What xprofile does:
1. Set wallpaper (feh)
2. Start compositor (picom)
3. Auto-detect network interfaces
4. Update polybar config with current interfaces
5. Start polybar (via launch.sh)
6. Start notification daemon (dunst)
7. Start screen locker (xss-lock)
8. Start redshift (night light)
9. Start polkit agentContributors modifying startup behavior should edit configs/xprofile.
draphyOS uses semantic versioning with integer version numbers (1, 2, 3, etc.).
Contains a single integer representing the current version:
1
| Change Type | Bump Version? | Migration Needed? |
|---|---|---|
| Typo fix in config | No | No |
| New optional keybinding | No | No |
| Changed default keybinding | Yes | Yes |
| New required package | Yes | No (auto-handled) |
| Removed package | Yes | No (auto-handled) |
| Config format change | Yes | Yes |
| Breaking change | Yes | Yes |
When making breaking changes, create a migration script:
# Copy template
cp migrations/TEMPLATE.sh migrations/v1_to_v2.sh
# Edit the migration
vim migrations/v1_to_v2.sh#!/bin/bash
source "$(dirname "$0")/common.sh"
FROM_VERSION=1
TO_VERSION=2
pre_migrate() {
migration_step "Running pre-migration checks..."
# Verify prerequisites, return 1 to abort
return 0
}
migrate() {
migration_step "Migrating from v${FROM_VERSION} to v${TO_VERSION}..."
# Example: Update a config line
config_replace_line "$HOME/.config/i3/config" \
"bindsym \$mod+old exec oldcmd" \
"bindsym \$mod+new exec newcmd"
# Example: Add a new line
config_add_line "$HOME/.config/polybar/config.ini" \
"new-setting = value"
# Example: Remove a deprecated line
config_remove_line "$HOME/.config/picom/picom.conf" \
"deprecated-option"
migration_success "Migration complete"
return 0
}
post_migrate() {
migration_step "Verifying migration..."
# Optional verification
return 0
}| Function | Usage | Description |
|---|---|---|
config_replace_line |
config_replace_line "file" "pattern" "replacement" |
Replace a line matching pattern |
config_add_line |
config_add_line "file" "line" ["after_pattern"] |
Add line (optionally after pattern) |
config_remove_line |
config_remove_line "file" "pattern" |
Remove lines matching pattern |
config_rename |
config_rename "old_path" "new_path" |
Rename file/directory |
config_is_user_modified |
config_is_user_modified "file" |
Check if user modified file |
migration_backup |
migration_backup "file" |
Backup file before changes |
migration_step |
migration_step "message" |
Print step message |
migration_success |
migration_success "message" |
Print success message |
migration_warning |
migration_warning "message" |
Print warning message |
migration_error |
migration_error "message" |
Print error message |
The PACKAGES file tracks required packages with version ranges:
# Format: package_name:min_version:max_version
# Empty min_version = always required
# Empty max_version = still required
# Both empty = required for all versions
# Core packages (always required)
polybar::
picom::
fish::
# Package added in v2
newpackage:2:
# Package removed after v2 (was required in v1-v2)
oldpackage::2
# Package only for v3-v5
temppackage:3:5
cd ~/.draphyOS
# Make changes
vim configs/i3/config
# Test locally
./update.sh -d
# Commit and push
git add -A
git commit -m "fix: Correct keybinding typo"
git push origin latestcd ~/.draphyOS
# 1. Bump version
echo "2" > VERSION
# 2. Create migration if needed
cp migrations/TEMPLATE.sh migrations/v1_to_v2.sh
vim migrations/v1_to_v2.sh
# 3. Update PACKAGES if adding/removing packages
vim PACKAGES
# 4. Make config changes
vim configs/i3/config
# 5. Test the full flow
./install.sh # Fresh install test
./update.sh -d # Update test
# 6. Commit and push
git add -A
git commit -m "feat: v2 - Add new feature X
BREAKING CHANGE: Changed keybinding for Y"
git push origin latest
⚠️ All testing must be done in a VM or test system, never on your main machine!
Before releasing:
-
bash -npasses on all scripts -
shellcheckpasses on all scripts - Fresh install works on Fedora i3 Spin (VM)
- Fresh install works on other Fedora variant (VM)
- Update from previous version works (VM)
- Uninstall cleanly removes everything (VM)
- Migration script runs correctly (if applicable)
- README is updated with new features
Recommended VM setup:
# Quick VM test cycle
1. Take VM snapshot before testing
2. Run install.sh
3. Log out and back in to i3
4. Verify all features work
5. Run update.sh -d
6. Run uninstall.sh
7. Restore snapshot for next testEnsure install.sh and uninstall.sh are in sync:
| install.sh Creates | uninstall.sh Removes |
|---|---|
~/.draphyOS/ |
rm -rf $INSTALL_DIR |
~/.draphyOS-installed |
rm -f $MARKER_FILE |
~/.draphyOS-packages-before |
rm -f in remove_install_dir |
~/.draphyOS-config-checksums |
rm -f in remove_install_dir |
~/.draphyOS-migration-backup/ |
rm -rf in remove_install_dir |
| Config symlinks | remove_configs() |
/usr/local/bin/update-draphyOS |
remove_update_script() |
/usr/share/backgrounds/draphyOS/ |
remove_lightdm() |
| LightDM config modification | Restored from backup |
| Battery limit service | remove_battery_limit() |
Fish in /etc/shells |
revert_shell() |
# Check if draphyOS is installed
cat ~/.draphyOS-installed
# View installed version
grep DRAPHYOS_VERSION ~/.draphyOS-installed
# Check config checksums
cat ~/.draphyOS-config-checksums
# View package state before install
cat ~/.draphyOS-packages-before | wc -l # Count packages
# Check symlinks
ls -la ~/.config/i3/config
ls -la ~/.config/polybar/config.ini
# Verify i3 config syntax
i3 -C -c ~/.config/i3/config
# Check polybar logs
cat /tmp/polybar.log
# Check picom running
pgrep picom
# Detect VM environment
systemd-detect-virt
# Check battery
ls /sys/class/power_supply/
# Check network interfaces
ip link show| Problem | Debug Command | Solution |
|---|---|---|
| Polybar not showing | ~/.config/polybar/launch.sh |
Check /tmp/polybar.log |
| picom issues in VM | systemd-detect-virt |
Ensure xrender backend |
| Battery module missing | ls /sys/class/power_supply/ |
Check BAT name in config |
| Network module missing | ip link show |
Update interface in config |
| i3 won't start | i3 -C |
Check config syntax |
| Fish not default | echo $SHELL |
Run chsh -s /usr/bin/fish |
| Log | Location | Contains |
|---|---|---|
| Install log | /tmp/draphyOS-install.log |
Installation output |
| Polybar log | /tmp/polybar.log |
Polybar errors |
| i3 log | ~/.xsession-errors |
i3/X session errors |
| System journal | journalctl -xe |
System services |
Thank you for contributing to draphyOS! Your efforts help make this project better for everyone.