Compare commits
17 Commits
fallenbage
...
preview-se
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8325986bf | ||
|
|
2123c1d0e9 | ||
|
|
c37ea8d8e2 | ||
|
|
6969f503ab | ||
|
|
86724a3067 | ||
|
|
ad1d8c1b0d | ||
|
|
199c6729a5 | ||
|
|
5b87b6fd8d | ||
|
|
8ab2731736 | ||
|
|
3b8f0076a1 | ||
|
|
d7b5be4bad | ||
|
|
33f1e01650 | ||
|
|
925247833f | ||
|
|
8c20223df6 | ||
|
|
442128a2de | ||
|
|
5d0f9ce30a | ||
|
|
f96dd64bf9 |
@@ -16,7 +16,6 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 'warn', // disable the rule for now to replicate previous behavior
|
||||
'@typescript-eslint/camelcase': 0,
|
||||
'@typescript-eslint/no-use-before-define': 0,
|
||||
'jsx-a11y/no-noninteractive-tabindex': 0,
|
||||
|
||||
13
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -1,7 +1,6 @@
|
||||
name: 🐛 Bug Report
|
||||
description: Report a problem
|
||||
labels: ['awaiting triage']
|
||||
type: bug
|
||||
labels: ['bug', 'awaiting triage']
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -92,19 +91,11 @@ body:
|
||||
attributes:
|
||||
label: Additional Context
|
||||
description: Please provide any additional information that may be relevant or helpful.
|
||||
- type: checkboxes
|
||||
id: search-existing
|
||||
attributes:
|
||||
label: Search Existing Issues
|
||||
description: Have you searched existing issues to see if this bug has already been reported?
|
||||
options:
|
||||
- label: Yes, I have searched existing issues.
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/seerr-team/seerr/blob/develop/CODE_OF_CONDUCT.md)
|
||||
description: By submitting this issue, you agree to follow our [Code of Conduct](/../../CODE_OF_CONDUCT.md)
|
||||
options:
|
||||
- label: I agree to follow Seerr's Code of Conduct
|
||||
required: true
|
||||
|
||||
63
.github/ISSUE_TEMPLATE/documentation.yml
vendored
@@ -1,63 +0,0 @@
|
||||
name: 📚 Documentation
|
||||
description: Report a docs problem or suggest a docs improvement
|
||||
title: "[Docs]: "
|
||||
labels: ["documentation", "awaiting triage"]
|
||||
type: task
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for helping improve the docs!
|
||||
|
||||
Use this template for documentation issues (typos, unclear steps, missing info, outdated screenshots).
|
||||
For app bugs or feature ideas, please use the other templates.
|
||||
- type: input
|
||||
id: doc-location
|
||||
attributes:
|
||||
label: Page / Location
|
||||
description: Link to the docs page or the file/path (e.g. https://docs.seerr.dev/... or README.md)
|
||||
placeholder: "https://docs.seerr.dev/..."
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: doc-area
|
||||
attributes:
|
||||
label: Docs Area
|
||||
options:
|
||||
- docs site
|
||||
- migration guide
|
||||
- README / repo docs
|
||||
- API / integrations
|
||||
- other
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: What’s wrong / missing?
|
||||
description: Describe the issue in the docs.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: suggested-fix
|
||||
attributes:
|
||||
label: Suggested change
|
||||
description: If you know what should be changed, describe it (or paste proposed wording).
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
id: search-existing
|
||||
attributes:
|
||||
label: Search Existing Issues
|
||||
description: Have you searched existing issues to see if this has already been reported?
|
||||
options:
|
||||
- label: Yes, I have searched existing issues.
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: By submitting this issue, you agree to follow our Code of Conduct.
|
||||
options:
|
||||
- label: I agree to follow Seerr's [Code of Conduct](https://github.com/seerr-team/seerr/blob/develop/CODE_OF_CONDUCT.md).
|
||||
required: true
|
||||
11
.github/ISSUE_TEMPLATE/enhancement.yml
vendored
@@ -1,7 +1,6 @@
|
||||
name: ✨ Feature Request
|
||||
description: Suggest an idea
|
||||
labels: ['awaiting triage']
|
||||
type: feature
|
||||
labels: ['enhancement', 'awaiting triage']
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -28,14 +27,6 @@ body:
|
||||
attributes:
|
||||
label: Additional Context
|
||||
description: Provide any additional information or screenshots that may be relevant or helpful.
|
||||
- type: checkboxes
|
||||
id: search-existing
|
||||
attributes:
|
||||
label: Search Existing Issues
|
||||
description: Have you searched existing issues to see if this feature has already been requested?
|
||||
options:
|
||||
- label: Yes, I have searched existing issues.
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
|
||||
65
.github/ISSUE_TEMPLATE/maintenance.yml
vendored
@@ -1,65 +0,0 @@
|
||||
name: 🧰 Maintenance / Chore
|
||||
description: CI, GitHub Actions, build, dependencies, refactors (non-feature work)
|
||||
title: "[Chore]: "
|
||||
labels: ["maintenance", "awaiting triage"]
|
||||
type: task
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Maintainers / contributors: use this for internal tasks (CI, workflows, tooling, refactors).
|
||||
If you're reporting a user-facing bug or requesting a feature, use the other templates.
|
||||
- type: dropdown
|
||||
id: area
|
||||
attributes:
|
||||
label: Area
|
||||
options:
|
||||
- CI / GitHub Actions
|
||||
- build / packaging
|
||||
- dependencies
|
||||
- release process
|
||||
- refactor / tech debt
|
||||
- tooling / scripts
|
||||
- other
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: summary
|
||||
attributes:
|
||||
label: Summary
|
||||
description: What needs doing and why?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: acceptance
|
||||
attributes:
|
||||
label: Acceptance criteria
|
||||
description: What does "done" look like?
|
||||
placeholder: |
|
||||
- [ ] ...
|
||||
- [ ] ...
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: related
|
||||
attributes:
|
||||
label: Related links
|
||||
description: PRs, failing workflow runs, logs, or relevant issues.
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
id: search-existing
|
||||
attributes:
|
||||
label: Search Existing Issues
|
||||
description: Have you searched existing issues to see if this has already been reported?
|
||||
options:
|
||||
- label: Yes, I have searched existing issues.
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: By submitting this issue, you agree to follow our Code of Conduct.
|
||||
options:
|
||||
- label: I agree to follow Seerr's [Code of Conduct](https://github.com/seerr-team/seerr/blob/develop/CODE_OF_CONDUCT.md).
|
||||
required: true
|
||||
35
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,33 +1,14 @@
|
||||
<!--
|
||||
Please read contributing guide before submitting
|
||||
your pull request. Please fill in each section below to help us better prioritize your pull request. Thanks!
|
||||
-->
|
||||
#### Description
|
||||
|
||||
## Description
|
||||
#### Screenshot (if UI-related)
|
||||
|
||||
<!--- Describe your changes in detail -->
|
||||
<!--- Why is this change required? What problem does it solve? -->
|
||||
<!--- If it fixes an open issue, please link to the issue here. -->
|
||||
#### To-Dos
|
||||
|
||||
- Fixes #XXXX
|
||||
|
||||
## How Has This Been Tested?
|
||||
|
||||
<!--- Please describe in detail how you tested your changes. -->
|
||||
<!--- Include details of your testing environment, and the tests you ran to -->
|
||||
<!--- see how your change affects other areas of the code, etc. -->
|
||||
|
||||
## Screenshots / Logs (if applicable)
|
||||
|
||||
## Checklist:
|
||||
|
||||
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||
|
||||
- [ ] I have read and followed the contribution [guidelines](https://github.com/seerr-team/seerr/blob/develop/CONTRIBUTING.md).
|
||||
- [ ] Disclosed any use of AI (see our [policy](https://github.com/seerr-team/seerr/blob/develop/CONTRIBUTING.md#ai-assistance-notice))
|
||||
- [ ] I have updated the documentation accordingly.
|
||||
- [ ] All new and existing tests passed.
|
||||
- [ ] Disclosed any use of AI (see our [policy](../CONTRIBUTING.md#ai-assistance-notice))
|
||||
- [ ] Successful build `pnpm build`
|
||||
- [ ] Translation keys `pnpm i18n:extract`
|
||||
- [ ] Database migration (if required)
|
||||
|
||||
#### Issues Fixed or Closed
|
||||
|
||||
- Fixes #XXXX
|
||||
|
||||
94
.github/cliff.toml
vendored
@@ -1,94 +0,0 @@
|
||||
# git-cliff ~ configuration
|
||||
# https://git-cliff.org/docs/configuration
|
||||
|
||||
[changelog]
|
||||
header = ""
|
||||
body = """
|
||||
{%- macro remote_url() -%}
|
||||
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- set excluded_users = ["github-actions[bot]", "dependabot[bot]", "renovate[bot]"] -%}
|
||||
|
||||
{% macro print_commit(commit) -%}
|
||||
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
|
||||
{% if commit.breaking %}[**breaking**] {% endif %}\
|
||||
{{ commit.message | upper_first }} - \
|
||||
([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\
|
||||
{% endmacro -%}
|
||||
|
||||
{% if version %}\
|
||||
{% if previous.version %}\
|
||||
## [{{ version | trim_start_matches(pat="v") }}]({{ self::remote_url() }}/compare/{{ previous.version }}..{{ version }}) - {{ timestamp | date(format="%Y-%m-%d") }}
|
||||
{% else %}\
|
||||
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
|
||||
{% endif %}\
|
||||
{% else %}\
|
||||
## [unreleased]
|
||||
{% endif %}\
|
||||
|
||||
{%- for group, commits in commits | group_by(attribute="group") %}
|
||||
### {{ group | striptags | trim | upper_first }}
|
||||
{%- for commit in commits | filter(attribute="scope") | sort(attribute="scope") %}
|
||||
{{ self::print_commit(commit=commit) }}
|
||||
{%- endfor %}
|
||||
{%- for commit in commits %}
|
||||
{%- if not commit.scope %}
|
||||
{{ self::print_commit(commit=commit) }}
|
||||
{%- endif %}
|
||||
{%- endfor -%}
|
||||
{%- endfor -%}
|
||||
|
||||
{%- set valid_contributors = [] -%}
|
||||
{%- for c in github.contributors | filter(attribute="is_first_time", value=true) %}
|
||||
{%- if c.username and c.username not in excluded_users and c.username not in valid_contributors %}
|
||||
{%- set_global valid_contributors = valid_contributors | concat(with=c.username) %}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
|
||||
{%- if valid_contributors | length > 0 %}
|
||||
## New Contributors ❤️
|
||||
{%- for username in valid_contributors %}
|
||||
* @{{ username }} made their first contribution
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
"""
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
trim = true
|
||||
postprocessors = []
|
||||
|
||||
[git]
|
||||
conventional_commits = true
|
||||
filter_unconventional = true
|
||||
split_commits = false
|
||||
filter_commits = true
|
||||
commit_preprocessors = [
|
||||
{ pattern = '.*\[skip ci\].*', replace = "" },
|
||||
{ pattern = '.*\[ci skip\].*', replace = "" },
|
||||
]
|
||||
commit_parsers = [
|
||||
{ message = "^feat", group = "<!-- 0 -->🚀 Features" },
|
||||
{ message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
|
||||
{ message = "^doc", group = "<!-- 3 -->📖 Documentation" },
|
||||
{ message = "^perf", group = "<!-- 4 -->⚡ Performance" },
|
||||
{ message = "^refactor", group = "<!-- 2 -->🚜 Refactor" },
|
||||
{ message = "^style", group = "<!-- 5 -->🎨 Styling" },
|
||||
{ message = "^test", group = "<!-- 6 -->🧪 Testing" },
|
||||
{ message = "^chore\\(release\\): prepare for", skip = true },
|
||||
{ message = "^chore\\(deps.*\\)", skip = true },
|
||||
{ message = "^chore\\(pr\\)", skip = true },
|
||||
{ message = "^chore\\(pull\\)", skip = true },
|
||||
{ message = "^chore\\(git-sync\\)", skip = true },
|
||||
{ message = "^chore|^ci", group = "<!-- 7 -->⚙️ Miscellaneous Tasks" },
|
||||
{ body = ".*security", group = "<!-- 8 -->🛡️ Security" },
|
||||
{ message = "^revert", group = "<!-- 9 -->◀️ Revert" },
|
||||
{ message = '.*\[skip ci\].*', skip = true },
|
||||
{ message = '.*\[ci skip\].*', skip = true },
|
||||
]
|
||||
protect_breaking_commits = false
|
||||
tag_pattern = "v?[0-9]+\\.[0-9]+\\.[0-9]+.*"
|
||||
skip_tags = "beta|alpha|rc"
|
||||
topo_order = false
|
||||
sort_commits = "newest"
|
||||
2
.github/renovate/helm.json5
vendored
@@ -16,7 +16,7 @@
|
||||
description: 'Update appVersion in Chart.yaml to match Docker image',
|
||||
fileMatch: ['(^|/)Chart\\.yaml$'],
|
||||
matchStrings: [
|
||||
"#\\s+renovate:\\s+image=(?<depName>\\S*)\nappVersion:\\s+'(?<currentValue>\\S*)'",
|
||||
'#\\s+renovate:\\s+image=(?<depName>\\S*)\nappVersion:\\s+"(?<currentValue>\\S*)"',
|
||||
],
|
||||
datasourceTemplate: 'docker',
|
||||
},
|
||||
|
||||
91
.github/workflows/ci.yml
vendored
@@ -14,91 +14,24 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
DOCKER_HUB: seerr/seerr
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
group: ci-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
i18n:
|
||||
name: i18n Check
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
NUMBER: ${{ github.event.pull_request.number }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Pnpm Setup
|
||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: bash
|
||||
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Install dependencies
|
||||
env:
|
||||
CI: true
|
||||
run: pnpm install
|
||||
|
||||
- name: i18n Check
|
||||
shell: bash
|
||||
env:
|
||||
I18N_LABEL: i18n-out-of-sync
|
||||
BODY: |
|
||||
The i18n check failed because translation messages are out of sync.
|
||||
|
||||
This usually happens when you've added or modified translation strings in your code but haven't updated the translation file.
|
||||
|
||||
Please run `pnpm i18n:extract` and commit the changes.
|
||||
run: |
|
||||
retry() { n=0; until "$@"; do n=$((n+1)); [ $n -ge 3 ] && break; echo "retry $n: $*" >&2; sleep 2; done; }
|
||||
check_failed=0; node bin/check-i18n.js || check_failed=$?
|
||||
pr_labels=$(gh pr view "$NUMBER" -R "$GH_REPO" --json labels -q '.labels[].name' 2>/dev/null) || true
|
||||
has_label=0
|
||||
while IFS= read -r name; do [ -n "$name" ] && [ "$name" = "$I18N_LABEL" ] && has_label=1 && break; done <<< "$pr_labels"
|
||||
if [ "$check_failed" -eq 1 ]; then
|
||||
[ "$has_label" -eq 0 ] && { retry gh pr edit "$NUMBER" -R "$GH_REPO" --add-label "$I18N_LABEL" || true; retry gh pr comment "$NUMBER" -R "$GH_REPO" -b "$BODY" || true; }
|
||||
else
|
||||
[ "$has_label" -eq 1 ] && retry gh pr edit "$NUMBER" -R "$GH_REPO" --remove-label "$I18N_LABEL" || true
|
||||
fi
|
||||
exit $check_failed
|
||||
test:
|
||||
name: Lint & Test Build
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-24.04
|
||||
container: node:22.22.0-alpine3.22@sha256:0c49915657c1c77c64c8af4d91d2f13fe96853bbd957993ed00dd592cbecc284
|
||||
container: node:22.20.0-alpine3.22@sha256:cb3143549582cc5f74f26f0992cdef4a422b22128cb517f94173a5f910fa4ee7
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Pnpm Setup
|
||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: sh
|
||||
@@ -129,7 +62,7 @@ jobs:
|
||||
|
||||
build:
|
||||
name: Build (per-arch, native runners)
|
||||
if: github.ref == 'refs/heads/develop'
|
||||
if: github.ref == 'refs/heads/develop' && !contains(github.event.head_commit.message, '[skip ci]')
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@@ -142,7 +75,7 @@ jobs:
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -151,7 +84,7 @@ jobs:
|
||||
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
|
||||
- name: Warm cache (no push) — ${{ matrix.platform }}
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
@@ -178,7 +111,7 @@ jobs:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -187,7 +120,7 @@ jobs:
|
||||
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
@@ -204,10 +137,10 @@ jobs:
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
|
||||
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||
with:
|
||||
images: |
|
||||
${{ env.DOCKER_HUB }}
|
||||
${{ github.repository }}
|
||||
ghcr.io/${{ github.repository }}
|
||||
tags: |
|
||||
type=raw,value=develop
|
||||
@@ -237,7 +170,7 @@ jobs:
|
||||
discord:
|
||||
name: Send Discord Notification
|
||||
needs: publish
|
||||
if: always() && github.event_name != 'pull_request'
|
||||
if: always() && github.event_name != 'pull_request' && !contains(github.event.head_commit.message, '[skip ci]')
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Determine Workflow Status
|
||||
|
||||
10
.github/workflows/codeql.yml
vendored
@@ -20,7 +20,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
group: codeql-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -37,20 +37,20 @@ jobs:
|
||||
language: [actions, javascript]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
|
||||
uses: github/codeql-action/init@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
|
||||
uses: github/codeql-action/autobuild@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
|
||||
uses: github/codeql-action/analyze@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
|
||||
with:
|
||||
category: '/language:${{ matrix.language }}'
|
||||
|
||||
2
.github/workflows/conflict_labeler.yml
vendored
@@ -14,7 +14,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
group: merge-conflict-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
87
.github/workflows/create-tag.yml
vendored
@@ -1,87 +0,0 @@
|
||||
---
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
||||
name: Create tag
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
determine-tag-version:
|
||||
name: Determine tag version
|
||||
if: github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
tag_version: ${{ steps.git-cliff.outputs.tag_version }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install git-cliff
|
||||
uses: taiki-e/install-action@cede0bb282aae847dfa8aacca3a41c86d973d4d7 # v2.68.1
|
||||
with:
|
||||
tool: git-cliff
|
||||
|
||||
- name: Get tag version
|
||||
id: git-cliff
|
||||
run: |
|
||||
tag_version=$(git-cliff -c .github/cliff.toml --bumped-version --unreleased)
|
||||
echo "Next tag version is ${tag_version}"
|
||||
echo "tag_version=${tag_version}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
create-tag:
|
||||
name: Create tag
|
||||
if: github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: write
|
||||
needs: determine-tag-version
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAG_VERSION: ${{ needs.determine-tag-version.outputs.tag_version }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
ssh-key: '${{ secrets.COMMIT_KEY }}'
|
||||
|
||||
- name: Pnpm Setup
|
||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version-file: 'package.json'
|
||||
# For workflows with elevated privileges we recommend disabling automatic caching.
|
||||
# https://github.com/actions/setup-node
|
||||
package-manager-cache: false
|
||||
|
||||
- name: Configure git
|
||||
run: |
|
||||
git config --global user.name "${{ github.actor }}"
|
||||
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
|
||||
|
||||
- name: Bump package.json
|
||||
run: npm version ${TAG_VERSION} --no-commit-hooks --no-git-tag-version
|
||||
|
||||
- name: Commit updated files
|
||||
run: |
|
||||
git add package.json
|
||||
git commit -m 'chore(release): prepare ${TAG_VERSION}'
|
||||
git push
|
||||
|
||||
- name: Create git tag
|
||||
run: |
|
||||
git tag ${TAG_VERSION}
|
||||
git push origin ${TAG_VERSION}
|
||||
8
.github/workflows/cypress.yml
vendored
@@ -28,7 +28,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
group: cypress-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
package-manager-cache: false
|
||||
|
||||
- name: Pnpm Setup
|
||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
run: pnpm exec cypress install
|
||||
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@f790eee7a50d9505912f50c2095510be7de06aa7 # v6.10.9
|
||||
uses: cypress-io/github-action@b8ba51a856ba5f4c15cf39007636d4ab04f23e3c # v6.10.2
|
||||
with:
|
||||
install: false
|
||||
build: pnpm cypress:build
|
||||
|
||||
83
.github/workflows/detect-duplicate.yml
vendored
@@ -1,83 +0,0 @@
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
||||
name: Duplicate Issue Detector
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
permissions: {}
|
||||
|
||||
env:
|
||||
EMBEDDING_MODEL: ${{ vars.EMBEDDING_MODEL }}
|
||||
GROQ_MODEL: ${{ vars.GROQ_MODEL }}
|
||||
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
|
||||
|
||||
jobs:
|
||||
detect-duplicate:
|
||||
runs-on: ubuntu-24.04
|
||||
if: ${{ !github.event.issue.pull_request }}
|
||||
permissions:
|
||||
issues: write
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
|
||||
- name: Pnpm Setup
|
||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: bash
|
||||
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: bin/duplicate-detector
|
||||
env:
|
||||
CI: true
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Download issue index
|
||||
uses: dawidd6/action-download-artifact@5c98f0b039f36ef966fdb7dfa9779262785ecb05 # v14
|
||||
with:
|
||||
name: issue-index
|
||||
workflow: rebuild-issue-index.yml
|
||||
path: bin/duplicate-detector
|
||||
search_artifacts: true
|
||||
if_no_artifact_found: warn
|
||||
|
||||
- name: Build index if missing
|
||||
working-directory: bin/duplicate-detector
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
INDEX_PATH: issue_index.json
|
||||
run: |
|
||||
if [ ! -f issue_index.json ]; then
|
||||
echo "No index found — building from scratch..."
|
||||
node build-index.mjs
|
||||
fi
|
||||
|
||||
- name: Detect duplicates
|
||||
working-directory: bin/duplicate-detector
|
||||
continue-on-error: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
||||
INDEX_PATH: issue_index.json
|
||||
run: node detect.mjs
|
||||
7
.github/workflows/docs-deploy.yml
vendored
@@ -3,7 +3,6 @@
|
||||
name: Deploy to GitHub Pages
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
@@ -15,7 +14,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
group: pages
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -23,7 +22,7 @@ jobs:
|
||||
name: Build Docusaurus
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
@@ -35,7 +34,7 @@ jobs:
|
||||
package-manager-cache: false
|
||||
|
||||
- name: Pnpm Setup
|
||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: sh
|
||||
|
||||
6
.github/workflows/docs-link-check.yml
vendored
@@ -25,7 +25,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
group: docs-link-check-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -36,13 +36,13 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Run Lychee link checker
|
||||
uses: lycheeverse/lychee-action@a8c4c7cb88f0c7386610c35eb25108e448569cb0 # v2.7.0
|
||||
uses: lycheeverse/lychee-action@885c65f3dc543b57c898c8099f4e08c8afd178a2 # v2.6.1
|
||||
with:
|
||||
fail: false
|
||||
args: >-
|
||||
|
||||
64
.github/workflows/helm.yml
vendored
@@ -14,7 +14,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
group: helm-charts
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
has_artifacts: ${{ steps.check-artifacts.outputs.has_artifacts }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
# get current version
|
||||
current_version=$(grep '^version:' "$chart_path/Chart.yaml" | awk '{print $2}')
|
||||
# try to get current release version
|
||||
if oras manifest fetch "ghcr.io/${{ github.repository }}/${chart_name}:${current_version}" >/dev/null 2>&1; then
|
||||
if oras manifest fetch "ghcr.io/${GITHUB_REPOSITORY@L}/${chart_name}:${current_version}" >/dev/null 2>&1; then
|
||||
echo "No version change for $chart_name. Skipping."
|
||||
else
|
||||
helm dependency build "$chart_path"
|
||||
@@ -87,13 +87,13 @@ jobs:
|
||||
name: Publish to ghcr.io
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
packages: write
|
||||
id-token: write
|
||||
packages: write # needed for pushing to github registry
|
||||
id-token: write # needed for signing the images with GitHub OIDC Token
|
||||
needs: [package-helm-chart]
|
||||
if: needs.package-helm-chart.outputs.has_artifacts == 'true'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
@@ -105,7 +105,7 @@ jobs:
|
||||
uses: oras-project/setup-oras@22ce207df3b08e061f537244349aac6ae1d214f6 # v1.2.4
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
|
||||
uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0
|
||||
|
||||
- name: Downloads artifacts
|
||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||
@@ -128,59 +128,17 @@ jobs:
|
||||
# push chart to OCI
|
||||
chart_release_file=$(basename "$chart_path")
|
||||
chart_name=${chart_release_file%-*}
|
||||
helm push ${chart_path} oci://ghcr.io/${{ github.repository }} |& tee helm-push-output.log
|
||||
helm push ${chart_path} oci://ghcr.io/${GITHUB_REPOSITORY@L} |& tee helm-push-output.log
|
||||
chart_digest=$(awk -F "[, ]+" '/Digest/{print $NF}' < helm-push-output.log)
|
||||
# sign chart
|
||||
cosign sign "ghcr.io/${{ github.repository }}/${chart_name}@${chart_digest}"
|
||||
cosign sign "ghcr.io/${GITHUB_REPOSITORY@L}/${chart_name}@${chart_digest}"
|
||||
# push artifacthub-repo.yml to OCI
|
||||
oras push \
|
||||
ghcr.io/${{ github.repository }}/${chart_name}:artifacthub.io \
|
||||
ghcr.io/${GITHUB_REPOSITORY@L}/${chart_name}:artifacthub.io \
|
||||
--config /dev/null:application/vnd.cncf.artifacthub.config.v1+yaml \
|
||||
charts/$chart_name/artifacthub-repo.yml:application/vnd.cncf.artifacthub.repository-metadata.layer.v1.yaml \
|
||||
|& tee oras-push-output.log
|
||||
artifacthub_digest=$(grep "Digest:" oras-push-output.log | awk '{print $2}')
|
||||
# sign artifacthub-repo.yml
|
||||
cosign sign "ghcr.io/${{ github.repository }}/${chart_name}:artifacthub.io@${artifacthub_digest}"
|
||||
done
|
||||
|
||||
verify:
|
||||
name: Verify signatures for each chart tag
|
||||
needs: [publish]
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
|
||||
|
||||
- name: Downloads artifacts
|
||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||
with:
|
||||
name: artifacts
|
||||
path: .cr-release-packages/
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Verify signatures for each chart tag
|
||||
run: |
|
||||
for chart_path in $(find .cr-release-packages -name '*.tgz' -print); do
|
||||
chart_release_file=$(basename "$chart_path")
|
||||
chart_name=${chart_release_file%-*}
|
||||
version=${chart_release_file#$chart_name-}
|
||||
version=${version%.tgz}
|
||||
|
||||
cosign verify "ghcr.io/${{ github.repository }}/${chart_name}:${version}" \
|
||||
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
cosign sign "ghcr.io/${GITHUB_REPOSITORY@L}/${chart_name}:artifacthub.io@${artifacthub_digest}"
|
||||
done
|
||||
|
||||
6
.github/workflows/lint-helm-charts.yml
vendored
@@ -18,7 +18,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
group: charts-lint-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
|
||||
|
||||
- name: Set up chart-testing
|
||||
uses: helm/chart-testing-action@6ec842c01de15ebb84c8627d2744a0c2f2755c9f # v2.8.0
|
||||
uses: helm/chart-testing-action@0d28d3144d3a25ea2cc349d6e59901c4ff469b3b # v2.7.0
|
||||
|
||||
- name: Ensure documentation is updated
|
||||
uses: docker://jnorwood/helm-docs:v1.14.2@sha256:7e562b49ab6b1dbc50c3da8f2dd6ffa8a5c6bba327b1c6335cc15ce29267979c
|
||||
|
||||
17
.github/workflows/preview.yml
vendored
@@ -11,11 +11,8 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
DOCKER_HUB: seerr/seerr
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
group: preview-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -33,7 +30,7 @@ jobs:
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -42,7 +39,7 @@ jobs:
|
||||
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
|
||||
- name: Derive preview version from tag
|
||||
id: ver
|
||||
@@ -79,7 +76,7 @@ jobs:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -88,7 +85,7 @@ jobs:
|
||||
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
@@ -115,10 +112,10 @@ jobs:
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
|
||||
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||
with:
|
||||
images: |
|
||||
${{ env.DOCKER_HUB }}
|
||||
${{ github.repository }}
|
||||
ghcr.io/${{ github.repository }}
|
||||
tags: |
|
||||
type=raw,value=preview-${{ steps.ver.outputs.version }}
|
||||
|
||||
65
.github/workflows/rebuild-issue-index.yml
vendored
@@ -1,65 +0,0 @@
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
||||
name: Rebuild Issue Index
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 3 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {}
|
||||
|
||||
env:
|
||||
EMBEDDING_MODEL: ${{ vars.EMBEDDING_MODEL }}
|
||||
|
||||
jobs:
|
||||
build-index:
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
issues: read
|
||||
actions: write
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
|
||||
- name: Pnpm Setup
|
||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: bash
|
||||
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: bin/duplicate-detector
|
||||
env:
|
||||
CI: true
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build issue index
|
||||
working-directory: bin/duplicate-detector
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
INDEX_PATH: issue_index.json
|
||||
run: node build-index.mjs
|
||||
|
||||
- name: Upload index artifact
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: issue-index
|
||||
path: bin/duplicate-detector/issue_index.json
|
||||
retention-days: 7
|
||||
265
.github/workflows/release.yml
vendored
@@ -3,65 +3,71 @@
|
||||
name: Seerr Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
group: release-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
DOCKER_HUB: seerr/seerr
|
||||
|
||||
jobs:
|
||||
changelog:
|
||||
name: Generate changelog
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
semantic-release:
|
||||
name: Tag and release latest version
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
HUSKY: 0
|
||||
outputs:
|
||||
release_body: ${{ steps.git-cliff.outputs.content }}
|
||||
new_release_published: ${{ steps.release.outputs.new_release_published }}
|
||||
new_release_version: ${{ steps.release.outputs.new_release_version }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Generate changelog
|
||||
id: git-cliff
|
||||
uses: orhun/git-cliff-action@e16f179f0be49ecdfe63753837f20b9531642772 # v4.7.0
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
config: .github/cliff.toml
|
||||
args: -vv --current
|
||||
env:
|
||||
OUTPUT: CHANGELOG.md
|
||||
GITHUB_REPO: ${{ github.repository }}
|
||||
node-version-file: package.json
|
||||
package-manager-cache: false
|
||||
|
||||
create-draft-release:
|
||||
name: Create draft release
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: write
|
||||
needs: changelog
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
- name: Pnpm Setup
|
||||
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: sh
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
path: ${{ env.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: Draft Release
|
||||
run: gh release create ${GITHUB_REF_NAME} -t "Release ${GITHUB_REF_NAME}" -n "${RELEASE_BODY}" --draft
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Release
|
||||
id: release
|
||||
uses: cycjimmy/semantic-release-action@9cc899c47e6841430bbaedb43de1560a568dfd16 # v5.0.0
|
||||
with:
|
||||
extra_plugins: |
|
||||
@semantic-release/git@10
|
||||
@semantic-release/changelog@6
|
||||
@codedependant/semantic-release-docker@5
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
RELEASE_BODY: ${{ needs.changelog.outputs.release_body }}
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
build:
|
||||
name: Build (${{ matrix.arch }})
|
||||
name: Build (per-arch, native runners)
|
||||
needs: semantic-release
|
||||
if: needs.semantic-release.outputs.new_release_published == 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@@ -72,11 +78,9 @@ jobs:
|
||||
platform: linux/arm64
|
||||
arch: arm64
|
||||
runs-on: ${{ matrix.runner }}
|
||||
env:
|
||||
VERSION: ${{ github.ref_name }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -85,9 +89,9 @@ jobs:
|
||||
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
|
||||
- name: Warm cache [${{ matrix.platform }}]
|
||||
- name: Warm cache (no push) — ${{ matrix.platform }}
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
with:
|
||||
context: .
|
||||
@@ -96,26 +100,24 @@ jobs:
|
||||
push: false
|
||||
build-args: |
|
||||
COMMIT_TAG=${{ github.sha }}
|
||||
BUILD_VERSION=${{ env.VERSION }}
|
||||
BUILD_VERSION=${{ needs.semantic-release.outputs.new_release_version }}
|
||||
SOURCE_DATE_EPOCH=${{ steps.ts.outputs.TIMESTAMP }}
|
||||
cache-from: type=gha,scope=${{ matrix.platform }}
|
||||
cache-to: type=gha,mode=max,scope=${{ matrix.platform }}
|
||||
provenance: false
|
||||
|
||||
publish:
|
||||
name: Publish multi-arch manifests
|
||||
needs: build
|
||||
name: Publish multi-arch image
|
||||
needs: [semantic-release, build]
|
||||
if: needs.semantic-release.outputs.new_release_published == 'true'
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
packages: write
|
||||
outputs:
|
||||
image_digest: ${{ steps.digests.outputs.IMAGE_DIGEST }}
|
||||
env:
|
||||
VERSION: ${{ github.ref_name }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -124,7 +126,7 @@ jobs:
|
||||
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
@@ -141,17 +143,17 @@ jobs:
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
|
||||
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||
with:
|
||||
images: |
|
||||
${{ env.DOCKER_HUB }}
|
||||
${{ github.repository }}
|
||||
ghcr.io/${{ github.repository }}
|
||||
tags: |
|
||||
type=raw,value=${{ env.VERSION }}
|
||||
type=raw,value=${{ needs.semantic-release.outputs.new_release_version }}
|
||||
labels: |
|
||||
org.opencontainers.image.created=${{ steps.ts.outputs.TIMESTAMP }}
|
||||
|
||||
- name: Build & Push (multi-arch)
|
||||
- name: Build & Push (multi-arch, single tag)
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
with:
|
||||
context: .
|
||||
@@ -160,7 +162,7 @@ jobs:
|
||||
push: true
|
||||
build-args: |
|
||||
COMMIT_TAG=${{ github.sha }}
|
||||
BUILD_VERSION=${{ env.VERSION }}
|
||||
BUILD_VERSION=${{ needs.semantic-release.outputs.new_release_version }}
|
||||
SOURCE_DATE_EPOCH=${{ steps.ts.outputs.TIMESTAMP }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
@@ -170,158 +172,37 @@ jobs:
|
||||
cache-to: type=gha,mode=max
|
||||
provenance: false
|
||||
|
||||
- name: Resolve manifest digest
|
||||
id: digests
|
||||
run: |
|
||||
DIGEST=$(docker buildx imagetools inspect "${{ env.DOCKER_HUB }}:${{ env.VERSION }}" --format '{{json .Manifest.Digest}}' | tr -d '"')
|
||||
echo "IMAGE_DIGEST=$DIGEST" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Also tag :latest (non-pre-release only)
|
||||
shell: bash
|
||||
if: ${{ !contains(env.VERSION, '-') }}
|
||||
run: |
|
||||
docker buildx imagetools create \
|
||||
-t ${{ env.DOCKER_HUB }}:latest \
|
||||
${{ env.DOCKER_HUB }}:${{ env.VERSION }}
|
||||
|
||||
docker buildx imagetools create \
|
||||
-t ghcr.io/${{ github.repository }}:latest \
|
||||
ghcr.io/${{ github.repository }}:${{ env.VERSION }}
|
||||
|
||||
sign:
|
||||
name: Sign images and create SBOM attestations
|
||||
needs: publish
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
packages: write
|
||||
env:
|
||||
VERSION: ${{ github.ref_name }}
|
||||
COSIGN_YES: 'true'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
|
||||
|
||||
- name: Install Trivy
|
||||
uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 # v0.2.5
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Sign images
|
||||
run: |
|
||||
cosign sign --recursive "ghcr.io/${{ github.repository }}@${{ needs.publish.outputs.image_digest }}"
|
||||
cosign sign --recursive "${{ env.DOCKER_HUB }}@${{ needs.publish.outputs.image_digest }}"
|
||||
|
||||
- name: Generate SBOMs
|
||||
run: |
|
||||
trivy image --format cyclonedx --output seerr-ghcr-image-${{ env.VERSION }}.sbom \
|
||||
"ghcr.io/${{ github.repository }}@${{ needs.publish.outputs.image_digest }}"
|
||||
|
||||
trivy image --format cyclonedx --output seerr-dockerhub-image-${{ env.VERSION }}.sbom \
|
||||
"${{ env.DOCKER_HUB }}@${{ needs.publish.outputs.image_digest }}"
|
||||
|
||||
- name: Attest SBOMs
|
||||
run: |
|
||||
cosign attest \
|
||||
--type cyclonedx \
|
||||
--predicate seerr-ghcr-image-${{ env.VERSION }}.sbom \
|
||||
"ghcr.io/${{ github.repository }}@${{ needs.publish.outputs.image_digest }}"
|
||||
|
||||
cosign attest \
|
||||
--type cyclonedx \
|
||||
--predicate seerr-dockerhub-image-${{ env.VERSION }}.sbom \
|
||||
"${{ env.DOCKER_HUB }}@${{ needs.publish.outputs.image_digest }}"
|
||||
|
||||
- name: Upload SBOMs
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: sboms-${{ env.VERSION }}
|
||||
path: '*.sbom'
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
verify:
|
||||
name: Verify signatures and attestations
|
||||
needs: [publish, sign]
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
env:
|
||||
VERSION: ${{ github.ref_name }}
|
||||
steps:
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
|
||||
|
||||
- name: Verify signatures
|
||||
run: |
|
||||
cosign verify "ghcr.io/${{ github.repository }}@${{ needs.publish.outputs.image_digest }}" \
|
||||
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
|
||||
cosign verify "${{ env.DOCKER_HUB }}@${{ needs.publish.outputs.image_digest }}" \
|
||||
--certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
|
||||
# - name: Verify attestations
|
||||
# run: |
|
||||
# cosign verify-attestation "ghcr.io/${{ github.repository }}@${{ needs.publish.outputs.image_digest }}" \
|
||||
# --type cyclonedx \
|
||||
# --certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
# --certificate-oidc-issuer "https://token.actions.githubusercontent.com" > /dev/null
|
||||
|
||||
# cosign verify-attestation "${{ env.DOCKER_HUB }}@${{ needs.publish.outputs.image_digest }}" \
|
||||
# --type cyclonedx \
|
||||
# --certificate-identity "https://github.com/${{ github.workflow_ref }}" \
|
||||
# --certificate-oidc-issuer "https://token.actions.githubusercontent.com" > /dev/null
|
||||
|
||||
publish-release:
|
||||
name: Publish release
|
||||
needs: [create-draft-release, verify]
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: write
|
||||
env:
|
||||
VERSION: ${{ github.ref_name }}
|
||||
steps:
|
||||
- name: Publish release
|
||||
run: gh release edit "${{ env.VERSION }}" --draft=false --repo "${{ github.repository }}"
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
VER="${{ needs.semantic-release.outputs.new_release_version }}"
|
||||
if [[ "$VER" != *"-"* ]]; then
|
||||
docker buildx imagetools create \
|
||||
-t ${{ github.repository }}:latest \
|
||||
${{ github.repository }}:${VER}
|
||||
docker buildx imagetools create \
|
||||
-t ghcr.io/${{ github.repository }}:latest \
|
||||
ghcr.io/${{ github.repository }}:${VER}
|
||||
fi
|
||||
|
||||
discord:
|
||||
name: Send Discord Notification
|
||||
needs: publish-release
|
||||
needs: publish
|
||||
if: always()
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Determine status
|
||||
- name: Determine Workflow Status
|
||||
id: status
|
||||
run: |
|
||||
case "${{ needs.publish-release.result }}" in
|
||||
case "${{ needs.publish.result }}" in
|
||||
success) echo "status=Success" >> $GITHUB_OUTPUT; echo "colour=3066993" >> $GITHUB_OUTPUT ;;
|
||||
failure) echo "status=Failure" >> $GITHUB_OUTPUT; echo "colour=15158332" >> $GITHUB_OUTPUT ;;
|
||||
cancelled) echo "status=Cancelled" >> $GITHUB_OUTPUT; echo "colour=10181046" >> $GITHUB_OUTPUT ;;
|
||||
*) echo "status=Skipped" >> $GITHUB_OUTPUT; echo "colour=9807270" >> $GITHUB_OUTPUT ;;
|
||||
esac
|
||||
|
||||
- name: Send notification
|
||||
- name: Send Discord notification
|
||||
shell: bash
|
||||
run: |
|
||||
WEBHOOK="${{ secrets.DISCORD_WEBHOOK }}"
|
||||
|
||||
@@ -336,7 +217,7 @@ jobs:
|
||||
{ "name": "Event", "value": "${{ github.event_name }}", "inline": true },
|
||||
{ "name": "Triggered by", "value": "${{ github.actor }}", "inline": true },
|
||||
{ "name": "Workflow", "value": "[${{ github.workflow }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})", "inline": true }
|
||||
]
|
||||
],
|
||||
}]
|
||||
}
|
||||
EOF
|
||||
|
||||
181
.github/workflows/renovate-helm-custom-hooks.yml
vendored
@@ -1,181 +0,0 @@
|
||||
---
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
||||
name: Renovate Helm Hooks
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- develop
|
||||
paths:
|
||||
- 'charts/**'
|
||||
|
||||
permissions: {}
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
renovate-post-run:
|
||||
name: Renovate Bump Chart Version
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
if: github.actor == 'renovate[bot]'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: 2138788
|
||||
private-key: ${{ secrets.APP_SEERR_HELM_PRIVATE_KEY }}
|
||||
|
||||
- name: Set up chart-testing
|
||||
uses: helm/chart-testing-action@6ec842c01de15ebb84c8627d2744a0c2f2755c9f # v2.8.0
|
||||
|
||||
- name: Run chart-testing (list-changed)
|
||||
id: list-changed
|
||||
run: |
|
||||
changed="$(ct list-changed --target-branch ${TARGET_BRANCH})"
|
||||
if [[ -n "$changed" ]]; then
|
||||
echo "changed=true" >> "$GITHUB_OUTPUT"
|
||||
echo "changed_list=${changed//$'\n'/ }" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
env:
|
||||
TARGET_BRANCH: ${{ github.event.repository.default_branch }}
|
||||
|
||||
- name: Bump chart version
|
||||
if: steps.list-changed.outputs.changed == 'true'
|
||||
env:
|
||||
CHART: ${{ steps.list-changed.outputs.changed_list }}
|
||||
run: |
|
||||
if [[ ! -d "${CHART}" ]]; then
|
||||
echo "${CHART} directory not found"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Extract current appVersion and chart version from Chart.yaml
|
||||
APP_VERSION=$(grep -e "^appVersion:" "$CHART/Chart.yaml" | cut -d ":" -f 2 | tr -d '[:space:]' | tr -d '"')
|
||||
CHART_VERSION=$(grep -e "^version:" "$CHART/Chart.yaml" | cut -d ":" -f 2 | tr -d '[:space:]' | tr -d '"')
|
||||
|
||||
# Extract major, minor and patch versions of appVersion
|
||||
APP_MAJOR_VERSION=$(printf '%s' "$APP_VERSION" | cut -d "." -f 1)
|
||||
APP_MINOR_VERSION=$(printf '%s' "$APP_VERSION" | cut -d "." -f 2)
|
||||
APP_PATCH_VERSION=$(printf '%s' "$APP_VERSION" | cut -d "." -f 3)
|
||||
|
||||
# Extract major, minor and patch versions of chart version
|
||||
CHART_MAJOR_VERSION=$(printf '%s' "$CHART_VERSION" | cut -d "." -f 1)
|
||||
CHART_MINOR_VERSION=$(printf '%s' "$CHART_VERSION" | cut -d "." -f 2)
|
||||
CHART_PATCH_VERSION=$(printf '%s' "$CHART_VERSION" | cut -d "." -f 3)
|
||||
|
||||
# Get previous appVersion from the base commit of the pull request
|
||||
BASE_COMMIT=$(git merge-base origin/main HEAD)
|
||||
PREV_APP_VERSION=$(git show "$BASE_COMMIT":"$CHART/Chart.yaml" | grep -e "^appVersion:" | cut -d ":" -f 2 | tr -d '[:space:]' | tr -d '"')
|
||||
|
||||
# Extract major, minor and patch versions of previous appVersion
|
||||
PREV_APP_MAJOR_VERSION=$(printf '%s' "$PREV_APP_VERSION" | cut -d "." -f 1)
|
||||
PREV_APP_MINOR_VERSION=$(printf '%s' "$PREV_APP_VERSION" | cut -d "." -f 2)
|
||||
PREV_APP_PATCH_VERSION=$(printf '%s' "$PREV_APP_VERSION" | cut -d "." -f 3)
|
||||
|
||||
# Check if the major, minor, or patch version of appVersion has changed
|
||||
if [[ "$APP_MAJOR_VERSION" != "$PREV_APP_MAJOR_VERSION" ]]; then
|
||||
# Bump major version of the chart and reset minor and patch versions to 0
|
||||
CHART_MAJOR_VERSION=$((CHART_MAJOR_VERSION+1))
|
||||
CHART_MINOR_VERSION=0
|
||||
CHART_PATCH_VERSION=0
|
||||
elif [[ "$APP_MINOR_VERSION" != "$PREV_APP_MINOR_VERSION" ]]; then
|
||||
# Bump minor version of the chart and reset patch version to 0
|
||||
CHART_MINOR_VERSION=$((CHART_MINOR_VERSION+1))
|
||||
CHART_PATCH_VERSION=0
|
||||
elif [[ "$APP_PATCH_VERSION" != "$PREV_APP_PATCH_VERSION" ]]; then
|
||||
# Bump patch version of the chart
|
||||
CHART_PATCH_VERSION=$((CHART_PATCH_VERSION+1))
|
||||
fi
|
||||
|
||||
# Update the chart version in Chart.yaml
|
||||
CHART_NEW_VERSION="${CHART_MAJOR_VERSION}.${CHART_MINOR_VERSION}.${CHART_PATCH_VERSION}"
|
||||
sed -i "s/^version:.*/version: ${CHART_NEW_VERSION}/" "$CHART/Chart.yaml"
|
||||
|
||||
- name: Ensure documentation is updated
|
||||
if: steps.list-changed.outputs.changed == 'true'
|
||||
uses: docker://jnorwood/helm-docs:v1.14.2@sha256:7e562b49ab6b1dbc50c3da8f2dd6ffa8a5c6bba327b1c6335cc15ce29267979c
|
||||
|
||||
- name: Commit changes
|
||||
if: steps.list-changed.outputs.changed == 'true'
|
||||
env:
|
||||
CHART: ${{ steps.list-changed.outputs.changed_list }}
|
||||
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
GITHUB_HEAD_REF: ${{ github.head_ref }}
|
||||
run: |
|
||||
# Define the target directory
|
||||
TARGET_DIR="$CHART"
|
||||
|
||||
# Fetch deleted files in the target directory
|
||||
DELETED_FILES=$(git diff --diff-filter=D --name-only HEAD -- "$TARGET_DIR")
|
||||
|
||||
# Fetch added/modified files in the target directory
|
||||
MODIFIED_FILES=$(git diff --diff-filter=ACM --name-only HEAD -- "$TARGET_DIR")
|
||||
|
||||
# Create a temporary file for JSON output
|
||||
FILE_CHANGES_JSON_FILE=$(mktemp)
|
||||
|
||||
# Initialize JSON structure in the file
|
||||
echo '{ "deletions": [], "additions": [] }' > "$FILE_CHANGES_JSON_FILE"
|
||||
|
||||
# Add deletions
|
||||
for file in $DELETED_FILES; do
|
||||
jq --arg path "$file" '.deletions += [{"path": $path}]' "$FILE_CHANGES_JSON_FILE" > "$FILE_CHANGES_JSON_FILE.tmp"
|
||||
mv "$FILE_CHANGES_JSON_FILE.tmp" "$FILE_CHANGES_JSON_FILE"
|
||||
done
|
||||
|
||||
# Add additions (new or modified files)
|
||||
for file in $MODIFIED_FILES; do
|
||||
BASE64_CONTENT=$(base64 -w 0 <"$file") # Encode file content
|
||||
jq --arg path "$file" --arg content "$BASE64_CONTENT" \
|
||||
'.additions += [{"path": $path, "contents": $content}]' "$FILE_CHANGES_JSON_FILE" > "$FILE_CHANGES_JSON_FILE.tmp"
|
||||
mv "$FILE_CHANGES_JSON_FILE.tmp" "$FILE_CHANGES_JSON_FILE"
|
||||
done
|
||||
|
||||
# Create a temporary file for the final JSON payload
|
||||
JSON_PAYLOAD_FILE=$(mktemp)
|
||||
|
||||
# Construct the final JSON using jq and store it in a file
|
||||
jq -n --arg repo "$GITHUB_REPOSITORY" \
|
||||
--arg branch "$GITHUB_HEAD_REF" \
|
||||
--arg message "fix: post upgrade changes from renovate" \
|
||||
--arg expectedOid "$GITHUB_SHA" \
|
||||
--slurpfile fileChanges "$FILE_CHANGES_JSON_FILE" \
|
||||
'{
|
||||
query: "mutation ($input: CreateCommitOnBranchInput!) {
|
||||
createCommitOnBranch(input: $input) {
|
||||
commit {
|
||||
url
|
||||
}
|
||||
}
|
||||
}",
|
||||
variables: {
|
||||
input: {
|
||||
branch: {
|
||||
repositoryNameWithOwner: $repo,
|
||||
branchName: $branch
|
||||
},
|
||||
message: { headline: $message },
|
||||
fileChanges: $fileChanges[0],
|
||||
expectedHeadOid: $expectedOid
|
||||
}
|
||||
}
|
||||
}' > "$JSON_PAYLOAD_FILE"
|
||||
|
||||
# Call GitHub API
|
||||
curl https://api.github.com/graphql -f \
|
||||
-sSf -H "Authorization: Bearer $GITHUB_TOKEN" \
|
||||
--data "@$JSON_PAYLOAD_FILE"
|
||||
|
||||
# Clean up temporary files
|
||||
rm "$FILE_CHANGES_JSON_FILE" "$JSON_PAYLOAD_FILE"
|
||||
111
.github/workflows/seerr-labeller.yml
vendored
@@ -1,111 +0,0 @@
|
||||
---
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
||||
name: 'Seerr Labeller'
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [labeled, unlabeled, reopened]
|
||||
issues:
|
||||
types: [labeled, unlabeled, reopened]
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
ai-generated-support:
|
||||
if: >
|
||||
github.event_name == 'pull_request_target' &&
|
||||
(github.event.label.name == 'ai-generated' || (github.event.action == 'reopened' && contains(github.event.pull_request.labels.*.name, 'ai-generated')))
|
||||
runs-on: ubuntu-24.04
|
||||
concurrency:
|
||||
group: ai-generated-${{ github.event.pull_request.number }}
|
||||
cancel-in-progress: true
|
||||
permissions:
|
||||
pull-requests: write
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
NUMBER: ${{ github.event.pull_request.number }}
|
||||
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
|
||||
steps:
|
||||
- name: Label added, comment and close pull request
|
||||
if: github.event.action == 'labeled' && github.event.label.name == 'ai-generated'
|
||||
shell: bash
|
||||
env:
|
||||
BODY: >
|
||||
:wave: @${{ env.PR_AUTHOR }}, thank you for your contribution!
|
||||
|
||||
However, this pull request has been closed because it appears to contain a significant amount of AI-generated code without sufficient human review or supervision.
|
||||
|
||||
AI-generated code can often introduce subtle bugs, poor design patterns, or inconsistent styles that make long-term maintenance difficult and reduce overall code quality. For the sake of the project's future stability and readability, we require that all contributions meet our established coding standards and demonstrate clear developer oversight.
|
||||
|
||||
This pull request is also too large for effective human review. Please discuss with us on how to break down these changes into smaller, more focused PRs to ensure a thorough and efficient review process.
|
||||
If you'd like to revise and resubmit your changes with careful review and cleanup, we'd be happy to take another look.
|
||||
run: |
|
||||
retry() { n=0; until "$@"; do n=$((n+1)); [ $n -ge 3 ] && break; echo "retry $n: $*" >&2; sleep 2; done; }
|
||||
retry gh pr comment "$NUMBER" -R "$GH_REPO" -b "$BODY" || true
|
||||
retry gh pr close "$NUMBER" -R "$GH_REPO" || true
|
||||
gh pr lock "$NUMBER" -R "$GH_REPO" -r "spam" || true
|
||||
|
||||
- name: Label removed, reopen and unlock pull request
|
||||
if: github.event.action == 'unlabeled' && github.event.label.name == 'ai-generated'
|
||||
shell: bash
|
||||
run: |
|
||||
retry() { n=0; until "$@"; do n=$((n+1)); [ $n -ge 3 ] && break; echo "retry $n: $*" >&2; sleep 2; done; }
|
||||
retry gh pr reopen "$NUMBER" -R "$GH_REPO" || true
|
||||
gh pr unlock "$NUMBER" -R "$GH_REPO" || true
|
||||
|
||||
- name: Remove AI-generated label on manual reopen
|
||||
if: github.event.action == 'reopened'
|
||||
shell: bash
|
||||
run: |
|
||||
gh pr edit "$NUMBER" -R "$GH_REPO" --remove-label "ai-generated" || true
|
||||
gh pr unlock "$NUMBER" -R "$GH_REPO" || true
|
||||
|
||||
support:
|
||||
if: >
|
||||
github.event_name == 'issues' &&
|
||||
(github.event.label.name == 'support' ||
|
||||
(github.event.action == 'reopened' && contains(github.event.issue.labels.*.name, 'support')))
|
||||
runs-on: ubuntu-24.04
|
||||
concurrency:
|
||||
group: support-${{ github.event.issue.number }}
|
||||
cancel-in-progress: true
|
||||
permissions:
|
||||
issues: write
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
NUMBER: ${{ github.event.issue.number }}
|
||||
ISSUE_AUTHOR: ${{ github.event.issue.user.login }}
|
||||
steps:
|
||||
- name: Label added, comment and close issue
|
||||
if: github.event.action == 'labeled' && github.event.label.name == 'support'
|
||||
shell: bash
|
||||
env:
|
||||
BODY: >
|
||||
:wave: @${{ env.ISSUE_AUTHOR }}, we use the issue tracker exclusively
|
||||
for bug reports and feature requests. However, this issue appears
|
||||
to be a support request. Please use our support channels
|
||||
to get help with Seerr.
|
||||
|
||||
- [Discord](https://discord.gg/seerr)
|
||||
run: |
|
||||
retry() { n=0; until "$@"; do n=$((n+1)); [ $n -ge 3 ] && break; echo "retry $n: $*" >&2; sleep 2; done; }
|
||||
retry gh issue comment "$NUMBER" -R "$GH_REPO" -b "$BODY" || true
|
||||
retry gh issue close "$NUMBER" -R "$GH_REPO" || true
|
||||
gh issue lock "$NUMBER" -R "$GH_REPO" -r "off_topic" || true
|
||||
|
||||
- name: Label removed, reopen and unlock issue
|
||||
if: github.event.action == 'unlabeled' && github.event.label.name == 'support'
|
||||
shell: bash
|
||||
run: |
|
||||
retry() { n=0; until "$@"; do n=$((n+1)); [ $n -ge 3 ] && break; echo "retry $n: $*" >&2; sleep 2; done; }
|
||||
retry gh issue reopen "$NUMBER" -R "$GH_REPO" || true
|
||||
gh issue unlock "$NUMBER" -R "$GH_REPO" || true
|
||||
|
||||
- name: Remove support label on manual reopen
|
||||
if: github.event.action == 'reopened'
|
||||
shell: bash
|
||||
run: |
|
||||
gh issue edit "$NUMBER" -R "$GH_REPO" --remove-label "support" || true
|
||||
gh issue unlock "$NUMBER" -R "$GH_REPO" || true
|
||||
28
.github/workflows/semantic-pr.yml
vendored
@@ -1,28 +0,0 @@
|
||||
name: "Semantic PR"
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
permissions: {}
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: Validate PR Title
|
||||
runs-on: ubuntu-slim
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
checks: write
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
4
.github/workflows/stale.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
permissions: {}
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
group: close-stale-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1
|
||||
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
|
||||
with:
|
||||
any-of-labels: "pending author's response"
|
||||
exempt-issue-labels: 'confirmed'
|
||||
|
||||
58
.github/workflows/support.yml
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
||||
name: 'Support requests'
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled, unlabeled, reopened]
|
||||
|
||||
permissions:
|
||||
issues: read
|
||||
|
||||
concurrency:
|
||||
group: support-${{ github.event.issue.number }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
support:
|
||||
if: github.event.label.name == 'support' || github.event.action == 'reopened'
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
issues: write
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
NUMBER: ${{ github.event.issue.number }}
|
||||
ISSUE_AUTHOR: ${{ github.event.issue.user.login }}
|
||||
steps:
|
||||
- name: Label added, comment and close issue
|
||||
if: github.event.action == 'labeled' && github.event.label.name == 'support'
|
||||
shell: bash
|
||||
env:
|
||||
BODY: >
|
||||
:wave: @${{ env.ISSUE_AUTHOR }}, we use the issue tracker exclusively
|
||||
for bug reports and feature requests. However, this issue appears
|
||||
to be a support request. Please use our support channels
|
||||
to get help with Seerr.
|
||||
|
||||
- [Discord](https://discord.gg/seerr)
|
||||
run: |
|
||||
retry() { n=0; until "$@"; do n=$((n+1)); [ $n -ge 3 ] && break; echo "retry $n: $*" >&2; sleep 2; done; }
|
||||
retry gh issue comment "$NUMBER" -R "$GH_REPO" -b "$BODY" || true
|
||||
retry gh issue close "$NUMBER" -R "$GH_REPO" || true
|
||||
gh issue lock "$NUMBER" -R "$GH_REPO" -r "off_topic" || true
|
||||
|
||||
- name: Reopened or label removed, unlock issue
|
||||
if: github.event.action == 'unlabeled' && github.event.label.name == 'support'
|
||||
shell: bash
|
||||
run: |
|
||||
retry() { n=0; until "$@"; do n=$((n+1)); [ $n -ge 3 ] && break; echo "retry $n: $*" >&2; sleep 2; done; }
|
||||
retry gh issue reopen "$NUMBER" -R "$GH_REPO" || true
|
||||
gh issue unlock "$NUMBER" -R "$GH_REPO" || true
|
||||
|
||||
- name: Remove support label on manual reopen
|
||||
if: github.event.action == 'reopened'
|
||||
shell: bash
|
||||
run: |
|
||||
gh issue edit "$NUMBER" -R "$GH_REPO" --remove-label "support" || true
|
||||
gh issue unlock "$NUMBER" -R "$GH_REPO" || true
|
||||
6
.github/workflows/test-docs-deploy.yml
vendored
@@ -14,7 +14,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
group: docs-pr-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
package-manager-cache: false
|
||||
|
||||
- name: Pnpm Setup
|
||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
|
||||
|
||||
- name: Get pnpm store directory
|
||||
shell: sh
|
||||
|
||||
6
.github/workflows/trivy-scan.yml
vendored
@@ -16,7 +16,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
group: trivy-scan-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
@@ -56,6 +56,6 @@ jobs:
|
||||
ignore-unfixed: true
|
||||
|
||||
- name: Upload SARIF to code scanning
|
||||
uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
|
||||
uses: github/codeql-action/upload-sarif@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
|
||||
with:
|
||||
sarif_file: trivy.sarif
|
||||
|
||||
3
.gitignore
vendored
@@ -71,6 +71,3 @@ tsconfig.tsbuildinfo
|
||||
|
||||
# Config Cache Directory
|
||||
config/cache
|
||||
|
||||
# Docker compose
|
||||
compose.override.yaml
|
||||
|
||||
@@ -2,19 +2,18 @@
|
||||
.next/
|
||||
dist/
|
||||
config/
|
||||
CHANGELOG.md
|
||||
pnpm-lock.yaml
|
||||
cypress/config/settings.cypress.json
|
||||
.github
|
||||
.vscode
|
||||
|
||||
# assets
|
||||
src/assets/
|
||||
docs/
|
||||
public/*
|
||||
public/
|
||||
!public/sw.js
|
||||
docs/
|
||||
!/public/
|
||||
/public/*
|
||||
!/public/sw.js
|
||||
|
||||
# helm charts
|
||||
**/charts
|
||||
|
||||
# Prettier breaks GitHub alert syntax in markdown
|
||||
*.md
|
||||
@@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: ['prettier-plugin-organize-imports', 'prettier-plugin-tailwindcss'],
|
||||
plugins: [require('./merged-prettier-plugin.js')],
|
||||
singleQuote: true,
|
||||
trailingComma: 'es5',
|
||||
overrides: [
|
||||
@@ -27,11 +27,5 @@ module.exports = {
|
||||
rangeEnd: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: 'public/offline.html',
|
||||
options: {
|
||||
rangeEnd: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
1216
CHANGELOG.md
Normal file
@@ -122,7 +122,7 @@ Steps:
|
||||
|
||||
- If you are taking on an existing bug or feature ticket, please comment on the [issue](/../../issues) to avoid multiple people working on the same thing.
|
||||
- All commits **must** follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
|
||||
- Pull requests with titles or commits not following this standard will **not** be merged. PR titles are automatically checked for compliance.
|
||||
- Pull requests with commits not following this standard will **not** be merged.
|
||||
- Please make meaningful commits, or squash them prior to opening a pull request.
|
||||
- Do not squash commits once people have begun reviewing your changes.
|
||||
- Always rebase your commit to the latest `develop` branch. Do **not** merge `develop` into your branch.
|
||||
@@ -151,9 +151,9 @@ When adding new UI text, please try to adhere to the following guidelines:
|
||||
|
||||
## Translation
|
||||
|
||||
We use [Weblate](https://translate.seerr.dev/projects/seerr/seerr-frontend/) for our translations, and your help with localizing Seerr would be greatly appreciated! If your language is not listed below, please [open a feature request](/../../issues/new/choose).
|
||||
We use [Weblate](https://jellyseerr.borgcube.de/projects/jellyseerr/jellyseerr-frontend/) for our translations, and your help with localizing Seerr would be greatly appreciated! If your language is not listed below, please [open a feature request](/../../issues/new/choose).
|
||||
|
||||
<a href="https://translate.seerr.dev/engage/seerr/"><img src="https://translate.seerr.dev/widget/seerr/multi-auto.svg" alt="Translation status" /></a>
|
||||
<a href="https://jellyseerr.borgcube.de/engage/jellysseerr/"><img src="https://jellyseerr.borgcube.de/widget/jellyseerr/multi-auto.svg" alt="Translation status" /></a>
|
||||
|
||||
## Migrations
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:22.22.0-alpine3.22@sha256:0c49915657c1c77c64c8af4d91d2f13fe96853bbd957993ed00dd592cbecc284 AS base
|
||||
FROM node:22.20.0-alpine3.22@sha256:cb3143549582cc5f74f26f0992cdef4a422b22128cb517f94173a5f910fa4ee7 AS base
|
||||
ARG SOURCE_DATE_EPOCH
|
||||
ARG TARGETPLATFORM
|
||||
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}
|
||||
@@ -13,10 +13,7 @@ WORKDIR /app
|
||||
FROM base AS prod-deps
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store CI=true pnpm install --prod --frozen-lockfile
|
||||
|
||||
FROM base AS build
|
||||
|
||||
ARG COMMIT_TAG
|
||||
ENV COMMIT_TAG=${COMMIT_TAG}
|
||||
FROM base as build
|
||||
|
||||
RUN \
|
||||
case "${TARGETPLATFORM}" in \
|
||||
@@ -33,7 +30,7 @@ RUN pnpm build
|
||||
|
||||
RUN rm -rf .next/cache
|
||||
|
||||
FROM node:22.22.0-alpine3.22@sha256:0c49915657c1c77c64c8af4d91d2f13fe96853bbd957993ed00dd592cbecc284
|
||||
FROM node:22.20.0-alpine3.22@sha256:cb3143549582cc5f74f26f0992cdef4a422b22128cb517f94173a5f910fa4ee7
|
||||
ARG SOURCE_DATE_EPOCH
|
||||
ARG COMMIT_TAG
|
||||
ENV NODE_ENV=production
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:22.22.0-alpine3.22@sha256:0c49915657c1c77c64c8af4d91d2f13fe96853bbd957993ed00dd592cbecc284
|
||||
FROM node:22.20.0-alpine3.22@sha256:cb3143549582cc5f74f26f0992cdef4a422b22128cb517f94173a5f910fa4ee7
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
|
||||
26
README.md
@@ -1,14 +1,14 @@
|
||||
<p align="center">
|
||||
<img src="./public/logo_full.svg" alt="Seerr" style="margin: 20px 0;">
|
||||
</p>
|
||||
<div align="center">⚠️ <strong>NOTE:</strong> We are currently in the process of merging Overseerr and Jellyseerr into this unified repository.</div>
|
||||
|
||||
<h1 align="center" style="font-size: 4em;">🚧 Seerr</h1>
|
||||
<p align="center">
|
||||
<img src="https://github.com/seerr-team/seerr/actions/workflows/release.yml/badge.svg" alt="Seerr Release" />
|
||||
<img src="https://github.com/seerr-team/seerr/actions/workflows/ci.yml/badge.svg" alt="Seerr CI">
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://discord.gg/seerr"><img src="https://img.shields.io/discord/783137440809746482" alt="Discord"></a>
|
||||
<a href="https://hub.docker.com/r/seerr/seerr"><img src="https://img.shields.io/docker/pulls/seerr/seerr" alt="Docker pulls"></a>
|
||||
<a href="https://translate.seerr.dev/engage/seerr/"><img src="https://translate.seerr.dev/widget/seerr/svg-badge.svg" alt="Translation status" /></a>
|
||||
<a href="https://hub.docker.com/r/fallenbagel/jellyseerr"><img src="https://img.shields.io/docker/pulls/fallenbagel/jellyseerr" alt="Docker pulls"></a>
|
||||
<a href="http://translate.jellyseerr.dev/engage/jellyseerr/"><img src="http://translate.jellyseerr.dev/widget/jellyseerr/jellyseerr-frontend/svg-badge.svg" alt="Translation status" /></a>
|
||||
<a href="https://github.com/seerr-team/seerr/blob/develop/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/seerr-team/seerr"></a>
|
||||
|
||||
**Seerr** is a free and open source software application for managing requests for your media library. It integrates with the media server of your choice: [Jellyfin](https://jellyfin.org), [Plex](https://plex.tv), and [Emby](https://emby.media/). In addition, it integrates with your existing services, such as **[Sonarr](https://sonarr.tv/)**, **[Radarr](https://radarr.video/)**.
|
||||
@@ -26,7 +26,7 @@
|
||||
- Granular permission system.
|
||||
- Support for various notification agents.
|
||||
- Mobile-friendly design, for when you need to approve requests on the go!
|
||||
- Support for watchlisting & blocklisting media.
|
||||
- Support for watchlisting & blacklisting media.
|
||||
|
||||
With more features on the way! Check out our [issue tracker](/../../issues) to see the features which have already been requested.
|
||||
|
||||
@@ -36,15 +36,15 @@ Check out our documentation for instructions on how to install and run Seerr:
|
||||
|
||||
https://docs.seerr.dev/getting-started/
|
||||
|
||||
### Packages:
|
||||
|
||||
Archlinux: [AUR](https://aur.archlinux.org/packages/jellyseerr)
|
||||
|
||||
Nix: [Nixpkg](https://search.nixos.org/packages?channel=unstable&show=jellyseerr)
|
||||
|
||||
## Preview
|
||||
|
||||
<img src="./public/preview.jpg" alt="Seerr application preview" />
|
||||
|
||||
## Migrating from Overseerr/Jellyseerr to Seerr
|
||||
|
||||
Read our [release announcement](https://docs.seerr.dev/blog/seerr-release) to learn what Seerr means for Jellyseerr and Overseerr users.
|
||||
|
||||
Please follow our [migration guide](https://docs.seerr.dev/migration-guide) for detailed instructions on migrating from Overseerr or Jellyseerr.
|
||||
<img src="./public/preview.jpg">
|
||||
|
||||
## Support
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Check that i18n locale files are in sync with extracted messages.
|
||||
* Runs `pnpm i18n:extract` and compares en.json; exits 1 if they differ.
|
||||
*/
|
||||
const { execSync } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const localePath = path.join(
|
||||
__dirname,
|
||||
'..',
|
||||
'src',
|
||||
'i18n',
|
||||
'locale',
|
||||
'en.json'
|
||||
);
|
||||
const backupPath = `${localePath}.bak`;
|
||||
|
||||
try {
|
||||
fs.copyFileSync(localePath, backupPath);
|
||||
execSync('pnpm i18n:extract', { stdio: 'inherit' });
|
||||
const original = fs.readFileSync(backupPath, 'utf8');
|
||||
const extracted = fs.readFileSync(localePath, 'utf8');
|
||||
fs.unlinkSync(backupPath);
|
||||
|
||||
if (original !== extracted) {
|
||||
console.error(
|
||||
"i18n messages are out of sync. Please run 'pnpm i18n:extract' and commit the changes."
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
} catch (err) {
|
||||
if (fs.existsSync(backupPath)) {
|
||||
fs.unlinkSync(backupPath);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
1
bin/duplicate-detector/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
node_modules/
|
||||
@@ -1,120 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Build Issue Embedding Index
|
||||
*
|
||||
* Fetches all open issues and recently closed ones,
|
||||
* generates embeddings using a local ONNX transformer model,
|
||||
* and saves them as a JSON artifact for the duplicate detector.
|
||||
*/
|
||||
|
||||
import { pipeline } from '@huggingface/transformers';
|
||||
import { mkdirSync, writeFileSync } from 'node:fs';
|
||||
import { dirname } from 'node:path';
|
||||
import { fetchIssues, issueText } from './utils.mjs';
|
||||
|
||||
const MODEL_NAME = process.env.EMBEDDING_MODEL || 'Xenova/all-MiniLM-L6-v2';
|
||||
const OUTPUT_PATH = 'issue_index.json';
|
||||
const INCLUDE_CLOSED_DAYS = 90;
|
||||
const MAX_ISSUES = 5000;
|
||||
const BATCH_SIZE = 64;
|
||||
|
||||
async function main() {
|
||||
console.log('Fetching open issues...');
|
||||
const openIssues = await fetchIssues({
|
||||
state: 'open',
|
||||
maxIssues: MAX_ISSUES,
|
||||
});
|
||||
console.log(`Fetched ${openIssues.length} open issues`);
|
||||
|
||||
const since = new Date(
|
||||
Date.now() - INCLUDE_CLOSED_DAYS * 24 * 60 * 60 * 1000
|
||||
).toISOString();
|
||||
console.log(
|
||||
`Fetching closed issues from last ${INCLUDE_CLOSED_DAYS} days...`
|
||||
);
|
||||
|
||||
const closedIssues = await fetchIssues({
|
||||
state: 'closed',
|
||||
since,
|
||||
maxIssues: MAX_ISSUES,
|
||||
});
|
||||
console.log(`Fetched ${closedIssues.length} closed issues`);
|
||||
let allIssues = [...openIssues, ...closedIssues];
|
||||
|
||||
const seen = new Set();
|
||||
allIssues = allIssues.filter((issue) => {
|
||||
if (seen.has(issue.number)) return false;
|
||||
seen.add(issue.number);
|
||||
return true;
|
||||
});
|
||||
|
||||
console.log(`Total unique issues to index: ${allIssues.length}`);
|
||||
|
||||
if (allIssues.length === 0) {
|
||||
console.warn('No issues found - writing empty index');
|
||||
writeFileSync(OUTPUT_PATH, JSON.stringify({ issues: [], embeddings: [] }));
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Loading model: ${MODEL_NAME}`);
|
||||
const extractor = await pipeline('feature-extraction', MODEL_NAME, {
|
||||
dtype: 'fp32',
|
||||
});
|
||||
|
||||
const texts = allIssues.map((issue) => issueText(issue.title, issue.body));
|
||||
const allEmbeddings = [];
|
||||
|
||||
console.log(`Generating embeddings for ${texts.length} issues...`);
|
||||
for (let i = 0; i < texts.length; i += BATCH_SIZE) {
|
||||
const batch = texts.slice(i, i + BATCH_SIZE);
|
||||
const output = await extractor(batch, {
|
||||
pooling: 'mean',
|
||||
normalize: true,
|
||||
});
|
||||
|
||||
const vectors = output.tolist();
|
||||
allEmbeddings.push(...vectors);
|
||||
|
||||
const progress = Math.min(i + BATCH_SIZE, texts.length);
|
||||
console.log(` ${progress}/${texts.length}`);
|
||||
}
|
||||
|
||||
const issueMetadata = allIssues.map((issue) => {
|
||||
const body = (issue.body || '').trim();
|
||||
return {
|
||||
number: issue.number,
|
||||
title: issue.title,
|
||||
state: issue.state,
|
||||
url: issue.html_url,
|
||||
body_preview: body.slice(0, 500) || '',
|
||||
labels: (issue.labels || []).map((l) => l.name),
|
||||
created_at: issue.created_at,
|
||||
updated_at: issue.updated_at,
|
||||
};
|
||||
});
|
||||
|
||||
const indexData = {
|
||||
issues: issueMetadata,
|
||||
embeddings: allEmbeddings,
|
||||
model: MODEL_NAME,
|
||||
issue_count: issueMetadata.length,
|
||||
built_at: new Date().toISOString(),
|
||||
};
|
||||
|
||||
const dir = dirname(OUTPUT_PATH);
|
||||
if (dir && dir !== '.') mkdirSync(dir, { recursive: true });
|
||||
writeFileSync(OUTPUT_PATH, JSON.stringify(indexData));
|
||||
|
||||
const sizeMb = (
|
||||
Buffer.byteLength(JSON.stringify(indexData)) /
|
||||
(1024 * 1024)
|
||||
).toFixed(1);
|
||||
console.log(
|
||||
`Index saved to ${OUTPUT_PATH} (${sizeMb} MB, ${issueMetadata.length} issues)`
|
||||
);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,274 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Duplicate Issue Detector
|
||||
*
|
||||
* Triggered on new issue creation. Compares the new issue against an
|
||||
* existing embedding index, then uses an LLM to
|
||||
* confirm duplicates before posting a comment for maintainer review.
|
||||
*/
|
||||
|
||||
import { pipeline } from '@huggingface/transformers';
|
||||
import { existsSync, readFileSync } from 'node:fs';
|
||||
import {
|
||||
addLabel,
|
||||
dotProduct,
|
||||
fetchIssues,
|
||||
getIssue,
|
||||
issueText,
|
||||
postComment,
|
||||
} from './utils.mjs';
|
||||
|
||||
const SIMILARITY_THRESHOLD = 0.55;
|
||||
const TOP_K = 5;
|
||||
const MAX_COMMENT_CANDIDATES = 3;
|
||||
const MODEL_NAME = process.env.EMBEDDING_MODEL || 'Xenova/all-MiniLM-L6-v2';
|
||||
const GROQ_MODEL = process.env.GROQ_MODEL || 'llama-3.3-70b-versatile';
|
||||
const INDEX_PATH = 'issue_index.json';
|
||||
const LABEL_NAME = 'possible-duplicate';
|
||||
|
||||
const GROQ_API_KEY = process.env.GROQ_API_KEY || '';
|
||||
const ISSUE_NUMBER = parseInt(process.env.ISSUE_NUMBER, 10);
|
||||
|
||||
function loadIndex(path) {
|
||||
if (!existsSync(path)) {
|
||||
console.error(
|
||||
`Index file not found at ${path}. Run build-index.mjs first.`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const data = JSON.parse(readFileSync(path, 'utf-8'));
|
||||
console.log(`Loaded index with ${data.issues.length} issues`);
|
||||
return data;
|
||||
}
|
||||
|
||||
function findSimilar(
|
||||
queryEmbedding,
|
||||
index,
|
||||
{ topK = TOP_K, threshold = SIMILARITY_THRESHOLD, excludeNumber } = {}
|
||||
) {
|
||||
const { issues, embeddings } = index;
|
||||
if (!issues.length) return [];
|
||||
|
||||
const scored = issues.map((issue, i) => ({
|
||||
...issue,
|
||||
score: dotProduct(queryEmbedding, embeddings[i]),
|
||||
}));
|
||||
|
||||
return scored
|
||||
.sort((a, b) => b.score - a.score)
|
||||
.filter(
|
||||
(c) =>
|
||||
c.score >= threshold && (!excludeNumber || c.number !== excludeNumber)
|
||||
)
|
||||
.slice(0, topK);
|
||||
}
|
||||
|
||||
const CONFIRM_SYSTEM_PROMPT = `You are a GitHub issue triage assistant. You will be given a NEW issue and one \
|
||||
or more CANDIDATE issues that may be duplicates.
|
||||
|
||||
For each candidate, determine if the new issue is truly a duplicate (same root \
|
||||
problem/request) or merely related (similar area but different issue).
|
||||
|
||||
Respond ONLY with a JSON array of objects, each with:
|
||||
- "number": the candidate issue number
|
||||
- "duplicate": true or false
|
||||
- "reason": one-sentence explanation
|
||||
|
||||
Example:
|
||||
[{"number": 123, "duplicate": true, "reason": "Both report the same crash when ..."}]`;
|
||||
|
||||
async function confirmWithLlm(newIssue, candidates) {
|
||||
if (!GROQ_API_KEY) {
|
||||
console.warn('GROQ_API_KEY not set — skipping LLM confirmation');
|
||||
return candidates;
|
||||
}
|
||||
|
||||
const candidateText = candidates
|
||||
.map(
|
||||
(c) =>
|
||||
`### Candidate #${c.number} (similarity: ${c.score.toFixed(2)})\n` +
|
||||
`**Title:** ${c.title}\n` +
|
||||
`**State:** ${c.state}\n` +
|
||||
`**Body preview:** ${(c.body_preview || 'N/A').slice(0, 500)}`
|
||||
)
|
||||
.join('\n\n');
|
||||
|
||||
const userPrompt =
|
||||
`## NEW ISSUE #${newIssue.number}\n` +
|
||||
`**Title:** ${newIssue.title}\n` +
|
||||
`**Body:**\n${(newIssue.body || 'No body').slice(0, 1500)}\n\n` +
|
||||
`---\n\n` +
|
||||
`## CANDIDATES\n${candidateText}`;
|
||||
|
||||
try {
|
||||
const resp = await fetch(
|
||||
'https://api.groq.com/openai/v1/chat/completions',
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${GROQ_API_KEY}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: GROQ_MODEL,
|
||||
messages: [
|
||||
{ role: 'system', content: CONFIRM_SYSTEM_PROMPT },
|
||||
{ role: 'user', content: userPrompt },
|
||||
],
|
||||
temperature: 0.1,
|
||||
max_tokens: 1024,
|
||||
}),
|
||||
signal: AbortSignal.timeout(30_000),
|
||||
}
|
||||
);
|
||||
|
||||
if (!resp.ok) {
|
||||
const text = await resp.text();
|
||||
throw new Error(`Groq API error ${resp.status}: ${text}`);
|
||||
}
|
||||
|
||||
let content = (await resp.json()).choices[0].message.content.trim();
|
||||
|
||||
if (content.startsWith('```')) {
|
||||
content = content
|
||||
.split('\n')
|
||||
.slice(1)
|
||||
.join('\n')
|
||||
.replace(/```\s*$/, '')
|
||||
.trim();
|
||||
}
|
||||
|
||||
const verdicts = JSON.parse(content);
|
||||
if (!Array.isArray(verdicts)) {
|
||||
throw new Error('Invalid LLM response format - expected array');
|
||||
}
|
||||
|
||||
const verdictMap = new Map(verdicts.map((v) => [v.number, v]));
|
||||
|
||||
const confirmed = [];
|
||||
for (const c of candidates) {
|
||||
const verdict = verdictMap.get(c.number);
|
||||
if (verdict?.duplicate) {
|
||||
c.llm_reason = verdict.reason || '';
|
||||
confirmed.push(c);
|
||||
} else {
|
||||
const reason = verdict?.reason || 'not evaluated';
|
||||
console.log(` #${c.number} ruled out by LLM: ${reason}`);
|
||||
}
|
||||
}
|
||||
|
||||
return confirmed;
|
||||
} catch (err) {
|
||||
console.warn(
|
||||
`LLM confirmation failed: ${err.message} - falling back to all candidates`
|
||||
);
|
||||
return candidates;
|
||||
}
|
||||
}
|
||||
|
||||
function formatComment(candidates) {
|
||||
const lines = [
|
||||
'**Possible duplicate detected**',
|
||||
'',
|
||||
'This issue may be a duplicate of the following (detected via semantic similarity + LLM review):',
|
||||
'',
|
||||
];
|
||||
|
||||
for (const c of candidates.slice(0, MAX_COMMENT_CANDIDATES)) {
|
||||
const confidence = `${(c.score * 100).toFixed(0)}%`;
|
||||
let line = `- #${c.number} (${confidence} match) — ${c.title}`;
|
||||
if (c.llm_reason) {
|
||||
line += `\n > *${c.llm_reason}*`;
|
||||
}
|
||||
lines.push(line);
|
||||
}
|
||||
|
||||
lines.push(
|
||||
'',
|
||||
'A maintainer will review this. If this is **not** a duplicate, no action is needed.',
|
||||
'',
|
||||
`<!-- duplicate-bot: candidates=${candidates.map((c) => c.number).join(',')} -->`
|
||||
);
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
async function main() {
|
||||
if (!ISSUE_NUMBER) {
|
||||
console.error('ISSUE_NUMBER not set');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Processing issue #${ISSUE_NUMBER}`);
|
||||
const issue = await getIssue(ISSUE_NUMBER);
|
||||
|
||||
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000).toISOString();
|
||||
const recentIssues = await fetchIssues({
|
||||
creator: issue.user.login,
|
||||
since: oneHourAgo,
|
||||
state: 'all',
|
||||
});
|
||||
|
||||
if (recentIssues.length > 10) {
|
||||
console.log(
|
||||
`User ${issue.user.login} created ${recentIssues.length} issues in the last hour - skipping to prevent spam`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (issue.pull_request) {
|
||||
console.log('Skipping - this is a pull request');
|
||||
return;
|
||||
}
|
||||
|
||||
if (issue.user.type === 'Bot') {
|
||||
console.log('Skipping - issue created by bot');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Loading model: ${MODEL_NAME}`);
|
||||
const extractor = await pipeline('feature-extraction', MODEL_NAME, {
|
||||
dtype: 'fp32',
|
||||
});
|
||||
const index = loadIndex(INDEX_PATH);
|
||||
|
||||
const text = issueText(issue.title, issue.body);
|
||||
const output = await extractor(text, { pooling: 'mean', normalize: true });
|
||||
const queryEmbedding = output.tolist()[0];
|
||||
|
||||
let candidates = findSimilar(queryEmbedding, index, {
|
||||
topK: TOP_K,
|
||||
threshold: SIMILARITY_THRESHOLD,
|
||||
excludeNumber: issue.number,
|
||||
});
|
||||
|
||||
if (!candidates.length) {
|
||||
console.log('No similar issues found above threshold - done');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Found ${candidates.length} candidates above threshold:`);
|
||||
for (const c of candidates) {
|
||||
console.log(` #${c.number} (${c.score.toFixed(3)}) - ${c.title}`);
|
||||
}
|
||||
|
||||
console.log('Running LLM confirmation via Groq...');
|
||||
candidates = await confirmWithLlm(issue, candidates);
|
||||
|
||||
if (!candidates.length) {
|
||||
console.log('LLM ruled out all candidates - done');
|
||||
return;
|
||||
}
|
||||
|
||||
const comment = formatComment(candidates);
|
||||
await postComment(ISSUE_NUMBER, comment);
|
||||
await addLabel(ISSUE_NUMBER, LABEL_NAME);
|
||||
|
||||
console.log('Done!');
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "duplicate-detector",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"packageManager": "pnpm@10.17.1",
|
||||
"scripts": {
|
||||
"build-index": "node build-index.mjs",
|
||||
"detect": "node detect.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@huggingface/transformers": "^3.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.0"
|
||||
}
|
||||
}
|
||||
655
bin/duplicate-detector/pnpm-lock.yaml
generated
@@ -1,655 +0,0 @@
|
||||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
'@huggingface/transformers':
|
||||
specifier: ^3.8.1
|
||||
version: 3.8.1
|
||||
|
||||
packages:
|
||||
|
||||
'@emnapi/runtime@1.8.1':
|
||||
resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==}
|
||||
|
||||
'@huggingface/jinja@0.5.5':
|
||||
resolution: {integrity: sha512-xRlzazC+QZwr6z4ixEqYHo9fgwhTZ3xNSdljlKfUFGZSdlvt166DljRELFUfFytlYOYvo3vTisA/AFOuOAzFQQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@huggingface/transformers@3.8.1':
|
||||
resolution: {integrity: sha512-tsTk4zVjImqdqjS8/AOZg2yNLd1z9S5v+7oUPpXaasDRwEDhB+xnglK1k5cad26lL5/ZIaeREgWWy0bs9y9pPA==}
|
||||
|
||||
'@img/colour@1.0.0':
|
||||
resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-darwin-x64@0.34.5':
|
||||
resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.2.4':
|
||||
resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-arm@0.34.5':
|
||||
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-ppc64@0.34.5':
|
||||
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-riscv64@0.34.5':
|
||||
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-s390x@0.34.5':
|
||||
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-x64@0.34.5':
|
||||
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-wasm32@0.34.5':
|
||||
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [wasm32]
|
||||
|
||||
'@img/sharp-win32-arm64@0.34.5':
|
||||
resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@img/sharp-win32-ia32@0.34.5':
|
||||
resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@img/sharp-win32-x64@0.34.5':
|
||||
resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@isaacs/fs-minipass@4.0.1':
|
||||
resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
'@protobufjs/aspromise@1.1.2':
|
||||
resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
|
||||
|
||||
'@protobufjs/base64@1.1.2':
|
||||
resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
|
||||
|
||||
'@protobufjs/codegen@2.0.4':
|
||||
resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==}
|
||||
|
||||
'@protobufjs/eventemitter@1.1.0':
|
||||
resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==}
|
||||
|
||||
'@protobufjs/fetch@1.1.0':
|
||||
resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==}
|
||||
|
||||
'@protobufjs/float@1.0.2':
|
||||
resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
|
||||
|
||||
'@protobufjs/inquire@1.1.0':
|
||||
resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==}
|
||||
|
||||
'@protobufjs/path@1.1.2':
|
||||
resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
|
||||
|
||||
'@protobufjs/pool@1.1.0':
|
||||
resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
|
||||
|
||||
'@protobufjs/utf8@1.1.0':
|
||||
resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
|
||||
|
||||
'@types/node@25.2.2':
|
||||
resolution: {integrity: sha512-BkmoP5/FhRYek5izySdkOneRyXYN35I860MFAGupTdebyE66uZaR+bXLHq8k4DirE5DwQi3NuhvRU1jqTVwUrQ==}
|
||||
|
||||
boolean@3.2.0:
|
||||
resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==}
|
||||
deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
|
||||
|
||||
chownr@3.0.0:
|
||||
resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
define-data-property@1.1.4:
|
||||
resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
define-properties@1.2.1:
|
||||
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
detect-libc@2.1.2:
|
||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
detect-node@2.1.0:
|
||||
resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==}
|
||||
|
||||
es-define-property@1.0.1:
|
||||
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-errors@1.3.0:
|
||||
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es6-error@4.1.1:
|
||||
resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==}
|
||||
|
||||
escape-string-regexp@4.0.0:
|
||||
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
flatbuffers@25.9.23:
|
||||
resolution: {integrity: sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==}
|
||||
|
||||
global-agent@3.0.0:
|
||||
resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==}
|
||||
engines: {node: '>=10.0'}
|
||||
|
||||
globalthis@1.0.4:
|
||||
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
gopd@1.2.0:
|
||||
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
guid-typescript@1.0.9:
|
||||
resolution: {integrity: sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==}
|
||||
|
||||
has-property-descriptors@1.0.2:
|
||||
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
|
||||
|
||||
json-stringify-safe@5.0.1:
|
||||
resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
|
||||
|
||||
long@5.3.2:
|
||||
resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
|
||||
|
||||
matcher@3.0.0:
|
||||
resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
minipass@7.1.2:
|
||||
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
minizlib@3.1.0:
|
||||
resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
object-keys@1.1.1:
|
||||
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
onnxruntime-common@1.21.0:
|
||||
resolution: {integrity: sha512-Q632iLLrtCAVOTO65dh2+mNbQir/QNTVBG3h/QdZBpns7mZ0RYbLRBgGABPbpU9351AgYy7SJf1WaeVwMrBFPQ==}
|
||||
|
||||
onnxruntime-common@1.22.0-dev.20250409-89f8206ba4:
|
||||
resolution: {integrity: sha512-vDJMkfCfb0b1A836rgHj+ORuZf4B4+cc2bASQtpeoJLueuFc5DuYwjIZUBrSvx/fO5IrLjLz+oTrB3pcGlhovQ==}
|
||||
|
||||
onnxruntime-node@1.21.0:
|
||||
resolution: {integrity: sha512-NeaCX6WW2L8cRCSqy3bInlo5ojjQqu2fD3D+9W5qb5irwxhEyWKXeH2vZ8W9r6VxaMPUan+4/7NDwZMtouZxEw==}
|
||||
os: [win32, darwin, linux]
|
||||
|
||||
onnxruntime-web@1.22.0-dev.20250409-89f8206ba4:
|
||||
resolution: {integrity: sha512-0uS76OPgH0hWCPrFKlL8kYVV7ckM7t/36HfbgoFw6Nd0CZVVbQC4PkrR8mBX8LtNUFZO25IQBqV2Hx2ho3FlbQ==}
|
||||
|
||||
platform@1.3.6:
|
||||
resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==}
|
||||
|
||||
protobufjs@7.5.4:
|
||||
resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
roarr@2.15.4:
|
||||
resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==}
|
||||
engines: {node: '>=8.0'}
|
||||
|
||||
semver-compare@1.0.0:
|
||||
resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==}
|
||||
|
||||
semver@7.7.4:
|
||||
resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
serialize-error@7.0.1:
|
||||
resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
sharp@0.34.5:
|
||||
resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
|
||||
sprintf-js@1.1.3:
|
||||
resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==}
|
||||
|
||||
tar@7.5.7:
|
||||
resolution: {integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
type-fest@0.13.1:
|
||||
resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
undici-types@7.16.0:
|
||||
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
||||
|
||||
yallist@5.0.0:
|
||||
resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@emnapi/runtime@1.8.1':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
optional: true
|
||||
|
||||
'@huggingface/jinja@0.5.5': {}
|
||||
|
||||
'@huggingface/transformers@3.8.1':
|
||||
dependencies:
|
||||
'@huggingface/jinja': 0.5.5
|
||||
onnxruntime-node: 1.21.0
|
||||
onnxruntime-web: 1.22.0-dev.20250409-89f8206ba4
|
||||
sharp: 0.34.5
|
||||
|
||||
'@img/colour@1.0.0': {}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-darwin-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-ppc64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-riscv64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-ppc64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-ppc64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-riscv64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-riscv64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-s390x@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-s390x': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.34.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-wasm32@0.34.5':
|
||||
dependencies:
|
||||
'@emnapi/runtime': 1.8.1
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-arm64@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-ia32@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-x64@0.34.5':
|
||||
optional: true
|
||||
|
||||
'@isaacs/fs-minipass@4.0.1':
|
||||
dependencies:
|
||||
minipass: 7.1.2
|
||||
|
||||
'@protobufjs/aspromise@1.1.2': {}
|
||||
|
||||
'@protobufjs/base64@1.1.2': {}
|
||||
|
||||
'@protobufjs/codegen@2.0.4': {}
|
||||
|
||||
'@protobufjs/eventemitter@1.1.0': {}
|
||||
|
||||
'@protobufjs/fetch@1.1.0':
|
||||
dependencies:
|
||||
'@protobufjs/aspromise': 1.1.2
|
||||
'@protobufjs/inquire': 1.1.0
|
||||
|
||||
'@protobufjs/float@1.0.2': {}
|
||||
|
||||
'@protobufjs/inquire@1.1.0': {}
|
||||
|
||||
'@protobufjs/path@1.1.2': {}
|
||||
|
||||
'@protobufjs/pool@1.1.0': {}
|
||||
|
||||
'@protobufjs/utf8@1.1.0': {}
|
||||
|
||||
'@types/node@25.2.2':
|
||||
dependencies:
|
||||
undici-types: 7.16.0
|
||||
|
||||
boolean@3.2.0: {}
|
||||
|
||||
chownr@3.0.0: {}
|
||||
|
||||
define-data-property@1.1.4:
|
||||
dependencies:
|
||||
es-define-property: 1.0.1
|
||||
es-errors: 1.3.0
|
||||
gopd: 1.2.0
|
||||
|
||||
define-properties@1.2.1:
|
||||
dependencies:
|
||||
define-data-property: 1.1.4
|
||||
has-property-descriptors: 1.0.2
|
||||
object-keys: 1.1.1
|
||||
|
||||
detect-libc@2.1.2: {}
|
||||
|
||||
detect-node@2.1.0: {}
|
||||
|
||||
es-define-property@1.0.1: {}
|
||||
|
||||
es-errors@1.3.0: {}
|
||||
|
||||
es6-error@4.1.1: {}
|
||||
|
||||
escape-string-regexp@4.0.0: {}
|
||||
|
||||
flatbuffers@25.9.23: {}
|
||||
|
||||
global-agent@3.0.0:
|
||||
dependencies:
|
||||
boolean: 3.2.0
|
||||
es6-error: 4.1.1
|
||||
matcher: 3.0.0
|
||||
roarr: 2.15.4
|
||||
semver: 7.7.4
|
||||
serialize-error: 7.0.1
|
||||
|
||||
globalthis@1.0.4:
|
||||
dependencies:
|
||||
define-properties: 1.2.1
|
||||
gopd: 1.2.0
|
||||
|
||||
gopd@1.2.0: {}
|
||||
|
||||
guid-typescript@1.0.9: {}
|
||||
|
||||
has-property-descriptors@1.0.2:
|
||||
dependencies:
|
||||
es-define-property: 1.0.1
|
||||
|
||||
json-stringify-safe@5.0.1: {}
|
||||
|
||||
long@5.3.2: {}
|
||||
|
||||
matcher@3.0.0:
|
||||
dependencies:
|
||||
escape-string-regexp: 4.0.0
|
||||
|
||||
minipass@7.1.2: {}
|
||||
|
||||
minizlib@3.1.0:
|
||||
dependencies:
|
||||
minipass: 7.1.2
|
||||
|
||||
object-keys@1.1.1: {}
|
||||
|
||||
onnxruntime-common@1.21.0: {}
|
||||
|
||||
onnxruntime-common@1.22.0-dev.20250409-89f8206ba4: {}
|
||||
|
||||
onnxruntime-node@1.21.0:
|
||||
dependencies:
|
||||
global-agent: 3.0.0
|
||||
onnxruntime-common: 1.21.0
|
||||
tar: 7.5.7
|
||||
|
||||
onnxruntime-web@1.22.0-dev.20250409-89f8206ba4:
|
||||
dependencies:
|
||||
flatbuffers: 25.9.23
|
||||
guid-typescript: 1.0.9
|
||||
long: 5.3.2
|
||||
onnxruntime-common: 1.22.0-dev.20250409-89f8206ba4
|
||||
platform: 1.3.6
|
||||
protobufjs: 7.5.4
|
||||
|
||||
platform@1.3.6: {}
|
||||
|
||||
protobufjs@7.5.4:
|
||||
dependencies:
|
||||
'@protobufjs/aspromise': 1.1.2
|
||||
'@protobufjs/base64': 1.1.2
|
||||
'@protobufjs/codegen': 2.0.4
|
||||
'@protobufjs/eventemitter': 1.1.0
|
||||
'@protobufjs/fetch': 1.1.0
|
||||
'@protobufjs/float': 1.0.2
|
||||
'@protobufjs/inquire': 1.1.0
|
||||
'@protobufjs/path': 1.1.2
|
||||
'@protobufjs/pool': 1.1.0
|
||||
'@protobufjs/utf8': 1.1.0
|
||||
'@types/node': 25.2.2
|
||||
long: 5.3.2
|
||||
|
||||
roarr@2.15.4:
|
||||
dependencies:
|
||||
boolean: 3.2.0
|
||||
detect-node: 2.1.0
|
||||
globalthis: 1.0.4
|
||||
json-stringify-safe: 5.0.1
|
||||
semver-compare: 1.0.0
|
||||
sprintf-js: 1.1.3
|
||||
|
||||
semver-compare@1.0.0: {}
|
||||
|
||||
semver@7.7.4: {}
|
||||
|
||||
serialize-error@7.0.1:
|
||||
dependencies:
|
||||
type-fest: 0.13.1
|
||||
|
||||
sharp@0.34.5:
|
||||
dependencies:
|
||||
'@img/colour': 1.0.0
|
||||
detect-libc: 2.1.2
|
||||
semver: 7.7.4
|
||||
optionalDependencies:
|
||||
'@img/sharp-darwin-arm64': 0.34.5
|
||||
'@img/sharp-darwin-x64': 0.34.5
|
||||
'@img/sharp-libvips-darwin-arm64': 1.2.4
|
||||
'@img/sharp-libvips-darwin-x64': 1.2.4
|
||||
'@img/sharp-libvips-linux-arm': 1.2.4
|
||||
'@img/sharp-libvips-linux-arm64': 1.2.4
|
||||
'@img/sharp-libvips-linux-ppc64': 1.2.4
|
||||
'@img/sharp-libvips-linux-riscv64': 1.2.4
|
||||
'@img/sharp-libvips-linux-s390x': 1.2.4
|
||||
'@img/sharp-libvips-linux-x64': 1.2.4
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
|
||||
'@img/sharp-linux-arm': 0.34.5
|
||||
'@img/sharp-linux-arm64': 0.34.5
|
||||
'@img/sharp-linux-ppc64': 0.34.5
|
||||
'@img/sharp-linux-riscv64': 0.34.5
|
||||
'@img/sharp-linux-s390x': 0.34.5
|
||||
'@img/sharp-linux-x64': 0.34.5
|
||||
'@img/sharp-linuxmusl-arm64': 0.34.5
|
||||
'@img/sharp-linuxmusl-x64': 0.34.5
|
||||
'@img/sharp-wasm32': 0.34.5
|
||||
'@img/sharp-win32-arm64': 0.34.5
|
||||
'@img/sharp-win32-ia32': 0.34.5
|
||||
'@img/sharp-win32-x64': 0.34.5
|
||||
|
||||
sprintf-js@1.1.3: {}
|
||||
|
||||
tar@7.5.7:
|
||||
dependencies:
|
||||
'@isaacs/fs-minipass': 4.0.1
|
||||
chownr: 3.0.0
|
||||
minipass: 7.1.2
|
||||
minizlib: 3.1.0
|
||||
yallist: 5.0.0
|
||||
|
||||
tslib@2.8.1:
|
||||
optional: true
|
||||
|
||||
type-fest@0.13.1: {}
|
||||
|
||||
undici-types@7.16.0: {}
|
||||
|
||||
yallist@5.0.0: {}
|
||||
@@ -1,116 +0,0 @@
|
||||
const GITHUB_API = 'https://api.github.com';
|
||||
const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
|
||||
const GITHUB_REPOSITORY = process.env.GITHUB_REPOSITORY;
|
||||
|
||||
function ghHeaders() {
|
||||
return {
|
||||
Authorization: `token ${GITHUB_TOKEN}`,
|
||||
Accept: 'application/vnd.github+json',
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchIssues({
|
||||
state = 'open',
|
||||
since,
|
||||
maxIssues = 5000,
|
||||
} = {}) {
|
||||
const issues = [];
|
||||
let page = 1;
|
||||
const perPage = 100;
|
||||
|
||||
while (issues.length < maxIssues) {
|
||||
const params = new URLSearchParams({
|
||||
state,
|
||||
per_page: String(perPage),
|
||||
page: String(page),
|
||||
sort: 'updated',
|
||||
direction: 'desc',
|
||||
});
|
||||
if (since) params.set('since', since);
|
||||
|
||||
const url = `${GITHUB_API}/repos/${GITHUB_REPOSITORY}/issues?${params}`;
|
||||
const resp = await fetch(url, { headers: ghHeaders() });
|
||||
|
||||
if (!resp.ok) {
|
||||
throw new Error(`GitHub API error: ${resp.status} ${resp.statusText}`);
|
||||
}
|
||||
|
||||
const batch = await resp.json();
|
||||
if (!batch.length) break;
|
||||
|
||||
for (const item of batch) {
|
||||
if (!item.pull_request) {
|
||||
issues.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
page++;
|
||||
if (batch.length < perPage) break;
|
||||
}
|
||||
|
||||
return issues.slice(0, maxIssues);
|
||||
}
|
||||
|
||||
export async function getIssue(issueNumber) {
|
||||
const url = `${GITHUB_API}/repos/${GITHUB_REPOSITORY}/issues/${issueNumber}`;
|
||||
const resp = await fetch(url, { headers: ghHeaders() });
|
||||
|
||||
if (!resp.ok) {
|
||||
throw new Error(`GitHub API error: ${resp.status} ${resp.statusText}`);
|
||||
}
|
||||
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
export async function postComment(issueNumber, body) {
|
||||
const url = `${GITHUB_API}/repos/${GITHUB_REPOSITORY}/issues/${issueNumber}/comments`;
|
||||
const resp = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { ...ghHeaders(), 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ body }),
|
||||
});
|
||||
|
||||
if (!resp.ok) {
|
||||
throw new Error(
|
||||
`Failed to post comment: ${resp.status} ${resp.statusText}`
|
||||
);
|
||||
}
|
||||
|
||||
console.log(`Posted comment on #${issueNumber}`);
|
||||
}
|
||||
|
||||
export async function addLabel(issueNumber, label) {
|
||||
const url = `${GITHUB_API}/repos/${GITHUB_REPOSITORY}/issues/${issueNumber}/labels`;
|
||||
const resp = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { ...ghHeaders(), 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ labels: [label] }),
|
||||
});
|
||||
|
||||
if (resp.status === 404) {
|
||||
console.warn(
|
||||
`Label '${label}' does not exist - skipping. Create it manually.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!resp.ok) {
|
||||
throw new Error(`Failed to add label: ${resp.status} ${resp.statusText}`);
|
||||
}
|
||||
|
||||
console.log(`Added label '${label}' to #${issueNumber}`);
|
||||
}
|
||||
|
||||
export function issueText(title, body) {
|
||||
body = (body || '').trim();
|
||||
if (body.length > 2000) body = body.slice(0, 2000) + '...';
|
||||
return body ? `${title}\n\n${body}` : title;
|
||||
}
|
||||
|
||||
export function dotProduct(a, b) {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
sum += a[i] * b[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
@@ -3,9 +3,9 @@ kubeVersion: '>=1.23.0-0'
|
||||
name: seerr-chart
|
||||
description: Seerr helm chart for Kubernetes
|
||||
type: application
|
||||
version: 3.1.0
|
||||
# renovate: image=ghcr.io/seerr-team/seerr
|
||||
appVersion: 'v3.0.1'
|
||||
version: 3.0.0
|
||||
# renovate: image=ghcr.io/fallenbagel/jellyseerr
|
||||
appVersion: '2.7.3'
|
||||
maintainers:
|
||||
- name: Seerr Team
|
||||
url: https://github.com/orgs/seerr-team/people
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# seerr-chart
|
||||
|
||||
  
|
||||
  
|
||||
|
||||
Seerr helm chart for Kubernetes
|
||||
|
||||
@@ -20,15 +20,11 @@ Seerr helm chart for Kubernetes
|
||||
|
||||
Kubernetes: `>=1.23.0-0`
|
||||
|
||||
## Installation
|
||||
|
||||
Refer to [Seerr kubernetes documentation](https://docs.seerr.dev/getting-started/kubernetes)
|
||||
|
||||
## Update Notes
|
||||
|
||||
### Updating to 3.0.0
|
||||
|
||||
Nothing has changed; we just rebranded the `jellyseerr` Helm chart to `seerr` 🥳 refer to our [Migration guide](https://docs.seerr.dev/migration-guide).
|
||||
Nothing has changed; we just rebranded the `jellyseerr` Helm chart to `seerr` 🥳.
|
||||
|
||||
### Updating to 2.7.0
|
||||
|
||||
@@ -44,10 +40,9 @@ If `replicaCount` value was used - remove it. Helm update should work fine after
|
||||
| Key | Type | Default | Description |
|
||||
|-----|------|---------|-------------|
|
||||
| affinity | object | `{}` | |
|
||||
| config | object | `{"persistence":{"accessModes":["ReadWriteOnce"],"annotations":{},"existingClaim":"","name":"","size":"5Gi","volumeName":""}}` | Creating PVC to store configuration |
|
||||
| config | object | `{"persistence":{"accessModes":["ReadWriteOnce"],"annotations":{},"name":"","size":"5Gi","volumeName":""}}` | Creating PVC to store configuration |
|
||||
| config.persistence.accessModes | list | `["ReadWriteOnce"]` | Access modes of persistent disk |
|
||||
| config.persistence.annotations | object | `{}` | Annotations for PVCs |
|
||||
| config.persistence.existingClaim | string | `""` | Specify an existing `PersistentVolumeClaim` to use. If this value is provided, the default PVC will not be created |
|
||||
| config.persistence.name | string | `""` | Config name |
|
||||
| config.persistence.size | string | `"5Gi"` | Size of persistent disk |
|
||||
| config.persistence.volumeName | string | `""` | Name of the permanent volume to reference in the claim. Can be used to bind to existing volumes. |
|
||||
@@ -71,20 +66,12 @@ If `replicaCount` value was used - remove it. Helm update should work fine after
|
||||
| nodeSelector | object | `{}` | |
|
||||
| podAnnotations | object | `{}` | |
|
||||
| podLabels | object | `{}` | |
|
||||
| podSecurityContext.fsGroup | int | `1000` | |
|
||||
| podSecurityContext.fsGroupChangePolicy | string | `"OnRootMismatch"` | |
|
||||
| podSecurityContext | object | `{}` | |
|
||||
| probes.livenessProbe | object | `{}` | Configure liveness probe |
|
||||
| probes.readinessProbe | object | `{}` | Configure readiness probe |
|
||||
| probes.startupProbe | string | `nil` | Configure startup probe |
|
||||
| resources | object | `{}` | |
|
||||
| securityContext.allowPrivilegeEscalation | bool | `false` | |
|
||||
| securityContext.capabilities.drop[0] | string | `"ALL"` | |
|
||||
| securityContext.privileged | bool | `false` | |
|
||||
| securityContext.readOnlyRootFilesystem | bool | `false` | |
|
||||
| securityContext.runAsGroup | int | `1000` | |
|
||||
| securityContext.runAsNonRoot | bool | `true` | |
|
||||
| securityContext.runAsUser | int | `1000` | |
|
||||
| securityContext.seccompProfile.type | string | `"RuntimeDefault"` | |
|
||||
| securityContext | object | `{}` | |
|
||||
| service.port | int | `80` | |
|
||||
| service.type | string | `"ClusterIP"` | |
|
||||
| serviceAccount.annotations | object | `{}` | Annotations to add to the service account |
|
||||
|
||||
@@ -14,15 +14,11 @@
|
||||
|
||||
{{ template "chart.requirementsSection" . }}
|
||||
|
||||
## Installation
|
||||
|
||||
Refer to [Seerr kubernetes documentation](https://docs.seerr.dev/getting-started/kubernetes)
|
||||
|
||||
## Update Notes
|
||||
|
||||
### Updating to 3.0.0
|
||||
|
||||
Nothing has changed; we just rebranded the `jellyseerr` Helm chart to `seerr` 🥳 refer to our [Migration guide](https://docs.seerr.dev/migration-guide).
|
||||
Nothing change we just rebranded `jellyseerr` helm-chart to `seerr` :)
|
||||
|
||||
### Updating to 2.7.0
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
{{- if not .Values.config.persistence.existingClaim -}}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
@@ -23,4 +22,3 @@ spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: "{{ .Values.config.persistence.size }}"
|
||||
{{- end -}}
|
||||
@@ -103,7 +103,7 @@ spec:
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ if .Values.config.persistence.existingClaim }}{{ .Values.config.persistence.existingClaim }}{{- else }}{{ include "seerr.configPersistenceName" . }}{{- end }}
|
||||
claimName: {{ include "seerr.configPersistenceName" . }}
|
||||
{{- with .Values.volumes }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -50,22 +50,16 @@ serviceAccount:
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
|
||||
podSecurityContext:
|
||||
fsGroup: 1000
|
||||
fsGroupChangePolicy: OnRootMismatch
|
||||
podSecurityContext: {}
|
||||
# fsGroup: 2000
|
||||
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
readOnlyRootFilesystem: false
|
||||
runAsNonRoot: true
|
||||
privileged: false
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
securityContext: {}
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
# readOnlyRootFilesystem: true
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
@@ -86,8 +80,6 @@ config:
|
||||
# -- Name of the permanent volume to reference in the claim.
|
||||
# Can be used to bind to existing volumes.
|
||||
volumeName: ''
|
||||
# -- Specify an existing `PersistentVolumeClaim` to use. If this value is provided, the default PVC will not be created
|
||||
existingClaim: ''
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
|
||||
@@ -31,6 +31,6 @@ services:
|
||||
ports:
|
||||
- '5432:5432'
|
||||
volumes:
|
||||
- postgres:/var/lib/postgresql
|
||||
- postgres:var/lib/postgresql/18/docker
|
||||
volumes:
|
||||
postgres:
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
"discoverRegion": "",
|
||||
"streamingRegion": "",
|
||||
"originalLanguage": "",
|
||||
"blocklistedTags": "",
|
||||
"blocklistedTagsLimit": 50,
|
||||
"blacklistedTags": "",
|
||||
"blacklistedTagsLimit": 50,
|
||||
"trustProxy": false,
|
||||
"mediaServerType": 1,
|
||||
"partialRequestsEnabled": true,
|
||||
|
||||
@@ -23,7 +23,7 @@ Welcome to the Seerr Documentation.
|
||||
- Localization into other languages.
|
||||
- Support for **PostgreSQL** and **SQLite** databases.
|
||||
- Support for various notification agents.
|
||||
- Easily **Watchlist** or **Blocklist** media.
|
||||
- Easily **Watchlist** or **Blacklist** media.
|
||||
- More features to come!
|
||||
|
||||
## We need your help!
|
||||
|
||||
@@ -20,7 +20,7 @@ DB_LOG_QUERIES="false" # (optional) Whether to log the DB queries for debugging.
|
||||
## PostgreSQL Options
|
||||
|
||||
:::caution
|
||||
When migrating Postgres from version 17 to 18 in Docker, note that the data mount point has changed. Instead of using `/var/lib/postgresql/data`, the correct mount path is now `/var/lib/postgresql`.
|
||||
When migrating Postgres from version 17 to 18 in Docker, note that the data mount point has changed. Instead of using `/var/lib/postgresql/data`, the correct mount path is now `/var/lib/postgresql/18/docker`.
|
||||
Refer to the [PostgreSQL Docker documentation](https://hub.docker.com/_/postgres/#pgdata) to learn how to migrate or opt out of this change.
|
||||
:::
|
||||
|
||||
@@ -30,7 +30,7 @@ If your PostgreSQL server is configured to accept TCP connections, you can speci
|
||||
|
||||
```dotenv
|
||||
DB_TYPE=postgres # Which DB engine to use, either sqlite or postgres. The default is sqlite.
|
||||
DB_HOST=localhost # (optional) The host (URL) of the database. The default is "localhost".
|
||||
DB_HOST="localhost" # (optional) The host (URL) of the database. The default is "localhost".
|
||||
DB_PORT="5432" # (optional) The port to connect to. The default is "5432".
|
||||
DB_USER= # (required) Username used to connect to the database.
|
||||
DB_PASS= # (required) Password of the user used to connect to the database.
|
||||
|
||||
@@ -266,36 +266,3 @@ Add the following Location block to your existing Server configuration.
|
||||
</TabItem>
|
||||
|
||||
</Tabs>
|
||||
|
||||
## HAProxy (v3)
|
||||
|
||||
:::warning
|
||||
This is a third-party documentation maintained by the community. We can't provide support for this setup and are unable to test it.
|
||||
:::
|
||||
|
||||
Add the following frontend and backend configurations for your seerr instance:
|
||||
```haproxy
|
||||
frontend seerr-frontend
|
||||
bind 0.0.0.0:80
|
||||
bind 0.0.0.0:443 ssl crt /etc/ssl/private/seerr.example.com.pem
|
||||
mode http
|
||||
log global
|
||||
option httplog
|
||||
option http-keep-alive
|
||||
http-request set-header X-Real-IP %[src]
|
||||
option forwardfor
|
||||
acl seerr hdr(host) -i seerr.example.com
|
||||
redirect scheme https code 301 if !{ ssl_fc }
|
||||
use_backend seerr-backend if seerr
|
||||
|
||||
backend seerr-backend
|
||||
mode http
|
||||
log global
|
||||
option httplog
|
||||
http-response set-header Strict-Transport-Security max-age=15552000
|
||||
option httpchk GET /api/v1/status
|
||||
timeout connect 30000
|
||||
timeout server 30000
|
||||
retries 3
|
||||
server seerr 127.0.0.1:5055 check inter 1000
|
||||
```
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
---
|
||||
title: AUR (Advanced)
|
||||
title: AUR (Arch User Repository)
|
||||
description: Install Seerr using the Arch User Repository
|
||||
sidebar_position: 2
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# AUR
|
||||
:::warning
|
||||
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
|
||||
# AUR (Arch User Repository)
|
||||
|
||||
:::note Disclaimer
|
||||
This AUR package is not maintained by us but by a third party. Please refer to the maintainer for any issues.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
:::info
|
||||
This method is not recommended for most users. It is intended for advanced users who are using Arch Linux or an Arch-based distribution.
|
||||
:::
|
||||
|
||||
@@ -23,12 +24,12 @@ import TabItem from '@theme/TabItem';
|
||||
<Tabs groupId="aur-methods" queryString>
|
||||
<TabItem value="yay" label="yay">
|
||||
```bash
|
||||
yay -S seerr
|
||||
yay -S jellyseerr
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="paru" label="paru">
|
||||
```bash
|
||||
paru -S seerr
|
||||
paru -S jellyseerr
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -38,5 +39,5 @@ After installing Seerr, configure it by visiting the web UI at `http://[address]
|
||||
:::
|
||||
|
||||
:::tip
|
||||
You can find the environment file at `/etc/conf.d/seerr` and the service file at `/etc/systemd/system/seerr.service`.
|
||||
You can find the environment file at `/etc/conf.d/jellyseerr` and the service file at `/etc/systemd/system/jellyseerr.service`.
|
||||
:::
|
||||
@@ -24,9 +24,10 @@ import TabItem from '@theme/TabItem';
|
||||
```bash
|
||||
sudo mkdir -p /opt/seerr && cd /opt/seerr
|
||||
```
|
||||
2. Clone the Seerr repository and checkout the main branch:
|
||||
2. Clone the Seerr repository and checkout the develop branch:
|
||||
```bash
|
||||
git clone https://github.com/seerr-team/seerr.git .
|
||||
git clone https://github.com/fallenbagel/jellyseerr.git
|
||||
cd jellyseerr
|
||||
git checkout main
|
||||
```
|
||||
3. Install the dependencies:
|
||||
@@ -198,9 +199,9 @@ pm2 status seerr
|
||||
mkdir C:\seerr
|
||||
cd C:\seerr
|
||||
```
|
||||
2. Clone the Seerr repository and checkout the main branch:
|
||||
2. Clone the Seerr repository and checkout the develop branch:
|
||||
```powershell
|
||||
git clone https://github.com/seerr-team/seerr.git .
|
||||
git clone https://github.com/fallenbagel/jellyseerr.git .
|
||||
git checkout main
|
||||
```
|
||||
3. Install the dependencies:
|
||||
|
||||
@@ -11,22 +11,6 @@ Details on how to install Docker can be found on the [official Docker website](h
|
||||
Refer to [Configuring Databases](/extending-seerr/database-config#postgresql-options) for details on how to configure your database.
|
||||
:::
|
||||
|
||||
:::info
|
||||
An alternative Docker image is available on Docker Hub for this project. You can find it at [Docker Hub Repository Link](https://hub.docker.com/r/seerr/seerr)
|
||||
|
||||
Our Docker images are available with the following tags:
|
||||
|
||||
- `latest`: Always points to the most recent stable release.
|
||||
- Version tags (e.g., `v3.0.0`): For specific stable versions.
|
||||
- `develop`: Rolling release/nightly builds for using the latest changes (use with caution).
|
||||
:::
|
||||
|
||||
:::info
|
||||
All official Seerr images are cryptographically signed and include a verified [Software Bill of Materials (SBOM)](https://cyclonedx.org/).
|
||||
|
||||
To confirm that the container image you are using is authentic and unmodified, please refer to the [Verifying Signed Artifacts](/using-seerr/advanced/verifying-signed-artifacts#verifying-signed-images) guide.
|
||||
:::
|
||||
|
||||
## Unix (Linux, macOS)
|
||||
:::warning
|
||||
Be sure to replace `/path/to/appdata/config` in the below examples with a valid host directory path. If this volume mount is not configured correctly, your Seerr settings/data will not be persisted when the container is recreated (e.g., when updating the image or rebooting your machine).
|
||||
@@ -44,13 +28,6 @@ For details on the Docker CLI, please [review the official `docker run` document
|
||||
|
||||
#### Installation:
|
||||
|
||||
```bash
|
||||
# Create the appdata folder
|
||||
mkdir /path/to/appdata/config
|
||||
# Chown the folder as the container runs as the `node` user (UID 1000).
|
||||
chown -R 1000:1000 /path/to/appdata/config
|
||||
```
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name seerr \
|
||||
@@ -61,16 +38,20 @@ docker run -d \
|
||||
-p 5055:5055 \
|
||||
-v /path/to/appdata/config:/app/config \
|
||||
--restart unless-stopped \
|
||||
ghcr.io/seerr-team/seerr
|
||||
```
|
||||
|
||||
The argument `-e PORT=5055` is optional.
|
||||
|
||||
If you want to add a healthcheck to the above command, you can add the following flags :
|
||||
```
|
||||
--health-cmd "wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/status || exit 1" \
|
||||
--health-start-period 20s \
|
||||
--health-timeout 3s \
|
||||
--health-interval 15s \
|
||||
--health-retries 3 \
|
||||
ghcr.io/seerr-team/seerr:latest
|
||||
```
|
||||
|
||||
The argument `-e PORT=5055` is optional.
|
||||
|
||||
To run the container as a specific user/group, you may optionally add `--user=[ user | user:group | uid | uid:gid | user:gid | uid:group ]` to the above command.
|
||||
|
||||
#### Updating:
|
||||
@@ -81,7 +62,7 @@ docker stop seerr && docker rm seerr
|
||||
```
|
||||
Pull the latest image:
|
||||
```bash
|
||||
docker pull ghcr.io/seerr-team/seerr:latest
|
||||
docker pull ghcr.io/seerr-team/seerr
|
||||
```
|
||||
Finally, run the container with the same parameters originally used to create the container:
|
||||
```bash
|
||||
@@ -124,13 +105,6 @@ services:
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
```bash
|
||||
# Create the appdata folder
|
||||
mkdir /path/to/appdata/config
|
||||
# Chown the folder as the container runs as the `node` user (UID 1000).
|
||||
chown -R 1000:1000 /path/to/appdata/config
|
||||
```
|
||||
|
||||
Then, start all services defined in the Compose file:
|
||||
```bash
|
||||
docker compose up -d
|
||||
@@ -145,9 +119,21 @@ Then, restart all services defined in the Compose file:
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
:::tip
|
||||
You may alternatively use a third-party mechanism like [dockge](https://github.com/louislam/dockge) to manage your docker compose files.
|
||||
:::
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
## Unraid
|
||||
|
||||
1. Ensure you have the **Community Applications** plugin installed.
|
||||
2. Inside the **Community Applications** app store, search for **Seerr**.
|
||||
3. Click the **Install Button**.
|
||||
4. On the following **Add Container** screen, make changes to the **Host Port** and **Host Path 1** \(Appdata\) as needed.
|
||||
5. Click apply and access "Seerr" at your `<ServerIP:HostPort>` in a web browser.
|
||||
|
||||
## Windows
|
||||
|
||||
Please refer to the [Docker Desktop for Windows user manual](https://docs.docker.com/docker-for-windows/) for details on how to install Docker on Windows. There is no need to install a Linux distro if using named volumes like in the example below.
|
||||
@@ -179,16 +165,20 @@ docker run -d \
|
||||
-p 5055:5055 \
|
||||
-v seerr-data:/app/config \
|
||||
--restart unless-stopped \
|
||||
ghcr.io/seerr-team/seerr
|
||||
```
|
||||
|
||||
The argument `-e PORT=5055` is optional.
|
||||
|
||||
If you want to add a healthcheck to the above command, you can add the following flags :
|
||||
```
|
||||
--health-cmd "wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/status || exit 1" \
|
||||
--health-start-period 20s \
|
||||
--health-timeout 3s \
|
||||
--health-interval 15s \
|
||||
--health-retries 3 \
|
||||
ghcr.io/seerr-team/seerr:latest
|
||||
```
|
||||
|
||||
The argument `-e PORT=5055` is optional.
|
||||
|
||||
#### Updating:
|
||||
Pull the latest image:
|
||||
```bash
|
||||
|
||||
@@ -1,26 +1,21 @@
|
||||
---
|
||||
title: Kubernetes (Advanced)
|
||||
description: Install Seerr in Kubernetes
|
||||
sidebar_position: 3
|
||||
description: Install Jellyseerr in Kubernetes
|
||||
sidebar_position: 5
|
||||
---
|
||||
# Kubernetes
|
||||
:::warning
|
||||
This method is not recommended for most users. It is intended for advanced users who are using Kubernetes.
|
||||
:::
|
||||
|
||||
:::info
|
||||
All official Seerr charts are cryptographically signed and include a verified [Software Bill of Materials (SBOM)](https://cyclonedx.org/).
|
||||
|
||||
To confirm that the chart you are using is authentic and unmodified, please refer to the [Verifying Signed Artifacts](/using-seerr/advanced/verifying-signed-artifacts#verifying-signed-helm-charts) guide.
|
||||
This method is not recommended for most users. It is intended for advanced users who are using Kubernetes.
|
||||
:::
|
||||
|
||||
## Installation
|
||||
```console
|
||||
helm install seerr oci://ghcr.io/seerr-team/seerr/seerr-chart
|
||||
```
|
||||
Helm values can be found in the Seerr repository under [charts/seerr-chart/README.md](https://github.com/seerr-team/seerr/tree/develop/charts/seerr-chart).
|
||||
Helm values can be found in the Jellyseerr repository under [charts/jellyseerr-chart/README.md](https://github.com/fallenbagel/jellyseerr/tree/develop/charts/jellyseerr-chart).
|
||||
|
||||
Verify the signature with [cosign](https://docs.sigstore.dev/cosign/system_config/installation/) (replace [tag], with the TAG you want to verify) :
|
||||
```console
|
||||
cosign verify ghcr.io/seerr-team/seerr/seerr-chart:[tag] --certificate-identity=https://github.com/seerr-team/seerr/.github/workflows/helm.yml@refs/heads/main --certificate-oidc-issuer=https://token.actions.githubusercontent.com
|
||||
cosign verify ghcr.io/fallenbagel/jellyseerr/jellyseerr-chart:[tag] --certificate-identity=https://github.com/fallenbagel/jellyseerr/.github/workflows/helm.yml@refs/heads/main --certificate-oidc-issuer=https://token.ac
|
||||
tions.githubusercontent.com
|
||||
```
|
||||
|
||||
271
docs/getting-started/nixpkg.mdx
Normal file
@@ -0,0 +1,271 @@
|
||||
---
|
||||
title: Nix Package Manager (Advanced)
|
||||
description: Install Seerr using Nix
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
import { SeerrVersion, NixpkgVersion } from '@site/src/components/SeerrVersion';
|
||||
import Admonition from '@theme/Admonition';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Nix Package Manager (Advanced)
|
||||
:::info
|
||||
This method is not recommended for most users. It is intended for advanced users who are using Nix as their package manager.
|
||||
:::
|
||||
|
||||
export const VersionMismatchWarning = () => {
|
||||
let seerrVersion = null;
|
||||
let nixpkgVersions = null;
|
||||
try {
|
||||
seerrVersion = SeerrVersion();
|
||||
nixpkgVersions = NixpkgVersion();
|
||||
} catch (err) {
|
||||
return (
|
||||
<Admonition type="error">
|
||||
Failed to load version information. Error: {err.message || JSON.stringify(err)}
|
||||
</Admonition>
|
||||
);
|
||||
}
|
||||
|
||||
if (!nixpkgVersions || nixpkgVersions.error) {
|
||||
return (
|
||||
<Admonition type="error">
|
||||
Failed to fetch Nixpkg versions: {nixpkgVersions?.error || 'Unknown error'}
|
||||
</Admonition>
|
||||
);
|
||||
}
|
||||
|
||||
const isUnstableUpToDate = seerrVersion === nixpkgVersions.unstable;
|
||||
const isStableUpToDate = seerrVersion === nixpkgVersions.stable;
|
||||
|
||||
return (
|
||||
<>
|
||||
{!isStableUpToDate ? (
|
||||
<Admonition type="warning">
|
||||
The{' '}
|
||||
<a href="https://github.com/NixOS/nixpkgs/blob/nixos-24.11/pkgs/servers/jellyseerr/default.nix#L14">
|
||||
upstream Jellyseerr Nix Package (v{nixpkgVersions.stable})
|
||||
</a>{' '}
|
||||
is not <b>up-to-date</b>. If you want to use <b>Jellyseerr v{seerrVersion}</b>,{' '}
|
||||
{isUnstableUpToDate ? (
|
||||
<>
|
||||
consider using the{' '}
|
||||
<a href="https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/by-name/je/jellyseerr/package.nix">
|
||||
unstable package
|
||||
</a>{' '}
|
||||
instead.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
you will need to{' '}
|
||||
<a href="#overriding-the-package-derivation">override the package derivation</a>.
|
||||
</>
|
||||
)}
|
||||
</Admonition>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
<VersionMismatchWarning />
|
||||
|
||||
## Installation
|
||||
To get up and running with jellyseerr using Nix, you can add the following to your `configuration.nix`:
|
||||
|
||||
```nix
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
services.jellyseerr.enable = true;
|
||||
}
|
||||
```
|
||||
|
||||
If you want more advanced configuration options, you can use the following:
|
||||
|
||||
<Tabs groupId="nixpkg-methods" queryString>
|
||||
<TabItem value="default" label="Default Configurations">
|
||||
```nix
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
services.jellyseerr = {
|
||||
enable = true;
|
||||
port = 5055;
|
||||
openFirewall = true;
|
||||
package = pkgs.jellyseerr; # Use the unstable package if stable is not up-to-date
|
||||
};
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="custom" label="Database Configurations">
|
||||
In order to use postgres, you will need to add override the default module of jellyseerr with the following as the current default module is not compatible with postgres:
|
||||
```nix
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.jellyseerr;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ maintainers.camillemndn ];
|
||||
|
||||
disabledModules = [ "services/misc/jellyseerr.nix" ];
|
||||
|
||||
options.services.jellyseerr = {
|
||||
enable = mkEnableOption ''Jellyseerr, a requests manager for Jellyfin'';
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''Open port in the firewall for the Jellyseerr web interface.'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 5055;
|
||||
description = ''The port which the Jellyseerr web UI should listen to.'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.jellyseerr;
|
||||
defaultText = literalExpression "pkgs.jellyseerr";
|
||||
description = ''
|
||||
Jellyseerr package to use.
|
||||
'';
|
||||
};
|
||||
|
||||
databaseConfig = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {
|
||||
type = "sqlite";
|
||||
configDirectory = "config";
|
||||
logQueries = "false";
|
||||
};
|
||||
description = ''
|
||||
Database configuration. For "sqlite", only "type", "configDirectory", and "logQueries" are relevant.
|
||||
For "postgres", include host, port, user, pass, name, and optionally socket.
|
||||
Example:
|
||||
{
|
||||
type = "postgres";
|
||||
socket = "/run/postgresql";
|
||||
user = "jellyseerr";
|
||||
name = "jellyseerr";
|
||||
logQueries = "false";
|
||||
}
|
||||
or
|
||||
{
|
||||
type = "postgres";
|
||||
host = "localhost";
|
||||
port = "5432";
|
||||
user = "dbuser";
|
||||
pass = "password";
|
||||
name = "jellyseerr";
|
||||
logQueries = "false";
|
||||
}
|
||||
or
|
||||
{
|
||||
type = "sqlite";
|
||||
configDirectory = "config";
|
||||
logQueries = "false";
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.jellyseerr = {
|
||||
description = "Jellyseerr, a requests manager for Jellyfin";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment =
|
||||
let
|
||||
dbConfig = cfg.databaseConfig;
|
||||
in
|
||||
{
|
||||
PORT = toString cfg.port;
|
||||
DB_TYPE = toString dbConfig.type;
|
||||
CONFIG_DIRECTORY = toString dbConfig.configDirectory or "";
|
||||
DB_LOG_QUERIES = toString dbConfig.logQueries;
|
||||
DB_HOST = if dbConfig.type == "postgres" && !(hasAttr "socket" dbConfig) then toString dbConfig.host or "" else "";
|
||||
DB_PORT = if dbConfig.type == "postgres" && !(hasAttr "socket" dbConfig) then toString dbConfig.port or "" else "";
|
||||
DB_SOCKET_PATH = if dbConfig.type == "postgres" && hasAttr "socket" dbConfig then toString dbConfig.socket or "" else "";
|
||||
DB_USER = if dbConfig.type == "postgres" then toString dbConfig.user or "" else "";
|
||||
DB_PASS = if dbConfig.type == "postgres" then toString dbConfig.pass or "" else "";
|
||||
DB_NAME = if dbConfig.type == "postgres" then toString dbConfig.name or "" else "";
|
||||
};
|
||||
serviceConfig = {
|
||||
Type = "exec";
|
||||
StateDirectory = "jellyseerr";
|
||||
WorkingDirectory = "${cfg.package}/libexec/jellyseerr";
|
||||
DynamicUser = true;
|
||||
ExecStart = "${cfg.package}/bin/jellyseerr";
|
||||
BindPaths = [ "/var/lib/jellyseerr/:${cfg.package}/libexec/jellyseerr/config/" ];
|
||||
Restart = "on-failure";
|
||||
ProtectHome = true;
|
||||
ProtectSystem = "strict";
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
ProtectHostname = true;
|
||||
ProtectClock = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectControlGroups = true;
|
||||
NoNewPrivileges = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
RemoveIPC = true;
|
||||
PrivateMounts = true;
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; };
|
||||
};
|
||||
}
|
||||
```
|
||||
Then, import the module into your `configuration.nix`:
|
||||
```nix
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
imports = [ ./modules/jellyseerr.nix ];
|
||||
|
||||
services.jellyseerr = {
|
||||
enable = true;
|
||||
port = 5055;
|
||||
openFirewall = true;
|
||||
package = pkgs.unstable.jellyseerr; # use the unstable package if stable is not up-to-date
|
||||
databaseConfig = {
|
||||
type = "postgres";
|
||||
host = "localhost"; # or socket: "/run/postgresql"
|
||||
port = "5432"; # if using socket, this is not needed
|
||||
user = "jellyseerr";
|
||||
pass = "jellyseerr";
|
||||
name = "jellyseerr";
|
||||
logQueries = "false";
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
After adding the configuration to your `configuration.nix`, you can run the following command to install jellyseerr:
|
||||
|
||||
```bash
|
||||
nixos-rebuild switch
|
||||
```
|
||||
After rebuild is complete jellyseerr should be running, verify that it is with the following command.
|
||||
```bash
|
||||
systemctl status jellyseerr
|
||||
```
|
||||
|
||||
:::info
|
||||
You can now access Seerr by visiting `http://localhost:5055` in your web browser.
|
||||
:::
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
title: Third-party Installation Methods
|
||||
---
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
:::warning
|
||||
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
|
||||
:::
|
||||
|
||||
:::info
|
||||
Want to add a third-party installation method? Contributions are welcome! Feel free to open a pull request.
|
||||
:::
|
||||
|
||||
|
||||
<DocCardList />
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
title: Nix Package Manager (Advanced)
|
||||
description: Install Seerr using Nixpkgs
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
import { SeerrVersion, NixpkgVersion } from '@site/src/components/SeerrVersion';
|
||||
import Admonition from '@theme/Admonition';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Nix Package Manager
|
||||
:::danger
|
||||
This method has not yet been updated for Seerr and is currently a work in progress.
|
||||
You can follow the ongoing work on these pull requests:
|
||||
- https://github.com/NixOS/nixpkgs/pull/450096
|
||||
- https://github.com/NixOS/nixpkgs/pull/450093
|
||||
:::
|
||||
|
||||
<!--
|
||||
:::warning
|
||||
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
This method is not recommended for most users. It is intended for advanced users who are using NixOS distribution.
|
||||
:::
|
||||
|
||||
Refer to [NixOS documentation](https://search.nixos.org/options?channel=25.05&query=seerr)
|
||||
-->
|
||||
@@ -1,111 +0,0 @@
|
||||
---
|
||||
title: Synology (Advanced)
|
||||
description: Install Seerr on Synology NAS using SynoCommunity
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
# Synology
|
||||
|
||||
:::warning
|
||||
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
This method is not recommended for most users. It is intended for advanced users who are using Synology NAS.
|
||||
:::
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Synology NAS running **DSM 7.2** or later
|
||||
- 64-bit architecture (x86_64 or ARMv8)
|
||||
- [SynoCommunity package source](https://synocommunity.com/) added to Package Center
|
||||
|
||||
## Adding the SynoCommunity Package Source
|
||||
|
||||
If you haven't already added SynoCommunity to your Package Center:
|
||||
|
||||
1. Open **Package Center** in DSM
|
||||
2. Click **Settings** in the top-right corner
|
||||
3. Go to the **Package Sources** tab
|
||||
4. Click **Add**
|
||||
5. Enter the following:
|
||||
- **Name**: `SynoCommunity`
|
||||
- **Location**: `https://packages.synocommunity.com`
|
||||
6. Click **OK**
|
||||
|
||||
## Installation
|
||||
|
||||
1. In **Package Center**, search for **Seerr**
|
||||
2. Click **Install**
|
||||
3. Follow the installation wizard prompts
|
||||
4. Package Center will automatically install any required dependencies (Node.js v22)
|
||||
|
||||
### Access Seerr
|
||||
|
||||
Once installed, access Seerr at:
|
||||
|
||||
```
|
||||
http://<your-synology-ip>:5055
|
||||
```
|
||||
|
||||
You can also click the **Open** button in Package Center or find Seerr in the DSM main menu.
|
||||
|
||||
## Configuration
|
||||
|
||||
Seerr's configuration files are stored at:
|
||||
|
||||
```
|
||||
/var/packages/seerr/var/config
|
||||
```
|
||||
|
||||
:::info
|
||||
The Seerr package runs as a dedicated service user managed by DSM. No manual permission configuration is required.
|
||||
:::
|
||||
|
||||
## Managing the Service
|
||||
|
||||
You can start, stop, and restart Seerr from **Package Center** → Find Seerr → Use the action buttons.
|
||||
|
||||
## Updating
|
||||
|
||||
When a new version is available:
|
||||
|
||||
1. Open **Package Center**
|
||||
2. Go to **Installed** packages
|
||||
3. Find **Seerr** and click **Update** if available
|
||||
|
||||
:::tip
|
||||
Enable automatic updates in Package Center settings to keep Seerr up to date.
|
||||
:::
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Viewing Logs
|
||||
|
||||
Seerr logs are located at `/var/packages/seerr/var/config/logs` and can be accessed using:
|
||||
|
||||
- **File Browser** package (recommended for most users)
|
||||
- SSH (advanced users)
|
||||
|
||||
### Port Conflicts
|
||||
|
||||
Seerr uses port 5055. If this port is already in use:
|
||||
|
||||
- **Docker containers**: Remap the conflicting container to a different port
|
||||
- **Other packages**: The conflicting package will need to be uninstalled as Seerr's port cannot be changed
|
||||
|
||||
SynoCommunity ensures there are no port conflicts with other SynoCommunity packages or official Synology packages.
|
||||
|
||||
### Package Won't Start
|
||||
|
||||
Ensure Node.js v22 is installed and running by checking its status in **Package Center**.
|
||||
|
||||
## Uninstallation
|
||||
|
||||
1. Open **Package Center**
|
||||
2. Find **Seerr** in your installed packages
|
||||
3. Click **Uninstall**
|
||||
|
||||
:::caution
|
||||
Uninstalling will remove the application but preserve your configuration data by default. Select "Remove data" during uninstallation if you want a complete removal.
|
||||
:::
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
title: TrueNAS (Advanced)
|
||||
description: Install Seerr using TrueNAS
|
||||
sidebar_position: 4
|
||||
---
|
||||
# TrueNAS
|
||||
:::warning
|
||||
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
This method is not recommended for most users. It is intended for advanced users who are using TrueNAS distribution.
|
||||
:::
|
||||
|
||||
## Installation
|
||||
|
||||
Go to the 'Apps' menu, click the 'Discover Apps' button in the top right, search for 'Seerr' in the search bar, and install the app.
|
||||
@@ -1,89 +0,0 @@
|
||||
---
|
||||
title: Unraid (Advanced)
|
||||
description: Install Seerr using Unraid
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Unraid
|
||||
|
||||
:::warning
|
||||
Third-party installation methods are maintained by the community. The Seerr team is not responsible for these packages.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
This method is not recommended for most users. It is intended for advanced users who are using Unraid.
|
||||
:::
|
||||
|
||||
|
||||
If an official Unraid Community Applications template for Seerr isn't available in your catalog, you can install Seerr manually using Unraid's Docker UI.
|
||||
|
||||
## Fresh Installation
|
||||
|
||||
### 1. Create the config directory
|
||||
|
||||
:::note
|
||||
Seerr is now rootless. Unraid typically runs Docker containers as `nobody:users` (UID 99, GID 100), but Seerr now runs internally as UID 1000, GID 1000. This creates a permission mismatch.
|
||||
:::
|
||||
|
||||
:::info
|
||||
**If migrating**: Copy your existing Jellyseerr/Overseerr config files (e.g., from `/mnt/user/appdata/overseerr/` or `/mnt/user/appdata/jellyseerr`) to `/mnt/user/appdata/seerr`, then apply the permissions below
|
||||
:::
|
||||
|
||||
Open the Unraid terminal and run:
|
||||
|
||||
```bash
|
||||
mkdir -p /mnt/user/appdata/seerr
|
||||
chown -R 1000:1000 /mnt/user/appdata/seerr
|
||||
```
|
||||
|
||||
### 2. Add the Docker container
|
||||
|
||||
Navigate to the **Docker** tab in Unraid and click **Add Container**. Fill in the following:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| **Name** | `seerr` |
|
||||
| **Repository** | `ghcr.io/seerr-team/seerr:latest` |
|
||||
| **Registry URL** (optional) | `https://ghcr.io` |
|
||||
| **Icon URL** | `https://raw.githubusercontent.com/seerr-team/seerr/develop/public/android-chrome-512x512.png` |
|
||||
| **WebUI** | `http://[IP]:[PORT:5055]` |
|
||||
| **Extra Parameters** | `--init` |
|
||||
| **Network Type** | `bridge` |
|
||||
| **Privileged** | `Off` |
|
||||
|
||||
Then click **Add another Path, Port, Variable** to add:
|
||||
|
||||
**Port:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Container Port | `5055` |
|
||||
| Host Port | `5055` |
|
||||
| Connection Type | `TCP` |
|
||||
|
||||
**Path:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Container Path | `/app/config` |
|
||||
| Host Path | `/mnt/user/appdata/seerr` |
|
||||
|
||||
**Variable:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Key | `TZ` |
|
||||
| Value | Your [TZ database name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) (e.g., `America/New_York`) |
|
||||
|
||||
**Variable (optional):**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Key | `LOG_LEVEL` |
|
||||
| Value | `info` |
|
||||
|
||||
Click **Apply** to create and start the container.
|
||||
|
||||
### 3. Access Seerr
|
||||
|
||||
Open the WebUI at `http://<your-unraid-ip>:5055` and follow the setup wizard.
|
||||
|
||||
:::info
|
||||
The `--init` flag in **Extra Parameters** is required. Seerr does not include its own init process, so `--init` ensures proper signal handling and clean container shutdowns.
|
||||
:::
|
||||
@@ -1,315 +0,0 @@
|
||||
---
|
||||
title: Migration guide
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
:::important
|
||||
Read our [release announcement](/blog/seerr-release) to learn what Seerr means for Jellyseerr and Overseerr users.
|
||||
:::
|
||||
|
||||
Whether you come from Overseerr or Jellyseerr, you don't need to perform any manual migration steps, your instance will automatically be migrated to Seerr.
|
||||
This migration will run automatically the first time you start your instance using the Seerr codebase (Docker image or source build or Kubernetes, etc.).
|
||||
An additional migration will happen for Overseerr users, to migrate their configuration to the new codebase.
|
||||
|
||||
:::danger
|
||||
Before doing anything you should backup your existing instance so that you can rollback in case something goes wrong.
|
||||
See [Backups](/using-seerr/backups) for details on how to properly backup your instance.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
Installation methods are now divided into two categories: official and third-party methods.
|
||||
The Seerr team is only responsible for official installation methods, while third-party methods are maintained by the community.
|
||||
Some methods are currently not maintained, but this does not mean they are permanently discontinued. The community may restore and support them if they choose to do so.
|
||||
|
||||
- **Snap package:** Not maintained
|
||||
:::
|
||||
|
||||
## Docker
|
||||
Refer to [Seerr Docker Documentation](/getting-started/docker), all of our examples have been updated to reflect the below change.
|
||||
|
||||
:::info
|
||||
Seerr provides a secure, fully featured image with everything you need included.
|
||||
We sincerely appreciate the past contributions from third-party maintainers, which helped enhance this image and its capabilities.
|
||||
To maintain consistency and security, we encourage everyone to use the features available in the official Seerr image.
|
||||
If you feel something is missing, please submit a feature request—your feedback is always welcome!
|
||||
|
||||
Our Docker images are available with the following tags:
|
||||
|
||||
- `latest`: Always points to the most recent stable release.
|
||||
- Version tags (e.g., `v3.0.0`): For specific stable versions.
|
||||
- `develop`: Rolling release/nightly builds for using the latest changes (use with caution).
|
||||
:::
|
||||
|
||||
Changes :
|
||||
- Renamed all references from `overseerr` or `jellyseerr` to `seerr`.
|
||||
- The container image reference has been updated.
|
||||
- The container can now be run as a non-root user (`node` user); remove the `user` directive if you have configured it.
|
||||
- The container no longer provides an init process, so you must configure it by adding `init: true` for Docker Compose or `--init` for the Docker CLI.
|
||||
|
||||
#### Config folder permissions
|
||||
:::info
|
||||
Since the container now runs as the `node` user (UID 1000), you must ensure your config folder has the correct permissions. The `node` user must have read and write access to the `/app/config` directory.
|
||||
|
||||
If you're migrating from a previous installation, you may need to update the ownership of your config folder:
|
||||
```bash
|
||||
docker run --rm -v /path/to/appdata/config:/data alpine chown -R 1000:1000 /data
|
||||
```
|
||||
|
||||
This ensures the `node` user (UID 1000) owns the config directory and can read and write to it.
|
||||
:::
|
||||
|
||||
### Unix
|
||||
|
||||
Summary of changes :
|
||||
<Tabs groupId="docker-methods" queryString>
|
||||
<TabItem value="docker-compose" label="Docker compose">
|
||||
```yaml {3-6}
|
||||
---
|
||||
services:
|
||||
seerr:
|
||||
image: ghcr.io/seerr-team/seerr:latest
|
||||
init: true
|
||||
container_name: seerr
|
||||
environment:
|
||||
- LOG_LEVEL=debug
|
||||
- TZ=Asia/Tashkent
|
||||
- PORT=5055 #optional
|
||||
ports:
|
||||
- 5055:5055
|
||||
volumes:
|
||||
- /path/to/appdata/config:/app/config
|
||||
healthcheck:
|
||||
test: wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/status || exit 1
|
||||
start_period: 20s
|
||||
timeout: 3s
|
||||
interval: 15s
|
||||
retries: 3
|
||||
restart: unless-stopped
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="docker-cli" label="Docker CLI">
|
||||
```bash {2-3,10}
|
||||
docker run -d \
|
||||
--name seerr \
|
||||
--init \
|
||||
-e LOG_LEVEL=debug \
|
||||
-e TZ=Asia/Tashkent \
|
||||
-e PORT=5055 \
|
||||
-p 5055:5055 \
|
||||
-v /path/to/appdata/config:/app/config \
|
||||
--restart unless-stopped \
|
||||
ghcr.io/seerr-team/seerr:latest
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Windows
|
||||
Summary of changes :
|
||||
<Tabs groupId="docker-methods" queryString>
|
||||
<TabItem value="docker-compose" label="Docker compose">
|
||||
```yaml {3-6,13,23}
|
||||
---
|
||||
services:
|
||||
seerr:
|
||||
image: ghcr.io/seerr-team/seerr:latest
|
||||
init: true
|
||||
container_name: seerr
|
||||
environment:
|
||||
- LOG_LEVEL=debug
|
||||
- TZ=Asia/Tashkent
|
||||
ports:
|
||||
- 5055:5055
|
||||
volumes:
|
||||
- seerr-data:/app/config
|
||||
healthcheck:
|
||||
test: wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/status || exit 1
|
||||
start_period: 20s
|
||||
timeout: 3s
|
||||
interval: 15s
|
||||
retries: 3
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
seerr-data:
|
||||
external: true
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="docker-cli" label="Docker CLI">
|
||||
```bash {2-3,8,10}
|
||||
docker run -d \
|
||||
--name seerr \
|
||||
--init \
|
||||
-e LOG_LEVEL=debug \
|
||||
-e TZ=Asia/Tashkent \
|
||||
-e PORT=5055 \
|
||||
-p 5055:5055 \
|
||||
-v seerr-data:/app/config \
|
||||
--restart unless-stopped \
|
||||
ghcr.io/seerr-team/seerr:latest
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
## Build From Source
|
||||
Refer to [Seerr Build From Source Documentation](/getting-started/buildfromsource), all of our examples have been updated to reflect the below change.
|
||||
|
||||
Install from scratch by following the documentation, restore your data as described in [Backups](/using-seerr/backups), and then start Seerr. No additional steps are required.
|
||||
|
||||
## Kubernetes
|
||||
Refer to [Seerr Kubernetes Documentation](/getting-started/kubernetes), all of our examples have been updated to reflect the below change.
|
||||
|
||||
Changes :
|
||||
- All references to `jellyseerr` have been renamed to `seerr` in the manifests.
|
||||
- The container image reference has been updated.
|
||||
- The default `securityContext` and `podSecurityContext` have been updated to support running the container without root permissions.
|
||||
|
||||
Summary of changes :
|
||||
<Tabs groupId="kubernetes-values" queryString>
|
||||
<TabItem value="old" label="Old values">
|
||||
```yaml
|
||||
image:
|
||||
repository: fallenbagel/jellyseerr
|
||||
podSecurityContext: {}
|
||||
securityContext: {}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="new" label="New values">
|
||||
```yaml
|
||||
image:
|
||||
repository: seerr-team/seerr
|
||||
podSecurityContext:
|
||||
fsGroup: 1000
|
||||
fsGroupChangePolicy: OnRootMismatch
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
readOnlyRootFilesystem: false
|
||||
runAsNonRoot: true
|
||||
privileged: false
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Third-party installation methods
|
||||
### Nix
|
||||
|
||||
Waiting for https://github.com/NixOS/nixpkgs/pull/450096 and https://github.com/NixOS/nixpkgs/pull/450093
|
||||
|
||||
### AUR
|
||||
|
||||
See https://aur.archlinux.org/packages/seerr
|
||||
|
||||
### TrueNAS
|
||||
|
||||
Refer to [Seerr TrueNAS Documentation](/getting-started/third-parties/truenas), all of our examples have been updated to reflect the below change.
|
||||
|
||||
<Tabs groupId="truenas-migration" queryString>
|
||||
<TabItem value="hostpath" label="Host Path">
|
||||
**This guide describes how to migrate from Host Path storage (not ixVolume).**
|
||||
1. Stop Jellyseerr/Overseerr
|
||||
2. Install Seerr and use the same Host Path storage that was used by Jellyseerr/Overseerr
|
||||
3. Start Seerr app
|
||||
4. Delete Jellyseerr/Overseerr app
|
||||
</TabItem>
|
||||
<TabItem value="ixvolume" label="ixVolume">
|
||||
**This guide describes how to migrate from ixVolume storage (not Host Path).**
|
||||
1. Stop Jellyseerr/Overseerr
|
||||
2. Create a dataset for Seerr
|
||||
If your apps normally store data under something like:
|
||||
```
|
||||
/mnt/storage/<app-name>
|
||||
```
|
||||
then create a dataset named:
|
||||
```
|
||||
storage/seerr
|
||||
```
|
||||
resulting in:
|
||||
```
|
||||
/mnt/storage/seerr
|
||||
```
|
||||
3. Copy ixVolume Data
|
||||
Open System Settings → Shell, or SSH into your TrueNAS server as root and run :
|
||||
```bash
|
||||
rsync -av /mnt/.ix-apps/app_mounts/jellyseerr/ /mnt/storage/seerr/
|
||||
```
|
||||
4. Install Seerr and use the same Host Path storage that was created before (`/mnt/storage/seerr/config` in our example)
|
||||
5. Start Seerr app
|
||||
6. Delete Jellyseerr/Overseerr app
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Unraid
|
||||
|
||||
Refer to [Seerr Unraid Documentation](/getting-started/third-parties/unraid), all of our examples have been updated to reflect the below change.
|
||||
|
||||
Seerr will automatically migrate your existing Overseerr or Jellyseerr data on first startup. No manual database migration is needed.
|
||||
|
||||
1. Stop and remove the old Overseerr (or Jellyseerr) container from the Unraid **Docker** tab. Click the container icon, then **Stop**, then **Remove**. **⚠️ Do not delete the appdata folder ⚠️**
|
||||
|
||||
2. Back up your existing appdata folder:
|
||||
```bash
|
||||
cp -a /mnt/user/appdata/overseerr /mnt/user/appdata/overseerr-backup
|
||||
```
|
||||
|
||||
3. Fix config folder permissions — Seerr runs as the `node` user (UID 1000) instead of root:
|
||||
```bash
|
||||
chown -R 1000:1000 /mnt/user/appdata/overseerr
|
||||
```
|
||||
For Jellyseerr users, replace `overseerr` with `jellyseerr` in the path above.
|
||||
|
||||
4. Add a new container in the Unraid **Docker** tab. Click **Add Container** and fill in the following:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| **Name** | `seerr` |
|
||||
| **Repository** | `ghcr.io/seerr-team/seerr:latest` |
|
||||
| **Registry URL** (optional) | `https://ghcr.io` |
|
||||
| **Icon URL** | `https://raw.githubusercontent.com/seerr-team/seerr/develop/public/android-chrome-512x512.png` |
|
||||
| **WebUI** | `http://[IP]:[PORT:5055]` |
|
||||
| **Extra Parameters** | `--init` |
|
||||
| **Network Type** | `bridge` |
|
||||
| **Privileged** | `Off` |
|
||||
|
||||
Then click **Add another Path, Port, Variable** to add:
|
||||
|
||||
**Port:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Container Port | `5055` |
|
||||
| Host Port | `5055` |
|
||||
| Connection Type | `TCP` |
|
||||
|
||||
**Path** — point this to your existing config folder:
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Container Path | `/app/config` |
|
||||
| Host Path | `/mnt/user/appdata/overseerr` |
|
||||
|
||||
For Jellyseerr users, use `/mnt/user/appdata/jellyseerr`.
|
||||
|
||||
**Variable:**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Key | `TZ` |
|
||||
| Value | Your [TZ database name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) (e.g., `America/New_York`) |
|
||||
|
||||
**Variable (optional):**
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Key | `LOG_LEVEL` |
|
||||
| Value | `info` |
|
||||
|
||||
5. Click **Apply** to start the container. Check the container logs to confirm the automatic migration completed successfully.
|
||||
|
||||
:::tip
|
||||
If you are using a reverse proxy (such as SWAG or Nginx Proxy Manager), update your proxy configuration to point to the new container name `seerr`. The default port remains `5055`.
|
||||
:::
|
||||
@@ -103,7 +103,7 @@ If you can't change your DNS servers or force IPV4 resolution, you can use Seerr
|
||||
|
||||
In some places (like China), the ISP blocks not only the DNS resolution but also the connection to the TMDB API.
|
||||
|
||||
You can configure Seerr to use a proxy with the [HTTP(S) Proxy](/using-seerr/settings/general#enable-proxy-support) setting.
|
||||
You can configure Seerr to use a proxy with the [HTTP(S) Proxy](/using-seerr/settings/general#https-proxy) setting.
|
||||
|
||||
### Option 3: Force IPV4 resolution first
|
||||
|
||||
@@ -174,36 +174,4 @@ This can happen if you have a new installation of Jellyfin/Emby or if you have c
|
||||
|
||||
This process should restore your admin privileges while preserving your settings.
|
||||
|
||||
## Failed to enable web push notifications
|
||||
|
||||
### Option 1: You are using Pi-hole
|
||||
|
||||
When using Pi-hole, you need to whitelist the proper domains in order for the queries to not be intercepted and blocked by Pi-hole.
|
||||
If you are using a chromium based browser (eg: Chrome, Brave, Edge...), the domain you need to whitelist is `fcm.googleapis.com`
|
||||
If you are using Firefox, the domain you need to whitelist is `push.services.mozilla.com`
|
||||
|
||||
1. Log into your Pi-hole through the admin interface, then click on Domains situated under GROUP MANAGEMENT.
|
||||
2. Add the domain corresponding to your browser in the `Domain to be added` field and then click on Add to allowed domains.
|
||||
3. Now in order for those changes to be used you need to flush your current dns cache.
|
||||
4. You can do so by using this command line in your Pi-hole terminal:
|
||||
```bash
|
||||
pihole restartdns
|
||||
```
|
||||
If this command fails (which is unlikely), use this equivalent:
|
||||
```bash
|
||||
pihole -f && pihole restartdns
|
||||
```
|
||||
5. Then restart your Seerr instance and try to enable the web push notifications again.
|
||||
|
||||
|
||||
### Option 2: You are using Brave browser
|
||||
|
||||
Brave is a "De-Googled" browser. So by default or if you refused a prompt in the past, it cuts the access to the FCM (Firebase Cloud Messaging) service, which is mandatory for the web push notifications on Chromium based browsers.
|
||||
|
||||
1. Open Brave and paste this address in the url bar: `brave://settings/privacy`
|
||||
2. Look for the option: "Use Google services for push messaging"
|
||||
3. Activate this option
|
||||
4. Relaunch Brave completely
|
||||
5. You should now see the notifications prompt appearing instead of an error message.
|
||||
|
||||
If you still encounter issues, please reach out on our support channels.
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
title: Advanced Features
|
||||
description: Advanced configuration and use cases.
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
# Advanced Features
|
||||
|
||||
## Advanced Configuration and Use Cases
|
||||
|
||||
Seerr currently offers advanced features for power users and specific use cases:
|
||||
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
<DocCardList />
|
||||
@@ -1,386 +0,0 @@
|
||||
---
|
||||
id: verifying-signed-artifacts
|
||||
title: Verifying Signed Artifacts
|
||||
sidebar_label: Verify Signed Artifacts
|
||||
description: Learn how to verify Seerr's signed artifacts and SBOM attestations.
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Verifying Signed Artifacts
|
||||
|
||||
These artifacts are cryptographically signed using [Sigstore Cosign](https://docs.sigstore.dev/quickstart/quickstart-cosign/):
|
||||
- Container images
|
||||
- Helm charts
|
||||
|
||||
This ensures that the images you pull are authentic, tamper-proof, and built by the official Seerr release pipeline.
|
||||
|
||||
Additionally each container image also includes a CycloneDX SBOM (Software Bill of Materials) attestation, generated with [Trivy](https://aquasecurity.github.io/trivy/), providing transparency about all dependencies included in the image.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
You will need the following tools installed:
|
||||
|
||||
- [Cosign](https://docs.sigstore.dev/cosign/system_config/installation/)
|
||||
|
||||
To verify images:
|
||||
|
||||
- [Docker](https://docs.docker.com/get-docker/) **or** [Podman](https://podman.io/getting-started/installation) (including [Skopeo](https://github.com/containers/skopeo/blob/main/install.md))
|
||||
|
||||
---
|
||||
|
||||
## Verifying Signed Images
|
||||
|
||||
### Image Locations
|
||||
|
||||
Official Seerr images are available from:
|
||||
|
||||
- GitHub Container Registry (GHCR): `ghcr.io/seerr-team/seerr:<tag>`
|
||||
- Docker Hub: `seerr/seerr:<tag>`
|
||||
|
||||
You can view all available tags on the [Seerr Releases page](https://github.com/seerr-team/seerr/releases).
|
||||
|
||||
---
|
||||
|
||||
### Verifying a Specific Release Tag
|
||||
|
||||
Each tagged release (for example `v2.7.4`) is immutable and cryptographically signed.
|
||||
Verification should always be performed using the image digest (SHA256).
|
||||
|
||||
#### Retrieve the Image Digest
|
||||
|
||||
<Tabs groupId="verify-methods">
|
||||
<TabItem value="docker" label="Docker">
|
||||
|
||||
```bash
|
||||
docker buildx imagetools inspect ghcr.io/seerr-team/seerr:v2.7.4 --format '{{json .Manifest.Digest}}' | tr -d '"'
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="podman" label="Podman / Skopeo">
|
||||
|
||||
```bash
|
||||
skopeo inspect docker://ghcr.io/seerr-team/seerr:v2.7.4 --format '{{.Digest}}'
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Example output:
|
||||
|
||||
```
|
||||
sha256:abcd1234...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Verify the Image Signature
|
||||
|
||||
<Tabs groupId="registry-methods">
|
||||
<TabItem value="ghcr" label="GitHub Container Registry (GHCR)">
|
||||
|
||||
```bash
|
||||
cosign verify ghcr.io/seerr-team/seerr@sha256:abcd1234... \
|
||||
--certificate-identity "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v2.7.4" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="dockerhub" label="Docker Hub">
|
||||
|
||||
```bash
|
||||
cosign verify seerr/seerr@sha256:abcd1234... \
|
||||
--certificate-identity "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v2.7.4" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::info Successful Verification Example
|
||||
Verification for `ghcr.io/seerr-team/seerr@sha256:abcd1234...`
|
||||
|
||||
The following checks were performed:
|
||||
|
||||
- Cosign claims validated
|
||||
- Signatures verified against the transparency log
|
||||
- Certificate issued by Fulcio to the expected workflow identity
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
### Verifying the `latest` Tag
|
||||
|
||||
:::warning Latest Tag Warning
|
||||
The `latest` tag is **mutable**, meaning it will change with each new release.
|
||||
Always verify the digest that `latest` currently points to.
|
||||
:::
|
||||
|
||||
#### Retrieve the Digest for `latest`
|
||||
|
||||
<Tabs groupId="verify-methods">
|
||||
<TabItem value="docker" label="Docker">
|
||||
|
||||
```bash
|
||||
docker buildx imagetools inspect ghcr.io/seerr-team/seerr:latest --format '{{json .Manifest.Digest}}' | tr -d '"'
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="podman" label="Podman / Skopeo">
|
||||
|
||||
```bash
|
||||
skopeo inspect docker://ghcr.io/seerr-team/seerr:latest --format '{{.Digest}}'
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Example output:
|
||||
|
||||
```
|
||||
sha256:abcd1234...
|
||||
```
|
||||
|
||||
#### Verify the Signature
|
||||
|
||||
<Tabs groupId="registry-methods">
|
||||
<TabItem value="ghcr" label="GHCR">
|
||||
|
||||
```bash
|
||||
cosign verify ghcr.io/seerr-team/seerr@sha256:abcd1234... \
|
||||
--certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="dockerhub" label="Docker Hub">
|
||||
|
||||
```bash
|
||||
cosign verify seerr/seerr@sha256:abcd1234... \
|
||||
--certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
The wildcard `v.*` ensures verification works for any versioned release that `latest` represents.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
### Verifying SBOM Attestations
|
||||
|
||||
Each image includes a CycloneDX SBOM attestation.
|
||||
|
||||
#### Verify the Attestation
|
||||
|
||||
```bash
|
||||
cosign verify-attestation ghcr.io/seerr-team/seerr@sha256:abcd1234... \
|
||||
--type cyclonedx \
|
||||
--certificate-identity "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v2.7.4" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
```
|
||||
:::info Successful Verification Example
|
||||
Verification for `ghcr.io/seerr-team/seerr@sha256:abcd1234...`
|
||||
|
||||
The following checks were performed:
|
||||
|
||||
- Cosign claims validated
|
||||
- Signatures verified against the transparency log
|
||||
- Certificate issued by Fulcio to the expected workflow identity
|
||||
:::
|
||||
|
||||
#### Extract the SBOM for Inspection
|
||||
|
||||
```bash
|
||||
cosign verify-attestation ghcr.io/seerr-team/seerr@sha256:abcd1234... \
|
||||
--type cyclonedx \
|
||||
--certificate-identity "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v2.7.4" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" | jq -r '.payload | @base64d' > sbom.json
|
||||
```
|
||||
|
||||
You can open `sbom.json` in a CycloneDX viewer or analyse it with [Trivy](https://aquasecurity.github.io/trivy/) or [Dependency-Track](https://dependencytrack.org/).
|
||||
|
||||
---
|
||||
|
||||
### Expected Certificate Identity
|
||||
|
||||
The expected certificate identity for all signed Seerr images is:
|
||||
|
||||
```
|
||||
https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v*
|
||||
```
|
||||
|
||||
This confirms that the image was:
|
||||
|
||||
- Built by the official Seerr Release workflow
|
||||
- Produced from the seerr-team/seerr repository
|
||||
- Signed using GitHub’s OIDC identity via Sigstore Fulcio
|
||||
|
||||
---
|
||||
|
||||
### Example: Full Verification Flow
|
||||
|
||||
<Tabs groupId="verify-examples">
|
||||
<TabItem value="docker" label="Docker">
|
||||
|
||||
```bash
|
||||
DIGEST=$(docker buildx imagetools inspect ghcr.io/seerr-team/seerr:latest --format '{{json .Manifest.Digest}}' | tr -d '"')
|
||||
|
||||
cosign verify ghcr.io/seerr-team/seerr@"$DIGEST" \
|
||||
--certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
|
||||
cosign verify-attestation ghcr.io/seerr-team/seerr@"$DIGEST" \
|
||||
--type cyclonedx \
|
||||
--certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="podman" label="Podman / Skopeo">
|
||||
|
||||
```bash
|
||||
DIGEST=$(skopeo inspect docker://ghcr.io/seerr-team/seerr:latest --format '{{.Digest}}')
|
||||
|
||||
cosign verify ghcr.io/seerr-team/seerr@"$DIGEST" \
|
||||
--certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/release.yml@refs/tags/v.*" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Verifying Signed Helm charts
|
||||
|
||||
### Helm Chart Locations
|
||||
|
||||
Official Seerr helm charts are available from:
|
||||
|
||||
- GitHub Container Registry (GHCR): `ghcr.io/seerr-team/seerr/seerr-chart/seerr-chart:<tag>`
|
||||
|
||||
You can view all available tags on the [Seerr Releases page](https://github.com/seerr-team/seerr/pkgs/container/seerr%2Fseerr-chart).
|
||||
|
||||
---
|
||||
|
||||
### Verifying a Specific Release Tag
|
||||
|
||||
Each tagged release (for example `3.0.0`) is immutable and cryptographically signed.
|
||||
Verification should always be performed using the image digest (SHA256).
|
||||
|
||||
#### Retrieve the Helm Chart Digest
|
||||
|
||||
<Tabs groupId="verify-methods">
|
||||
<TabItem value="docker" label="Docker">
|
||||
|
||||
```bash
|
||||
docker buildx imagetools inspect ghcr.io/seerr-team/seerr/seerr-chart:3.0.0 --format '{{json .Manifest.Digest}}' | tr -d '"'
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="podman" label="Podman / Skopeo">
|
||||
|
||||
```bash
|
||||
skopeo inspect docker://ghcr.io/seerr-team/seerr/seerr-chart:3.0.0 --format '{{.Digest}}'
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Example output:
|
||||
|
||||
```
|
||||
sha256:abcd1234...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Verify the Helm Chart Signature
|
||||
|
||||
```bash
|
||||
cosign verify ghcr.io/seerr-team/seerr/seerr-chart@sha256:abcd1234... \
|
||||
--certificate-identity "https://github.com/seerr-team/seerr/.github/workflows/helm.yml@refs/heads/main" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
```
|
||||
|
||||
:::info Successful Verification Example
|
||||
Verification for `ghcr.io/seerr-team/seerr/seerr-chart@sha256:abcd1234...`
|
||||
|
||||
The following checks were performed:
|
||||
|
||||
- Cosign claims validated
|
||||
- Signatures verified against the transparency log
|
||||
- Certificate issued by Fulcio to the expected workflow identity
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
### Expected Certificate Identity
|
||||
|
||||
The expected certificate identity for all signed Seerr images is:
|
||||
|
||||
```
|
||||
https://github.com/seerr-team/seerr/.github/workflows/helm.yml@refs/heads/main
|
||||
```
|
||||
|
||||
This confirms that the image was:
|
||||
|
||||
- Built by the official Seerr Release workflow
|
||||
- Produced from the seerr-team/seerr repository
|
||||
- Signed using GitHub’s OIDC identity via Sigstore Fulcio
|
||||
|
||||
---
|
||||
|
||||
### Example: Full Verification Flow
|
||||
|
||||
<Tabs groupId="verify-examples">
|
||||
<TabItem value="docker" label="Docker">
|
||||
|
||||
```bash
|
||||
DIGEST=$(docker buildx imagetools inspect ghcr.io/seerr-team/seerr/seerr-chart:3.0.0 --format '{{json .Manifest.Digest}}' | tr -d '"')
|
||||
|
||||
cosign verify ghcr.io/seerr-team/seerr/seerr-chart@"$DIGEST" \
|
||||
--certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/helm.yml@refs/heads/main" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
|
||||
cosign verify-attestation ghcr.io/seerr-team/seerr/seerr-chart@"$DIGEST" \
|
||||
--type cyclonedx \
|
||||
--certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/helm.yml@refs/heads/main" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="podman" label="Podman / Skopeo">
|
||||
|
||||
```bash
|
||||
DIGEST=$(skopeo inspect docker://ghcr.io/seerr-team/seerr/seerr-chart:3.0.0 --format '{{.Digest}}')
|
||||
|
||||
cosign verify ghcr.io/seerr-team/seerr/seerr-chart@"$DIGEST" \
|
||||
--certificate-identity-regexp "https://github.com/seerr-team/seerr/.github/workflows/helm.yml@refs/heads/main" \
|
||||
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Issue | Likely Cause | Suggested Fix |
|
||||
|-------|---------------|----------------|
|
||||
| `no matching signatures` | Incorrect digest or tag | Retrieve the digest again using Docker or Skopeo |
|
||||
| `certificate identity does not match expected` | Workflow reference changed | Ensure your `--certificate-identity` matches this documentation |
|
||||
| `cosign: command not found` | Cosign not installed | Install Cosign from the official release |
|
||||
| `certificate expired` | Old release | Verify a newer tag or digest |
|
||||
|
||||
---
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [Sigstore Documentation](https://docs.sigstore.dev)
|
||||
- [Cosign Verification Guide](https://docs.sigstore.dev/cosign/verifying/verify/)
|
||||
- [CycloneDX Specification](https://cyclonedx.org/specification/overview/)
|
||||
- [Trivy Documentation](https://trivy.dev/latest/docs/)
|
||||
- [Skopeo Documentation](https://github.com/containers/skopeo)
|
||||
- [Podman Documentation](https://podman.io/get-started/)
|
||||
- [Docker Documentation](https://docs.docker.com/)
|
||||
- [Seerr GitHub Repository](https://github.com/seerr-team/seerr)
|
||||
@@ -13,7 +13,7 @@ These settings are stored in the `settings.json` file located in the Seerr data
|
||||
|
||||
## User Data
|
||||
|
||||
Apart from the settings, all other data—including user accounts, media requests, blocklist etc. are stored in the database (either SQLite or PostgreSQL).
|
||||
Apart from the settings, all other data—including user accounts, media requests, blacklist etc. are stored in the database (either SQLite or PostgreSQL).
|
||||
|
||||
# Backup
|
||||
|
||||
|
||||
@@ -22,4 +22,4 @@ Users can customize their notification preferences in their own user notificatio
|
||||
|
||||
## Requesting New Notification Agents
|
||||
|
||||
If we do not currently support your preferred notification agent, feel free to [submit a feature request on GitHub](https://github.com/seerr-team/seerr/issues). However, please be sure to search first and confirm that there is not already an existing request for the agent!
|
||||
If we do not currently support your preferred notification agent, feel free to [submit a feature request on GitHub](https://github.com/fallenbagel/jellyseerr/issues). However, please be sure to search first and confirm that there is not already an existing request for the agent!
|
||||
|
||||
@@ -16,7 +16,7 @@ User notifications are separate from system notifications, and the available not
|
||||
|
||||
### Application/API Token
|
||||
|
||||
[Register an application](https://pushover.net/apps/build) and enter the API token in this field. (You can use one of the [official icons in our GitHub repository](https://github.com/seerr-team/seerr/tree/develop/public) when configuring the application.)
|
||||
[Register an application](https://pushover.net/apps/build) and enter the API token in this field. (You can use one of the [official icons in our GitHub repository](https://github.com/fallenbagel/jellyseerr/tree/develop/public) when configuring the application.)
|
||||
|
||||
For more details on registering applications or the API token, please see the [Pushover API documentation](https://pushover.net/api#registration).
|
||||
|
||||
|
||||
@@ -6,22 +6,18 @@ sidebar_position: 2
|
||||
|
||||
# Web Push
|
||||
|
||||
The web push notification agent enables you and your users to receive Seerr notifications in a supported browser.
|
||||
|
||||
This notification agent does not require any configuration, but is not enabled in Seerr
|
||||
|
||||
:::warning
|
||||
Web push notifications require a secure connection to your Seerr instance. Refer to the [Reverse Proxy](/extending-seerr/reverse-proxy) documentation for more information.
|
||||
:::
|
||||
|
||||
The web push notification agent enables you and your users to receive Seerr notifications in a supported browser. This offers a native notification experience without the need to install an app.
|
||||
To set up web push notifications, simply enable the agent in **Settings → Notifications → Web Push**. You and your users will then be prompted to allow notifications in your web browser.
|
||||
|
||||
This notification agent does not require any configuration, but is not enabled by default in Seerr.
|
||||
Users can opt out of these notifications, or customize the notification types they would like to subscribe to, in their user settings.
|
||||
|
||||
To set up web push notifications, simply enable the agent in **Settings → Notifications → Web Push**.
|
||||
|
||||
You and your users have the option to enable web push notifications by going to your **User Profile → Edit Settings → Notifications → Web Push → Enable web push**. Here you can also customize the notifications you'd like to receive.
|
||||
|
||||
:::info[Mobile Users]
|
||||
For Web Push notifications to work on mobile you need to add Seerr to your home screen as progressive web app (PWA).
|
||||
:::
|
||||
|
||||
:::info[iOS Users]
|
||||
On iOS you may need to enable the Safari notifications feature flag by going to **Settings → Safari → Advanced → Feature Flags** and enabling "Notifications".
|
||||
:::info
|
||||
Web push notifications offer a native notification experience without the need to install an app.
|
||||
:::
|
||||
|
||||
@@ -62,13 +62,13 @@ Set the default display language for Seerr. Users can override this setting in t
|
||||
|
||||
These settings filter content shown on the "Discover" home page based on regional availability and original language, respectively. The Streaming Region filters the available streaming providers on the media page. Users can override these global settings by configuring these same options in their user settings.
|
||||
|
||||
## Blocklist Content with Tags and Limit Content Blocklisted per Tag
|
||||
## Blacklist Content with Tags and Limit Content Blacklisted per Tag
|
||||
|
||||
These settings blocklist any TV shows or movies that have one of the entered tags. The "Process Blocklisted Tags" job adds entries to the blocklist based on the configured blocklisted tags. If a blocklisted tag is removed, any media blocklisted under that tag will be removed from the blocklist when the "Process Blocklisted Tags" job runs.
|
||||
These settings blacklist any TV shows or movies that have one of the entered tags. The "Process Blacklisted Tags" job adds entries to the blacklist based on the configured blacklisted tags. If a blacklisted tag is removed, any media blacklisted under that tag will be removed from the blacklist when the "Process Blacklisted Tags" job runs.
|
||||
|
||||
The limit setting determines how many pages per tag the job will process, with each page containing 20 entries. The job cycles through all 16 available discovery sort options, querying the defined number of pages to blocklist media that is most likely to appear at the top of each sort. Higher limits will create a more accurate blocklist, but will require more storage.
|
||||
The limit setting determines how many pages per tag the job will process, with each page containing 20 entries. The job cycles through all 16 available discovery sort options, querying the defined number of pages to blacklist media that is most likely to appear at the top of each sort. Higher limits will create a more accurate blacklist, but will require more storage.
|
||||
|
||||
Blocklisted tags are disabled until at least one tag is entered. These settings cannot be overridden in user settings.
|
||||
Blacklisted tags are disabled until at least one tag is entered. These settings cannot be overridden in user settings.
|
||||
|
||||
## Hide Available Media
|
||||
|
||||
@@ -78,9 +78,9 @@ Available media will still appear in search results, however, so it is possible
|
||||
|
||||
This setting is **disabled** by default.
|
||||
|
||||
## Hide Blocklisted Items
|
||||
## Hide Blacklisted Items
|
||||
|
||||
When enabled, media that has been blocklisted will not appear on the "Discover" home page, for all administrators. This can be useful to hide content that you don't want to see, such as content with specific tags or content that has been manually blocklisted when you have the "Manage Blocklist" permission.
|
||||
When enabled, media that has been blacklisted will not appear on the "Discover" home page, for all administrators. This can be useful to hide content that you don't want to see, such as content with specific tags or content that has been manually blacklisted when you have the "Manage Blacklist" permission.
|
||||
|
||||
This setting is **disabled** by default.
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ Seerr docs will be available at [docs.seerr.dev](https://docs.seerr.dev).
|
||||
### Installation
|
||||
|
||||
```
|
||||
$ pnpm install
|
||||
$ pnpm
|
||||
```
|
||||
|
||||
### Local Development
|
||||
|
||||
24
gen-docs/blog/2025-09-29-introducing-jellyseerr-blog.md
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
title: Welcome to the Jellyseerr Blog
|
||||
description: The official Jellyseerr blog for release notes, technical updates, and community news.
|
||||
slug: welcome
|
||||
authors: [fallenbagel, gauthier-th]
|
||||
tags: [announcement, jellyseerr, blog]
|
||||
image: https://raw.githubusercontent.com/fallenbagel/jellyseerr/refs/heads/develop/gen-docs/static/img/logo.svg
|
||||
hide_table_of_contents: false
|
||||
---
|
||||
|
||||
We are pleased to introduce the official Jellyseerr blog.
|
||||
|
||||
This space will serve as the central place for:
|
||||
|
||||
- Release announcements
|
||||
- Updates on new features and improvements
|
||||
- Technical articles, such as details on our [**DNS caching package**](https://github.com/jellyseerr/dns-caching) and other enhancements
|
||||
- Community-related news
|
||||
|
||||
<!--truncate-->
|
||||
|
||||
Our goal is to keep the community informed and provide deeper insights into the ongoing development of Jellyseerr.
|
||||
|
||||
Thank you for being part of the Jellyseerr project. More updates will follow soon.
|
||||
@@ -1,24 +0,0 @@
|
||||
---
|
||||
title: Welcome to the Seerr Blog
|
||||
description: The official Seerr blog for release notes, technical updates, and community news.
|
||||
slug: welcome
|
||||
authors: [fallenbagel, gauthier-th]
|
||||
tags: [announcement, seerr, blog]
|
||||
image: https://raw.githubusercontent.com/seerr-team/seerr/refs/heads/develop/gen-docs/static/img/logo_full.svg
|
||||
hide_table_of_contents: false
|
||||
---
|
||||
|
||||
We are pleased to introduce the official Seerr blog.
|
||||
|
||||
This space will serve as the central place for:
|
||||
|
||||
- Release announcements
|
||||
- Updates on new features and improvements
|
||||
- Technical articles, such as details on our [**DNS caching package**](https://github.com/seerr/dns-caching) and other enhancements
|
||||
- Community-related news
|
||||
|
||||
<!--truncate-->
|
||||
|
||||
Our goal is to keep the community informed and provide deeper insights into the ongoing development of Seerr.
|
||||
|
||||
Thank you for being part of the Seerr project. More updates will follow soon.
|
||||
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 166 KiB |
@@ -1,127 +0,0 @@
|
||||
---
|
||||
title: "Seerr Release: Unifying Overseerr and Jellyseerr"
|
||||
description: "Overseerr and Jellyseerr are merging into a unified project: Seerr"
|
||||
slug: seerr-release
|
||||
authors: [seerr-team]
|
||||
image: https://raw.githubusercontent.com/seerr-team/seerr/refs/heads/develop/gen-docs/static/img/logo_full.svg
|
||||
hide_table_of_contents: false
|
||||
---
|
||||
|
||||
We're excited to announce a major update: the Jellyseerr and Overseerr teams are officially merging into a single team called **Seerr**. This unification marks an important step forward as we bring our efforts together under one banner.
|
||||
|
||||
For users, this means one shared codebase combining all existing Overseerr functionalities with the latest Jellyseerr features, along with Jellyfin and Emby support, allowing us to deliver updates more efficiently and keep the project moving forward.
|
||||
|
||||
Please check how to migrate to Seerr in our [migration guide](https://docs.seerr.dev/migration-guide) and stay tuned for more updates on the project!
|
||||
|
||||
<!--truncate-->
|
||||
|
||||
## What's new in Seerr for Overseerr users
|
||||
|
||||
Seerr brings several features that were previously available in Jellyseerr but missing from Overseerr. These additions improve flexibility, performance, and overall control for admins and power users:
|
||||
|
||||
* **Alternative media solution:** Added support for Jellyfin and Emby as alternatives to Plex. Only one integration can be used at a time.
|
||||
* **PostgreSQL support**: In addition to SQLite, you can now opt in to using a PostgreSQL database.
|
||||
* **Blocklist for movies, series, and tags**: Allows permitted users to hide movies, series, or tags from regular users.
|
||||
* **Override rules**: Adjust default request settings based on conditions such as user, tag, or other criteria.
|
||||
* **TVDB metadata**: Option to use TheTVDB metadata for series (as in Sonarr) instead of TMDB.
|
||||
* **DNS caching**: Reduces lookup times and external requests, especially useful when using systems like Pi-Hole/Adguard Home.
|
||||
* **Helm chart included**: Enables easier installation and maintenance in Kubernetes environments.
|
||||
* **ntfy.sh notifications**: Support for sending notifications via ntfy.sh.
|
||||
* **Disable special seasons:** Adds a setting to prevent special seasons from being shown or requested.
|
||||
* **New languages**: Turkish and Basque
|
||||
|
||||
## What's new since the previous Jellyseerr release
|
||||
|
||||
This release also brings several important improvements and long-requested features, including **TheTVDB metadata support**, **DNS caching**, and **dynamic webhook placeholders**, along with a few quality-of-life improvements for developers and users alike.
|
||||
|
||||
### PNPM v10 Upgrade
|
||||
|
||||
We're updating Seerr to **PNPM v10** to keep up-to-date development tools. If you are building Seerr from source or if you contribute to Seerr, you'll need to **update your local PNPM installation** before working on the project.
|
||||
|
||||
This doesn't concern you if you're using Docker.
|
||||
|
||||
To update, run the following command:
|
||||
`pnpm self-update`
|
||||
|
||||
After updating, verify your version with:
|
||||
`pnpm -v`
|
||||
|
||||
You should see version **10.x.x**.
|
||||
|
||||
### TVDB Metadata Provider (Experimental)
|
||||
|
||||
We're excited to introduce support for **TheTVDB** as a new metadata provider!
|
||||
Previously, Seerr relied solely on **TMDB** for movie and TV show information, which sometimes led to discrepancies in season and episode numbering when working with **Sonarr**, since Sonarr uses **TheTVDB** as its metadata source.
|
||||
|
||||
With this new integration, Seerr can now use **the same data source as Sonarr** for series and anime, ensuring consistent and accurate season and episode information across both platforms.
|
||||
|
||||
You can try this new experimental feature in the new “Metadata Providers” tab of the settings page:
|
||||
|
||||

|
||||
|
||||
### DNS Caching (Experimental)
|
||||
|
||||
By default, Node.js doesn't cache any DNS requests. Our DNS cache manager addresses the problems caused by extremely high DNS query rates, particularly for large Jellyfin libraries as each HTTP request was also resulting in another DNS request. Therefore, by caching these DNS lookups, **Seerr will now reduce stress on DNS servers** and avoid rate-limiting or blocks encountered with services like **Pi-Hole**/**Adguard Home**.
|
||||
|
||||
We will post another blog post soon on all the issues we encountered with DNS caching in Node.js.
|
||||
|
||||
You can enable this by checking the “DNS Cache” setting in the network tabs of the Seerr settings:
|
||||
|
||||

|
||||
|
||||
### AniDB for Jellyfin Libraries
|
||||
|
||||
This new version also brings additional metadata to Jellyfin-managed collections. When there's no provider ID from TMDB or TVDB, Seerr will automatically **fall back on AniDB**, expanding coverage for lesser-known or region-specific anime.
|
||||
|
||||
### Dynamic Placeholders in Webhook URLs
|
||||
|
||||
Webhook notifications are now more powerful and adaptable with **dynamic placeholder support in webhook URLs**. This allows Seerr to automatically replace placeholders in the webhook URL with real values at runtime.
|
||||
|
||||
For example, you can include the requester's username directly in your webhook URL to better integrate with third-party services or user-specific endpoints.
|
||||
|
||||
This feature can be enabled from the **Notifications** settings page, where available placeholders are listed for reference. It's currently marked as **experimental**, and we welcome community feedback to help refine and expand support for additional placeholders in future releases.
|
||||
|
||||
### Optional Images in Notifications
|
||||
|
||||
Another small feature: **images in notifications are now optional** (but still enabled by default). Previous versions always included images in notifications, which could lead to broken links or failed requests if images were missing or unavailable.
|
||||
|
||||
### Security improvement
|
||||
|
||||
Some outdated dependencies have been updated (some work is still in progress). Helm charts and containers are now cryptographically signed and can be verified and enforced client-side. Containers now run as rootless. Workflows have been completely reworked to minimize third-party actions. Permissions have been strengthened, and actions are now pinned to specific hashes for better traceability. The release process has been updated to remove many outdated and plugin dependencies, replacing them with more standard industry solutions.
|
||||
|
||||
:::important
|
||||
## Note for PostgreSQL users (optional)
|
||||
|
||||
If you're migrating Postgres from version 17 to 18 in Docker, note that the data mount point has changed. Instead of using `/var/lib/postgresql/data`, the correct mount path is now `/var/lib/postgresql`. This update of the mount point is required to ensure the container functions correctly after the upgrade.
|
||||
:::
|
||||
|
||||
## Conclusion
|
||||
|
||||
Seerr is built and maintained by dedicated volunteer contributors, whose skills and commitment make it all possible. Many thanks to everyone who contributed to this version:
|
||||
|
||||
* [0xsysr3ll](https://github.com/0xSysR3ll)
|
||||
* [ale183](https://github.com/ale183)
|
||||
* [Brandon Cohen](https://github.com/OwsleyJr)
|
||||
* [Disparate2761](https://github.com/Disparate2761)
|
||||
* [fallenbagel](https://github.com/fallenbagel)
|
||||
* [Gauthier](https://github.com/gauthier-th)
|
||||
* [Gauvain](https://github.com/Gauvino)
|
||||
* [Georgy](https://github.com/tarasverq)
|
||||
* [Ishan Jain](https://github.com/ishanjain28)
|
||||
* [James Kruger](https://github.com/theGunner295)
|
||||
* [Joe Harrison](https://github.com/sudo-kraken)
|
||||
* [J. Winters-Brown](https://github.com/ofgrenudo)
|
||||
* [Ludovic Ortega](https://github.com/M0NsTeRRR)
|
||||
* [RolliePollie18](https://github.com/RolliePollie18)
|
||||
* [Ryan Cohen](https://github.com/sct)
|
||||
* [salty](https://github.com/saltydk)
|
||||
* [samohtxotom](https://github.com/samohtxotom)
|
||||
* [Sergii Bogomolov](https://github.com/sbogomolov)
|
||||
* [Someone](https://github.com/InterN0te)
|
||||
* [TacoCake](https://github.com/TacoCake)
|
||||
* [Terry Sposato](https://github.com/tsposato)
|
||||
* [TheCatLady](https://github.com/TheCatLady)
|
||||
* [Thibaut Noah](https://github.com/tirrorex)
|
||||
* [THOMAS B](https://github.com/TOomaAh)
|
||||
|
||||
Keep an eye on our blog for in-depth looks at our work and upcoming releases!
|
||||
@@ -1,8 +1,8 @@
|
||||
fallenbagel:
|
||||
name: Fallenbagel
|
||||
page: true
|
||||
title: Developer & Maintainer of Seerr
|
||||
description: Core Maintainer & Developer of Seerr | Full-Stack Software Engineer | MSc Software Engineering Student.
|
||||
title: Developer & Maintainer of Jellyseerr
|
||||
description: Core Maintainer & Developer of Jellyseerr | Full-Stack Software Engineer | MSc Software Engineering Candidate.
|
||||
url: https://github.com/fallenbagel
|
||||
image_url: https://github.com/fallenbagel.png
|
||||
email: hello@fallenbagel.com
|
||||
@@ -12,18 +12,10 @@ fallenbagel:
|
||||
gauthier-th:
|
||||
name: Gauthier
|
||||
page: true
|
||||
title: Developer & Maintainer of Seerr
|
||||
description: Core Maintainer & Developer of Seerr | PhD Student in AI at ICB, Dijon
|
||||
title: Co-Developer & Co-Maintainer of Jellyseerr
|
||||
description: Co-Maintainer & Developer of Jellyseerr | PhD Student in AI at ICB, Dijon
|
||||
url: https://gauthierth.fr
|
||||
image_url: https://github.com/gauthier-th.png
|
||||
email: mail@gauthierth.fr
|
||||
socials:
|
||||
github: gauthier-th
|
||||
|
||||
seerr-team:
|
||||
name: Seerr Team
|
||||
title: The team behind Seerr, formerly known as the Jellyseerr and Overseerr teams.
|
||||
url: https://seerr.dev
|
||||
image_url: https://github.com/seerr-team.png
|
||||
socials:
|
||||
github: seerr-team
|
||||
|
||||
@@ -16,12 +16,7 @@ const config: Config = {
|
||||
deploymentBranch: 'gh-pages',
|
||||
|
||||
onBrokenLinks: 'throw',
|
||||
|
||||
markdown: {
|
||||
hooks: {
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
},
|
||||
},
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
@@ -69,7 +64,7 @@ const config: Config = {
|
||||
navbar: {
|
||||
logo: {
|
||||
alt: 'Seerr',
|
||||
src: 'img/logo_full.svg',
|
||||
src: 'img/logo.svg',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
@@ -77,11 +72,6 @@ const config: Config = {
|
||||
label: 'Blog',
|
||||
position: 'right',
|
||||
},
|
||||
{
|
||||
href: 'https://discord.gg/seerr',
|
||||
label: 'Discord',
|
||||
position: 'right',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/seerr-team/seerr',
|
||||
label: 'GitHub',
|
||||
|
||||
@@ -7,7 +7,7 @@ export const SeerrVersion = () => {
|
||||
async function fetchVersion() {
|
||||
try {
|
||||
const response = await fetch(
|
||||
'https://raw.githubusercontent.com/seerr-team/seerr/main/package.json'
|
||||
'https://raw.githubusercontent.com/fallenbagel/jellyseerr/main/package.json'
|
||||
);
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
@@ -60,12 +60,12 @@
|
||||
|
||||
.table-of-contents__link--active,
|
||||
a:not(
|
||||
.card,
|
||||
.menu__link,
|
||||
.menu__link--sublist,
|
||||
.menu__link--sublist-item,
|
||||
.table-of-contents__link
|
||||
) {
|
||||
.card,
|
||||
.menu__link,
|
||||
.menu__link--sublist,
|
||||
.menu__link--sublist-item,
|
||||
.table-of-contents__link
|
||||
) {
|
||||
/* color: #793ae8; */
|
||||
color: #6366f1;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
185
gen-docs/static/img/logo.svg
Normal file
|
After Width: | Height: | Size: 25 KiB |
@@ -1,21 +0,0 @@
|
||||
<svg width="322" height="96" viewBox="0 0 322 96" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="52" cy="52" r="28" fill="#131928"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M48 96C74.5097 96 96 74.5097 96 48C96 21.4903 74.5097 0 48 0C21.4903 0 0 21.4903 0 48C0 74.5097 21.4903 96 48 96ZM80.0001 52C80.0001 67.464 67.4641 80 52.0001 80C36.5361 80 24.0001 67.464 24.0001 52C24.0001 49.1303 24.4318 46.3615 25.2338 43.7548C27.4288 48.6165 32.3194 52 38.0001 52C45.7321 52 52.0001 45.732 52.0001 38C52.0001 32.3192 48.6166 27.4287 43.755 25.2337C46.3616 24.4317 49.1304 24 52.0001 24C67.4641 24 80.0001 36.536 80.0001 52Z" fill="url(#paint0_linear_311_158)"/>
|
||||
<path opacity="0.2" fill-rule="evenodd" clip-rule="evenodd" d="M80.0002 52C80.0002 67.464 67.4642 80 52.0002 80C36.864 80 24.5329 67.9897 24.017 52.9791C24.0057 53.318 24 53.6583 24 54C24 70.5685 37.4315 84 54 84C70.5685 84 84 70.5685 84 54C84 37.4315 70.5685 24 54 24C53.6597 24 53.3207 24.0057 52.9831 24.0169C67.9919 24.5347 80.0002 36.865 80.0002 52Z" fill="#131928"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M48 12C28.1177 12 12 28.1177 12 48C12 50.2091 10.2091 52 8 52C5.79086 52 4 50.2091 4 48C4 23.6995 23.6995 4 48 4C50.2091 4 52 5.79086 52 8C52 10.2091 50.2091 12 48 12Z" fill="url(#paint1_linear_311_158)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M298.984 30.8668V70.2724H308.169V46.8278C308.169 42.3005 309.082 39.1207 310.909 37.2882C312.789 35.4558 315.528 34.5395 319.127 34.5395H321.463V25C318.402 25 315.743 25.6467 313.487 26.9402C311.285 28.1798 309.512 29.9315 308.169 32.1951V25.7276H307.886L298.984 30.8668Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M269.573 31.1166V70.2724H278.758V46.8278C278.758 42.3005 279.671 39.1207 281.498 37.2882C283.377 35.4558 286.117 34.5395 289.716 34.5395H292.052V25C288.99 25 286.332 25.6467 284.076 26.9402C281.874 28.1798 280.101 29.9315 278.758 32.1951V25.8137L269.573 31.1166Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M260.689 43.8748C260.922 45.5294 261.026 47.0387 261 48.4029L232.595 52.395L233.533 44.7524L250.79 42.3272C250.264 38.9722 248.689 36.4452 246.063 34.746C243.438 33.0468 240.396 32.4402 236.939 32.9261C233.801 33.3671 231.257 34.7587 229.308 37.1008C227.756 38.9167 226.837 41.1061 226.55 43.6692C226.192 46.3457 226.195 50.8608 227.977 55.1055C228.886 57.629 230.398 59.6138 232.513 61.0602C235.153 62.8661 238.176 63.5299 241.58 63.0514C246.473 62.3637 249.642 59.823 251.085 55.4294L260.899 54.0501C260.139 58.2932 258.188 61.9691 255.045 65.0776C251.948 68.1254 247.819 70.0118 242.66 70.7369C238.458 71.3274 234.55 70.9242 230.936 69.5272C227.369 68.0693 224.387 65.767 221.992 62.6204C219.643 59.4129 218.15 55.5408 217.512 51.0043C216.875 46.4677 217.22 42.3645 218.549 38.6946C219.923 34.9638 222.127 31.9327 225.163 29.6012C228.251 27.2623 231.949 25.7901 236.258 25.1846C240.407 24.6015 244.231 24.9892 247.731 26.3479C251.23 27.7065 254.117 29.9132 256.39 32.9681C258.656 35.9696 260.089 39.6051 260.689 43.8748Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M209.921 43.8748C210.154 45.5293 210.258 47.0387 210.232 48.4029L181.827 52.395L182.765 44.7524L200.022 42.3272C199.496 38.9722 197.921 36.4452 195.295 34.746C192.67 33.0468 189.628 32.4402 186.171 32.9261C183.033 33.3671 180.489 34.7587 178.54 37.1008C176.988 38.9166 176.069 41.1059 175.782 43.6688C175.424 46.3453 175.427 50.8605 177.209 55.1055C178.118 57.629 179.63 59.6138 181.745 61.0602C184.385 62.8661 187.407 63.5299 190.812 63.0514C195.705 62.3637 198.874 59.823 200.317 55.4294L210.131 54.0501C209.371 58.2932 207.42 61.9691 204.277 65.0776C201.18 68.1254 197.051 70.0118 191.892 70.7369C187.69 71.3274 183.782 70.9242 180.168 69.5272C176.601 68.0693 173.619 65.767 171.224 62.6204C168.875 59.4129 167.382 55.5408 166.744 51.0043C166.107 46.4677 166.452 42.3645 167.78 38.6946C169.155 34.9638 171.359 31.9327 174.395 29.6012C177.483 27.2623 181.181 25.7901 185.49 25.1846C189.639 24.6015 193.463 24.9892 196.962 26.3479C200.462 27.7065 203.349 29.9132 205.622 32.9681C207.888 35.9696 209.321 39.6051 209.921 43.8748Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M143.297 71C139.806 71 136.664 70.3802 133.87 69.1406C131.131 67.8471 128.956 66.1224 127.344 63.9666C126.751 63.153 126.26 62.3066 125.87 61.4272L134.397 57.451C134.721 58.9735 135.566 60.2831 136.932 61.3796C138.597 62.6192 140.665 63.239 143.136 63.239C145.714 63.239 147.702 62.754 149.098 61.7838C150.548 60.7598 151.273 59.4663 151.273 57.9033C151.273 56.2326 150.468 54.993 148.856 54.1845C147.299 53.3761 144.801 52.4868 141.363 51.5167C138.033 50.6005 135.321 49.7112 133.226 48.8489C131.131 47.9865 129.305 46.6661 127.747 44.8875C126.243 43.109 125.491 40.7645 125.491 37.8541C125.491 35.4827 126.189 33.3269 127.586 31.3866C128.983 29.3925 130.97 27.8295 133.548 26.6977C136.18 25.5659 139.188 25 142.572 25C147.621 25 151.676 26.2935 154.738 28.8805C156.667 30.4488 158.04 32.3787 158.857 34.6701L150.459 38.5862C150.177 36.9271 149.402 35.5782 148.131 34.5395C146.681 33.3538 144.72 32.761 142.25 32.761C139.833 32.761 137.979 33.2191 136.69 34.1353C135.401 35.0516 134.757 36.2642 134.757 37.7733C134.757 38.959 135.186 39.9561 136.046 40.7645C136.905 41.5729 137.953 42.2197 139.188 42.7047C140.423 43.1359 142.25 43.7018 144.667 44.4025C147.89 45.2648 150.521 46.1541 152.563 47.0703C154.657 47.9326 156.457 49.2261 157.961 50.9508C159.465 52.6755 160.244 54.966 160.297 57.8225C160.297 60.3556 159.599 62.6192 158.202 64.6134C156.806 66.6075 154.818 68.1705 152.24 69.3023C149.716 70.4341 146.735 71 143.297 71Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_311_158" x1="48" y1="-2.07126e-06" x2="117.5" y2="69.5" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#C395FC"/>
|
||||
<stop offset="1" stop-color="#4F65F5"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_311_158" x1="28" y1="8" x2="28" y2="48" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0.4"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.0 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" fill="none" viewBox="0 0 96 96"><path fill="url(#paint0_linear)" fill-rule="evenodd" d="M48 96C74.5097 96 96 74.5097 96 48C96 21.4903 74.5097 0 48 0C21.4903 0 0 21.4903 0 48C0 74.5097 21.4903 96 48 96ZM80.0001 52C80.0001 67.464 67.4641 80 52.0001 80C36.5361 80 24.0001 67.464 24.0001 52C24.0001 49.1303 24.4318 46.3615 25.2338 43.7548C27.4288 48.6165 32.3194 52 38.0001 52C45.7321 52 52.0001 45.732 52.0001 38C52.0001 32.3192 48.6166 27.4287 43.755 25.2337C46.3616 24.4317 49.1304 24 52.0001 24C67.4641 24 80.0001 36.536 80.0001 52Z" clip-rule="evenodd"/><path fill="#131928" fill-rule="evenodd" d="M80.0002 52C80.0002 67.464 67.4642 80 52.0002 80C36.864 80 24.5329 67.9897 24.017 52.9791C24.0057 53.318 24 53.6583 24 54C24 70.5685 37.4315 84 54 84C70.5685 84 84 70.5685 84 54C84 37.4315 70.5685 24 54 24C53.6597 24 53.3207 24.0057 52.9831 24.0169C67.9919 24.5347 80.0002 36.865 80.0002 52Z" clip-rule="evenodd" opacity=".2"/><path fill="url(#paint1_linear)" fill-rule="evenodd" d="M48 12C28.1177 12 12 28.1177 12 48C12 50.2091 10.2091 52 8 52C5.79086 52 4 50.2091 4 48C4 23.6995 23.6995 4 48 4C50.2091 4 52 5.79086 52 8C52 10.2091 50.2091 12 48 12Z" clip-rule="evenodd"/><defs><linearGradient id="paint0_linear" x1="48" x2="117.5" y1="0" y2="69.5" gradientUnits="userSpaceOnUse"><stop stop-color="#C395FC"/><stop offset="1" stop-color="#4F65F5"/></linearGradient><linearGradient id="paint1_linear" x1="28" x2="28" y1="8" y2="48" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" stop-opacity=".4"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient></defs></svg>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
21
merged-prettier-plugin.js
Normal file
@@ -0,0 +1,21 @@
|
||||
/* eslint-disable */
|
||||
const tailwind = require('prettier-plugin-tailwindcss');
|
||||
const organizeImports = require('prettier-plugin-organize-imports');
|
||||
|
||||
const combinedFormatter = {
|
||||
...tailwind,
|
||||
parsers: {
|
||||
...tailwind.parsers,
|
||||
...Object.keys(organizeImports.parsers).reduce((acc, key) => {
|
||||
acc[key] = {
|
||||
...tailwind.parsers[key],
|
||||
preprocess(code, options) {
|
||||
return organizeImports.parsers[key].preprocess(code, options);
|
||||
},
|
||||
};
|
||||
return acc;
|
||||
}, {}),
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = combinedFormatter;
|
||||
@@ -24,6 +24,6 @@ module.exports = {
|
||||
},
|
||||
experimental: {
|
||||
scrollRestoration: true,
|
||||
largePageDataBytes: 512 * 1000,
|
||||
largePageDataBytes: 256000,
|
||||
},
|
||||
};
|
||||
|
||||
225
package.json
@@ -2,9 +2,10 @@
|
||||
"name": "seerr",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@10.24.0",
|
||||
"packageManager": "pnpm@10.17.1",
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"postinstall": "node postinstall-win.js",
|
||||
"dev": "nodemon -e ts --watch server --watch seerr-api.yml -e .json,.ts,.yml -x ts-node -r tsconfig-paths/register --files --project server/tsconfig.json server/index.ts",
|
||||
"build:server": "tsc --project server/tsconfig.json && copyfiles -u 2 server/templates/**/*.{html,pug} dist/templates && tsc-alias -p server/tsconfig.json",
|
||||
"build:next": "next build",
|
||||
@@ -16,7 +17,7 @@
|
||||
"migration:generate": "ts-node -r tsconfig-paths/register --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:generate -d server/datasource.ts",
|
||||
"migration:create": "ts-node -r tsconfig-paths/register --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:create -d server/datasource.ts",
|
||||
"migration:run": "ts-node -r tsconfig-paths/register --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:run -d server/datasource.ts",
|
||||
"format": "prettier --log-level warn --write --cache .",
|
||||
"format": "prettier --loglevel warn --write --cache .",
|
||||
"format:check": "prettier --check --cache .",
|
||||
"typecheck": "pnpm typecheck:server && pnpm typecheck:client",
|
||||
"typecheck:server": "tsc --project server/tsconfig.json --noEmit",
|
||||
@@ -32,150 +33,155 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@dr.pogodin/csurf": "^1.16.6",
|
||||
"@formatjs/intl-displaynames": "6.8.13",
|
||||
"@dr.pogodin/csurf": "^1.14.1",
|
||||
"@formatjs/intl-displaynames": "6.2.6",
|
||||
"@formatjs/intl-locale": "3.1.1",
|
||||
"@formatjs/intl-pluralrules": "5.4.6",
|
||||
"@formatjs/intl-pluralrules": "5.1.10",
|
||||
"@formatjs/intl-utils": "3.8.4",
|
||||
"@formatjs/swc-plugin-experimental": "^0.4.0",
|
||||
"@headlessui/react": "1.7.12",
|
||||
"@heroicons/react": "2.2.0",
|
||||
"@seerr-team/react-tailwindcss-datepicker": "^1.3.4",
|
||||
"@heroicons/react": "2.0.16",
|
||||
"@supercharge/request-ip": "1.2.0",
|
||||
"@svgr/webpack": "6.5.1",
|
||||
"@tanem/react-nprogress": "5.0.56",
|
||||
"@tanem/react-nprogress": "5.0.30",
|
||||
"@types/ua-parser-js": "^0.7.36",
|
||||
"@types/wink-jaro-distance": "^2.0.2",
|
||||
"ace-builds": "1.43.4",
|
||||
"axios": "1.13.3",
|
||||
"axios-rate-limit": "1.4.0",
|
||||
"bcrypt": "6.0.0",
|
||||
"bowser": "2.13.1",
|
||||
"ace-builds": "1.15.2",
|
||||
"axios": "1.10.0",
|
||||
"axios-rate-limit": "1.3.0",
|
||||
"bcrypt": "5.1.0",
|
||||
"bowser": "2.11.0",
|
||||
"connect-typeorm": "1.1.4",
|
||||
"cookie-parser": "1.4.7",
|
||||
"copy-to-clipboard": "3.3.3",
|
||||
"country-flag-icons": "1.6.4",
|
||||
"country-flag-icons": "1.5.5",
|
||||
"cronstrue": "2.23.0",
|
||||
"date-fns": "2.29.3",
|
||||
"dayjs": "1.11.7",
|
||||
"dns-caching": "^0.2.7",
|
||||
"email-templates": "12.0.3",
|
||||
"email-templates": "12.0.1",
|
||||
"email-validator": "2.0.4",
|
||||
"express": "4.21.2",
|
||||
"express-openapi-validator": "4.13.8",
|
||||
"express-rate-limit": "6.7.0",
|
||||
"express-session": "1.18.2",
|
||||
"formik": "^2.4.9",
|
||||
"express-session": "1.17.3",
|
||||
"formik": "^2.4.6",
|
||||
"gravatar-url": "3.1.0",
|
||||
"http-proxy-agent": "^7.0.2",
|
||||
"https-proxy-agent": "^7.0.6",
|
||||
"lodash": "4.17.23",
|
||||
"lodash": "4.17.21",
|
||||
"mime": "3",
|
||||
"next": "^14.2.35",
|
||||
"next": "^14.2.25",
|
||||
"node-cache": "5.1.2",
|
||||
"node-gyp": "9.3.1",
|
||||
"node-schedule": "2.1.1",
|
||||
"nodemailer": "7.0.12",
|
||||
"openpgp": "6.3.0",
|
||||
"pg": "8.17.2",
|
||||
"nodemailer": "6.10.0",
|
||||
"openpgp": "5.11.2",
|
||||
"pg": "8.11.0",
|
||||
"plex-api": "5.3.2",
|
||||
"pug": "3.0.3",
|
||||
"react": "^18.3.1",
|
||||
"react-ace": "10.1.0",
|
||||
"react-animate-height": "2.1.2",
|
||||
"react-aria": "3.44.0",
|
||||
"react-aria": "3.23.0",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-intersection-observer": "9.4.3",
|
||||
"react-intl": "^6.6.8",
|
||||
"react-markdown": "8.0.5",
|
||||
"react-popper-tooltip": "4.4.2",
|
||||
"react-select": "5.10.2",
|
||||
"react-select": "5.7.0",
|
||||
"react-spring": "9.7.1",
|
||||
"react-tailwindcss-datepicker-sct": "1.3.4",
|
||||
"react-toast-notifications": "2.5.1",
|
||||
"react-transition-group": "^4.4.5",
|
||||
"react-truncate-markup": "5.1.2",
|
||||
"react-use-clipboard": "1.0.9",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"secure-random-password": "0.2.3",
|
||||
"semver": "7.7.3",
|
||||
"semver": "7.7.1",
|
||||
"sharp": "^0.33.4",
|
||||
"sqlite3": "5.1.7",
|
||||
"swagger-ui-express": "4.6.2",
|
||||
"swr": "2.3.8",
|
||||
"swr": "2.2.5",
|
||||
"tailwind-merge": "^2.6.0",
|
||||
"typeorm": "0.3.28",
|
||||
"typeorm": "0.3.12",
|
||||
"ua-parser-js": "^1.0.35",
|
||||
"undici": "^7.18.2",
|
||||
"validator": "^13.15.23",
|
||||
"web-push": "3.6.7",
|
||||
"undici": "^7.3.0",
|
||||
"web-push": "3.5.0",
|
||||
"wink-jaro-distance": "^2.0.0",
|
||||
"winston": "3.19.0",
|
||||
"winston": "3.8.2",
|
||||
"winston-daily-rotate-file": "4.7.1",
|
||||
"xml2js": "0.5.0",
|
||||
"xml2js": "0.4.23",
|
||||
"yamljs": "0.3.0",
|
||||
"yup": "0.32.11",
|
||||
"zod": "4.3.6"
|
||||
"zod": "3.24.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "17.4.4",
|
||||
"@commitlint/config-conventional": "17.4.4",
|
||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@types/bcrypt": "6.0.0",
|
||||
"@types/cookie-parser": "1.4.10",
|
||||
"@types/country-flag-icons": "1.2.2",
|
||||
"@types/csurf": "1.11.5",
|
||||
"@tailwindcss/aspect-ratio": "0.4.2",
|
||||
"@tailwindcss/forms": "0.5.10",
|
||||
"@tailwindcss/typography": "0.5.16",
|
||||
"@types/bcrypt": "5.0.0",
|
||||
"@types/cookie-parser": "1.4.3",
|
||||
"@types/country-flag-icons": "1.2.0",
|
||||
"@types/csurf": "1.11.2",
|
||||
"@types/email-templates": "8.0.4",
|
||||
"@types/express": "4.17.17",
|
||||
"@types/express-session": "1.18.2",
|
||||
"@types/lodash": "4.17.21",
|
||||
"@types/express-session": "1.17.6",
|
||||
"@types/lodash": "4.14.191",
|
||||
"@types/mime": "3",
|
||||
"@types/node": "22.10.5",
|
||||
"@types/node-schedule": "2.1.8",
|
||||
"@types/nodemailer": "7",
|
||||
"@types/node-schedule": "2.1.0",
|
||||
"@types/nodemailer": "6.4.7",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/react-transition-group": "4.4.12",
|
||||
"@types/react-transition-group": "4.4.5",
|
||||
"@types/secure-random-password": "0.2.1",
|
||||
"@types/semver": "7.7.1",
|
||||
"@types/swagger-ui-express": "4.1.8",
|
||||
"@types/validator": "^13.15.10",
|
||||
"@types/web-push": "3.6.4",
|
||||
"@types/xml2js": "0.4.14",
|
||||
"@types/semver": "7.3.13",
|
||||
"@types/swagger-ui-express": "4.1.3",
|
||||
"@types/web-push": "3.3.2",
|
||||
"@types/xml2js": "0.4.11",
|
||||
"@types/yamljs": "0.2.31",
|
||||
"@types/yup": "0.29.14",
|
||||
"@typescript-eslint/eslint-plugin": "7.18.0",
|
||||
"@typescript-eslint/parser": "7.18.0",
|
||||
"autoprefixer": "^10.4.23",
|
||||
"baseline-browser-mapping": "^2.8.32",
|
||||
"commitizen": "4.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "5.54.0",
|
||||
"@typescript-eslint/parser": "5.54.0",
|
||||
"autoprefixer": "10.4.13",
|
||||
"commitizen": "4.3.0",
|
||||
"copyfiles": "2.4.1",
|
||||
"cy-mobile-commands": "0.3.0",
|
||||
"cypress": "14.5.4",
|
||||
"cypress": "14.1.0",
|
||||
"cz-conventional-changelog": "3.3.0",
|
||||
"eslint": "8.57.1",
|
||||
"eslint-config-next": "^14.2.35",
|
||||
"eslint": "8.35.0",
|
||||
"eslint-config-next": "^14.2.4",
|
||||
"eslint-config-prettier": "8.6.0",
|
||||
"eslint-plugin-formatjs": "4.9.0",
|
||||
"eslint-plugin-jsx-a11y": "6.10.2",
|
||||
"eslint-plugin-no-relative-import-paths": "1.6.1",
|
||||
"eslint-plugin-jsx-a11y": "6.7.1",
|
||||
"eslint-plugin-no-relative-import-paths": "1.5.2",
|
||||
"eslint-plugin-prettier": "4.2.1",
|
||||
"eslint-plugin-react": "7.37.5",
|
||||
"eslint-plugin-react": "7.32.2",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"husky": "8.0.3",
|
||||
"lint-staged": "13.1.2",
|
||||
"nodemon": "3.1.11",
|
||||
"postcss": "^8.5.6",
|
||||
"prettier": "3.8.1",
|
||||
"prettier-plugin-organize-imports": "4.3.0",
|
||||
"prettier-plugin-tailwindcss": "0.6.14",
|
||||
"tailwindcss": "3.4.19",
|
||||
"ts-node": "10.9.2",
|
||||
"tsc-alias": "1.8.16",
|
||||
"tsconfig-paths": "4.2.0",
|
||||
"typescript": "5.4.5"
|
||||
"nodemon": "3.1.9",
|
||||
"postcss": "8.4.31",
|
||||
"prettier": "2.8.4",
|
||||
"prettier-plugin-organize-imports": "3.2.2",
|
||||
"prettier-plugin-tailwindcss": "0.2.3",
|
||||
"tailwindcss": "3.2.7",
|
||||
"ts-node": "10.9.1",
|
||||
"tsc-alias": "1.8.2",
|
||||
"tsconfig-paths": "4.1.2",
|
||||
"typescript": "4.9.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^22.0.0",
|
||||
"pnpm": "^10.0.0"
|
||||
},
|
||||
"overrides": {
|
||||
"sqlite3/node-gyp": "8.4.1",
|
||||
"@types/express-session": "1.17.6"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
@@ -195,17 +201,74 @@
|
||||
"@commitlint/config-conventional"
|
||||
]
|
||||
},
|
||||
"release": {
|
||||
"plugins": [
|
||||
"@semantic-release/commit-analyzer",
|
||||
"@semantic-release/release-notes-generator",
|
||||
"@semantic-release/npm",
|
||||
[
|
||||
"@codedependant/semantic-release-docker",
|
||||
{
|
||||
"dockerArgs": {
|
||||
"COMMIT_TAG": "${GITHUB_SHA}"
|
||||
},
|
||||
"dockerLogin": false,
|
||||
"dockerProject": "fallenbagel",
|
||||
"dockerImage": "jellyseerr",
|
||||
"dockerTags": [
|
||||
"latest",
|
||||
"{{major}}",
|
||||
"{{major}}.{{minor}}",
|
||||
"{{major}}.{{minor}}.{{patch}}"
|
||||
],
|
||||
"dockerPlatform": [
|
||||
"linux/amd64",
|
||||
"linux/arm64"
|
||||
]
|
||||
}
|
||||
],
|
||||
[
|
||||
"@codedependant/semantic-release-docker",
|
||||
{
|
||||
"dockerArgs": {
|
||||
"COMMIT_TAG": "${GITHUB_SHA}"
|
||||
},
|
||||
"dockerLogin": false,
|
||||
"dockerRegistry": "ghcr.io",
|
||||
"dockerProject": "fallenbagel",
|
||||
"dockerImage": "jellyseerr",
|
||||
"dockerTags": [
|
||||
"latest",
|
||||
"{{major}}",
|
||||
"{{major}}.{{minor}}",
|
||||
"{{major}}.{{minor}}.{{patch}}"
|
||||
],
|
||||
"dockerPlatform": [
|
||||
"linux/amd64",
|
||||
"linux/arm64"
|
||||
]
|
||||
}
|
||||
],
|
||||
[
|
||||
"@semantic-release/github",
|
||||
{
|
||||
"addReleases": "bottom"
|
||||
}
|
||||
]
|
||||
],
|
||||
"branches": [
|
||||
"main"
|
||||
],
|
||||
"npmPublish": false,
|
||||
"publish": [
|
||||
"@codedependant/semantic-release-docker",
|
||||
"@semantic-release/github"
|
||||
]
|
||||
},
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
"@swc/core",
|
||||
"bcrypt",
|
||||
"cypress",
|
||||
"sharp",
|
||||
"sqlite3"
|
||||
],
|
||||
"overrides": {
|
||||
"sqlite3>node-gyp": "8.4.1",
|
||||
"@types/express-session": "1.18.2"
|
||||
}
|
||||
"sqlite3",
|
||||
"bcrypt"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
9451
pnpm-lock.yaml
generated
13
postinstall-win.js
Normal file
@@ -0,0 +1,13 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
const typeormPath = path.resolve('node_modules/typeorm');
|
||||
|
||||
if (fs.existsSync(typeormPath)) {
|
||||
process.stdout.write('> Installing typeorm@0.3.11 for Windows\n');
|
||||
execSync('pnpm add typeorm@0.3.11', { stdio: 'inherit' });
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 38 KiB |
BIN
public/apple-splash-1179-2556.jpg
Normal file
|
After Width: | Height: | Size: 38 KiB |