Check if the API key already exists in the database before stopping
and restarting Jellyfin. This prevents unnecessary restarts on every
jellarr timer trigger, avoiding race conditions where Jellyfin returns
503 while still initializing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The bootstrap service was using wantedBy=multi-user.target which caused
it to run during NixOS activation. Since the script calls systemctl
stop/start on jellyfin, this deadlocked - systemd can't process service
state changes while in an activation transaction.
Changed to requiredBy/before jellarr.service so bootstrap only runs
when the jellarr timer fires, after activation is complete.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This example uses 0.0.1 and also enables the bootstrap feature, but that
feature did not exist in that version.
This feature is not in a tagged release yet so just use the default ref
of the repo.
Adds support for completing the Jellyfin startup wizard via config.
When startup.completeStartupWizard is true, calls POST /Startup/Complete.
Closes#23
- Add multi-platform uncomment tool integration via Nix flake
- Configure treefmt to enforce AAA-only comment policy
- Remove all explanatory comments from codebase
- Preserve only Arrange/Act/Assert test comments
Added @typescript-eslint/stylistic-type-checked preset with selective overrides for our deliberate choices:
Preset Benefits:
- 30+ battle-tested stylistic rules from the TypeScript ESLint team
- Automatic maintenance and updates
- Comprehensive coverage of TypeScript-specific patterns
Targeted Overrides:
- array-type: "array-simple" for better readability on complex types
- consistent-generic-constructors: "type-annotation" to keep generics on left side
- no-inferrable-types: "off" to avoid conflicts with typedef strictness
- non-nullable-type-assertion-style: "off" to avoid conflicts with strict rules
Manual Fixes Applied:
- prefer-nullish-coalescing: library.ts, users.ts, users.spec.ts
- prefer-optional-chain: users.ts
- no-empty-function: logger.spec.ts, library.spec.ts
- array-type: auto-fixed across multiple test files
Zero ESLint violations remaining
Added comprehensive typedef ESLint rule enforcement requiring explicit types everywhere:
- Arrow function parameters in forEach loops and array operations
- Object destructuring parameters in tests and source code
- Function parameters for sorting, mapping, and filtering operations
- Catch block error parameters with proper z.core.$ZodIssue typing
- Variable declarations and array destructuring patterns
All 78+ typedef violations fixed across 16 files while maintaining full test coverage.
ESLint now enforces nazi-level static typing with explicit annotations required
for all function parameters, destructuring, and variable declarations.
- Add @typescript-eslint/naming-convention rule
- Support API property names (PascalCase, snake_case)
- Exclude generated files from linting
- Ensure current codebase passes without errors
- Update User Management section with policy example (admin user)
- Update Full Configuration Example to include policy fields
- Show 3-user pattern: regular users + admin with policy
- Complete documentation for user policy support feature
- Add policy configuration to test users in sanity.nix
- Enhance user validation to verify IsAdministrator and LoginAttemptsBeforeLockout
- Add password authentication testing via /Users/AuthenticateByName
- Refactor API calls with generic jellyfin_api_call method for GET/POST
- Merge duplicate assertions for cleaner validation logic
- Add UserPolicyConfig type with isAdministrator and loginAttemptsBeforeLockout support
- Implement mapUserPolicyConfigToSchema mapper for policy field translation
- Add calculateUserPoliciesDiff and applyUserPolicies functions following calculate/apply pattern
- Extend JellyfinClient with updateUserPolicy method for PUT /Users/{userId}/Policy
- Wire user policy management into pipeline with proper sequencing
- Update config.yml with test users featuring different policy configurations
- Comprehensive manual integration testing confirms idempotent behavior
- All 314 tests passing, buildfull validation complete
- Replace individual it1 test with comprehensive sanity test
- Add PyHamcrest for expressive test assertions
- Implement AAA (Arrange/Act/Assert) testing pattern
- Add complete configuration validation (system, encoding, library, branding, users)
- Include initial state validation to prove declarative behavior
- Fix network connectivity with DNS resolution checks
- Add isort for Python import sorting with Black compatibility
- Update CI pipeline with sandbox bypass for GitHub Actions
- Expand test coverage while maintaining similar execution time
Resolves#15
- Add declarative user configuration via YAML
- Support plaintext passwords (dev) and passwordFile (production)
- Implement XOR validation: exactly one password source required
- Add comprehensive API client integration (getUsers, createUser)
- Implement calculate/apply pattern for user management
- Add sops-nix integration support for secure secret management
- Wire user management into main configuration pipeline
- Add comprehensive test coverage (15 config + 13 mapper + 12 apply tests)
- Fix API client test coverage gaps (encoding, branding, users endpoints)
- Improve root config test coverage and remove duplicates
- Update documentation with security best practices
Closes#12Closes#13
This implements comprehensive integration testing infrastructure to validate
jellarr's declarative behavior against real Jellyfin instances.
## Key Features
- **NixOS VM test framework**: Uses pkgs.testers.runNixOSTest for isolated testing
- **Automated Jellyfin setup**: Fresh instances with API key injection via SQLite
- **Data-driven test registration**: Add tests by updating simple list
- **IT1 implementation**: Validates enableMetrics preservation when omitted
- **Scalable architecture**: Clean separation with base.nix and setup.py utilities
## Architecture
- `nix/tests/integration/default.nix` - Test registry with data-driven approach
- `nix/tests/integration/base.nix` - Common VM configuration
- `nix/tests/integration/setup.py` - Reusable Python utilities
- `nix/tests/integration/it1.nix` - First integration test (enableMetrics preservation)
- `treefmt.nix` - Added Python black formatter integration
Tests run via `nix flake check` with 600-second timeout for complex VM operations.
Foundation ready for IT2-IT10 covering all declarative behavior scenarios.
Resolves#8
- Replace all ReturnType<typeof z.url> with z.ZodURL in config types
- Replace all ReturnType<typeof createClient<paths>> with Client<paths>
- Add ApiResponse<T> interface and specific response types in jellyfin.types.ts
- Remove all 8 eslint-disable-next-line @typescript-eslint/typedef instances
- Add proper explicit type annotations for all API client methods
- Improve type safety and maintainability across API client layer
All 251 tests passing, TypeScript compilation clean, ESLint validation passing
- Publishes bundle.cjs instead of Nix binary wrapper
- Updates instructions to use 'node jellarr-v*.cjs'
- This actually works on non-Nix systems unlike the binary
- Updated README to reflect new approach
Back to the original working approach that published just the
jellarr binary wrapper which worked on non-Nix systems.
Removes the complex .cjs/.sh splitting approach.
Reverted to working release workflow that publishes both:
- bundle.cjs (the JavaScript bundle)
- wrapper script (for Node.js execution)
This fixes the broken binary release introduced in da02434.
- Fix release date to 2025-11-17 (correct year)
- Update GitHub release workflow to include usage instructions and changelog
- Preserve installation instructions while adding changelog content