quasarr 2.4.10__tar.gz → 2.4.11__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of quasarr might be problematic. Click here for more details.
- {quasarr-2.4.10 → quasarr-2.4.11}/.github/workflows/PullRequests.yml +65 -58
- {quasarr-2.4.10 → quasarr-2.4.11}/.github/workflows/Release.yml +43 -72
- {quasarr-2.4.10 → quasarr-2.4.11}/.gitignore +4 -0
- quasarr-2.4.11/.pre-commit-config.yaml +9 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/CONTRIBUTING.md +9 -3
- {quasarr-2.4.10 → quasarr-2.4.11}/PKG-INFO +1 -1
- quasarr-2.4.10/maintenance.py → quasarr-2.4.11/pre-commit.py +42 -53
- {quasarr-2.4.10 → quasarr-2.4.11}/pyproject.toml +5 -2
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/__init__.py +3 -3
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/api/__init__.py +1 -1
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/api/captcha/__init__.py +1 -1
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/api/config/__init__.py +1 -1
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/api/sponsors_helper/__init__.py +2 -2
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/linkcrypters/hide.py +1 -1
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/packages/__init__.py +5 -5
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/al.py +1 -1
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/dw.py +1 -1
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/sf.py +1 -1
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/notifications.py +1 -1
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/shared_state.py +0 -6
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/version.py +1 -1
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/al.py +0 -5
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/he.py +1 -2
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/storage/sqlite_database.py +1 -1
- {quasarr-2.4.10 → quasarr-2.4.11}/uv.lock +135 -1
- {quasarr-2.4.10 → quasarr-2.4.11}/.github/FUNDING.yml +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/.github/workflows/HostnameRedaction.yml +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/LICENSE +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/Quasarr.png +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/Quasarr.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/README.md +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/docker/Dockerfile +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/docker/dev-services-compose.yml +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/docker/docker-compose.yml +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/api/arr/__init__.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/api/packages/__init__.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/api/statistics/__init__.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/__init__.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/linkcrypters/__init__.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/linkcrypters/al.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/linkcrypters/filecrypt.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/__init__.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/by.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/dd.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/dj.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/dl.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/dt.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/he.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/mb.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/nk.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/nx.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/sj.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/sl.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/wd.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/downloads/sources/wx.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/__init__.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/auth.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/cloudflare.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/hostname_issues.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/html_images.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/html_templates.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/imdb_metadata.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/jd_cache.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/log.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/myjd_api.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/obfuscated.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/sessions/__init__.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/sessions/al.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/sessions/dd.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/sessions/dl.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/sessions/nx.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/statistics.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/utils.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/providers/web_server.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/__init__.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/__init__.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/by.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/dd.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/dj.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/dl.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/dt.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/dw.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/fx.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/mb.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/nk.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/nx.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/sf.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/sj.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/sl.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/wd.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/search/sources/wx.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/storage/__init__.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/storage/config.py +0 -0
- {quasarr-2.4.10 → quasarr-2.4.11}/quasarr/storage/setup.py +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: Pull Requests
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
workflow_dispatch:
|
|
@@ -34,8 +34,9 @@ jobs:
|
|
|
34
34
|
with:
|
|
35
35
|
enable-cache: true
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
- run: |
|
|
38
|
+
echo "🐍 Installing Python 3.12..."
|
|
39
|
+
uv python install 3.12
|
|
39
40
|
|
|
40
41
|
- name: Run Maintenance
|
|
41
42
|
id: manager
|
|
@@ -46,7 +47,9 @@ jobs:
|
|
|
46
47
|
GITHUB_REPO: ${{ github.repository }}
|
|
47
48
|
WORKFLOW_NAME: ${{ github.workflow }}
|
|
48
49
|
run: |
|
|
49
|
-
|
|
50
|
+
echo "🛠️ Running pre-commit.py..."
|
|
51
|
+
uv run pre-commit.py --ci
|
|
52
|
+
echo "✨ Maintenance complete."
|
|
50
53
|
|
|
51
54
|
version:
|
|
52
55
|
needs: [ quality-check ]
|
|
@@ -63,7 +66,10 @@ jobs:
|
|
|
63
66
|
with:
|
|
64
67
|
enable-cache: true
|
|
65
68
|
- id: version
|
|
66
|
-
run:
|
|
69
|
+
run: |
|
|
70
|
+
VERSION=$(uv run python quasarr/providers/version.py)
|
|
71
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
72
|
+
echo "🏷️ Detected version: $VERSION"
|
|
67
73
|
|
|
68
74
|
build-wheel:
|
|
69
75
|
needs: [ quality-check, version ]
|
|
@@ -83,7 +89,9 @@ jobs:
|
|
|
83
89
|
- uses: astral-sh/setup-uv@v5
|
|
84
90
|
with:
|
|
85
91
|
enable-cache: true
|
|
86
|
-
- run:
|
|
92
|
+
- run: |
|
|
93
|
+
echo "📦 Building Python Wheel..."
|
|
94
|
+
uv build
|
|
87
95
|
- id: attest
|
|
88
96
|
uses: actions/attest-build-provenance@v2
|
|
89
97
|
with:
|
|
@@ -106,38 +114,32 @@ jobs:
|
|
|
106
114
|
- uses: actions/setup-python@v5
|
|
107
115
|
with:
|
|
108
116
|
python-version: '3.12'
|
|
109
|
-
|
|
110
117
|
- uses: astral-sh/setup-uv@v5
|
|
111
118
|
with:
|
|
112
119
|
enable-cache: true
|
|
113
|
-
cache-suffix: "win-build"
|
|
114
|
-
|
|
115
|
-
# --- CACHE ---
|
|
120
|
+
cache-suffix: "win-build"
|
|
116
121
|
- name: Cache PyInstaller Analysis
|
|
117
122
|
uses: actions/cache@v4
|
|
118
123
|
with:
|
|
119
124
|
path: |
|
|
120
125
|
build
|
|
121
126
|
~\AppData\Local\pyinstaller
|
|
122
|
-
# Invalidates cache only if dependencies (uv.lock) change
|
|
123
127
|
key: pyinstaller-analysis-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
|
124
128
|
restore-keys: |
|
|
125
129
|
pyinstaller-analysis-${{ runner.os }}-
|
|
126
|
-
|
|
127
130
|
- shell: powershell
|
|
128
|
-
run:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
run: |
|
|
132
|
+
echo "🛡️ Disabling Real-time Monitoring..."
|
|
133
|
+
Set-MpPreference -DisableRealtimeMonitoring $true
|
|
134
|
+
- run: |
|
|
135
|
+
echo "📥 Syncing dependencies..."
|
|
136
|
+
uv sync --group build
|
|
133
137
|
- run: |
|
|
138
|
+
echo "🪟 Starting PyInstaller build..."
|
|
134
139
|
uv run python -c "from PIL import Image; Image.open('Quasarr.png').save('Quasarr.ico')"
|
|
135
140
|
uv run python quasarr/providers/version.py --create-version-file
|
|
136
|
-
# 1. Removed '--clean'
|
|
137
|
-
# 2. Added '--workpath "build"' (Matches the cached path above)
|
|
138
|
-
# 3. Added '--distpath "dist"' (Explicit output folder)
|
|
139
141
|
uv run pyinstaller --onefile -y --version-file "file_version_info.txt" --workpath "build" --distpath "dist" --icon "Quasarr.ico" "Quasarr.py" -n "quasarr-${{ needs.version.outputs.version }}-standalone-win64"
|
|
140
|
-
|
|
142
|
+
echo "✅ EXE build finished."
|
|
141
143
|
- uses: actions/upload-artifact@v4
|
|
142
144
|
with:
|
|
143
145
|
name: exe-amd64
|
|
@@ -165,6 +167,7 @@ jobs:
|
|
|
165
167
|
myToken: ${{ secrets.GITHUB_TOKEN }}
|
|
166
168
|
- name: Create Release Body
|
|
167
169
|
run: |
|
|
170
|
+
echo "📝 Generating Release Body..."
|
|
168
171
|
echo "### Docker:" > release_body.md
|
|
169
172
|
echo "\`docker pull ${{ env.GHCR_ENDPOINT }}:beta\`" >> release_body.md
|
|
170
173
|
echo "### Python:" >> release_body.md
|
|
@@ -200,7 +203,8 @@ jobs:
|
|
|
200
203
|
registry: ghcr.io
|
|
201
204
|
username: ${{ github.actor }}
|
|
202
205
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
203
|
-
-
|
|
206
|
+
- name: Build and Push
|
|
207
|
+
uses: docker/build-push-action@v6
|
|
204
208
|
with:
|
|
205
209
|
context: ./docker
|
|
206
210
|
platforms: linux/amd64
|
|
@@ -231,7 +235,8 @@ jobs:
|
|
|
231
235
|
registry: ghcr.io
|
|
232
236
|
username: ${{ github.actor }}
|
|
233
237
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
234
|
-
-
|
|
238
|
+
- name: Build and Push
|
|
239
|
+
uses: docker/build-push-action@v6
|
|
235
240
|
with:
|
|
236
241
|
context: ./docker
|
|
237
242
|
platforms: linux/arm64
|
|
@@ -257,6 +262,7 @@ jobs:
|
|
|
257
262
|
username: ${{ github.actor }}
|
|
258
263
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
259
264
|
- run: |
|
|
265
|
+
echo "🔗 Merging Docker manifests..."
|
|
260
266
|
TAG_AMD64="${{ needs.version.outputs.version }}-beta-amd64"
|
|
261
267
|
TAG_ARM64="${{ needs.version.outputs.version }}-beta-arm64"
|
|
262
268
|
ANNOTATION="index:org.opencontainers.image.description=$DESCRIPTION"
|
|
@@ -274,15 +280,13 @@ jobs:
|
|
|
274
280
|
notify:
|
|
275
281
|
name: Notify Discord & PR
|
|
276
282
|
needs: [ quality-check, version, beta-release, merge-docker-manifest ]
|
|
277
|
-
# Only run if the build wasn't skipped by the auto-fixer and the release succeeded
|
|
278
283
|
if: needs.quality-check.outputs.changes_pushed != 'true' && needs.beta-release.result == 'success'
|
|
279
284
|
runs-on: ubuntu-latest
|
|
280
285
|
permissions:
|
|
281
|
-
pull-requests: write
|
|
286
|
+
pull-requests: write
|
|
282
287
|
contents: read
|
|
283
288
|
steps:
|
|
284
289
|
- uses: actions/checkout@v6
|
|
285
|
-
|
|
286
290
|
- name: Send Notifications
|
|
287
291
|
env:
|
|
288
292
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -290,45 +294,48 @@ jobs:
|
|
|
290
294
|
VERSION: ${{ needs.version.outputs.version }}
|
|
291
295
|
REPO: ${{ github.repository }}
|
|
292
296
|
run: |
|
|
293
|
-
echo "
|
|
294
|
-
# Get the body of the release we just created (beta tag)
|
|
297
|
+
echo "📢 Notifying stakeholders..."
|
|
295
298
|
RELEASE_BODY=$(gh release view beta --json body --jq .body)
|
|
296
|
-
|
|
297
|
-
# --- 1. DISCORD NOTIFICATION ---
|
|
298
299
|
if [ -n "$DISCORD_WEBHOOK" ]; then
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
# Construct a JSON payload safely using jq (handles escaping quotes/newlines)
|
|
302
|
-
# We create a simple embed with the version and the release body
|
|
303
|
-
jq -n \
|
|
304
|
-
--arg title "🚀 New Beta Build: $VERSION" \
|
|
305
|
-
--arg desc "$RELEASE_BODY" \
|
|
306
|
-
--arg url "https://github.com/$REPO/releases/tag/beta" \
|
|
307
|
-
'{content: null, embeds: [{title: $title, description: $desc, url: $url, color: 5814783}]}' \
|
|
308
|
-
> discord_payload.json
|
|
309
|
-
|
|
310
|
-
curl -H "Content-Type: application/json" \
|
|
311
|
-
-d @discord_payload.json \
|
|
312
|
-
"$DISCORD_WEBHOOK"
|
|
313
|
-
else
|
|
314
|
-
echo "::warning::Skipping Discord notification (DISCORD_WEBHOOK secret not set)"
|
|
300
|
+
jq -n --arg title "🚀 New Beta Build: $VERSION" --arg desc "$RELEASE_BODY" --arg url "https://github.com/$REPO/releases/tag/beta" '{content: null, embeds: [{title: $title, description: $desc, url: $url, color: 5814783}]}' > discord_payload.json
|
|
301
|
+
curl -H "Content-Type: application/json" -d @discord_payload.json "$DISCORD_WEBHOOK"
|
|
315
302
|
fi
|
|
316
|
-
|
|
317
|
-
# --- 2. PR COMMENT FALLBACK ---
|
|
318
|
-
# Find the PR associated with the commit that triggered this push
|
|
319
|
-
echo "Looking for associated PR..."
|
|
320
303
|
PR_NUMBER=$(gh pr list --search "${{ github.sha }}" --state merged --json number --jq '.[0].number')
|
|
321
|
-
|
|
322
304
|
if [ -n "$PR_NUMBER" ]; then
|
|
323
|
-
echo "Found PR #$PR_NUMBER. Posting comment..."
|
|
324
|
-
|
|
325
305
|
echo "## 🚀 Beta Release $VERSION is Live!" > pr_comment.md
|
|
326
|
-
echo "" >> pr_comment.md
|
|
327
306
|
echo "$RELEASE_BODY" >> pr_comment.md
|
|
328
|
-
echo "" >> pr_comment.md
|
|
329
|
-
echo "[View Release on GitHub](https://github.com/$REPO/releases/tag/beta)" >> pr_comment.md
|
|
330
|
-
|
|
331
307
|
gh pr comment "$PR_NUMBER" --body-file pr_comment.md
|
|
308
|
+
fi
|
|
309
|
+
|
|
310
|
+
job-summary:
|
|
311
|
+
name: 📊 Beta Summary
|
|
312
|
+
runs-on: ubuntu-latest
|
|
313
|
+
needs: [ quality-check, version, beta-release ]
|
|
314
|
+
if: always()
|
|
315
|
+
steps:
|
|
316
|
+
- name: Generate Summary
|
|
317
|
+
run: |
|
|
318
|
+
echo "## 🧪 Beta Build Summary" >> $GITHUB_STEP_SUMMARY
|
|
319
|
+
|
|
320
|
+
# Maintenance Outcome
|
|
321
|
+
if [[ "${{ needs.quality-check.outputs.changes_pushed }}" == "true" ]]; then
|
|
322
|
+
echo "### 🛠️ Maintenance Status: **Auto-Fixed**" >> $GITHUB_STEP_SUMMARY
|
|
323
|
+
echo "The script found formatting or dependency issues and pushed fixes directly. The current build was skipped to allow the new commit to run." >> $GITHUB_STEP_SUMMARY
|
|
332
324
|
else
|
|
333
|
-
echo "
|
|
325
|
+
echo "### ✨ Maintenance Status: **Clean**" >> $GITHUB_STEP_SUMMARY
|
|
326
|
+
echo "No formatting or maintenance issues were detected." >> $GITHUB_STEP_SUMMARY
|
|
334
327
|
fi
|
|
328
|
+
|
|
329
|
+
# Decision Logic
|
|
330
|
+
echo "### 🚦 Workflow Decision" >> $GITHUB_STEP_SUMMARY
|
|
331
|
+
if [[ "${{ needs.version.result }}" == "success" ]]; then
|
|
332
|
+
echo "✅ **Proceeded:** The build moved to beta release (Dev branch detected)." >> $GITHUB_STEP_SUMMARY
|
|
333
|
+
else
|
|
334
|
+
echo "🛑 **Stopped:** Build did not proceed to release (Not on dev or quality-check failed)." >> $GITHUB_STEP_SUMMARY
|
|
335
|
+
fi
|
|
336
|
+
|
|
337
|
+
echo "### 📦 Artifact Details" >> $GITHUB_STEP_SUMMARY
|
|
338
|
+
echo "| Metric | Value |" >> $GITHUB_STEP_SUMMARY
|
|
339
|
+
echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY
|
|
340
|
+
echo "| **Version** | \`${{ needs.version.outputs.version || 'N/A' }}\` |" >> $GITHUB_STEP_SUMMARY
|
|
341
|
+
echo "| **Release Job** | ${{ needs.beta-release.result || 'Skipped' }} |" >> $GITHUB_STEP_SUMMARY
|
|
@@ -37,7 +37,9 @@ jobs:
|
|
|
37
37
|
- name: Get Version
|
|
38
38
|
id: version
|
|
39
39
|
run: |
|
|
40
|
-
|
|
40
|
+
VERSION=$(uv run python quasarr/providers/version.py)
|
|
41
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
42
|
+
echo "🏷️ Version: $VERSION"
|
|
41
43
|
|
|
42
44
|
build-wheel:
|
|
43
45
|
name: Build Wheel
|
|
@@ -58,7 +60,9 @@ jobs:
|
|
|
58
60
|
with:
|
|
59
61
|
enable-cache: true
|
|
60
62
|
- name: Build wheel
|
|
61
|
-
run:
|
|
63
|
+
run: |
|
|
64
|
+
echo "📦 Starting Wheel build..."
|
|
65
|
+
uv build
|
|
62
66
|
- name: Generate artifact attestation
|
|
63
67
|
id: attest
|
|
64
68
|
uses: actions/attest-build-provenance@v2
|
|
@@ -74,26 +78,20 @@ jobs:
|
|
|
74
78
|
runs-on: windows-latest
|
|
75
79
|
needs: version
|
|
76
80
|
env:
|
|
77
|
-
# We define a consistent build path to make caching reliable
|
|
78
81
|
BUILD_PATH: "build"
|
|
79
82
|
steps:
|
|
80
83
|
- uses: actions/checkout@v6
|
|
81
84
|
- uses: actions/setup-python@v5
|
|
82
85
|
with:
|
|
83
86
|
python-version: '3.12'
|
|
84
|
-
|
|
85
|
-
# 1. Install uv with its own persistent cache
|
|
86
87
|
- name: Install uv
|
|
87
88
|
uses: astral-sh/setup-uv@v5
|
|
88
89
|
with:
|
|
89
90
|
enable-cache: true
|
|
90
91
|
cache-suffix: "win-build"
|
|
91
|
-
|
|
92
|
-
# 2. PyInstaller Caching
|
|
93
|
-
# We cache the local 'build' folder AND the global PyInstaller cache.
|
|
94
|
-
# The key invalidates if 'uv.lock' changes, forcing a re-analysis only when deps update.
|
|
95
92
|
- name: Cache PyInstaller Analysis
|
|
96
93
|
uses: actions/cache@v4
|
|
94
|
+
id: pyinstaller-cache
|
|
97
95
|
with:
|
|
98
96
|
path: |
|
|
99
97
|
build
|
|
@@ -101,25 +99,20 @@ jobs:
|
|
|
101
99
|
key: pyinstaller-analysis-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
|
102
100
|
restore-keys: |
|
|
103
101
|
pyinstaller-analysis-${{ runner.os }}-
|
|
104
|
-
|
|
105
102
|
- name: Disable Windows Defender
|
|
106
103
|
shell: powershell
|
|
107
104
|
run: Set-MpPreference -DisableRealtimeMonitoring $true
|
|
108
|
-
|
|
109
105
|
- name: Install dependencies
|
|
110
106
|
run: |
|
|
107
|
+
echo "📥 Installing build dependencies..."
|
|
111
108
|
uv sync --group build
|
|
112
|
-
|
|
113
109
|
- name: Build exe
|
|
114
|
-
# CHANGES:
|
|
115
|
-
# 1. Removed '--clean' (Critical for speed)
|
|
116
|
-
# 2. Added '--workpath' to point to our cached folder
|
|
117
|
-
# 3. Added '--distpath' explicitly
|
|
118
110
|
run: |
|
|
111
|
+
echo "🪟 Building Windows Binary..."
|
|
119
112
|
uv run python -c "from PIL import Image; Image.open('Quasarr.png').save('Quasarr.ico')"
|
|
120
113
|
uv run python quasarr/providers/version.py --create-version-file
|
|
121
114
|
uv run pyinstaller --onefile -y --version-file "file_version_info.txt" --workpath "build" --distpath "dist" --icon "Quasarr.ico" "Quasarr.py" -n "quasarr-${{ needs.version.outputs.version }}-standalone-win64"
|
|
122
|
-
|
|
115
|
+
echo "✨ Windows binary created."
|
|
123
116
|
- uses: actions/upload-artifact@v4
|
|
124
117
|
with:
|
|
125
118
|
name: exe-amd64
|
|
@@ -220,27 +213,14 @@ jobs:
|
|
|
220
213
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
221
214
|
- name: Create and Push Manifests
|
|
222
215
|
run: |
|
|
216
|
+
echo "🔗 Linking Multi-arch images..."
|
|
223
217
|
TAG_AMD64="${{ needs.version.outputs.version }}-amd64"
|
|
224
218
|
TAG_ARM64="${{ needs.version.outputs.version }}-arm64"
|
|
225
219
|
ANNOTATION="index:org.opencontainers.image.description=$DESCRIPTION"
|
|
226
|
-
|
|
227
|
-
docker buildx imagetools create -t ${{ env.ENDPOINT }}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
docker buildx imagetools create -t ${{ env.ENDPOINT }}:${{ needs.version.outputs.version }} \
|
|
232
|
-
${{ env.ENDPOINT }}:${TAG_AMD64} \
|
|
233
|
-
${{ env.ENDPOINT }}:${TAG_ARM64}
|
|
234
|
-
|
|
235
|
-
docker buildx imagetools create -t ${{ env.GHCR_ENDPOINT }}:latest \
|
|
236
|
-
--annotation "$ANNOTATION" \
|
|
237
|
-
${{ env.GHCR_ENDPOINT }}:latest-amd64 \
|
|
238
|
-
${{ env.GHCR_ENDPOINT }}:latest-arm64
|
|
239
|
-
|
|
240
|
-
docker buildx imagetools create -t ${{ env.GHCR_ENDPOINT }}:${{ needs.version.outputs.version }} \
|
|
241
|
-
--annotation "$ANNOTATION" \
|
|
242
|
-
${{ env.GHCR_ENDPOINT }}:${TAG_AMD64} \
|
|
243
|
-
${{ env.GHCR_ENDPOINT }}:${TAG_ARM64}
|
|
220
|
+
docker buildx imagetools create -t ${{ env.ENDPOINT }}:latest ${{ env.ENDPOINT }}:latest-amd64 ${{ env.ENDPOINT }}:latest-arm64
|
|
221
|
+
docker buildx imagetools create -t ${{ env.ENDPOINT }}:${{ needs.version.outputs.version }} ${{ env.ENDPOINT }}:${TAG_AMD64} ${{ env.ENDPOINT }}:${TAG_ARM64}
|
|
222
|
+
docker buildx imagetools create -t ${{ env.GHCR_ENDPOINT }}:latest --annotation "$ANNOTATION" ${{ env.GHCR_ENDPOINT }}:latest-amd64 ${{ env.GHCR_ENDPOINT }}:latest-arm64
|
|
223
|
+
docker buildx imagetools create -t ${{ env.GHCR_ENDPOINT }}:${{ needs.version.outputs.version }} --annotation "$ANNOTATION" ${{ env.GHCR_ENDPOINT }}:${TAG_AMD64} ${{ env.GHCR_ENDPOINT }}:${TAG_ARM64}
|
|
244
224
|
|
|
245
225
|
release:
|
|
246
226
|
name: Create Release
|
|
@@ -252,7 +232,6 @@ jobs:
|
|
|
252
232
|
- uses: actions/checkout@v6
|
|
253
233
|
with:
|
|
254
234
|
fetch-depth: 0
|
|
255
|
-
|
|
256
235
|
- uses: actions/download-artifact@v4
|
|
257
236
|
with:
|
|
258
237
|
name: wheel
|
|
@@ -261,16 +240,15 @@ jobs:
|
|
|
261
240
|
with:
|
|
262
241
|
name: exe-amd64
|
|
263
242
|
path: ./exe-amd64
|
|
264
|
-
|
|
265
243
|
- name: Install uv
|
|
266
244
|
uses: astral-sh/setup-uv@v5
|
|
267
245
|
with:
|
|
268
246
|
enable-cache: true
|
|
269
|
-
|
|
270
247
|
- name: Publish to PyPI
|
|
271
248
|
if: ${{ !inputs.skip_pypi }}
|
|
272
|
-
run:
|
|
273
|
-
|
|
249
|
+
run: |
|
|
250
|
+
echo "🚀 Publishing to PyPI..."
|
|
251
|
+
uv publish ./wheel/* --token ${{ secrets.PYPI_TOKEN }}
|
|
274
252
|
- name: Generate changelog
|
|
275
253
|
id: changelog
|
|
276
254
|
uses: metcalfc/changelog-generator@v4.6.2
|
|
@@ -281,25 +259,16 @@ jobs:
|
|
|
281
259
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
282
260
|
run: |
|
|
283
261
|
PR_BODY=$(gh pr list --search "${{ github.sha }}" --state merged --json body --jq '.[0].body // empty')
|
|
284
|
-
if [ -n "$PR_BODY" ]; then
|
|
285
|
-
echo -e "\n$PR_BODY" >> .github/Changelog.md
|
|
286
|
-
fi
|
|
262
|
+
if [ -n "$PR_BODY" ]; then echo -e "\n$PR_BODY" >> .github/Changelog.md; fi
|
|
287
263
|
- name: Create Release Body
|
|
288
264
|
run: |
|
|
289
265
|
echo "### Docker:" > release_body.md
|
|
290
|
-
echo "" >> release_body.md
|
|
291
266
|
echo "\`docker pull ${{ env.GHCR_ENDPOINT }}:latest\`" >> release_body.md
|
|
292
|
-
echo "" >> release_body.md
|
|
293
267
|
echo "### Python:" >> release_body.md
|
|
294
|
-
echo "" >> release_body.md
|
|
295
268
|
echo "\`uv tool upgrade quasarr\`" >> release_body.md
|
|
296
|
-
echo "" >> release_body.md
|
|
297
269
|
echo "### Changelog:" >> release_body.md
|
|
298
|
-
echo "" >> release_body.md
|
|
299
270
|
echo "${{ steps.changelog.outputs.changelog }}" >> release_body.md
|
|
300
|
-
echo "" >> release_body.md
|
|
301
271
|
echo "[Attestation](https://github.com/${{ github.repository }}/attestations/${{ needs.build-wheel.outputs.attestation-id }})" >> release_body.md
|
|
302
|
-
|
|
303
272
|
- name: Create Release
|
|
304
273
|
uses: ncipollo/release-action@v1
|
|
305
274
|
with:
|
|
@@ -315,7 +284,6 @@ jobs:
|
|
|
315
284
|
runs-on: ubuntu-latest
|
|
316
285
|
steps:
|
|
317
286
|
- uses: actions/checkout@v6
|
|
318
|
-
|
|
319
287
|
- name: Send Discord Webhook
|
|
320
288
|
env:
|
|
321
289
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -323,28 +291,31 @@ jobs:
|
|
|
323
291
|
VERSION: ${{ needs.version.outputs.version }}
|
|
324
292
|
REPO: ${{ github.repository }}
|
|
325
293
|
run: |
|
|
326
|
-
# Use the exact tag format defined in the release job (v.X.X.X)
|
|
327
294
|
TAG="v.$VERSION"
|
|
328
|
-
echo "Fetching release details for $TAG..."
|
|
329
|
-
|
|
330
|
-
# Fetch the body from the release we just created
|
|
331
295
|
RELEASE_BODY=$(gh release view "$TAG" --json body --jq .body)
|
|
332
|
-
|
|
333
296
|
if [ -n "$DISCORD_WEBHOOK" ]; then
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
# Construct JSON payload using jq
|
|
337
|
-
# Color 5763719 is 'Green'
|
|
338
|
-
jq -n \
|
|
339
|
-
--arg title "🚀 New Release: $TAG" \
|
|
340
|
-
--arg desc "$RELEASE_BODY" \
|
|
341
|
-
--arg url "https://github.com/$REPO/releases/tag/$TAG" \
|
|
342
|
-
'{content: null, embeds: [{title: $title, description: $desc, url: $url, color: 5763719}]}' \
|
|
343
|
-
> discord_payload.json
|
|
344
|
-
|
|
345
|
-
curl -H "Content-Type: application/json" \
|
|
346
|
-
-d @discord_payload.json \
|
|
347
|
-
"$DISCORD_WEBHOOK"
|
|
348
|
-
else
|
|
349
|
-
echo "::warning::Skipping Discord notification (DISCORD_WEBHOOK secret not set)"
|
|
297
|
+
jq -n --arg title "🚀 New Release: $TAG" --arg desc "$RELEASE_BODY" --arg url "https://github.com/$REPO/releases/tag/$TAG" '{content: null, embeds: [{title: $title, description: $desc, url: $url, color: 5763719}]}' > discord_payload.json
|
|
298
|
+
curl -H "Content-Type: application/json" -d @discord_payload.json "$DISCORD_WEBHOOK"
|
|
350
299
|
fi
|
|
300
|
+
|
|
301
|
+
job-summary:
|
|
302
|
+
name: 📈 Build Report
|
|
303
|
+
runs-on: ubuntu-latest
|
|
304
|
+
needs: [ version, build-wheel, build-exe, build-docker-amd64, build-docker-arm64, release ]
|
|
305
|
+
if: always()
|
|
306
|
+
steps:
|
|
307
|
+
- name: Generate Job Summary
|
|
308
|
+
run: |
|
|
309
|
+
echo "## 📊 Release Production Report" >> $GITHUB_STEP_SUMMARY
|
|
310
|
+
echo "| Artifact | Status |" >> $GITHUB_STEP_SUMMARY
|
|
311
|
+
echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY
|
|
312
|
+
echo "| **Python Wheel** | ${{ needs.build-wheel.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
|
|
313
|
+
echo "| **Windows Standalone** | ${{ needs.build-exe.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
|
|
314
|
+
echo "| **Docker AMD64** | ${{ needs.build-docker-amd64.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
|
|
315
|
+
echo "| **Docker ARM64** | ${{ needs.build-docker-arm64.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
|
|
316
|
+
echo "| **GitHub Release** | ${{ needs.release.result == 'success' && '🚀 Published' || '⚠️ Failed' }} |" >> $GITHUB_STEP_SUMMARY
|
|
317
|
+
|
|
318
|
+
echo "### ⚡ Cache Performance" >> $GITHUB_STEP_SUMMARY
|
|
319
|
+
# This assumes you use the default GITHUB_TOKEN permissions to read cache API if you wanted complex stats,
|
|
320
|
+
# but for simplicity we report on the PyInstaller cache key match.
|
|
321
|
+
echo "* **PyInstaller Cache:** ${{ needs.build-exe.outputs.cache-hit == 'true' && 'Hit (Fast 🚀)' || 'Miss (Full Build 🐢)' }}" >> $GITHUB_STEP_SUMMARY
|
|
@@ -10,6 +10,12 @@ Ensure you have the development tools (like `ruff`) installed and your environme
|
|
|
10
10
|
uv sync --group dev
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
Install the pre-commit hook that ensures linting, formatting and version upgrades through pre-commit.py
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
uv run pre-commit install
|
|
17
|
+
```
|
|
18
|
+
|
|
13
19
|
**2. Run Quasarr with the `--internal_address` parameter**
|
|
14
20
|
|
|
15
21
|
```bash
|
|
@@ -33,10 +39,10 @@ The `CONFIG_VOLUMES` environment variable is **mandatory**.
|
|
|
33
39
|
### Code Quality & Maintenance
|
|
34
40
|
|
|
35
41
|
The CI pipeline enforces strict code styling and import optimization. Please run this commands before pushing your
|
|
36
|
-
changes
|
|
42
|
+
changes. Alternatively, you should just set up the pre-commit hook as described above.
|
|
37
43
|
|
|
38
|
-
**Format code AND upgrade
|
|
44
|
+
**Format code AND upgrade dependencie manually:**
|
|
39
45
|
|
|
40
46
|
```bash
|
|
41
|
-
uv run
|
|
47
|
+
uv run pre-commit.py --upgrade
|
|
42
48
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: quasarr
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.11
|
|
4
4
|
Summary: Quasarr connects JDownloader with Radarr, Sonarr and LazyLibrarian. It also decrypts links protected by CAPTCHAs.
|
|
5
5
|
Author-email: rix1337 <rix1337@users.noreply.github.com>
|
|
6
6
|
License-File: LICENSE
|