Skip to content

chore: refresh linuxserver.io catalog index - #815

Merged
hanthor merged 1 commit into
mainfrom
bot/catalog-lsio-20260914-060005
Sep 18, 2026
Merged

hanthor merged 1 commit into
mainfrom
bot/catalog-lsio-20260914-060005

Conversation

@castrojo

Copy link
Copy Markdown
Collaborator

Weekly refresh of docs/data/catalog/linuxserver.json from 2026-09-14T06:00:05Z.

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

@hanthor hanthor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Metrics-only, and I checked that mechanically rather than eyeballing 512 lines

A 256/256 diff is exactly the shape where a consequential change can hide, so I diffed it structurally instead of reading it. Every app is accounted for and nothing that affects behaviour moved:

$ python3  # comparing 830ed5e:docs/data/catalog/linuxserver.json against this PR's
app count: 201 -> 201
added: []
removed: []
changed field monthly_pulls: 201 apps
changed field stars: 54 apps

Those are the only two fields that differ, across the whole file. image_ref, logo_url, category, architectures, config_pointer, readonly_supported, nonroot_supported, verified and description are byte-identical for all 201 apps. That is the check that actually matters on these weekly refreshes — a silently changed image_ref or a flipped nonroot_supported is the thing that would bite — and there are none.

The file is also unmistakably unmodified generator output, not something hand-touched on its way through:

byte-identical to json.dumps(d, indent=2, ensure_ascii=False)+"\n": True    # collect_lsio_catalog.py:135
apps sorted by name: True                                                   # collect_lsio_catalog.py's contract
uniform key order across all apps: True
duplicate names: 0   duplicate image_refs: 0
registries in use: {'lscr.io'}

Single registry, and lscr.io is in ALLOWLISTED_REGISTRIES at scripts/catalog_validate.py:17-27. Values are all sane — no nulls, no negatives, no zeroed monthly_pulls, stars deltas span -2 (wireguard) to +8 (jellyfin).

Tests, both sides:

$ (base 830ed5e) python3 -m pytest tests/unit/ -q   ->  620 passed in 14.28s
$ (this PR)      python3 -m pytest tests/unit/ -q   ->  620 passed in 14.34s
$ python3 -m pytest tests/unit/test_collect_lsio_catalog.py tests/unit/test_catalog_validate.py -q  ->  48 passed

The branch is 477 commits behind main, but nothing in that range touched docs/data/catalog/linuxserver.json and git merge-tree origin/main <head> reports zero conflict markers, so it still applies cleanly. mergeable_state comes back unknown from the API, which is just GitHub's lazy computation on a stale branch — it'll resolve on the merge attempt.

Approving.

The part worth acting on: the green checks here don't check this file

Two checks are green on 0046bb9validate and lint. Neither looks at the catalog:

  • validate is docs.yml's job, which fires on paths: docs/** (so it does trigger, since the file is under docs/data/) and runs scripts/validate-docs.py. But grep -n "catalog\|\.json" scripts/validate-docs.py returns nothing — it validates docs structure and links, then greps for stale skill references. It has no opinion about this file's contents.
  • lint is lint.yaml, repo-wide and generic.

Meanwhile the job that does know about this data — ci.yml, which runs tests/unit/test_collect_lsio_catalog.py — never ran, because its trigger is:

paths:
  - 'tests/**'
  - 'scripts/**'
  - '.python-scope'
  - 'requirements.txt'
  - 'pyproject.toml'
  - '.github/workflows/ci.yml'

docs/data/catalog/linuxserver.json matches none of those. So every weekly catalog refresh PR arrives with two green checkmarks that attest to nothing about the payload. Nothing is broken today — I ran the suite by hand and it's clean both sides — but the gate a reviewer would assume is there isn't.

Two suggestions, in order of value:

  1. Add docs/data/catalog/*.json to ci.yml's paths:. One line, and test_collect_lsio_catalog.py starts guarding the refreshes it was written for.
  2. Have the poller classify its own diff. manifests/catalog-lsio-poller.yaml:65 already does the clever thing of using git diff --quiet -I '"generated_at"' to avoid opening timestamp-only PRs. Extending that to state in the PR body whether the change is metrics-only, or whether an image_ref / capability flag moved, would turn the review I just did by hand into something the bot says up front. That is the difference between "201 apps, metrics only" and a human squinting at 512 lines every week.

One thing I can't adjudicate

A few monthly_pulls moves are far outside the weekly noise band:

budge            6641 ->  123222   (+1755%)
shotcut         20055 ->  114118   (+469%)
pelorus           487 ->     979   (+101%)
gitqlient         207 ->     150   (-27.5%)
webcord         16831 ->   12372   (-26.5%)

budge at 18× in one week is either a genuine spike, a mirror/CI pulling in a loop, or upstream changing how it counts. collect_lsio_catalog.py:80 takes monthly_pulls straight from the API via as_int() with no plausibility check, so whatever the API says lands in the file. Not a reason to hold this PR — these are display metrics, not anything that gates an install — but if the catalog card ever sorts or ranks by monthly_pulls, an order-of-magnitude outlier guard in the collector would be cheap insurance.


Generated by Claude Code

@hanthor
hanthor merged commit 61a9998 into main Sep 18, 2026
2 checks passed
@hanthor
hanthor deleted the bot/catalog-lsio-20260914-060005 branch September 18, 2026 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants