SkinHub

What's New

Recent updates to the site, backend and skin pipeline. Each release links to its full notes.

  1. Publish CI v1.1.4 2026-06-10
    Fixed
    • bind manifest media oid+size to the rendered artifact bytes
    • bind publish artifact osu_id to the trusted repo identity
  2. Publish CI v1.1.3 2026-06-10
    Fixed
    • tag a skin repo only when the ci run created a commit
  3. Publish CI v1.1.2 2026-06-10
    Fixed
    • harden publish trust gate against untrusted artifact fields
  4. Backend v4.11.0 2026-06-09
    New
    • country-based default skin limits (Swiss 20, others 5)
    Fixed
    • degrade rate limiter to in-process governor fallback on DB error
  5. Backend v4.10.1 2026-06-09
    Fixed
    • check ownership before CI-lock on skin mutations
    • reject non-zip .osk uploads before parsing
  6. Backend v4.10.0 2026-06-09
    New
    • send X-Content-Type-Options: nosniff on all responses
    Fixed
    • guard commit file paths against repo-root traversal
  7. Render CI v1.3.0 2026-06-09
    New
    • name generated assets by dir_name (not the live skin.ini name)
  8. Backend v4.9.0 2026-06-09
    New
    • flat media endpoints /media/{kind}/{dir} (no ext, osk kind, Content-Disposition)
  9. Publish CI v1.1.1 2026-06-09
    Fixed
    • drop the dead .gitea paths from tag-diff + cleanup (fleet is .forgejo-only)
  10. Render CI v1.2.0 2026-06-09
    New
    • pretty-print manifest.json (2-space indent)
  11. Backend v4.8.6 2026-06-09
    Fixed
    • reap stuck 'running' CI rows whose done callback was lost
  12. Backend v4.8.5 2026-06-09
    Fixed
    • dispatch deploy-ci on skins-template (moved there from reusable-actions)
  13. Frontend v2.9.3 2026-06-09
    Fixed
    • point the skins.json help text at .forgejo/workflows
  14. Backend v4.8.4 2026-06-09
    Fixed
    • write skins.json to .forgejo/workflows (fleet migrated off .gitea)
  15. Render CI v1.1.1 2026-06-09
    Fixed
    • prefix ./ on osk member paths so a leading-dash filename isn't a zip flag
  16. Backend v4.8.3 2026-06-09
    Faster
    • index skins on (osu_id, tag) for the roster and pick joins
  17. Publish CI v1.1.0 2026-06-09
    New
    • recognize .forgejo workflow paths in tag-diff + cleanup
  18. Render CI v1.1.0 2026-06-09
    New
    • read skins.json + classify workflow changes under .gitea or .forgejo
  19. Publish CI v1.0.5 2026-06-09
    Fixed
    • self-bump the report sub-path pin alongside the publish pin
  20. Publish CI v1.0.4 2026-06-09
    Fixed
    • remove the downloaded artifact dir before staging (never commit _artifact)
  21. Publish CI v1.0.3 2026-06-09
    Fixed
    • read osc-meta.json (drop dot — upload-artifact globs out hidden files)
  22. Render CI v1.0.3 2026-06-09
    Fixed
    • rename osc-meta.json (drop dot — upload-artifact globs out hidden files)
  23. Render CI v1.0.2 2026-06-09
    Fixed
    • cross-device-safe move for prepare/previews (EXDEV on /workspace↔/app/danser)
  24. Publish CI v1.0.2 2026-06-09
    Fixed
    • resolve the artifact root robustly (handle upload path nesting)
  25. Render CI v1.0.1 2026-06-09
    Fixed
    • stage only this run's rendered outputs into _artifact
  26. Backend v4.8.2 2026-06-09
    Fixed
    • cap the admin download-all archive size
    • pin rate-limit client IP to the socket peer for untrusted hits
    • rate-limit the ci-status tag ingest to bound amplification
    • shut down gracefully on SIGTERM
    • stop leaking internal error detail in 5xx responses
    Faster
    • single-flight the osu! app-token refresh
  27. Publish CI v1.0.1 2026-06-09
    Fixed
    • make the report action self-contained (no .. escape in main)
  28. Publish CI v1.0.0 2026-06-09
    New
    • trusted publish half of the skin CI (allowlist-validate, commit, tag)
  29. Render CI v1.0.0 2026-06-09
    New
    • untrusted render half of the skin CI (discover, render, manifest)
    Fixed
    • stop sending the notify token as a bearer header
  30. Backend v4.8.1 2026-06-09
    Fixed
    • require a signed ci-status request and drop the legacy bearer
  31. Frontend v2.9.2 2026-06-09
    Fixed
    • anchor the What's New popover under its button
  32. Backend v4.8.0 2026-06-09
    New
    • back the rate limiter with Postgres for multi-replica budgets
    • fan out live CI frames via Postgres LISTEN/NOTIFY
    Fixed
    • add a replay-safe signature scheme to the ci-status webhook
    • bail instead of caching an empty osu! access token
    • bound push-triggered tag ingests and prune atomically on reproject
    • build media response headers without panicking on bad metadata
    • cap admin uploads instead of leaving the spool unbounded
    • guard CI phase merge against a non-object snapshot
    • guard the LFS S3 key against a malformed oid
    • key XFF-less direct callers by peer IP for rate limiting
    • re-check the admin allowlist on every request
    • reject non-release tags on the ci-status ingest path
    • stop following redirects and cap response size in the avatar proxy
    Faster
    • batch pick validation into one skin lookup
    • index community_skins by tag
  33. Frontend v2.9.1 2026-06-09
    Fixed
    • ci-banner: clear the build banner on a no-change run
    • clone tags in SkinsEditor reset so edits don't alias the prop
    • footer: grouped-column layout; drop Source link
    • invalidate instead of full-reload on pick save and clear the copy timer on unmount
    • order changelog markers by date then version for chronological compare
    • re-stream a repeat deep-link to the same CI run after close
    • seed TagSelector default month from today instead of a literal
    • skins-editor: auto-scroll the page when dragging a row to the edge
    • ui: dvh heights + overscroll-contain for clean mobile modal scroll
    • ui: keep version + What's New dropdowns on-screen on mobile
    • ui: lock page scroll behind open modals and popovers
    • whats-new: portal the popover so it sits on-screen and taps off close it
  34. Frontend v2.9.0 2026-06-09
    New
    • add unified What's New popover and /changelog page
    • filterable changelog timeline with per-service theming
    • wayback-style calendar version picker
  35. Backend v4.7.0 2026-06-09
    New
    • add /api/changelog merging Forgejo release notes
    • paginate changelog releases for full stable history
    Fixed
    • exclude prerelease tags from the changelog feed
  36. Backend v4.6.3 2026-06-08
    Fixed
    • exclude phantom runs from the render-load runner count
    • reject path traversal in skin folder names
    Faster
    • skip LFS smudge when committing skins so saves/deletes don't pull every skin's content
  37. Frontend v2.8.2 2026-06-08
    Fixed
    • stop rendering errored phantom CI runs as 'about to start' in the build panel
  38. Backend v4.6.2 2026-06-08
    Fixed
    • commit skin saves/deletes via git push in the background to avoid the Forgejo bulk-commit timeout
  39. Frontend v2.8.1 2026-06-08
    Fixed
    • forward the session cookie on internal SSR fetches so login survives the origin rewrite
  40. Frontend v2.8.0 2026-06-08
    New
    • forward X-Forwarded-For on internal SSR fetches so rate limits stay per-client
    Fixed
    • resolve the CI watcher to a stalled state on timeout instead of spinning forever
  41. Backend v4.6.1 2026-06-08
    Fixed
    • reap unclaimed CI phantoms every 5 min instead of every 6h
  42. Frontend v2.7.2 2026-06-08
    Fixed
    • poll user fresh in the CI watcher so fast-run version banners aren't masked by the nav cache
    Faster
    • make the admin pick target a typeahead instead of a 100-cap list
    • pause CI-load polling while the tab is hidden
    • route SSR API fetches to the internal backend when configured
  43. Backend v4.6.0 2026-06-08
    New
    • dispatch CI with a self-callback URL so beta builds report to beta
    • dispatch skin-save CI with a self-callback instead of a bare push
    Fixed
    • add connect/read timeouts to the shared HTTP client
    • authorize ci-status webhook before full body deserialization
    • cap user download-all zip at 4 GiB to bound disk use
    • stop ci-status stream registry from leaking senders
    Faster
    • assemble download-all zip on a blocking thread
    • batch osu! user lookups 50 per call
    • index ci_runs on (repo, run_number) and (repo, created_at)
    • offload .osk parsing to a blocking thread
    • prune old ci_runs and expired cache_entries in maintenance
    • run user-page reads concurrently
    • serve ci-load from the ci_runs read model and rate-limit the route
  44. Backend v4.5.0 2026-06-07
    New
    • admin: backfill per-repo CI notify secrets
    • set a per-repo CI notify secret on repo creation
  45. Backend v4.4.1 2026-06-07
    Faster
    • batch roster identity cache reads into one query
    • bound the Postgres connection pool with an acquire timeout
    • load the membership row once in get_user
    • resolve bot picks with a single-row lookup
  46. Frontend v2.7.1 2026-06-07
    Faster
    • fetch the current user in a server load to avoid a duplicate request
    • lazy-load the skins editor and CI panel
  47. Frontend v2.7.0 2026-06-07
    New
    • admin: add re-run-CI toggle to the deploy-CI panel
  48. Backend v4.4.0 2026-06-07
    New
    • admin: pass skip_ci through to the deploy-ci dispatch
  49. Backend v4.3.0 2026-06-07
    New
    • ci: add run_number/event/progress columns to ci_runs
    • webhooks: add push-based ci-status endpoint + broadcast hub
    • webhooks: ingest on the CI tag event; drop ci-done; org hook invalidate-only
    Fixed
    • avatar: only seed upstream avatars for members or the caller
    • ci: cap concurrent live CI streams per user or IP
    • ci: guard SSE log delta against a non-char-boundary offset on source switch
    • ci: require owner or admin to read CI runs, logs, and streams
    • upload: cap .osk decompression by actual bytes, not declared sizes
    • upload: scope the large request body limit to the upload route
    Faster
    • community: single-flight the roster cache rebuild
    • zip: stream each .osk to disk instead of buffering it in memory
  50. Frontend v2.6.0 2026-06-07
    New
    • ci: drive build panel from pushed status, drop log view
    Fixed
    • ui: show a friendly 404 page for a user with no profile
  51. Frontend v2.5.1 2026-06-06
    Fixed
    • csp: drop git.sulej.net from img-src/media-src
    • download: mark download-all as a native download so the nav bar clears
  52. Backend v4.2.0 2026-06-06
    New
    • ops: add a container HEALTHCHECK on /api/health
    • rate-limit: rate-limit skin-detail and pick endpoints, add picks_save bucket
    Fixed
    • db: track applied read-model migrations in a ledger
    • download: stream download-all .osk from Garage by OID, not Forgejo media
    • picks: keep owner_kind on picks embedded in the user page
    • rate-limit: compare integration token in constant time
    • rate-limit: key on the rightmost X-Forwarded-For hop
    • upload: stream multipart parts to disk and bound batch size
    Faster
    • auth: resolve session and user in a single query
    • ci: render only new log lines in the live stream
    • ci: resolve dispatch run id in the background, return immediately
    • community: count member skins in one grouped query
    • media: skip ref resolution when the tag already matches
    • rate-limit: shard the token-bucket map across 16 locks
    • reads: resolve repo tags once per page instead of three times
    • upload: spool decompressed .osk members to disk instead of RAM
    • zip: fetch skin .osk files concurrently when building zips
  53. Backend v4.1.0 2026-06-05
    New
    • ops: sweep expired sessions and reap stranded CI runs
    Fixed
    • auth: verify OAuth state nonce to block login CSRF
    • rate-limit: scope integration token to user_get and meter download-all
  54. Frontend v2.5.0 2026-06-05
    New
    • list all version tags, drop main from the version picker
    • ui: dedicated /osc-skins collection routes + community render picks
    • ui: infinite-scroll community + skin grids, paginated admin users
    • ui: per-tag download-all, /limits page, queued high-load banner
    Fixed
    • ui: drop redundant community-skin labels from picks views
    • ui: gate CI and skin-folder Forgejo links to admins
    • ui: gate Forgejo repo links to admins; correct privacy copy for private repos
  55. Backend v4.0.0 2026-06-05
    New
    • api: centralize rate-limit catalog + public GET /api/rate-limits
    • api: model the OSC community skin as its own collection, drop virtual user 0
    • api: paginate /api/community, user skins, and admin users
    • ci: GET /api/health/ci-load (running/queued) for the high-load banner
    • restore per-tag browsing in the read model
    • skins: download-all honors the selected tag (?ref=)
    Fixed
    • forgejo: create skin repos private to close direct-clone bypass
    • read-model: ingest osc_skins as virtual user 0 (was dropped by numeric repo filter)
  56. Frontend v2.4.1 2026-06-03
    Fixed
    • ui: honest version banner on main + disable overscroll past footer
  57. Backend v3.0.1 2026-06-03
    Fixed
    • ingest: take tag from the ci-done/webhook payload, not the manifest
  58. Frontend v2.4.0 2026-06-03
    New
    • adopt the skins read model — loading bar, reproject admin control, drop cache panel
  59. Backend v3.0.0 2026-06-03
    New
    • skins read model (v3) — serve pages from Postgres, decommission unused endpoints
  60. Frontend v2.3.0 2026-06-02
    New
    • adopt the Rust backend's OpenAPI (Scalar docs, regenerated types)
  61. Backend v2.3.0 2026-06-02
    New
    • rewrite the backend in Rust (axum + sea-orm)
  62. Backend v2.2.1 2026-06-01
    Fixed
    • health: derive degraded signal from leaf Forgejo calls, not the community composite
  63. Frontend v2.2.0 2026-06-01
    New
    • ui: banner when the git backend is degraded
    Faster
    • nav: cache user/skin/community reads to remove refetch-on-navigation
  64. Backend v2.2.0 2026-06-01
    New
    • health: expose /api/health/forgejo degraded signal for the UI banner
    Faster
    • avatar: cache avatar bytes in-process in front of Garage
    • cache: serve stale Forgejo data on restart, cache community payload, fix roster invalidation
  65. Backend v2.1.2 2026-06-01
    Fixed
    • ci-gate: record pending CIRun before commit so resolver matches
  66. Backend v2.1.1 2026-05-19
    Fixed
    • docs: vendor redark for Redoc dark mode (replaces hand-rolled theme)
    • docs: vendor unwrapped Amoenus SwaggerDark, inline into /api/docs
  67. Frontend v2.1.2 2026-05-19
    Fixed
    • privacy: mention /api/redoc as a jsdelivr consumer too
  68. Frontend v2.1.1 2026-05-19
    Fixed
    • footer: move version row below nav links
  69. Frontend v2.1.0 2026-05-19
    New
    • add /license page and footer link
  70. Backend v2.1.0 2026-05-19
    New
    • docs: dark mode for /api/docs (Swagger) and /api/redoc
  71. Backend v2.0.1 2026-05-19
    Fixed
    • api: revert /api/community asyncio.gather (overran DB pool); back to serial
  72. Frontend v2.0.0 2026-05-19
    New
    • ui: add 'API docs' link to admin panel header (-> /api/docs)
    • ui: add /privacy and /rules pages, link from footer
    • ui: add API docs link to footer (-> /api/docs Swagger)
    • ui: hide manual rebuild form from non-admins; owners trigger CI implicitly via upload/edit/delete
    • ui: per-page Open Graph / Twitter embeds (main, user, skin)
    • ui: split previews toggle into gameplay/panel/thumbnail
    • ui: typed ApiBackoffError for 429/409 + getRateLimits + hide force_rebuild from non-admins
    Fixed
    • skins-editor: disable row drag while editing so dblclick selects text
    • ui: drop docs phase from CI progress visualizer (no longer emitted)
    • ui: drop the non-admin explanatory line from CI panel
    • ui: main page logo back as small embed; skin page large embed, title is just skin.ini name
    • ui: privacy and rules pages in first-person, no em-dash, escape {your_osu_id}
    • ui: remove Cloudflare from privacy (no proxy on sulej.net, direct IP)
    • ui: smaller Discord embeds (twitter:card summary); drop main page logo+counts; drop og:video from skin page
    Faster
    • ui: hero img eager+fetchpriority high; avatar grid lazy+decoding async; explicit width/height to skip CLS
  73. Backend v2.0.0 2026-05-19
    New
    • api: ci_lock service + no_active_ci dependency (reject 409 when CI in-flight)
    • api: dispatch_ci is admin-only (owners trigger CI via upload / edit / delete)
    • api: gate writes on no-active-CI + apply rate limits + admin-only force_rebuild
    • api: GET /api/users/{osu_id}/rate-limits snapshot for the caller
    • api: in-memory token-bucket rate limiter + rate_limit dependency factory
    • api: INTEGRATION_TOKEN bypasses rate limits on read endpoints (for trusted proxies)
    • api: list_ci_runs only returns runs from the last 24h
    • api: rate-limit public read endpoints (media w/ own-repo bonus, avatar, community, users, ci runs/log/stream)
    • api: serve swagger ui + redoc + openapi spec under /api/
    • api: split do_previews into do_gameplay/do_panel/do_thumbnail
    • api: structured skin detail endpoint with author + build history
    • semver: rank CalVer tags newer than legacy semver in sort_desc
    Fixed
    • api: read version from package metadata so Swagger shows the real release tag
    • ci-lock: drop stale rows + close all non-terminal rows on ci-done webhook
    Faster
    • api: parallelize skin_count lookups in /api/community (gather)
  74. Frontend v1.8.2 2026-05-18
    Fixed
    • svelte: clear all vite-plugin-svelte build warnings
  75. Frontend v1.8.1 2026-05-18
    Fixed
    • layout: pin footer to viewport bottom on short pages
  76. Frontend v1.8.0 2026-05-17
    New
    • footer: redesign with brand, links, and build metadata
  77. Frontend v1.7.0 2026-05-17
    New
    • footer: show app version with link to release notes
  78. Backend v1.4.2 2026-05-17
    Fixed
    • avatar: log non-2xx upstream responses at warning for operator visibility
  79. Backend v1.4.1 2026-05-17
    Fixed
    • config: correct stale garage_bucket default from "gitea" to "forgejo"
  80. Frontend v1.6.0 2026-05-17
    New
    • security: F-5 frontend — attach CSRF token to every mutation
  81. Frontend v1.5.0 2026-05-17
    New
    • security: F-6 CSP nonces + bump JSON editor height
  82. Frontend v1.4.0 2026-05-17
    New
    • security: F-10 add HSTS header
  83. Frontend v1.3.0 2026-05-17
    New
    • security: re-add CSP with Anubis-compatible allowlist
  84. Frontend v1.2.0 2026-05-17
    New
    • security: add CSP + companion hardening headers
  85. Frontend v1.1.1 2026-05-17
    Fixed
    • json-editor: visible cursor + dark-theme lint tooltips
  86. Frontend v1.1.0 2026-05-17
    New
    • user-page: link avatar + username to osu! profile
  87. Frontend v1.0.0 2026-05-17
    Fixed
    • install with --legacy-peer-deps for openapi-typescript
  88. Backend v1.4.0 2026-05-17
    New
    • security: F-5 backend — double-submit CSRF tokens
  89. Backend v1.3.0 2026-05-17
    New
    • security: F-8 + F-14 quick wins
  90. Backend v1.2.3 2026-05-17
    Fixed
    • auth: admin role tracks ADMIN_OSU_IDS in both directions
  91. Backend v1.2.2 2026-05-17
    Fixed
    • pregen: log.exception instead of log.warning(..., e)
  92. Backend v1.2.1 2026-05-17
    Fixed
    • nh3: drop 'rel' from <a> attribute allowlist
  93. Backend v1.2.0 2026-05-17
    New
    • security: sanitize rendered skin docs with nh3
  94. Backend v1.1.1 2026-05-17
    Fixed
    • avatar: pass through upstream content-type instead of hardcoding png
  95. Backend v1.1.0 2026-05-17
    New
    • api: proxy + cache a.ppy.sh avatars through /api/avatar/{osu_id}
  96. Backend v1.0.0 2026-05-17
    Fixed
    • upload: clear target Skins/<dir>/ before writing the new files

Showing the most recent releases.