528 lines
8.1 KiB
Markdown
528 lines
8.1 KiB
Markdown
|
|
# Development Workflow Guide
|
||
|
|
|
||
|
|
Development, testing, and contribution workflow for m3ta-nixpkgs.
|
||
|
|
|
||
|
|
## Initial Setup
|
||
|
|
|
||
|
|
### Clone Repository
|
||
|
|
|
||
|
|
```bash
|
||
|
|
git clone https://code.m3ta.dev/m3tam3re/nixpkgs.git
|
||
|
|
cd nixpkgs
|
||
|
|
```
|
||
|
|
|
||
|
|
### Enter Development Shell
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Default shell (includes linting tools)
|
||
|
|
nix develop
|
||
|
|
|
||
|
|
# Python shell
|
||
|
|
nix develop .#python
|
||
|
|
|
||
|
|
# DevOps shell
|
||
|
|
nix develop .#devops
|
||
|
|
```
|
||
|
|
|
||
|
|
### Development Shell Tools
|
||
|
|
|
||
|
|
The default dev shell includes:
|
||
|
|
|
||
|
|
- `statix` - Nix linter
|
||
|
|
- `deadnix` - Find dead code
|
||
|
|
- `alejandra` - Code formatter
|
||
|
|
|
||
|
|
## Workflow
|
||
|
|
|
||
|
|
### 1. Create Feature Branch
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Checkout main and pull latest
|
||
|
|
git checkout main
|
||
|
|
git pull
|
||
|
|
|
||
|
|
# Create feature branch
|
||
|
|
git checkout -b feature/my-new-package
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Make Changes
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Create new package
|
||
|
|
mkdir -p pkgs/my-package
|
||
|
|
vim pkgs/my-package/default.nix
|
||
|
|
|
||
|
|
# Or modify existing package
|
||
|
|
vim pkgs/existing-package/default.nix
|
||
|
|
|
||
|
|
# Or add module
|
||
|
|
vim modules/nixos/my-module.nix
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Format Code
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Format all files
|
||
|
|
nix fmt
|
||
|
|
|
||
|
|
# Format specific file
|
||
|
|
alejandra path/to/file.nix
|
||
|
|
```
|
||
|
|
|
||
|
|
**Always format before committing.**
|
||
|
|
|
||
|
|
### 4. Test Changes
|
||
|
|
|
||
|
|
#### Build Package
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Build specific package
|
||
|
|
nix build .#my-package
|
||
|
|
|
||
|
|
# Build all packages
|
||
|
|
nix build .#packages.x86_64-linux
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Run Package
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Test if package runs
|
||
|
|
nix run .#my-package -- --help
|
||
|
|
|
||
|
|
# Or enter shell with package
|
||
|
|
nix shell .#my-package
|
||
|
|
my-package --version
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Validate Flake
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Validate all outputs
|
||
|
|
nix flake check
|
||
|
|
|
||
|
|
# Show all outputs
|
||
|
|
nix flake show
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Test Module
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Test NixOS configuration
|
||
|
|
sudo nixos-rebuild test --flake .#hostname
|
||
|
|
|
||
|
|
# Test Home Manager configuration
|
||
|
|
home-manager switch --flake .#username@hostname
|
||
|
|
```
|
||
|
|
|
||
|
|
### 5. Lint Code
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Enter dev shell for linting tools
|
||
|
|
nix develop
|
||
|
|
|
||
|
|
# Run statix
|
||
|
|
statix check .
|
||
|
|
|
||
|
|
# Run deadnix
|
||
|
|
deadnix .
|
||
|
|
|
||
|
|
# Fix auto-fixable issues
|
||
|
|
statix fix .
|
||
|
|
```
|
||
|
|
|
||
|
|
### 6. Commit Changes
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Stage changes
|
||
|
|
git add .
|
||
|
|
|
||
|
|
# Commit with conventional format
|
||
|
|
git commit -m "feat: add my-package for doing X"
|
||
|
|
|
||
|
|
# Commit types: feat, fix, docs, style, refactor, chore, test
|
||
|
|
```
|
||
|
|
|
||
|
|
### 7. Push and Create PR
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Push branch
|
||
|
|
git push origin feature/my-new-package
|
||
|
|
|
||
|
|
# Create PR via web interface or CLI
|
||
|
|
gh pr create --title "feat: add my-package" --body "Description of changes"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Testing Strategies
|
||
|
|
|
||
|
|
### Local Testing
|
||
|
|
|
||
|
|
#### Test Package Build
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Build for current system
|
||
|
|
nix build .#my-package
|
||
|
|
|
||
|
|
# Build for specific system
|
||
|
|
nix build .#my-package --system aarch64-linux
|
||
|
|
|
||
|
|
# Build for macOS
|
||
|
|
nix build .#my-package --system x86_64-darwin
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Test Package Functionality
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Enter shell with package
|
||
|
|
nix shell .#my-package
|
||
|
|
|
||
|
|
# Run the program
|
||
|
|
my-package --help
|
||
|
|
my-package --version
|
||
|
|
|
||
|
|
# Test with sample data
|
||
|
|
echo "test" | my-package
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Test Configuration
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Test NixOS configuration
|
||
|
|
sudo nixos-rebuild test --flake .#hostname
|
||
|
|
|
||
|
|
# Test Home Manager configuration
|
||
|
|
home-manager switch --flake .#username@hostname
|
||
|
|
|
||
|
|
# Check configuration syntax
|
||
|
|
nix eval .#nixosConfigurations.hostname.config --apply builtins.attrNames
|
||
|
|
```
|
||
|
|
|
||
|
|
### Integration Testing
|
||
|
|
|
||
|
|
#### Test with Real Services
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# If package is a service
|
||
|
|
# 1. Add to configuration
|
||
|
|
# 2. Apply configuration
|
||
|
|
sudo nixos-rebuild switch
|
||
|
|
|
||
|
|
# 3. Test service
|
||
|
|
systemctl status my-service
|
||
|
|
journalctl -u my-service -f
|
||
|
|
|
||
|
|
# 4. Test functionality
|
||
|
|
curl http://localhost:8080
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Test with Dependencies
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Build dependency chain
|
||
|
|
nix build .#my-package \
|
||
|
|
--rebuild \
|
||
|
|
--keep-going
|
||
|
|
|
||
|
|
# Check if dependencies are satisfied
|
||
|
|
nix path-info .#my-package --references
|
||
|
|
```
|
||
|
|
|
||
|
|
## Continuous Integration
|
||
|
|
|
||
|
|
### Pre-Commit Hook
|
||
|
|
|
||
|
|
Create `.git/hooks/pre-commit`:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
#!/usr/bin/env bash
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
# Format code
|
||
|
|
nix fmt
|
||
|
|
|
||
|
|
# Lint
|
||
|
|
statix check .
|
||
|
|
deadnix .
|
||
|
|
|
||
|
|
# Validate
|
||
|
|
nix flake check
|
||
|
|
|
||
|
|
# Test build
|
||
|
|
nix build .#your-package
|
||
|
|
```
|
||
|
|
|
||
|
|
Make executable:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
chmod +x .git/hooks/pre-commit
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pre-Push Hook
|
||
|
|
|
||
|
|
Create `.git/hooks/pre-push`:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
#!/usr/bin/env bash
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
# Validate flake
|
||
|
|
nix flake check
|
||
|
|
|
||
|
|
# Run tests if they exist
|
||
|
|
# make test
|
||
|
|
```
|
||
|
|
|
||
|
|
## Debugging
|
||
|
|
|
||
|
|
### Build Failures
|
||
|
|
|
||
|
|
#### Hash Mismatch
|
||
|
|
|
||
|
|
Error: `got: sha256-AAAAAAAA... expected: sha256-BBBBBB...`
|
||
|
|
|
||
|
|
Solution: Copy the `got` hash and update package:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
src = fetchFromGitHub {
|
||
|
|
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Use actual hash
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Dependency Not Found
|
||
|
|
|
||
|
|
Error: `error: undefined variable 'somelib'`
|
||
|
|
|
||
|
|
Solution: Check function arguments:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
{
|
||
|
|
lib,
|
||
|
|
stdenv,
|
||
|
|
fetchFromGitHub,
|
||
|
|
somelib, # Add this if missing
|
||
|
|
}:
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Build Failed
|
||
|
|
|
||
|
|
Error: `builder for '/nix/store/...' failed`
|
||
|
|
|
||
|
|
Solution:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Build with verbose output
|
||
|
|
nix build .#my-package -v --show-trace
|
||
|
|
|
||
|
|
# Check build logs
|
||
|
|
nix log .#my-package
|
||
|
|
|
||
|
|
# Enter build environment for debugging
|
||
|
|
nix shell -f .#my-package .bashInteractive
|
||
|
|
```
|
||
|
|
|
||
|
|
### Runtime Failures
|
||
|
|
|
||
|
|
#### Package Not Executable
|
||
|
|
|
||
|
|
Error: `error: operation not permitted`
|
||
|
|
|
||
|
|
Solution: Check `mainProgram` in meta:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
meta = with lib; {
|
||
|
|
mainProgram = "my-app"; # Must match executable name
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Library Not Found
|
||
|
|
|
||
|
|
Error: `error while loading shared libraries: libfoo.so`
|
||
|
|
|
||
|
|
Solution: Add to build inputs:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
buildInputs = [someLib];
|
||
|
|
```
|
||
|
|
|
||
|
|
### Configuration Failures
|
||
|
|
|
||
|
|
#### Option Not Found
|
||
|
|
|
||
|
|
Error: `error: The option 'm3ta.mymodule' does not exist`
|
||
|
|
|
||
|
|
Solution: Import the module:
|
||
|
|
|
||
|
|
```nix
|
||
|
|
imports = [
|
||
|
|
m3ta-nixpkgs.nixosModules.default
|
||
|
|
];
|
||
|
|
```
|
||
|
|
|
||
|
|
## Common Tasks
|
||
|
|
|
||
|
|
### Update Package Version
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 1. Update version in package definition
|
||
|
|
vim pkgs/my-package/default.nix
|
||
|
|
|
||
|
|
# 2. Build to get new hash
|
||
|
|
nix build .#my-package
|
||
|
|
|
||
|
|
# 3. Update hash from error message
|
||
|
|
|
||
|
|
# 4. Test new version
|
||
|
|
nix run .#my-package -- --version
|
||
|
|
|
||
|
|
# 5. Commit
|
||
|
|
git commit -m "chore: update my-package to v2.0.0"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Update Dependencies
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 1. Update fetcher version/rev
|
||
|
|
vim pkgs/my-package/default.nix
|
||
|
|
|
||
|
|
# 2. Update dependencies if needed
|
||
|
|
vim pkgs/my-package/default.nix
|
||
|
|
|
||
|
|
# 3. Build and test
|
||
|
|
nix build .#my-package
|
||
|
|
nix run .#my-package -- --help
|
||
|
|
|
||
|
|
# 4. Commit
|
||
|
|
git commit -m "fix: update dependencies for my-package"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Add Tests
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 1. Add test to package
|
||
|
|
vim pkgs/my-package/default.nix
|
||
|
|
|
||
|
|
# 2. Run tests
|
||
|
|
nix build .#my-package
|
||
|
|
|
||
|
|
# 3. Verify tests pass
|
||
|
|
|
||
|
|
# 4. Commit
|
||
|
|
git commit -m "test: add tests for my-package"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Fix Linting Issues
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 1. Run linter
|
||
|
|
nix develop
|
||
|
|
statix check .
|
||
|
|
|
||
|
|
# 2. Fix issues manually or auto-fix
|
||
|
|
statix fix .
|
||
|
|
|
||
|
|
# 3. Check again
|
||
|
|
statix check .
|
||
|
|
|
||
|
|
# 4. Commit
|
||
|
|
git commit -m "style: fix linting issues"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Performance Optimization
|
||
|
|
|
||
|
|
### Use Caching
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Use binary cache (if available)
|
||
|
|
nix build .#my-package --substituters https://cache.nixos.org https://your-cache.example.com
|
||
|
|
|
||
|
|
# Use local cache
|
||
|
|
nix build .#my-package --max-jobs 4
|
||
|
|
```
|
||
|
|
|
||
|
|
### Parallel Builds
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Build multiple packages in parallel
|
||
|
|
nix build .#package1 .#package2 .#package3
|
||
|
|
```
|
||
|
|
|
||
|
|
### Incremental Builds
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Only rebuild changed packages
|
||
|
|
nix build .#my-package --check
|
||
|
|
|
||
|
|
# Don't rebuild dependencies
|
||
|
|
nix build .#my-package --no-link
|
||
|
|
```
|
||
|
|
|
||
|
|
## Release Process
|
||
|
|
|
||
|
|
### Version Bump
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 1. Update versions as needed
|
||
|
|
vim pkgs/*/default.nix
|
||
|
|
|
||
|
|
# 2. Update CHANGELOG.md
|
||
|
|
vim CHANGELOG.md
|
||
|
|
|
||
|
|
# 3. Test all packages
|
||
|
|
nix flake check
|
||
|
|
|
||
|
|
# 4. Commit
|
||
|
|
git commit -m "chore: prepare release v1.0.0"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Tag Release
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Create tag
|
||
|
|
git tag -a v1.0.0 -m "Release v1.0.0"
|
||
|
|
|
||
|
|
# Push tag
|
||
|
|
git push origin v1.0.0
|
||
|
|
|
||
|
|
# Push with tags
|
||
|
|
git push --follow-tags
|
||
|
|
```
|
||
|
|
|
||
|
|
### Update Flakes
|
||
|
|
|
||
|
|
Update flake lock after release:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Update lock file
|
||
|
|
nix flake update
|
||
|
|
|
||
|
|
# Commit
|
||
|
|
git commit -m "chore: update flake lock"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Checklist
|
||
|
|
|
||
|
|
### Before Committing
|
||
|
|
|
||
|
|
- [ ] Code formatted with `nix fmt`
|
||
|
|
- [ ] Passes `statix check .`
|
||
|
|
- [ ] Passes `deadnix .`
|
||
|
|
- [ ] Passes `nix flake check`
|
||
|
|
- [ ] Package builds successfully
|
||
|
|
- [ ] Package runs as expected
|
||
|
|
- [ ] Documentation updated (if needed)
|
||
|
|
- [ ] Commit message follows convention
|
||
|
|
|
||
|
|
### Before Merging PR
|
||
|
|
|
||
|
|
- [ ] All tests pass
|
||
|
|
- [ ] Code review approved
|
||
|
|
- [ ] No merge conflicts
|
||
|
|
- [ ] Documentation complete
|
||
|
|
- [ ] Breaking changes documented
|
||
|
|
|
||
|
|
## Resources
|
||
|
|
|
||
|
|
- [Contributing Guide](../CONTRIBUTING.md) - Code style and guidelines
|
||
|
|
- [Architecture](../ARCHITECTURE.md) - Understanding repository structure
|
||
|
|
- [Adding Packages](./adding-packages.md) - Package creation guide
|
||
|
|
- [Quick Start](../QUICKSTART.md) - Getting started guide
|