Skip to content

feat(steam): import a user's Steam library - #5362

Draft
sdornan wants to merge 8 commits into
masterfrom
claude/trusting-einstein-4rgkz7
Draft

sdornan wants to merge 8 commits into
masterfrom
claude/trusting-einstein-4rgkz7

Conversation

@sdornan

@sdornan sdornan commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Description

This PR imports a user's Steam library into RomM, end to end. Each user links a Steam account. RomM then tracks which games that account owns, adds the owned games to the library, and lets the user filter by them.

How it works:

  • Configuration.
    • A single STEAM_API_KEY covers the whole server.
    • ENABLE_SCHEDULED_STEAM_LIBRARY_SYNC and SCHEDULED_STEAM_LIBRARY_SYNC_CRON control the nightly sync of every linked user.
    • The heartbeat exposes STEAM_LIBRARY_ENABLED, and the UI hides everything Steam-related when no key is set.
  • Linking.
    • PUT /api/users/{id}/steam accepts a SteamID64, a profile link (/profiles/<id> or /id/<name>), or a custom URL name.
    • It resolves the account through ResolveVanityURL and GetPlayerSummaries, then stores steam_id (as a string, since a SteamID64 overflows JS integers) and steam_persona_name.
    • Linking a different account clears the old ownership rows.
    • DELETE /api/users/{id}/steam unlinks the account.
    • These endpoints use the same "self or admin" rule as RetroAchievements.
    • Link and unlink change the account before clearing its games. A sync re-checks the account under a lock on the user row before writing, so a sync that is still running can't restore an unlinked account's games.
  • Syncing.
    • POST /api/users/{id}/steam/sync (202) queues the sync_steam_libraries task for that user. The scheduled run of the same task syncs every linked user.
    • The task reads GetOwnedGames.
    • A private library fails with a message telling the user to set "Game details" to Public. The task framework sends that message to the user as a "task failed" notification.
    • Connection errors and unreadable replies from Steam fail only that user's sync. The scheduled run carries on with the rest.
  • Matching owned games.
    • An owned game that already has a rom with that steam_id on a PC-family platform links to that rom. A rom with a file is preferred.
    • Every other owned game gets a store-only rom on win, with storefront = "steam" and its steam_id preset. Its fs_path is <win>/.steam, a folder no scan lists (the same approach as physical games).
    • Store-only roms with no cover yet are queued for an UNMATCHED metadata scan by rom id, because a library scan never reaches a game without a file.
    • The win platform and its folder are created if missing; otherwise mark_missing_platforms would flag them.
  • New table steam_library_entries. One row per user per owned app, with playtime and last played. It cascades on user and rom delete. GET /api/users/{id}/steam/library lists the owned app ids.
  • Filtering.
    • GET /api/roms gains a per-user owned_on_steam filter. It matches every rom carrying an owned app id, on any platform.
    • It also works in smart collections. Their cached membership is refreshed when a sync, relink or unlink changes what a user owns.
    • There is also a store_only filter.
  • File-less roms.
    • Physical and store-only roms now share one check: Rom.never_has_file in Python, rom_without_file() in SQL.
    • Missing-file marking skips both kinds.
    • The HAS_FILE_ON_DISK_FILTERS used by feeds and exporters gains store_only: False.
    • Rescanning one of these roms goes straight to metadata, without reading files from disk or marking the rom missing.
  • UI.
    • Profile → Steam section. Link an account by any of the three forms. Linking starts a sync right away. When linked, the section shows how many games the account owns, a Sync button, and Unlink (behind a confirmation). It shows only when the server has a key.
    • Updates. A sync's completion arrives as the existing "task completed" notification. That notification refreshes the owned list, and for this task it links to the profile rather than the admin page. The list also refreshes when the tab becomes visible again, which covers the scheduled sync.
    • Gallery filter. An Owned on Steam filter appears in the filter drawer for linked users. It is kept in the URL (?filterOwnedOnSteam=) and can be saved as a smart collection. It stays listed when set from a shared link, so it can be cleared.
  • Task title. The task title is now "Steam library sync", since users start it too and the title appears in their notification.
  • Migration 0155_steam_library (follows 0154_ownerless_own_only). It adds roms.storefront (through ensure_roms_columns), the two user columns and the new table. Each step is guarded so a partial run can be replayed. Upgrade, downgrade and upgrade again were run on MariaDB.
flowchart LR
    subgraph Frontend
      PS[Profile: SteamLibrarySection]
      FD[Gallery: Owned on Steam filter]
      SL[(steamLibrary store)]
    end
    PS -->|PUT / DELETE /users/id/steam| EP[endpoints/user.py]
    PS -->|POST /users/id/steam/sync| EP
    SL -->|GET /users/id/steam/library| EP
    PS --> SL
    FD -->|GET /roms?owned_on_steam| ROMS[roms_handler filter]
    EP -->|enqueue| T[tasks/scheduled/sync_steam_libraries]
    CRON[Scheduler: SCHEDULED_STEAM_LIBRARY_SYNC_CRON] --> T
    T --> H[handler/steam_library_handler]
    EP -->|link / unlink / resolve| H
    H --> API[adapters/services/steam_web_api]
    H -->|link existing rom or create store-only rom on win| DB[(roms + steam_library_entries)]
    H -->|ownership changes| SC[smart collection refresh]
    T -->|unmatched store-only rom ids| SCAN[UNMATCHED scan by rom id]
    T -.->|task completed / failed notification| SL
    ROMS --> DB
Loading

AI assistance: Claude Code (an AI coding agent) wrote this PR, including the design discussion, implementation, tests, migration, translations and this description. A human directed it and made the design calls (the win platform, per-user ownership, one server-wide key, and filtering by ownership). The new strings are machine-translated into all 18 locales and would benefit from a native speaker's review. The work was not run end to end against the real Steam API, because no real key was available. Steam was reached, and correctly rejected a placeholder key.

Checklist

  • I've tested the changes locally
  • I've updated relevant comments
  • I've assigned reviewers for this PR
  • I've added unit tests that cover the changes

Local verification:

  • Backend tests:
    • Steam Web API client (including connection and non-JSON failures).
    • Link and sync handler, including an unlink in the middle of a sync and the smart collection refresh.
    • Endpoints, the task, and the owned_on_steam filter.
    • Missing-file logic and migration replay.
    • Scan tests run through _identify_rom for roms with no file.
  • Frontend tests:
    • SteamLibrarySection: link then sync, a rejected profile, the owned count, and unlink after confirmation.
    • The store: refetch when the tab becomes visible again, and an older reply arriving late.
    • Smart collection criteria and the cached API params.
  • Checks: mypy, trunk check, vue-tsc, and both i18n checks are clean.
  • Browser pass, run on a dev server seeded through the real sync code with only the Steam HTTP call stubbed:
    • The profile section in both themes, linked and unlinked.
    • The unlink confirmation, where focus starts on Cancel.
    • The link error toast ("Steam rejected the API key").
    • The filter drawer in both themes. ?filterOwnedOnSteam=true leaves the five owned games and hides an unowned Steam game.

Screenshots (if applicable)

I took the screenshots from the running app during the browser pass. This session has no way to upload images to a PR, so the author will attach them:

  • Profile, Steam section linked (dark and light)
  • Profile, Steam section unlinked
  • Unlink confirmation
  • Gallery filter drawer with "Owned on Steam" active (dark and light)

🤖 Generated with Claude Code

https://claude.ai/code/session_01XGA3D2oZ1hq3QUdnubMNXh

Users can link a Steam account (SteamID64, profile link or custom URL name)
and sync the games it owns. The sync links each owned game to the rom that
already stands for it on win, linux or mac, matched by Steam app id, and
gives the rest a store-only rom on win (created with its folder when the
library has none). Store-only roms have no file: `roms.storefront` marks
them and, like physical games, keeps them out of the missing-file sync,
the missing cleanup, the feeds and the exporters. Store-only roms that no
source has matched yet are queued for a rom-id scan after each sync.

- STEAM_API_KEY enables it; the heartbeat reports STEAM_LIBRARY_ENABLED.
- PUT/DELETE /api/users/{id}/steam link and unlink an account,
  POST /api/users/{id}/steam/sync queues the sync for one user.
- sync_steam_libraries syncs every linked user on a schedule
  (ENABLE_SCHEDULED_STEAM_LIBRARY_SYNC, SCHEDULED_STEAM_LIBRARY_SYNC_CRON).
- steam_library_entries holds each user's owned games with playtime and
  last played time; migration 0155 adds it, the user columns and
  roms.storefront.
- A rom-id scan no longer marks a physical or store-only rom missing.
- New store_only rom filter, part of HAS_FILE_ON_DISK_FILTERS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XGA3D2oZ1hq3QUdnubMNXh
@sdornan sdornan added the build-preview Trigger a preview image build label Oct 26, 2026
@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

✅ Preview build completed!

Docker image: ghcr.io/rommapp/romm-testing:claude-trusting-einstein-4rgkz7

Adds the frontend for the Steam library import:

- A Steam section in the user profile links an account by SteamID64,
  profile link or custom URL name, starts a sync, shows how many games
  the account owns, and unlinks it after a confirmation. It only shows
  when the server has a Steam API key.
- An "Owned on Steam" gallery filter, kept in the URL and usable in
  smart collections. The backend gains an `owned_on_steam` rom filter
  and `GET /api/users/{id}/steam/library` for the owned app ids.
- "Open in Steam" shows only on owned games once a linked account's
  library has loaded; without a linked account it behaves as before.

Smart collections filtering on ownership are refreshed when a sync,
relink or unlink changes what a user owns. The sync task is renamed
"Steam library sync" since users start it too, and its completion
notification opens their profile rather than the admin page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XGA3D2oZ1hq3QUdnubMNXh
@sdornan
sdornan marked this pull request as ready for review October 27, 2026 02:35
Copilot AI balanced review requested due to automatic review settings October 27, 2026 02:35
@greptile-apps

greptile-apps Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The latest changes appear safe to merge; no new blocking issue was found.

Summary

This PR adds per-user Steam library imports, store-only games, ownership filters, and profile controls.

  • Users can link a Steam account and import its owned games into RomM.
  • The gallery and Steam launch action can follow each user’s owned games.
  • Store-only games stay in the library without being treated as missing files.

Reviews (4) · Last reviewed commit: "fix(steam): keep the newest owned list a..." · Reviewed by Greptile

Renumbers the Steam library migration to 0156 so it follows master's
0155_rom_release_types.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XGA3D2oZ1hq3QUdnubMNXh
Comment thread backend/tasks/scheduled/sync_steam_libraries.py Outdated
Comment thread backend/handler/steam_library_handler.py Outdated
Comment thread backend/adapters/services/steam_web_api.py
Comment thread frontend/src/stores/steamLibrary.ts
Comment thread frontend/src/components/Settings/SteamLibrarySection.test.ts Outdated
Comment thread backend/alembic/versions/0156_steam_library.py Outdated
Comment thread backend/endpoints/user.py Outdated
…types

The merge renamed the file to 0156 but left its revision ids behind,
giving alembic two heads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XGA3D2oZ1hq3QUdnubMNXh

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Metadata scanning remains blocked, account changes can race with ownership writes, and connection failures can abort scheduled synchronization.

4 open issues
6 files not reviewed
  • frontend/src/__generated__/index.ts: Generated file
  • frontend/src/__generated__/models/Body_link_steam_account_api_users__id__steam_put.ts: Generated file
  • frontend/src/__generated__/models/DetailedRomSchema.ts: Generated file
  • frontend/src/__generated__/models/MetadataSourcesDict.ts: Generated file
  • frontend/src/__generated__/models/SimpleRomSchema.ts: Generated file
  • frontend/src/__generated__/models/UserSchema.ts: Generated file
What changed in this PR

Adds per-user Steam library imports to RomM, integrating account linking, background synchronization, ownership filtering, and store-only games into the existing library.

Changes:

  • Adds Steam API access, ownership storage, account endpoints, and scheduled synchronization.
  • Extends file-less ROM handling and connects ownership to gallery filters and smart collections.
  • Adds profile controls, ownership-aware Steam actions, translations, generated types, and tests.
File Description
frontend/​src/​views/​Settings/​UserProfile.vue Shows Steam settings when configured.
frontend/​src/​utils/​tasks.ts Defines the Steam sync task identifier.
frontend/​src/​utils/​smartCollectionCriteria.ts Serializes and summarizes ownership criteria.
frontend/​src/​utils/​smartCollectionCriteria.test.ts Tests ownership criteria serialization.
frontend/​src/​utils/​rom.fixtures.ts Adds storefront fixture data.
frontend/​src/​utils/​notifications.ts Routes Steam task notifications to the profile.
frontend/​src/​stores/​steamLibrary.ts Loads ownership and refreshes after sync notifications.
frontend/​src/​stores/​heartbeat.ts Defaults Steam library availability to disabled.
frontend/​src/​stores/​galleryRoms.ts Passes ownership into gallery requests.
frontend/​src/​stores/​galleryFilter.ts Tracks and resets ownership filtering.
frontend/​src/​services/​cache/​api.test.ts Tests ownership query parameters.
frontend/​src/​services/​api/​user.ts Adds Steam account and library API methods.
frontend/​src/​services/​api/​rom.ts Adds the ownership query parameter.
frontend/​src/​locales/​zh_TW/​settings.json Adds Traditional Chinese Steam settings text.
frontend/​src/​locales/​zh_TW/​platform.json Adds Traditional Chinese ownership filter labels.
frontend/​src/​locales/​zh_CN/​settings.json Adds Simplified Chinese Steam settings text.
frontend/​src/​locales/​zh_CN/​platform.json Adds Simplified Chinese ownership filter labels.
frontend/​src/​locales/​tr_TR/​settings.json Adds Turkish Steam settings text.
frontend/​src/​locales/​tr_TR/​platform.json Adds Turkish ownership filter labels.
frontend/​src/​locales/​ru_RU/​settings.json Adds Russian Steam settings text.
frontend/​src/​locales/​ru_RU/​platform.json Adds Russian ownership filter labels.
frontend/​src/​locales/​ro_RO/​settings.json Adds Romanian Steam settings text.
frontend/​src/​locales/​ro_RO/​platform.json Adds Romanian ownership filter labels.
frontend/​src/​locales/​pt_BR/​settings.json Adds Brazilian Portuguese Steam settings text.
frontend/​src/​locales/​pt_BR/​platform.json Adds Brazilian Portuguese ownership filter labels.
frontend/​src/​locales/​pl_PL/​settings.json Adds Polish Steam settings text.
frontend/​src/​locales/​pl_PL/​platform.json Adds Polish ownership filter labels.
frontend/​src/​locales/​ko_KR/​settings.json Adds Korean Steam settings text.
frontend/​src/​locales/​ko_KR/​platform.json Adds Korean ownership filter labels.
frontend/​src/​locales/​ja_JP/​settings.json Adds Japanese Steam settings text.
frontend/​src/​locales/​ja_JP/​platform.json Adds Japanese ownership filter labels.
frontend/​src/​locales/​it_IT/​settings.json Adds Italian Steam settings text.
frontend/​src/​locales/​it_IT/​platform.json Adds Italian ownership filter labels.
frontend/​src/​locales/​hu_HU/​settings.json Adds Hungarian Steam settings text.
frontend/​src/​locales/​hu_HU/​platform.json Adds Hungarian ownership filter labels.
frontend/​src/​locales/​fr_FR/​settings.json Adds French Steam settings text.
frontend/​src/​locales/​fr_FR/​platform.json Adds French ownership filter labels.
frontend/​src/​locales/​es_ES/​settings.json Adds Spanish Steam settings text.
frontend/​src/​locales/​es_ES/​platform.json Adds Spanish ownership filter labels.
frontend/​src/​locales/​en_US/​settings.json Adds source Steam settings text.
frontend/​src/​locales/​en_US/​platform.json Adds source ownership filter labels.
frontend/​src/​locales/​en_GB/​settings.json Adds British English Steam settings text.
frontend/​src/​locales/​en_GB/​platform.json Adds British English ownership filter labels.
frontend/​src/​locales/​de_DE/​settings.json Adds German Steam settings text.
frontend/​src/​locales/​de_DE/​platform.json Adds German ownership filter labels.
frontend/​src/​locales/​cs_CZ/​settings.json Adds Czech Steam settings text.
frontend/​src/​locales/​cs_CZ/​platform.json Adds Czech ownership filter labels.
frontend/​src/​locales/​bg_BG/​settings.json Adds Bulgarian Steam settings text.
frontend/​src/​locales/​bg_BG/​platform.json Adds Bulgarian ownership filter labels.
frontend/​src/​composables/​useGameActions/​index.ts Gates Steam actions by loaded ownership.
frontend/​src/​composables/​useGameActions/​index.test.ts Tests ownership-based Steam actions.
frontend/​src/​composables/​useGalleryFilterUrl/​index.ts Persists ownership filtering in URLs.
frontend/​src/​components/​Settings/​SteamLibrarySection.vue Adds linking, syncing, and confirmed unlinking.
frontend/​src/​components/​Settings/​SteamLibrarySection.test.ts Tests Steam profile interactions.
frontend/​src/​components/​GameDetails/​RelatedGameCard.vue Adds storefront to synthetic ROM data.
frontend/​src/​components/​Gallery/​listRowFixture.ts Updates gallery fixture shape.
frontend/​src/​components/​Gallery/​GalleryShell.vue Counts and watches ownership filtering.
frontend/​src/​components/​Gallery/​FilterDrawer.vue Adds the tri-state ownership control.
frontend/​src/​components/​Dialogs/​CreateSmartCollectionDialog.vue Saves ownership criteria in collections.
frontend/​src/​__generated__/​models/​UserSchema.ts Exposes linked Steam account fields.
frontend/​src/​__generated__/​models/​SimpleRomSchema.ts Exposes storefront on simple ROMs.
frontend/​src/​__generated__/​models/​MetadataSourcesDict.ts Exposes Steam library availability.
frontend/​src/​__generated__/​models/​DetailedRomSchema.ts Exposes storefront on detailed ROMs.
frontend/​src/​__generated__/​models/​Body_link_steam_account_api_users__id__steam_put.ts Defines the account-link request type.
frontend/​src/​__generated__/​index.ts Exports the generated link request type.
env.template Documents API key and schedule settings.
docs/​BACKEND_ARCHITECTURE.md Documents Steam storage, endpoints, and scheduling.
backend/​utils/​roms_columns.py Registers the storefront column.
backend/​tests/​test_migrations.py Adds migration replay coverage.
backend/​tests/​tasks/​test_sync_steam_libraries.py Tests sync orchestration and failure handling.
backend/​tests/​models/​test_rom.py Tests store-only file availability.
backend/​tests/​handler/​test_steam_library_handler.py Tests profile resolution and library import.
backend/​tests/​handler/​test_db_handler.py Tests linked users and file-less filtering.
backend/​tests/​handler/​database/​test_roms_owned_on_steam_filter.py Tests per-user ownership matching.
backend/​tests/​endpoints/​test_user_steam.py Tests Steam endpoints and collection refresh.
backend/​tests/​endpoints/​sockets/​test_scan.py Tests bypassing file-less existence checks.
backend/​tests/​adapters/​services/​test_steam_web_api.py Tests Steam API responses and errors.
backend/​tasks/​scheduled/​sync_steam_libraries.py Orchestrates imports and follow-up scans.
backend/​tasks/​registry.py Registers configurable Steam synchronization.
backend/​models/​user.py Stores linked Steam account details.
backend/​models/​steam_library.py Defines per-user game ownership records.
backend/​models/​rom.py Adds storefront and shared file-less predicates.
backend/​handler/​steam_library_handler.py Resolves profiles and imports owned games.
backend/​handler/​scan_handler.py Preserves storefront during metadata scanning.
backend/​handler/​database/​users_handler.py Filters users by linked Steam accounts.
backend/​handler/​database/​steam_library_handler.py Matches ROMs and maintains ownership records.
backend/​handler/​database/​roms_handler.py Adds ownership and store-only filtering.
backend/​handler/​database/​rom_filters.py Defines new ROM filter parameters.
backend/​handler/​database/​__init__.py Exports the Steam library database handler.
backend/​endpoints/​user.py Adds account linking, unlinking, listing, and sync.
backend/​endpoints/​tasks.py Exposes the queued-task response builder.
backend/​endpoints/​sockets/​scan.py Adjusts file-less checks and task-initiated scans.
backend/​endpoints/​responses/​rom.py Adds storefront to ROM responses.
backend/​endpoints/​responses/​identity.py Adds linked Steam account response fields.
backend/​endpoints/​responses/​heartbeat.py Defines the Steam availability response flag.
backend/​endpoints/​heartbeat.py Reports Steam library configuration status.
backend/​config/​__init__.py Loads Steam API key and schedule settings.
backend/​alembic/​versions/​0155_steam_library.py Adds account fields, storefront, and ownership table.
backend/​adapters/​services/​steam_web_api.py Implements the keyed Steam API client.
backend/​adapters/​services/​steam_types.py Defines Steam account and ownership response types.

Review effort: Balanced

Comment thread backend/handler/steam_library_handler.py Outdated
Comment thread backend/adapters/services/steam_web_api.py
Comment thread backend/endpoints/sockets/scan.py
Comment thread backend/tasks/scheduled/sync_steam_libraries.py Outdated
sdornan and others added 2 commits October 27, 2026 02:52
- Queue the metadata scan for unmatched store-only games as UNMATCHED:
  a QUICK scan only reconciles an existing rom's files, so these games
  never got covers or metadata.
- Re-check the linked account under a row lock before a sync writes its
  ownership rows, and clear the account before forgetting its games on
  unlink or relink, so a sync still in flight can't bring them back.
- Report a connection failure or a non-JSON reply from Steam as a Steam
  error, so one user's failure no longer stops the nightly sync.
- Refetch the owned list when a tab becomes visible again, since a
  scheduled sync notifies nobody.
- Move link, unlink and the smart collection refresh into the Steam
  library handler, out of the endpoints.
- Use object-form props in the test stubs and trim the migration
  docstring.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XGA3D2oZ1hq3QUdnubMNXh
A selected-rom scan rebuilt each rom's files from disk before matching
metadata, so a store-only or physical game failed there and never got
its cover. Such a rom now goes straight to metadata, and a quick scan
leaves it alone. Raised by Copilot on the Steam library import.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XGA3D2oZ1hq3QUdnubMNXh
Comment thread frontend/src/stores/steamLibrary.ts
Comment thread backend/handler/steam_library_handler.py
A slow earlier request for the owned Steam apps could overwrite a newer
reply, so only the latest request now writes. Also trims two docstrings
to the one-sentence rule. Addresses Greptile's second review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XGA3D2oZ1hq3QUdnubMNXh
greptile-apps[bot]
greptile-apps Bot previously approved these changes Oct 27, 2026
Master reverted the release-type classification and the Open in Steam
action. The Steam library migration goes back to 0155 on top of
0154_ownerless_own_only, and this branch drops the Open in Steam
ownership gating along with the action it gated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XGA3D2oZ1hq3QUdnubMNXh
@greptile-apps
greptile-apps Bot dismissed their stale review October 27, 2026 15:34

Dismissed because a newer commit was pushed; Greptile will re-review the current head.

@gantoine
gantoine marked this pull request as draft October 27, 2026 20:10
@gantoine gantoine added the on-hold Pending further research or blocked by another issue label Oct 27, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build-preview Trigger a preview image build on-hold Pending further research or blocked by another issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants