This document outlines the development workflow for managing and extending these dotfiles. The goal is to maintain a clean, stable, and testable configuration by using a develop branch for integration and keeping main as a stable release branch.
This project is built on the declarative nature of Nix and organized as a modular monolith.
-
Declarative: The core principle of Nix. We do not write scripts that command the system to do things (e.g.,
apt install htop). Instead, we write.nixfiles that declare the desired final state of the system (e.g.,packages = [ htop ];). Nix's job is to figure out the steps to make the system match this declaration, ensuring reproducible and reliable environments. -
Monolith: The entire user environment is defined as a single, cohesive configuration that is deployed atomically with a single
home-manager switchcommand. This ensures the whole system is always in a consistent state. -
Modular: Internally, this monolith is broken down into independent modules (e.g.,
git.nix,zsh.nix). Each module declaratively defines a specific tool or piece of functionality. This structure makes it easy to manage, update, and understand individual components without affecting the whole.
We use two primary branches to manage changes:
develop: The main development branch. All new features are integrated here. It should always be functional, but it's where active development happens.main: The stable release branch. This branch only receives updates fromdevelopwhen a set of features is complete and considered stable.
All new work, from adding a small tool to a big refactor, follows this cycle.
Before starting any work, create your feature branch from the latest version of the develop branch.
# Get the latest version of the develop branch
git checkout develop
git pull origin develop
# Create your new feature branch
git checkout -b feature/add-btop-configMake your changes to the .nix files, preferably by creating a new, self-contained module.
Crucially, for any new functionality, add a corresponding test in the tests/programs directory.
The project uses Python + Pytest for integration testing. The build is validated automatically.
- Create a file named
tests/programs/test_<program>.py. - Use the
home_manager_buildfixture to inspect the build output. - (See TEST TEMPLATES for examples).
Running Tests Locally:
You can run the full test suite using nix-shell:
nix-shell -p python3Packages.pytest --run "pytest tests/"Alternatively, just run ./switch.sh, which automatically runs tests before applying changes.
Commit your changes to your feature branch and push it to the remote repository. Use a descriptive commit message following the Conventional Commits standard.
git add .
git commit -m "feat: Add configuration for btop"
git push -u origin feature/add-btop-configGo to your repository on GitHub and open a Pull Request (PR) from your feature branch to the develop branch.
The CI pipeline will run on the PR. After it passes and you are satisfied with the changes, you can merge it into develop.
Periodically, when the develop branch contains a stable and complete set of features, you can create a new "release" on the main branch.
-
Merge
developintomain:# Go to the main branch and make sure it's up to date git checkout main git pull origin main # Merge all the changes from develop into main git merge develop --no-ff -m "chore(release): Merge develop into main" # Push the updated main branch git push origin main
(
--no-ffcreates a merge commit, which is good for visualizing the history of releases). -
(Optional) Create a Version Tag: After merging to
main, it is good practice to create a tag to mark the new version.git tag -a v1.1.0 -m "Release v1.1.0" git push origin v1.1.0