TITLE=WarpEngine ROUTE=/engines/warp-engine LOCALE=hu MODIFIED=1792417593 URL=https://wiki.teletypegames.org/hu/engines/warp-engine L=1 #54 L=2 #53 L=3 #46 L=4 #24 L=5 #45 L=6 #47 L=7 #43 L=8 #44 L=9 #68 L=10 #70 L=11 https://woodpecker-ci.org/docs/usage/extensions/configuration-extension q│ A WarpEngine mountolható Rails engine, amely bármelyik Rails-appból retró q│ szoftverkatalógust csinál. Egy játékrepó egyetlen soros c.woodpecker.yaml q│ jelölőt visz, a motor kiszolgálja a teljes CI-pipeline-t, a buildek HTTP-n q│ töltődnek fel, egy publikálási hívás pedig upserteli a katalógust. Publikus, q│ read-only JSON API és opcionális ActiveAdmin resource-ok is járnak hozzá. 1WarpEngine-hez kapcsolódó oldalak 1═════════════════════════════════ t┌───────────────────────────────┬────────────────────────────────┬───────────┐ t│h Oldal t│h Mi az t│h Szerep t│ t├───────────────────────────────┼────────────────────────────────┼───────────┤ t│0 1WECP — WarpEngine Catalog t│0 Az olvasó oldali HTTP/JSON t│0 protokoll t│ t│0 1Protocol t│0 szerződés végpontonként: t│0 t│ t│0 t│0 amivel minden katalógusolvasó t│0 t│ t│0 t│0 beszél. t│0 t│ t├───────────────────────────────┼────────────────────────────────┼───────────┤ t│0 2WarpEngine Admin API t│0 Az 1.0 óta: amit az admin tud, t│0 protokoll t│ t│0 t│0 JSON API-ként, OpenAPI 3.1 t│0 t│ t│0 t│0 leírással és MCP-szerverrel. t│0 t│ t│0 t│0 Kikapcsolva érkezik. t│0 t│ t├───────────────────────────────┼────────────────────────────────┼───────────┤ t│0 3WarpEngine Client t│0 Az asztali app: a katalógus t│0 kliens t│ t│0 t│0 kártyarácsként, telepítés, t│0 t│ t│0 t│0 indítás, eltávolítás. Linux, t│0 t│ t│0 t│0 macOS, Windows. t│0 t│ t├───────────────────────────────┼────────────────────────────────┼───────────┤ t│0 4warpstore t│0 A shell-szkriptes t│0 kliens t│ t│0 t│0 áruházmotorok közös magja: egy t│0 t│ t│0 t│0 fájl, amely ismeri a t│0 t│ t│0 t│0 WarpEngine-katalógust. t│0 t│ t├───────────────────────────────┼────────────────────────────────┼───────────┤ t│0 5WarpEngine Batocera Store t│0 Bármelyik WarpEngine-katalógus t│0 kliens t│ t│0 t│0 egy Batocera-dobozon, saját t│0 t│ t│0 t│0 EmulationStation-menü alatt. t│0 t│ t├───────────────────────────────┼────────────────────────────────┼───────────┤ t│0 6WarpEngine RetroArch Store t│0 Bármelyik WarpEngine-katalógus t│0 kliens t│ t│0 t│0 RetroArch-lejátszási t│0 t│ t│0 t│0 listaként, borítókkal. t│0 t│ t├───────────────────────────────┼────────────────────────────────┼───────────┤ t│0 7TTG Batocera Store · 8TTG t│0 A saját két áruházunk: egy-egy t│0 áruház t│ t│0 8RetroArch Store t│0 konfig a fenti motorok t│0 t│ t│0 t│0 tetején. t│0 t│ t├───────────────────────────────┼────────────────────────────────┼───────────┤ t│0 9Nyilvános oldal t│0 teletypegames.org, az első t│0 hoszt t│ t│0 t│0 hoszt: a monorepó, amelyben a t│0 t│ t│0 t│0 motor fejlődik, és a t│0 t│ t│0 t│0 katalógus, amire a legtöbb t│0 t│ t│0 t│0 olvasó mutat. t│0 t│ t├───────────────────────────────┼────────────────────────────────┼───────────┤ t│0 10Teletype Orbit t│0 Az áruházplatform a t│0 hoszt t│ t│0 t│0 WarpEngine-en: vásárlás, t│0 t│ t│0 t│0 jogosultságok, kapuzott t│0 t│ t│0 t│0 letöltések, eszközös t│0 t│ t│0 t│0 bejelentkezés. t│0 t│ t└───────────────────────────────┴────────────────────────────────┴───────────┘ 1Amit kapsz 1══════════ • bKatalógus domain0 — cSoftware0, cRelease0, cReleaseAsset0, cExternalLink0, cPlatformLink0, cSoftwareImage0, cDownload0. Mind soft delete-tel, download tracking-gel. • bCI-pipeline-szerver0 — Woodpecker 11configuration extension. A játékrepókban csak egy platform marker van. A builder image-ek szerver oldalon élnek, így egy image bump egyszerre ér el minden repót. • bPluggable CI0 — 0.7-től minden CI-funkció egyetlen adapteren megy át. A Woodpecker az engine-nel érkezik cWarpEngine::CI::Woodpecker0 néven, és ez a default; a c:none0 kikapcsolja a CI-t, más szerver pedig a hoszt által adott objektum. • bBuild endpoint-ok0 — cPOST /build/upload0 és cPOST /build/publish0, shared secret-tel vagy adatbázisbeli application token-ekkel hitelesítve. • bPublikus JSON API0 — katalógus, kiemelt cím, platformonkénti build mátrix, download tracking, statikus fájlszerver a webes buildekhez. • bA hoszt képtára0 — 0.6-tól az cImage0 modell, a fájljai, az c/api/image/:id endpoint-ja és az admin oldala a hosztban él; az engine egy szoftvert egy képhez köt, és adapteren keresztül publikálja az URL-t. Ugyanaz a tábla ezután avatarokat vagy bármi mást is kiszolgálhat, ami a site-nak kell. • bPluggable access0 — a hoszt ad egy policy-t, a katalógus pedig árakat, jogosultságokat és gated download-okat kap, és ezt az API-ban is közli, így egy kliens a fizetős címet fizetősként tudja mutatni ahelyett, hogy letöltéskor bukna el. Default: a nyílt katalógus. • bClient sign-in0 — RFC 8628 device authorization grant a hoszt user modelljén, böngésző nélküli klienseknek. Konfig nélkül kikapcsolva. • bOpcionális admin0 — ActiveAdmin resource-ok (katalógusszerkesztő, fájlkezelő, download statisztika, application token-ek). ActiveAdmin nélkül az engine headless módban fut. • bCI-kezelés0 — API token-nel az admin vezérli a CI-szervert: repo sync, pipeline history kézi trigger-rel, CI secret-ként kiosztott application token-ek. • bAsset-ellenőrzőlista0 — 0.8-tól a crake warp_engine:builds:check szoftverenként és kiadásonként kiírja, mely assetek vannak meg, és melyeket tudná még a platform pipeline-ja leszállítani. Lásd: iMely assetek ihiányoznak0. 2Támogatott platformok 2───────────────────── Platformonként két lista, és a különbség számít. Az belfogadott assetek0 az, amit a frissítő befogad egy kiadás publikálásakor (cWarpEngine::Platform#expected_kinds0). A bpipeline ezeket építi0 az, amit a Woodpecker-sablonok ténylegesen elő is állítanak. Ahol eltérnek, ott a maradék kézi feltöltés. t┌────────────┬────────────┬────────────────────────┬─────────────────────────┐ t│h Platform t│h Felirat t│h Elfogadott assetek t│h A pipeline ezeket építi t│ t├────────────┼────────────┼────────────────────────┼─────────────────────────┤ t│0 cgodot0 t│0 Godot t│0 html, win_x86, t│0 mindet t│ t│0 t│0 t│0 win_x64, linux_x64, t│0 t│ t│0 t│0 t│0 mac_universal t│0 t│ t├────────────┼────────────┼────────────────────────┼─────────────────────────┤ t│0 ctic800 t│0 TIC-80 t│0 cartridge, source, t│0 mindet t│ t│0 t│0 t│0 html, docs, win_x64, t│0 t│ t│0 t│0 t│0 linux_x64, mac_x64 t│0 t│ t├────────────┼────────────┼────────────────────────┼─────────────────────────┤ t│0 cbevy0 t│0 Bevy t│0 html, win_x64, t│0 mindet t│ t│0 t│0 t│0 linux_x64, linux_arm64 t│0 t│ t├────────────┼────────────┼────────────────────────┼─────────────────────────┤ t│0 clove0 t│0 LÖVE t│0 html, win_x64, t│0 mindet t│ t│0 t│0 t│0 linux_x64, t│0 t│ t│0 t│0 t│0 mac_universal t│0 t│ t├────────────┼────────────┼────────────────────────┼─────────────────────────┤ t│0 cebitengine0 t│0 Ebitengine t│0 html, win_x86, t│0 html, win_x86, win_x64, t│ t│0 t│0 t│0 win_x64, linux_x64, t│0 linux_x64, linux_arm64 t│ t│0 t│0 t│0 linux_arm64, mac_x64, t│0 t│ t│0 t│0 t│0 mac_arm64 t│0 t│ t├────────────┼────────────┼────────────────────────┼─────────────────────────┤ t│0 cphaser0 t│0 Phaser t│0 html t│0 mindet t│ t├────────────┼────────────┼────────────────────────┼─────────────────────────┤ t│0 cc640 t│0 C64 t│0 cartridge, html, t│0 mindet t│ t│0 t│0 t│0 win_x64, linux_x64, t│0 t│ t│0 t│0 t│0 mac_universal t│0 t│ t├────────────┼────────────┼────────────────────────┼─────────────────────────┤ t│0 cplus40 t│0 Plus/4 t│0 cartridge, html, t│0 mindet t│ t│0 t│0 t│0 win_x64, linux_x64, t│0 t│ t│0 t│0 t│0 mac_universal t│0 t│ t└────────────┴────────────┴────────────────────────┴─────────────────────────┘ Az Ebitengine az egyetlen hiányosság: egy macOS-bináris osxcrosst igényel, amit a linuxos builder image nem visz, így a cmac_x640 és a cmac_arm640 mindig csak kézzel érkezik. 2Mely assetek hiányoznak 2─────────────────────── Egy kiadás akkor teljes, ha minden olyan asset-típust visz, amit a platformja pipeline-ja elő tud állítani — és semmi nem kényszeríti ki. Elbukik egy buildlépés, egy platform új célt kap, egy címet laptopról publikálnak, és a katalógus hét assetből hárommal szolgál ki egy kiadást. A motor ellenőrzőlistát szállít hozzá: p $ bin/rails warp_engine:builds:check p p WarpEngine release asset coverage — latest release per software p expected: the kinds a platform's updater registers · [ ] the CI builds it · » p [-] the CI does not, upload it by hand p p rabbitroller ebitengine v1.1.1 3/7 p [x] html p [x] win_x64 p [x] linux_x64 p [ ] win_x86 p [ ] linux_arm64 p [-] mac_x64 p [-] mac_arm64 p p The CI can build these and the release does not have them: p rabbitroller v1.1.1 (ebitengine): win_x86, linux_arm64 p p 12 softwares, 12 releases, 61/78 assets present, 11 missing from CI-built ki» p nds p 4 softwares are missing an asset the CI builds p 2 assets are expected but this CI does not build them t┌─────────┬──────────────────────────────────────────────────────────────────┐ t│h Jelölés t│h Jelentés t│ t├─────────┼──────────────────────────────────────────────────────────────────┤ t│0 c[x]0 t│0 a kiadásnak megvan ez az assetje t│ t├─────────┼──────────────────────────────────────────────────────────────────┤ t│0 c[ ]0 t│0 a platform elvárja, bés0 a pipeline meg is építi — valódi hiány, t│ t│0 t│0 és ez az a sor, amivel érdemes kezdeni valamit t│ t├─────────┼──────────────────────────────────────────────────────────────────┤ t│0 c[-]0 t│0 elvárt, de ez a CI nem tudja megépíteni (lásd a fenti t│ t│0 t│0 táblázatot) — kézi feltöltés, vagy semmi t│ t├─────────┼──────────────────────────────────────────────────────────────────┤ t│0 c[+]0 t│0 a kiadás olyan assetet visz, amit a platform nem vár el t│ t└─────────┴──────────────────────────────────────────────────────────────────┘ A beállítások környezeti változók, így shellből komponálhatók: t┌─────────────────────┬──────────────────────────────────────────────────────┐ t│h Változó t│h Hatás t│ t├─────────────────────┼──────────────────────────────────────────────────────┤ t│0 cNAME=rabbitroller0 t│0 egyetlen szoftver t│ t├─────────────────────┼──────────────────────────────────────────────────────┤ t│0 cPLATFORM=ebitengine0 t│0 egyetlen platform t│ t├─────────────────────┼──────────────────────────────────────────────────────┤ t│0 cRELEASES=all0 t│0 minden kiadás, nem csak a szoftverenkénti t│ t│0 t│0 legfrissebb t│ t├─────────────────────┼──────────────────────────────────────────────────────┤ t│0 cONLY=missing0 t│0 csak azok a kiadások, amelyekből hiányzik egy CI t│ t│0 t│0 által épített asset t│ t├─────────────────────┼──────────────────────────────────────────────────────┤ t│0 cSTRICT=10 t│0 nem nulla kilépési kód, ha bármi hiányzik — t│ t│0 t│0 ütemezett ellenőrzéshez t│ t└─────────────────────┴──────────────────────────────────────────────────────┘ A „legfrissebb" a legfrissebb nem cdev-0 verzió — ugyanaz a szabály, amit a katalógus API is használ, amikor megnevezi egy cím legutóbbi kiadását. A számok is objektumok: a cWarpEngine::AssetCoverage0 a c#rows0, c#missing_rows0 és c#totals0 metódusokra válaszol, a cWarpEngine::AssetCoverageChecklist0 pedig kirendereli őket. Mindkét hoszton elérhető: a 9nyilvános oldalon és a 10Teletype Orbitban. 1Végpontok 1═════════ 2Nyilvános API 2───────────── Ez az API olvasó oldala — a bWECP, WarpEngine Catalog Protocol0. Minden végpont kérés- és válaszalakja a 1WECP-oldalon van; ez a tábla a térkép. t┌─────────────────────────────────┬──────────────────────────────────────────┐ t│h Végpont t│h Mire való t│ t├─────────────────────────────────┼──────────────────────────────────────────┤ t│0 cGET /api/service0 t│0 Mi ez a telepítés: verzió, kapuz-e a t│ t│0 t│0 katalógus, hogyan lehet belépni. t│ t├─────────────────────────────────┼──────────────────────────────────────────┤ t│0 cGET /api/software0 t│0 A katalógus kiadásokkal, assetekkel, t│ t│0 t│0 linkekkel, letöltésszámokkal, opcionális t│ t│0 t│0 ccategory0 mezővel és egy caccess0 blokkal — t│ t│0 t│0 egészben, vagy laponként (c?page=0, t│ t│0 t│0 c?per_page=0), cstatus0, cplatform0, ccategory0, t│ t│0 t│0 cq0, cowner_id0 szűrőkkel. t│ t├─────────────────────────────────┼──────────────────────────────────────────┤ t│0 cGET /api/software/facets0 t│0 Hány szoftvert mutatna az egyes t│ t│0 t│0 státusz-, platform- és kategóriaértékek t│ t│0 t│0 a többi szűrő mellett. t│ t├─────────────────────────────────┼──────────────────────────────────────────┤ t│0 cGET /api/software/vocabulary0 t│0 A katalógus státuszai és kategóriái, t│ t│0 t│0 címkével és sorrenddel. t│ t├─────────────────────────────────┼──────────────────────────────────────────┤ t│0 cGET /api/software/highlighted0 t│0 A kiemelt cím. t│ t├─────────────────────────────────┼──────────────────────────────────────────┤ t│0 cGET /api/builds0 t│0 Platformonként elvárt asset-típusok. t│ t├─────────────────────────────────┼──────────────────────────────────────────┤ t│0 cGET /api/softwares/:name/builds0 t│0 Kiadásonként a meglévő és a hiányzó t│ t│0 t│0 buildassetek. t│ t├─────────────────────────────────┼──────────────────────────────────────────┤ t│0 cGET /api/image/:id0 t│0 Képek. 0.6 óta ba hoszt végpontja0 — a t│ t│0 t│0 motor közli a címet, a hoszt szolgálja t│ t│0 t│0 ki. t│ t├─────────────────────────────────┼──────────────────────────────────────────┤ t│0 cGET /api/download?path=0 t│0 Kiszolgál egy artifactot, és naplózza a t│ t│0 t│0 letöltést. t│ t├─────────────────────────────────┼──────────────────────────────────────────┤ t│0 cGET /file/*path0 t│0 Statikus buildkimenet (böngészőben t│ t│0 t│0 játszható játékok, dokumentáció). t│ t├─────────────────────────────────┼──────────────────────────────────────────┤ t│0 cPOST /api/auth/device0 t│0 Elindít egy eszközbelépést, visszaadja a t│ t│0 t│0 kódpárt. 404, ha nincs kliensidentitás t│ t│0 t│0 beállítva. t│ t├─────────────────────────────────┼──────────────────────────────────────────┤ t│0 cPOST /api/auth/device/token0 t│0 Lekérdezi egy eszközbelépés tokenjét. t│ t├─────────────────────────────────┼──────────────────────────────────────────┤ t│0 cDELETE /api/auth/token0 t│0 Visszavonja a kérésen érkező bearer t│ t│0 t│0 tokent — kilépés. t│ t└─────────────────────────────────┴──────────────────────────────────────────┘ Minden olvasó végpont elfogad egy opcionális cAuthorization: Bearer …0 fejlécet; egyik sem követeli meg. A token csak azt változtatja meg, amit a hozzáférési szabályzattól kérdezünk. Az anonim hívó támogatott hívó. Minden válasz visz egy cWarpEngine-Version0 fejlécet, amely az akció lefutása előtt kerül rá — így a hibaválaszokon is rajta van, és egy kliens plusz kérés nélkül tud a motorverzió szerint ágazni. p $ curl -sI https://teletypegames.org/api/software | grep -i warpengine p WarpEngine-Version: 0.13.1 A hosztalkalmazás saját végpontjai (például az áruház-nyilvántartás) nem viszik — azok nem részei a motornak. 2Build / CI 2────────── t┌─────────────────────────────┬──────────────────────────────────────────────┐ t│h Végpont t│h Mire való t│ t├─────────────────────────────┼──────────────────────────────────────────────┤ t│0 cPOST /build/upload0 t│0 Egy artifact (multipart cfile0, opcionális t│ t│0 t│0 csha2560). cX-Update-Secret0 kell hozzá. t│ t├─────────────────────────────┼──────────────────────────────────────────────┤ t│0 cPOST /build/publish0 t│0 A feltöltött artifactok regisztrálása t│ t│0 t│0 kiadásként. cX-Update-Secret0 kell hozzá. t│ t├─────────────────────────────┼──────────────────────────────────────────────┤ t│0 cPOST /build/config0 t│0 Woodpecker-konfigurációs kiterjesztés; a t│ t│0 t│0 pipeline-YAML-t szolgálja ki. t│ t│0 t│0 Aláírás-ellenőrzött (RFC 9421, ed25519). t│ t├─────────────────────────────┼──────────────────────────────────────────────┤ t│0 cGET /build/config?platform=0 t│0 A generált YAML nyilvános előnézete. t│ t└─────────────────────────────┴──────────────────────────────────────────────┘ 1Hozzáférés és identitás 1═══════════════════════ Két seam került be a b0.5.00-ban, mindkettő a storage adapter mintájára: dokumentált contract, a régi viselkedéssel azonos default, és egyetlen config kulcs a cseréjéhez. Ha egyiket sem állítod be, semmi nem változik. 2Ki mit láthat és tölthet le 2─────────────────────────── p c.access_policy = MyStore::AccessPolicy.new # :open (alapérték) = a kataló» p gus, ahogy volt A szabályzat három kérdésre válaszol: t┌────────────────────────┬─────────────────────────────────────────────────┐ t│h Metódus t│h Kérdés t│ t├────────────────────────┼─────────────────────────────────────────────────┤ t│0 cvisible_software_scope0 t│0 mely címeket listázza a cGET /api/software0 t│ t│0 caccess_for0 t│0 mit tudunk meg egy kliensként az egyes címekről t│ t│0 cauthorize_download0 t│0 átadható-e ez az artifact t│ t└────────────────────────┴─────────────────────────────────────────────────┘ Az cauthorize_download0 kérdést az c/api/download0 bés0 a c/file/*0 is felteszi, mielőtt bármit kiszolgálna, így egy hosztnak már nem kell árnyékolnia ezeket az útvonalakat. Minden katalógusbejegyzés visz egy caccess0 blokkot, ba nyílt szabályzat alatt is — egy kliensnek soha nem kell találgatnia, hogy a katalógus hallgat-e, vagy a cím egyszerűen nincs kapuzva: p "access": { "gated": true, "entitled": false, p "price": { "amountCents": 1490, "currency": "EUR" }, p "purchaseUrl": "https://shop.example/games/slug", p "webUrl": "https://shop.example/play/slug" } A mezőnevek szándékosan általánosak, mert egy kliens több katalógust olvas. bHa a policy exception-t dob, az elutasításnak számít0: üres katalógus, megtagadott letöltés, logolva. Egy artifactot soha nem szabad azért kiszolgálni, mert a gatekeeper crashelt. 2Client sign-in 2────────────── Egy desktop kliensnek nincs cookie jar-ja és nincs böngésző session-je, ezért az engine login form helyett a device authorization grant-et (RFC 8628) használja. p c.access_token_owner_class = "User" # nil (alapérték): sehol nincs bel» p épés p c.identity_verification_url = "/devices" # a te oldalad, ahol valaki beírja» p a kódot p c.subject_resolver = ->(request) { request.env["warden"]&.user } # böngész» p ő felismerése 1. a kliens cPOST0-ol az c/api/auth/device0 végpontra, és megmutatja a cuserCode értéket; 2. az ember megnyitja az ellenőrzőoldalt, és beírja azt a kódot; 3. ba hoszt oldala0 meghívja a cWarpEngine::DeviceGrantService#approve(user_code:, subject:)0 metódust — a jóváhagyáshoz session és HTML kell, ami nem az engine dolga; 4. a kliens következő lekérdezése elviszi a tokent. Pontosan egyszer adjuk át. A token egy cWarpEngine::ApplicationToken0 a ccatalog0 scope-pal, így a publish és a kliens credential-ök egyetlen táblában is szétválaszthatók maradnak. A csubject_resolver0 fedi le a másik esetet: egy böngésző session-t visz, nem bearer token-t, és enélkül egy gated áruház a saját bejelentkezett látogatóit utasítaná vissza. Ha az caccess_token_owner_class0 nincs beállítva, az c/api/auth/*0 404-et ad, az c/api/service0 pedig cauth: null0-t jelent, így a kliens nem kínál sign-in-t. 1A képtár 1════════ A kép nem katalógusfogalom — ugyanaz a képtár szolgálja ki a borítókat, a képernyőképeket és az avatarokat —, ezért a b0.6.00-tól a motoré csak a kapcsolat (cSoftwareImage0: sorrendezett, egy alapértelmezett), miközben a modell, a fájlok, a végpont és az adminoldal a hoszté. A crails g cwarp_engine:install0 kiír egy működő készletet (capp/models/image.rb0, capp/controllers/api/images_controller.rb0, egy ccreate_images0 migrációt), a motor pedig adapteren keresztül éri el: p c.image_class_name = "Image" # alapérték p c.image_adapter = MyLibrary.new # vagy cseréld le teljesen az adaptert t┌─────────────────────────────────────┬──────────────────────────────────────┐ t│h Metódus t│h Mire használjuk t│ t├─────────────────────────────────────┼──────────────────────────────────────┤ t│0 cmodel_name0 / cmodel0 t│0 az az osztály, amelyhez a t│ t│0 t│0 cSoftwareImage#image0 tartozik t│ t├─────────────────────────────────────┼──────────────────────────────────────┤ t│0 curl_for(image_id)0 t│0 az cimageUrl0 és az cimages[].url0 a t│ t│0 t│0 katalógus JSON-jában, valamint az t│ t│0 t│0 adminelőnézetek t│ t├─────────────────────────────────────┼──────────────────────────────────────┤ t│0 cselect_options0 t│0 a képválasztó a szoftverűrlapon t│ t├─────────────────────────────────────┼──────────────────────────────────────┤ t│0 cbuild_from_upload(upload)0 t│0 „új kép feltöltése" ugyanezen az t│ t│0 t│0 űrlapon t│ t├─────────────────────────────────────┼──────────────────────────────────────┤ t│0 clabel_for(record)0, t│0 az admin felirata és a „megvan-e a t│ t│0 cavailable?(record)0 t│0 fájl" ellenőrzés t│ t└─────────────────────────────────────┴──────────────────────────────────────┘ Az alapértelmezett adapter az c/api/image/0 címet publikálja — azt, amit a kliensek mindig is használtak —, ezért a generált útvonal pontosan ezt szolgálja ki. bAz cimagesb tábla nem költözött0: a motor egyszerűen abbahagyta a létrehozását, és a csoftware_images.image_id0 továbbra is ugyanazokra a sorokra mutat. 1A Woodpecker használata a WarpEngine-nel 1════════════════════════════════════════ Egy játékrepónak nincs saját pipeline-ja. A Woodpecker minden pipeline-indításkor POST-olja az egysoros jelölőt a c/build/config0 végpontra, és visszakapja a teljes YAML-t. 1. A Woodpecker úgy van beállítva, hogy a WarpEngine a konfigurációs kiterjesztése. 2. A repó c.woodpecker.yaml0 fájljában csak a cplatform:0 van (és a cname:0, ha a szoftvernév eltér a repó nevétől). 3. Egy push elküldi a jelölőt a cPOST /build/config0 végpontra. 4. A CI-adapter rendereli a clib/warp_engine/ci/woodpecker/platforms//pipeline.yaml.erb sablont a beállított builder image-dzsel — a YAML-nyelvjárás a szolgáltatóé, tehát az adapterrel együtt él. Az 1.1-től a segédlépések (version, lint, minify, docs, upload, publish) a platform ctools0 image-ében futnak, ha van ilyen, és semmit nem telepítenek; nélküle calpine0-ban futnak, és minden futáskor capk add0-dal (vagy cluarocks install0-lal) rakják fel, ami kell nekik. 5. A pipeline lefut: verzió → build → feltöltés → publikálás. Egy repó úgy lép ki ebből, hogy valódi pipeline-YAML-t commitol: a nem jelölő konfiguráció c204 No Content0 választ kap, és változatlanul fut. 2Egy játékrepó beállítása 2──────────────────────── p # .woodpecker.yaml p platform: godot p name: mygame # opcionális, alapból a repó neve p // metadata.json — a TIC-80-on kívül minden platformon ugyanez p { p "name": "mygame", p "version": "1.0.0", p "title": "My Godot Game", p "author": "You", p "desc": "A cool game", p "license": "MIT", p "category": "puzzle" p } A ccategory0 opcionális szabad szöveg, amely szerint egy kliens csoportosíthatja a címeket — ipuzzle0, iaction0, idemo0. A 0.12-től a cSoftware0 rekordra és a cGET c/api/software0 válaszába kerül; a WarpEngine Client kategória-tengelyt rajzol a szűrőjébe, amint egy katalógus publikál ilyet. A csite0 és a crepo0 is opcionális, belőlük külső link lesz. t┌────────────┬───────────────────────────────┬───────────────────────────────┐ t│h Platform t│h Forráselvárások t│h Mit épít a pipeline t│ t├────────────┼───────────────────────────────┼───────────────────────────────┤ t│0 cgodot0 t│0 exportbeállítások: Web, t│0 cgodot --headless0 t│ t│0 t│0 Windows x86, Windows x64, t│0 c--export-release0 t│ t│0 t│0 Linux x64, Mac universal t│0 előbeállításonként t│ t├────────────┼───────────────────────────────┼───────────────────────────────┤ t│0 cbevy0 t│0 szabványos Cargo-projekt; az t│0 WASM, linux-x64, win-x64 t│ t│0 t│0 cassets/0 a natív binárisok t│0 (mingw) t│ t│0 t│0 mellé kerül becsomagolva t│0 t│ t├────────────┼───────────────────────────────┼───────────────────────────────┤ t│0 clove0 t│0 szabványos LÖVE-projekt t│0 love.js webes build, Windows t│ t│0 t│0 t│0 exe, Linux AppImage, t│ t│0 t│0 t│0 univerzális macOS c.app0 t│ t├────────────┼───────────────────────────────┼───────────────────────────────┤ t│0 cebitengine0 t│0 szabványos Go-projekt t│0 WASM, win x86/x64, linux x64, t│ t│0 t│0 t│0 mac x64/arm64 t│ t├────────────┼───────────────────────────────┼───────────────────────────────┤ t│0 cphaser0 t│0 JS-fájlok a csrc/0 alatt t│0 szintaxisellenőrzés, a t│ t│0 t│0 t│0 Phaser-runtime letöltése, t│ t│0 t│0 t│0 webes zip t│ t├────────────┼───────────────────────────────┼───────────────────────────────┤ t│0 cc640 t│0 cmain.asm0 t│0 ACME-fordítás c.prg0 kazettává, t│ t│0 t│0 t│0 majd ccommodore-pack0 az t│ t│0 t│0 t│0 cexporter0 image-ben: t│ t│0 t│0 t│0 EmulatorJS webes build a t│ t│0 t│0 t│0 cvice_x64sc0 core-ral és t│ t│0 t│0 t│0 yapeSDL-csomagok linux-x64, t│ t│0 t│0 t│0 win-x64 és mac-universal t│ t│0 t│0 t│0 célra t│ t├────────────┼───────────────────────────────┼───────────────────────────────┤ t│0 cplus40 t│0 cmain.asm0 t│0 ugyanaz, mint a cc640, a t│ t│0 t│0 t│0 cvice_xplus40 core-ral és t│ t│0 t│0 t│0 Plus/4 módú yapeSDL-lel t│ t├────────────┼───────────────────────────────┼───────────────────────────────┤ t│0 ctic800 t│0 c.inc0, amely felsorolja t│0 összefűzés, luacheck, t│ t│0 t│0 az cinc/0 alatti darabokat t│0 minifikálás, LDoc, HTML + t│ t│0 t│0 t│0 kazetta + natív binárisok t│ t└────────────┴───────────────────────────────┴───────────────────────────────┘ A TIC-80-nak nem kell cmetadata.json0 — a metaadat a Lua-fejléc: p -- title: My TIC Game p -- name: mygame p -- author: You p -- desc: A TIC-80 game p -- category: puzzle p -- version: 1.0.0 p function TIC() end 2A jelölő beállításai 2──────────────────── t┌──────────┬──────────┬──────────────────────────────────────────────────────┐ t│h Kulcs t│h Kötelező t│h Leírás t│ t├──────────┼──────────┼──────────────────────────────────────────────────────┤ t│0 cplatform0 t│0 igen t│0 cgodot0, ctic800, cbevy0, clove0, cebitengine0, cphaser0, cc640, t│ t│0 t│0 t│0 cplus40 t│ t├──────────┼──────────┼──────────────────────────────────────────────────────┤ t│0 cname0 t│0 nem t│0 Szoftvernév; alapból a repó neve t│ t└──────────┴──────────┴──────────────────────────────────────────────────────┘ 2Pipeline előnézete 2────────────────── p curl "https://your-host/build/config?platform=godot" 2Lapozás és szótár (0.13) 2──────────────────────── A cGET /api/software0 borítékban válaszol — capi0 (a JSON-alak saját verziója, 2), cpage0, cperPage0, ctotal0, ctotalPages0, cnextPage0 és csoftwares0. cpageb nélkül a teljes bkatalógus jön vissza0 ebben a borítékban, amit minden 2-es API előtti olvasó a csoftwares0 alatt talál meg; cpage0-gel egy lap cper_page0 elemmel (ccatalog_page_size0, ha nincs megadva, legfeljebb ccatalog_max_page_size0). A szűrők a lapozás előtt szűkítik a katalógust; a hozzáférési szabályzat mindkettő előtt dönt a láthatóságról. A státuszok és a kategóriák badatbázisbeli szótár0 — cWarpEngine::SoftwareStatus és cWarpEngine::SoftwareCategory0, adminban szerkeszthető —, nem kódba írt lista. Egy szoftver cstatus0-a ismert kulcs kell legyen: a migráció a négyet seedeli, és a 0.13.1-től a modell maga teszi vissza őket egy üres táblába az első használatnál — egy cdb:schema:load0-dal, nem migrációval épült adatbázisban, ami minden teszt-adatbázis, különben nem lenne egy sor sem. Egy publish által hozott, még el nem nevezett kategória a kulcsával mint címkével és cneeds_review0 jelzéssel kerül a szótárba. A cGET /api/software/vocabulary mindkettőt publikálja, az oldal katalógusa és a WarpEngine Client ebből veszi a címkéket. 2Titkok és verziók 2───────────────── Minden generált pipeline egyetlen Woodpecker-secretet vár, az capplication_token0 értéket, amelyet cX-Update-Secret0 fejlécként küld a c/build/upload0 és a c/build/publish0 végpontokra. A verziózás mindenhol ugyanaz: a cmain0/cmaster0 ágon a verzió a cmetadata.json fájlból jön (TIC-80 esetén a c-- version:0 sorból); más ágakon előtagot kap, pl. cdev-1.0.0-my-feature0. 1CI-kezelés (Woodpecker API) 1═══════════════════════════ Csak ott aktív, ahol az adapternek van curl0 és capi_token0 értéke (cWarpEngine.ci.configured?0). Addig az adminoldalak elrejtik magukat. • bRepószinkron0 — iAdmin → Pipelines → Sync from Woodpecker0 (a gomb az adapter nevét viseli). Tükrözi a repólistát cPipeline0 rekordokba, név alapján párosítja az egyes repókat egy cSoftware0 rekorddal, és örökli annak platformját. A Woodpeckerből eltűnt repók deaktiválódnak. A linkek kézzel szerkeszthetők maradnak. • bPipeline-ok0 — minden bejegyzés felsorolja a legutóbbi futásait (státusz, ág, üzenet, idő) egy kézi bTrigger0 gombbal. A legfrissebb futás frissíti a listaoldalon gyorsítótárazott státuszt. Egy szoftver adminoldala hivatkozik a pipeline-jaira. • bSecret-kiosztás0 — egy token létrehozása kiosztja az capplication_token secretet a tulajdonos repóira (korlátozás nélküli tokenek esetén minden aktív repóra); a törlés eltávolítja; a bRotate0 létrehoz egy cserét, mindenhova kiosztja, és egy lépésben visszavonja a régit. A PAT-nak Woodpecker-bpéldányadminhoz0 kell tartoznia — a repók listázása csak admin által hívható végpont, minden más c403 User not authorized0 választ ad. Vedd fel a felhasználót a cWOODPECKER_ADMIN0 listába, majd blépj ki és vissza0: az adminjelző a bejelentkezéskor íródik, a szerver újraindítása nem elég. 1Buildhitelesítés 1════════════════ Az cX-Update-Secret0 kétféle hitelesítő adat egyikét viszi, amit az capplication_token_source0 választ ki. A módok kizárják egymást. t┌──────────────────┬─────────────────────────────────────────────────────────┐ t│h Mód t│h Hitelesítő adat t│ t├──────────────────┼─────────────────────────────────────────────────────────┤ t│0 c:env0 (alapérték) t│0 a közös titok az cupdate_secret0 értékben; ha nincs t│ t│0 t│0 beállítva, minden kérés elutasításra kerül t│ t├──────────────────┼─────────────────────────────────────────────────────────┤ t│0 c:database0 t│0 cWarpEngine::ApplicationToken0 rekordok: tulajdonos (pl. t│ t│0 t│0 cAdminUser0), jogosultságok (cupdate0 a publikáláshoz, t│ t│0 t│0 cupload0 a feltöltéshez), opcionális lejárat. Az adminban t│ t│0 t│0 jönnek létre; a nyílt token egyszer jelenik meg, csak a t│ t│0 t│0 SHA256-lenyomata tárolódik. A clast_used_at0 követi a t│ t│0 t│0 használatot. t│ t└──────────────────┴─────────────────────────────────────────────────────────┘ q│ bCutover warning:q a c:databaseq módra váltás azonnal érvényteleníti a shared q│ secret-et. Előbb hozd létre a token-eket. 1Telepítés egy hosztba 1═════════════════════ p # Gemfile — gitből: p gem "warp_engine", git: "https://git.teletypegames.org/engines/warp_engine.g» p it" p p # ...vagy a Forgejo rubygems-regiszteréből (taggelt kiadások): p source "https://git.teletypegames.org/api/packages/engines/rubygems" do p gem "warp_engine" p end p rails g warp_engine:install # initializer, képtár, migrációk p rails db:migrate p # config/routes.rb p namespace :api do p get "image/:id", to: "images#show" # a képtár a tiéd (lásd lentebb) p end p p # a mount maradjon az utolsó, hogy a hoszt saját útvonalai nyerjenek p mount WarpEngine::Engine => "/" A generátor kiírja a cconfig/initializers/warp_engine.rb0 fájlt: p Rails.application.config.to_prepare do p WarpEngine.configure do |c| p c.file_container_path = ENV.fetch("FILE_CONTAINER_PATH", "/softwares") p p # The image library is the host's; "Image" is the adapter's default. p # c.image_class_name = "Media::Picture" p # c.image_adapter = MyImageLibrary.new p p c.update_secret = ENV["UPDATE_SECRET"] p p # c.application_token_source = :database p # c.application_token_owner_class = "AdminUser" p p # One adapter carries the whole CI side: server, recipes, signing key. p c.ci_adapter = WarpEngine::CI::Woodpecker::Adapter.new( p url: ENV["WOODPECKER_URL"], p api_token: ENV["WOODPECKER_API_TOKEN"], p repo_owner: ENV["WOODPECKER_REPO_OWNER"], p public_key_url: "https://ci.example.org/api/signature/public-key", p update_server: "https://catalog.example.org", p platforms: { p "godot" => { builder: "registry.example/godot-builder:4.6" }, p "tic80" => { builder: "registry.example/tic80-builder:1.0", p exporter: "registry.example/tic80pro:1.0" }, p "bevy" => { builder: "registry.example/bevy-builder:1.0" }, p "love" => { builder: "registry.example/love-builder:1.0" }, p "ebitengine" => { builder: "registry.example/ebitengine-builder:1.0"» p }, p "phaser" => { builder: "registry.example/phaser-builder:1.0" }, p "c64" => { builder: "registry.example/c64-builder:1.0", p exporter: "registry.example/commodore-player:1.0" » p }, p "plus4" => { builder: "registry.example/plus4-builder:1.0", p exporter: "registry.example/commodore-player:1.0" » p } p } p # Bármelyik spec megnevezhet egy tools image-et is a segédlépésekhez (» p 1.1): p # "love" => { builder: "...", tools: "registry.example/ci-tools:1.0"» p } p ) p p # c.max_upload_size = 500 * 1024 * 1024 p # c.enforce_software_ownership = true p end p end t┌────────────────────────┬─────────────────────────┬─────────────────────────┐ t│h Kulcs t│h Alapérték t│h Leírás t│ t├────────────────────────┼─────────────────────────┼─────────────────────────┤ t│0 cfile_container_path0 t│0 cENV["FILE_CONTAINER_0 t│0 Hol tárolódnak a t│ t│0 t│0 cPATH"]0 vagy c/softwares0 t│0 buildartifactok t│ t├────────────────────────┼─────────────────────────┼─────────────────────────┤ t│0 cupdate_secret0 t│0 cENV["UPDATE_SECRET"]0 t│0 Közös titok a c/build/*0 t│ t│0 t│0 t│0 végpontokhoz t│ t├────────────────────────┼─────────────────────────┼─────────────────────────┤ t│0 capplication_token_0 t│0 c:env0 t│0 c:env0 vagy c:database0, t│ t│0 csource0 t│0 t│0 kizárólagosan t│ t├────────────────────────┼─────────────────────────┼─────────────────────────┤ t│0 capplication_token_0 t│0 cnil0 t│0 Tulajdonosmodell a t│ t│0 cowner_class0 t│0 t│0 c:database0 módhoz t│ t├────────────────────────┼─────────────────────────┼─────────────────────────┤ t│0 cmax_upload_size0 t│0 500 MB t│0 Korlát a c/build/upload0 t│ t│0 t│0 t│0 végponthoz t│ t├────────────────────────┼─────────────────────────┼─────────────────────────┤ t│0 cenforce_software_0 t│0 cfalse0 t│0 Adatbázistoken- t│ t│0 cownership0 t│0 t│0 tulajdonos szerinti t│ t│0 t│0 t│0 elszigetelés t│ t├────────────────────────┼─────────────────────────┼─────────────────────────┤ t│0 cci_adapter0 t│0 c:woodpecker0 t│0 Melyik CI-szerver építi t│ t│0 t│0 t│0 a játékokat; a c:none0 t│ t│0 t│0 t│0 kikapcsolja a CI-t, t│ t│0 t│0 t│0 vagy egy hosztobjektum t│ t├────────────────────────┼─────────────────────────┼─────────────────────────┤ t│0 cimage_class_name0 t│0 c"Image"0 t│0 A képtár mögötti t│ t│0 t│0 t│0 hosztmodell t│ t├────────────────────────┼─────────────────────────┼─────────────────────────┤ t│0 cimage_adapter0 t│0 cnil0 t│0 Lecseréli az t│ t│0 t│0 t│0 alapértelmezett t│ t│0 t│0 t│0 hosztmodell-adaptert t│ t├────────────────────────┼─────────────────────────┼─────────────────────────┤ t│0 caccess_policy0 t│0 c:open0 t│0 Hozzáférési szabályzat t│ t│0 t│0 t│0 objektum t│ t├────────────────────────┼─────────────────────────┼─────────────────────────┤ t│0 caccess_token_owner_0 t│0 cnil0 t│0 Felhasználómodell az t│ t│0 cclass0 t│0 t│0 eszközbelépéshez; nil = t│ t│0 t│0 t│0 nincs belépés t│ t├────────────────────────┼─────────────────────────┼─────────────────────────┤ t│0 cadmin_api.*0 t│0 cenabled = false0 t│0 Az 2Admin API és az t│ t│0 t│0 t│0 MCP-szervere (1.0) t│ t└────────────────────────┴─────────────────────────┴─────────────────────────┘ Egy platform-spec három image-et kaphat. A cbuilder0 futtatja a build lépéseket. Az cexporter0 egy második image, amelyben egy sablon lépést futtathat — a c64 és a plus4 pipeline itt csomagolja a c.prg0-t a böngészős és a natív lejátszókba. A ctools0 (1.1, opcionális) a segédlépéseké: version, lint, minify, docs, upload, publish. Nélküle ezek calpine0-ban futnak, és minden futáskor capk add0-dal felrakják a git, jq, curl, zip és lua5.4 csomagot, a tic80-nál cluarocks cinstall0-lal a luacheck-et és az ldoc-ot is; vele semmit nem telepítenek, tehát az image-ben ezeknek már benne kell lenniük, a Lua 5.4-gyel clua0 néven. Az upload és a publish lépés megkapja az capplication_token0 secretet, ezért a tools image-re digest szerint hivatkozz. A teletypegames.org így adja minden platformnak a cbuild/ci-tools0 image-ét. 1Adminintegráció 1═══════════════ Az ActiveAdmin-példány a hoszté (hitelesítés, téma, útvonalak); a WarpEngine hozzáfűzi az erőforrásait az cActiveAdmin.application.load_paths0 listához. Egy új hosztnak két dolog kell: • a fájlválasztó JS a kiadási assetek útvonalmezőihez (iframe → c/admin/files?picker=1&field=0) az cactive_admin.js0 fájljában; • apipie-dokumentáció esetén a c"#{WarpEngine::Engine.root}/app/controllers/**/*.rb"0 bejegyzés az capi_controllers_matcher0 beállításban. Az 1.0 óta ugyanezek az erőforrások JSON API-ként is elérhetők — lásd 2WarpEngine Admin API. Az adminoldalak és az API ugyanazokat a service-eket hívják (cApplicationTokenService0, cDownloadStatsService0, cFileManagerService0), így a kettő nem tud elcsúszni egymástól. 1Viselkedési megjegyzések 1════════════════════════ • Minden modell soft delete-tel dolgozik (cdefault_scope { where(deleted_at: cnil) }0). • A JSON shape stabil, és bug-compatible a korábbi Go backenddel: Go-féle nulla timestamp-ek, camelCase kulcsok, legacy flat path field-ek. • Model extension point-ok: cActiveSupport.on_load(:warp_engine_)0. 1Tesztelés 1═════════ p bundle install p bundle exec rake app:db:prepare RAILS_ENV=test p bundle exec rspec