# 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