Skip to content

Add Helm chart for deployment#492

Open
Doezer wants to merge 53 commits into
mainfrom
helm-chart
Open

Add Helm chart for deployment#492
Doezer wants to merge 53 commits into
mainfrom
helm-chart

Conversation

@Doezer
Copy link
Copy Markdown
Owner

@Doezer Doezer commented Mar 28, 2026

This pull request introduces a new Helm chart for the questarr application, enabling Kubernetes-based deployment and configuration. The chart includes templates for deployment, service, ingress, persistent storage, secrets management, and customizable values, providing a comprehensive and flexible way to run questarr in Kubernetes environments.

The most important changes are:

Helm Chart Introduction and Structure:

  • Added a new Helm chart for questarr with all standard chart files, including Chart.yaml for metadata and values.yaml for configurable parameters. [1] [2]
  • Added Helm chart helper templates in _helpers.tpl to standardize naming, labels, and secret references.

Kubernetes Manifests:

  • Added deployment template (deployment.yaml) for managing the questarr application pods, with support for environment variables, probes, persistent storage, and secret injection.
  • Added service template (service.yaml) for exposing the application within the cluster, and ingress template (ingress.yaml) for optional external access with TLS and host/path configuration. [1] [2]
  • Added PVC template (pvc.yaml) to manage persistent storage for application data, configurable via values.
  • Added secret template (secret.yaml) for securely managing sensitive environment variables, with support for user-provided or auto-generated secrets.

User Guidance and Quality-of-life:

  • Added a NOTES.txt template to provide post-install instructions and access information for users deploying the chart.
  • Updated .prettierignore to exclude the helm/ directory from formatting.

Doezer and others added 30 commits March 15, 2026 09:16
…#398)

Bumps the dev-dependencies group with 1 update: [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).

Updates `typescript-eslint` from 8.54.0 to 8.55.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.55.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.55.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [dotenv](https://github.com/motdotla/dotenv) from 17.2.4 to 17.3.1.
- [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md)
- [Commits](motdotla/dotenv@v17.2.4...v17.3.1)

---
updated-dependencies:
- dependency-name: dotenv
  dependency-version: 17.3.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 0.563.0 to 0.564.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/0.564.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 0.564.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* 🛡️ Sentinel: [HIGH] Fix SSRF DNS Rebinding vulnerability

- Modified `server/ssrf.ts` to check ALL resolved IP addresses using `dns.lookup({ all: true })`.
- Updated `safeFetch` to reject requests if any resolved IP is unsafe.
- Added regression test in `server/__tests__/ssrf.test.ts` for mixed safe/unsafe IPs.

Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>

* chore: address PR review feedback on SSRF DNS empty array and XSS fix

* test: add utils.test.ts and fallback for DOM in safeUrl

* chore: typing fixes to resolve linting warnings in test files

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>
* feat: server-side filtering for user games

Optimizes the fetching of user games by implementing server-side filtering for game statuses. This reduces the payload size for the Library and Wishlist pages, which previously fetched all games and filtered them on the client.

- Updates `IStorage` and implementations to support `statuses` array in `getUserGames`.
- Updates `GET /api/games` to parse `status` query parameter.
- Updates `LibraryPage` and `WishlistPage` to request specific statuses.
- Ensures backward compatibility for existing callers.

Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>

* feat: server-side filtering for user games

Optimizes the fetching of user games by implementing server-side filtering for game statuses. This reduces the payload size for the Library and Wishlist pages.

- Updates `IStorage` and implementations to support `statuses` array in `getUserGames`.
- Updates `GET /api/games` to parse `status` query parameter.
- Updates `LibraryPage` and `WishlistPage` to request specific statuses.
- Adds comprehensive tests for storage implementations and API routes.

Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>

* Fix status parameter parsing for arrays and add tests

* Fix typescript and lint errors in server tests

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>
* feat(client): enhance accessibility with dynamic aria-labels

- Update `GameCard` and `CompactGameCard` to use dynamic aria-labels including game titles for actions (Download, View details, Hide/Unhide).
- Update `AddGameModal` to use dynamic aria-labels for "Add" buttons in search results.
- Add `aria-live="polite"` to `AddGameModal` search results container for better screen reader feedback.
- Add `client/__tests__/Accessibility.test.tsx` to verify accessibility improvements.
- Add `.jules/palette.md` to document accessibility learnings.
* Shield: Prevent SSRF in RSS feeds by validating URLs

- Add `isSafeUrl` validation to `POST /api/rss/feeds` and `PUT /api/rss/feeds/:id`
- Add defense-in-depth `isSafeUrl` check in `server/rss.ts` `refreshFeed`
- Add regression tests in `server/__tests__/rss-ssrf.test.ts`
- Document vulnerability in `.jules/sentinel.md`

Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>

* Shield: Prevent SSRF in RSS feeds by validating URLs

- Add `isSafeUrl` validation to `POST /api/rss/feeds` and `PUT /api/rss/feeds/:id`
- Add defense-in-depth `isSafeUrl` check in `server/rss.ts` `refreshFeed`
- Add regression tests in `server/__tests__/rss-ssrf.test.ts`
- Fix `server/__tests__/rss.test.ts` to mock `isSafeUrl`
- Document vulnerability in `.jules/sentinel.md`

Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>

* Rebase, adressing pr comments

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>
* ⚡ Bolt: Optimize game update cron job with batch DB updates

💡 What: Refactored checkGameUpdates in server/cron.ts to collect updates and execute them in a single batch transaction using storage.updateGamesBatch. Also consolidated notification logic.
🎯 Why: Prevents N+1 database transaction overhead when checking for game updates, especially for large libraries. SQLite performance is sensitive to transaction overhead.
📊 Impact: Reduces database transactions from O(N) to O(1) for the update phase. Improves scalability.
🔬 Measurement: Verified with new test server/__tests__/cron_updates.test.ts which confirms updates are batched.

Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>

* fix(cron): batch notification DB insertions and use fake timers in tests

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>
…optionally (#394)

* feat: allow disabling auto-search for unreleased games
This pull request introduces a new statistics feature for the game library, including a dedicated statistics page, reusable stats calculation logic, and UI enhancements. The main changes are the addition of a robust stats utility, integration of the stats page into the app navigation, updates to the dashboard to use the new stats logic, and comprehensive tests to ensure correctness.
* feat: Implement core game data integrations with IGDB and Steam, backend services, database schema, and essential client UI.
…t, missing brute-force protection (#415)

* Fix security vulnerabilities: credential exposure, brute force, session secret, x-forwarded-proto injection
* Remove redundant authenticateToken from /api/settings/igdb routes (already covered by global middleware)
* Fix linting errors & test coverage related to server/steam-routes.ts & routes.ts
* Fix sesson refreshing when reloading page

* fix(auth): avoid logout on transient /me failures
…#428)

* Updates to the steam algo
* Fix steam sync success toast
* Remove Steam sign in and API key. Remove passport usage
* Updates regarding new IGDB API changes
* log: added game info to steam sync response
* Harden Steam sync and restore route coverage
…m main (#425)

* Switch version check from package.json on main to GitHub Releases API
* Improve version check API error diagnostics
* feat(ui): add contextual aria-labels to game cards
Added dynamic `aria-label` attributes to action buttons in `GameCard` and `CompactGameCard`.
Updated tests to verify accessibility improvements.
* ⚡ Bolt: Lazy load game details and download dialogs

Optimizes initial bundle size and load performance by lazy loading heavy interactive components (`GameDetailsModal` and `GameDownloadDialog`) within `GameCard` and `CompactGameCard`.
…log serialization (#436)

* Fix Transmission error reporting and pino error logging
* Harden Transmission error parsing and add regression tests
* feat(security): sanitize internal error details in production

- Moved global error handler to `server/middleware.ts` for testability and reuse.
- Updated `errorHandler` to sanitize 500 error messages to "Internal Server Error" when `NODE_ENV` is production.
- Replaced `throw err` with `expressLogger` logging to prevent crashes/double-logging.
- Added regression test `server/__tests__/security_error_handling.test.ts` to verify production vs development behavior.

This prevents leaking sensitive database or stack trace information to clients in production environments.

Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>

* fix(security): refactor routes to use centralized error handler

- Updated multiple routes in `server/routes.ts` to use `next(error)` instead of manual `res.status(500)` calls, ensuring errors are sanitized by the new middleware.
- Manually sanitized error messages in `api/downloaders/storage` and `api/downloads` where errors are returned as part of a JSON array.
- This addresses PR feedback regarding consistent usage of the error handler and preventing information leakage.

Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>

* chore: acknowledge logging comment

- Reply to PR review acknowledging that the error sanitizer correctly retains full, unsanitized stack traces and original error messages in the server logs (`expressLogger`).

Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* test: raise patch coverage for error sanitization changes

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…, add autosearch tests (#438)

* Update game update notifications to trigger only on owned games
* Refactor ownedGames & wantedGames paths in checkAutoSearch
* Add tests for autosearch
* Refactor auto-search matching and stabilize cron tests
* Refresh download search cache when indexers change and add manual clear button in Maintenance
* Extract clearSearchCache into shared queryClient utility
* Invalidate enabled indexer cache after mutations
Doezer and others added 16 commits March 17, 2026 10:05
…nloaders setup (#472)

* fix: downloadPath not used for rTorrent + remove path from usenet downloaders setup

* test(rtorrent): mock parse-torrent to fix downloadPath test assertions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(igdb): paginate platform retrieval for complete results
* refactor(igdb): extract processPlatforms helper to remove duplication
* Update settings page to full width
* Simplify migrate.ts
* chore: update package dependencies
* fix: handle string errors in getErrorText for migration error detection
The version service fetches from api.github.com client-side, but it
was blocked by the Content Security Policy connect-src directive.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Initial plan

* Add GitHub link with version info to login page

Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Doezer/Questarr/sessions/5783c409-fcab-437f-8b13-a3e9cd7baaad

* Update client/src/pages/auth/login.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update client/src/pages/auth/login.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update client/src/pages/auth/login.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Extract GitHubVersionLink shared component to avoid duplication

Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Doezer/Questarr/sessions/83fa7b03-0864-43cc-a758-f527eb9f4874

* Fix sonar smell

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Doezer <11655673+Doezer@users.noreply.github.com>
Co-authored-by: Doezer <doezerx@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* refacto: extract steam sync UI logic
* refacto: extract helper functions from syncUserSteamWishlist
* test(steam-sync): add regression tests for cron.ts helper fixes
* test(steam-sync): add branch coverage for syncUserSteamWishlist paths
* test(steam-sync): add coverage for empty wishlist and partial IGDB responses
…ces (#480)

* Sanitize URL, password, and username fields from trailing spaces
* Fix login route: validate username/password are strings before trimming
* Improve routes.ts coverage: add tests for PATCH /api/auth/password and GET /api/ready
* Fix SonarCloud duplication, security hotspot, and Copilot review comments
- Extract trimIfString helper in shared/schema.ts to eliminate 4 duplicate
  nullable-aware trim transforms (resolves SonarCloud duplication report)
- Add backward-compatible login: try raw password before trimmed to avoid
  locking out users whose stored hash predates trimming (security hotspot)
- Improve login type-guard error message to cover both missing and non-string
  inputs ("required and must be strings")
- Log trimmedUsername (not raw username) in setup route to match persisted value

* Remove duplicate user mock objects and suppress SonarCloud false positive
- Extract mockUserHashed and mockUserOldHash constants in api_routes.test.ts,
  replacing 5 identical inline object literals across login and password tests
- Add NOSONAR comment on private IP assertion in middleware.test.ts to suppress
  SonarCloud security hotspot on intentional test data
…rols (#484)

* feat: add download indicators, hasDownloads filter, and shared view controls

- Visual download status dot on GameCard (overlay) and CompactGameCard (inline):
  blue=downloading (pulse), emerald=completed, amber=paused, red=failed
  with tooltip showing count and download type (torrent/usenet)
- New GET /api/downloads/summary endpoint with storage-layer aggregation
  using priority-based status resolution (failed > downloading > paused > completed)
- useDownloadSummary React Query hook (60s stale/refetch, invalidated on mutations)
- hasDownloads filter toggle on Library and Wishlist pages
- Extract shared useViewControls hook + ViewControlsToolbar component,
  replacing duplicated density/view code in library.tsx and wishlist.tsx
- Extract getReleaseStatus() to client/src/lib/game-utils.ts, removing
  the duplicate definition from both card components
- 11 new test files covering all new logic (628 tests total, all passing)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add search results available indicator and filter

When the auto-search cron finds indexer results for a wanted game, sets
searchResultsAvailable=true on the game. Resets to false when a download
is initiated. Surfaces as a violet Search icon badge on game cards (overlay
on grid view, inline on compact list) and a filter toggle on Library and
Wishlist pages.

- Add searchResultsAvailable boolean to games table (migration 0007)
- updateGameSearchResultsAvailable() storage method (MemStorage + DatabaseStorage)
- cron.ts: set flag on "Game Available" and "Multiple Results Found" results
- routes.ts: clear flag when download is initiated for a game
- SearchResultsBadge component (violet, Search icon, overlay + inline variants)
- Wire into GameCard and CompactGameCard via game.searchResultsAvailable
- hasSearchResults filter on Library and Wishlist pages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: address review feedback and sync with release/1.3.0

- Remove test-report.junit.xml from tracking; add *.junit.xml to .gitignore
- Use fake timers in game-utils.test.ts for deterministic date-based tests
- Move getDownloadSummaryByGame aggregation to SQL layer (GROUP BY + CASE/group_concat)
- Add NOSONAR suppression for test-only JWT secret in auth.test.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: improve patch coverage for PR #484 changes

- ViewControlsToolbar: mock Radix dropdown, add density menu item click tests
- use-view-controls: add fallback tests for invalid stored values
- database_storage_integration: add getDownloadSummaryByGame SQL aggregation test
- PagesHiddenWiring: add filter button tests (hasDownloads, searchResults) for LibraryPage
- cron_autosearch: add updateGameSearchResultsAvailable mock + coverage tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix Sonar smells

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@Doezer Doezer added this to the 1.4.0 milestone Mar 28, 2026
@Doezer Doezer added this to Questarr Mar 28, 2026
@github-project-automation github-project-automation Bot moved this to Backlog in Questarr Mar 28, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new Helm chart for the Questarr application, including templates for deployment, service, ingress, and persistence. Feedback focuses on preventing database corruption by restricting the replica count when using SQLite, improving the robustness of the LoadBalancer IP retrieval in the deployment notes, and enhancing security by providing a default random JWT secret. Additionally, it is recommended to include a maintainer email in the chart metadata and remove misleading commented-out environment variables.

Comment thread helm/questarr/templates/deployment.yaml
Comment thread helm/questarr/values.yaml
Comment thread helm/questarr/templates/NOTES.txt
Comment thread helm/questarr/Chart.yaml
Comment thread helm/questarr/templates/secret.yaml Outdated
Comment thread helm/questarr/values.yaml Outdated
@Doezer Doezer moved this from Backlog to In progress in Questarr Mar 29, 2026
…Balancer hostname, cleanup

- Add template fail guard when replicaCount > 1 with persistence enabled (SQLite limitation)
- Add prominent warning comment in values.yaml about the same constraint
- Remove misleading commented IGDB env vars from env section (they belong under secret)
- Auto-generate a random 64-char JWT secret when none is provided (randAlphaNum 64)
- Fix LoadBalancer IP/hostname detection in NOTES.txt to handle hostname-only ingress
- Add maintainer GitHub URL to Chart.yaml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

{{- end }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:

Check warning

Code scanning / SonarCloud

Service account permissions should be restricted Medium

Bind this resource's automounted service account to RBAC or disable automounting. See more on SonarQube Cloud
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}

Check warning

Code scanning / SonarCloud

Memory limits should be enforced Medium

Specify a memory limit for this container. See more on SonarQube Cloud
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}

Check warning

Code scanning / SonarCloud

Storage limits should be enforced Medium

Specify a storage limit for this container. See more on SonarQube Cloud
Base automatically changed from release/1.3.0 to main April 26, 2026 09:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

3 participants