mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 19:01:39 -04:00
The extension is hosted in a sibling repo and
is distributed off-store. Each WROLPi release ships the prebuilt artifacts
under wrolpi/static/extensions/ and serves them at /api/extensions/<file>:
- wrolpi-chrome.zip Load-Unpacked sideload for Chrome / Brave / Edge
- wrolpi-firefox.xpi Mozilla-signed (unlisted self-distribution),
one-click install in any Firefox
- versions.json Per-browser version metadata for the install page
Backend (modules/archive/api.py, wrolpi/root_api.py):
- POST /api/archive/upload accepts an optional repeated `tagNames`
multipart form field; the upload switch handler applies tags to the
new FileGroup via FileGroup.set_tags(). Unknown tag names are auto-
created inside a per-name SAVEPOINT so concurrent inserts on the same
novel name don't abort the transaction (Tag.name has unique=True).
- GET /api/extensions returns metadata (per-file availability + size +
versions.json contents) for the install page.
- GET /api/extensions/<filename> serves the binary, whitelisted by
filename. Firefox .xpi is served as application/x-xpinstall WITHOUT a
Content-Disposition: attachment header, so Firefox triggers its
add-on install handler instead of saving the file.
Frontend (app/src/):
- New /admin/extension page (linked from AdminRoute) detects the user's
browser via navigator.userAgent and renders an install card per
Firefox / Chromium / Other. Pulls metadata from /api/extensions to
show file size and version, and gracefully reports 'Not yet
available' when binaries are missing.
- Dashboard's Getters component supports a deep link from the
extension's 'Configure Download' button:
/?downloader=<archive|video|...>&download_url=<u1>&download_url=<u2>
On mount, the matching downloader form auto-opens with URLs pre-
filled. Query params are cleared on close so a refresh doesn't
re-open the modal.
- DownloadMenu and the per-downloader forms accept an `initialUrls`
seed via the existing `download` prop pattern, joined with newlines
for the `urls` textarea (and first URL for single-URL forms).
Behavior is fully backwards compatible: pre-existing API callers can
still POST to /api/archive/upload without `tagNames`, and the
DashboardPage modal continues to open via the existing button click
when no deep-link query params are present.
52 lines
1.5 KiB
YAML
52 lines
1.5 KiB
YAML
name: Jest Tests
|
|
|
|
on:
|
|
push:
|
|
branches: [master, feature/*]
|
|
pull_request:
|
|
branches: [master]
|
|
|
|
jobs:
|
|
jest-tests:
|
|
runs-on: ubuntu-latest
|
|
|
|
defaults:
|
|
run:
|
|
working-directory: app
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
cache: 'npm'
|
|
cache-dependency-path: app/package-lock.json
|
|
|
|
- name: Install dependencies
|
|
run: npm install --legacy-peer-deps
|
|
|
|
- name: Run Jest tests
|
|
run: CI=true npm test -- --watchAll=false --coverage --coverageReporters=text --coverageReporters=lcov
|
|
|
|
# Webpack build catches errors that Jest+Babel don't, e.g. named imports
|
|
# that resolve to `undefined` because the source module doesn't actually
|
|
# export that name (Babel turns these into runtime undefined; webpack
|
|
# rejects them at build time). GitHub Actions sets CI=true in every
|
|
# step's environment by default, which makes react-scripts treat any
|
|
# lint warning as a fatal error — so we override it here. The webpack
|
|
# build still fails on real errors (the goal of this step); only
|
|
# pre-existing lint warnings stop being blocking.
|
|
- name: Build app (catches missing imports etc.)
|
|
env:
|
|
CI: ''
|
|
run: npm run build
|
|
|
|
- name: Upload coverage report
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: coverage-report
|
|
path: app/coverage
|
|
retention-days: 30
|