7.2 KiB
Contributing
Contributing to m3ta-nixpkgs.
Setting Up Development Environment
# Clone repository
git clone https://code.m3ta.dev/m3tam3re/nixpkgs.git
cd nixpkgs
# Enter development shell (includes linting tools)
nix develop
# Or use a specific shell
nix develop .#python
nix develop .#devops
Code Style and Formatting
Formatting
Use alejandra to format Nix files:
# Format all files
nix fmt
# Format specific file
alejandra path/to/file.nix
Always run nix fmt before committing.
Linting
Linting tools are only available inside the dev shell:
# Enter dev shell first
nix develop
# Run statix (linter)
statix check .
# Run deadnix (find dead code)
deadnix .
Conventions
Naming
- Packages:
lowercase-hyphen(e.g.,hyprpaper-random) - Variables:
camelCase(e.g.,portHelpers) - Module options:
m3ta.*namespace - Files:
lowercase-hyphen(e.g.,my-module.nix)
Imports
Multi-line, trailing commas:
{
lib,
stdenv,
fetchFromGitHub,
}:
Meta Fields
Always include all fields in package definitions:
meta = with lib; {
description = "Short description";
homepage = "https://github.com/author/repo";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "program-name";
};
Module Pattern
Standard module pattern:
{ config, lib, pkgs, ... }:
with lib; let
cfg = config.m3ta.myModule;
in {
options.m3ta.myModule = {
enable = mkEnableOption "description";
};
config = mkIf cfg.enable {
# Configuration
};
}
Adding a Package
- Create package directory in
pkgs/your-package/ - Write
default.nixwith package definition - Register in
pkgs/default.nix
See Adding Packages Guide for detailed instructions.
Note: Package versions are automatically updated weekly via Gitea Actions using nix-update. You don't need to worry about keeping versions current - the automation will create PRs for updates. Just focus on ensuring the package builds and works correctly.
Package Testing
# Build the package
nix build .#your-package
# Test if package runs
nix run .#your-package -- --help
# Check with linter
nix develop
statix check pkgs/your-package/
Adding a NixOS Module
- Create module file in
modules/nixos/your-module.nix - Import in
modules/nixos/default.nix(or use directly)
# modules/nixos/default.nix
{
imports = [
./your-module.nix
./other-module.nix
];
}
Adding a Home Manager Module
- Choose appropriate category:
cli/,coding/, or root - Create module file
- Import in category's
default.nixor rootdefault.nix
# modules/home-manager/cli/default.nix
{
imports = [
./your-tool.nix
];
}
Development Workflow
Making Changes
# Create feature branch
git checkout -b feature/your-change
# Make changes
# Format code
nix fmt
# Test builds
nix build .#your-package
nix flake check
# Lint
nix develop
statix check .
deadnix .
Commit Format
Use conventional commits:
type: brief description
Types:
- feat: New feature
- fix: Bug fix
- docs: Documentation changes
- style: Code style changes (formatting)
- refactor: Code refactoring
- chore: Maintenance tasks
- test: Adding or updating tests
Examples:
feat: add new package for myapp
fix: resolve port conflict in mem0 module
docs: update installation instructions
style: format nix files
refactor: simplify port management
chore: update dependencies
Before Committing
# Format all files
nix fmt
# Validate flake
nix flake check
# Run linters
nix develop
statix check .
deadnix .
# Add files
git add .
# Commit
git commit -m "type: description"
Testing
Package Testing
# Build for specific system
nix build .#your-package --system x86_64-linux
# Test on different systems
nix build .#your-package --system aarch64-linux
Module Testing
# Test NixOS configuration
sudo nixos-rebuild test --flake .#hostname
# Test Home Manager configuration
home-manager switch --flake .#username@hostname
Flake Validation
# Validate all outputs
nix flake check
# Show all outputs
nix flake show
Pull Requests
Before Submitting
- Code formatted with
nix fmt - Passes
statix check . - Passes
deadnix . - Passes
nix flake check - New packages include
metafields - Documentation updated if needed
- Commit messages follow convention
Handling Automated Update PRs
The repository has automated package updates via Gitea Actions (see main README for details). When reviewing automated update PRs:
- Build and test: Verify the updated package builds successfully
- Check changelinks: Review upstream release notes for breaking changes
- Test functionality: Ensure the package still works as expected
- Review package definition: Check if any manual adjustments are needed
For urgent updates, you can manually trigger the workflow from the Gitea UI or update the package manually.
PR Description
Include:
- What changed and why
- How to test
- Any breaking changes
- Related issues
Troubleshooting
Hash Errors
When building packages, you may encounter hash errors:
got: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
expected: sha256-BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=
Solution: Copy the got hash and update the package:
src = fetchFromGitHub {
# ...
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Use actual hash
};
Dependency Not Found
If a package isn't found, check:
- Package registered in
pkgs/default.nix - Overlay applied in your configuration
- System matches supported platform
Linting Errors
# Fix statix issues manually or use auto-fix where available
statix fix .
# Review deadnix suggestions
deadnix -e .
Getting Help
- Check existing packages and modules for patterns
- Read Architecture for design decisions
- Review Code Patterns for conventions
- Open an issue for questions
Anti-Patterns
| Don't | Do Instead |
|---|---|
lib.fakeHash in commits |
Get real hash: nix build, copy from error |
| Flat module files | Organize by category (cli/, coding/) |
| Hardcode ports | Use m3ta.ports module |
| Skip meta fields | Include all: description, homepage, license, platforms, mainProgram |
with pkgs; in modules |
Explicit pkgs.package or with pkgs; [ ... ] in lists only |
| Suppress type errors | Fix underlying type issues |
| Delete tests to "pass" | Fix failing tests |
Code Review Checklist
- Follows naming conventions
- Properly formatted (
nix fmt) - Passes linting (
statix,deadnix) - Has complete
metafields (packages) - Documentation updated if needed
- No dead code
- No obvious bugs or issues
- Appropriate for scope
Release Process
This is a personal repository, but semantic versioning is followed for tags:
- Update versions as needed
- Update changelog
- Tag release
- Push tags
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0