Két dolog volt beépítve az engine-be, ami nem az övé. A **képtár** eddig `WarpEngine::Image` volt, pedig a modell teljesen általános: a teletypegames-ben a tagok arcképét is ez hordozza, nem csak a katalógus borítóit. Az `Image` modell, a feltöltött fájlok, az `/api/image/:id` végpont és az admin oldal ezért átkerült a hosztba, az engine pedig adapteren szól hozzá (`WarpEngine::Images`): `url_for` adja a katalógus JSON `imageUrl`-jét, `select_options` a software-form képválasztóját, `build_from_upload` a "tölts fel új képet" ágat. Az alapértelmezés az `Image` osztály, tehát a default útvonal bitre a régi. A `SoftwareImage` (a katalógus-kapcsolat) maradt az engine-ben, és **az `images` tábla nem mozdult**: az engine csak abbahagyta a létrehozását, a generátor írja meg hoszt-kódként. A **CI** eddig végig Woodpecker volt: kliens, aláírás-ellenőrzés, pipeline-receptek, repo-szinkron, secret-kiosztás. Mindez egy adapter mögé került (`WarpEngine.ci`), a Woodpecker-implementáció pedig az engine-ben maradt `WarpEngine::CI::Woodpecker` néven — kliens, adapter, httpsig-ellenőrző és a platformonkénti pipeline-receptek, mert a YAML-dialektus a szolgáltatóé. Az engine saját kódja már nem nevez szolgáltatót: `CI::Repo` és `CI::Run` értékeket kap, `CI::ConnectionError`/`ApiError`/`NotConfigured` hibákat dob, a `Pipeline` pedig `remote_repo_id`-t ad a történelmi `woodpecker_repo_id` kolumna fölött (a tábla itt sem mozdult). `c.ci_adapter = :none` azt jelenti, hogy ez a hoszt nem buildel: az `/api/ci/*` 503, a `/build/config` elutasít, az admin akciók elbújnak. Mindkét seam a hoszt initializerében van kimondva, nem alapértelmezésre hagyva — a hoszt megnevezi, mi a képtára és mi a CI-ja. Törés a 0.6-hoz képest: `image_container_path`, `image_owners`, `ci_platforms`, `ci_update_server`, `ci_extension_public_key(_url)`, `woodpecker_url`, `woodpecker_api_token`, `woodpecker_repo_owner` és a `WarpEngine.woodpecker_configured?` megszűnt; a helyük `c.image_class_name` / `c.image_adapter` és `c.ci_adapter`. Az `/api/ci/*` `latest_run`/`trigger` válasza a normalizált `CI::Run` alakot adja (number, status, branch, message, createdAt, url), a `pipelines` lista pedig `repo_id`-t is közöl a megtartott `woodpecker_repo_id` mellett. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
95 lines
2.7 KiB
Ruby
95 lines
2.7 KiB
Ruby
module WarpEngine
|
|
|
|
module CI
|
|
class Error < StandardError; end
|
|
|
|
class ConnectionError < Error; end
|
|
|
|
class NotConfigured < Error; end
|
|
|
|
class ApiError < Error
|
|
attr_reader :status, :body
|
|
|
|
def initialize(message, status: nil, body: nil)
|
|
super(message)
|
|
@status = status
|
|
@body = body
|
|
end
|
|
end
|
|
|
|
Repo = Struct.new(:id, :name, :owner, :active, :raw, keyword_init: true) do
|
|
def active? = active ? true : false
|
|
def full_name = "#{owner}/#{name}"
|
|
end
|
|
|
|
Run = Struct.new(:number, :status, :branch, :message, :created_at, :url, :raw, keyword_init: true) do
|
|
def success? = status.to_s == "success"
|
|
|
|
def as_json(*)
|
|
{
|
|
number: number,
|
|
status: status,
|
|
branch: branch,
|
|
message: message,
|
|
createdAt: created_at&.utc&.iso8601,
|
|
url: url
|
|
}
|
|
end
|
|
end
|
|
|
|
class Null
|
|
MESSAGE = "no CI adapter is configured (WarpEngine.config.ci_adapter)".freeze
|
|
|
|
def name = "none"
|
|
def configured? = false
|
|
def platforms = {}
|
|
def update_server = nil
|
|
|
|
def repos = raise(NotConfigured, MESSAGE)
|
|
def repo(_id) = raise(NotConfigured, MESSAGE)
|
|
def activate_repo(_id) = raise(NotConfigured, MESSAGE)
|
|
def deactivate_repo(_id) = raise(NotConfigured, MESSAGE)
|
|
def runs(_repo_id, page: 1) = raise(NotConfigured, MESSAGE)
|
|
def run(_repo_id, _number) = raise(NotConfigured, MESSAGE)
|
|
def trigger(_repo_id, branch: nil) = raise(NotConfigured, MESSAGE)
|
|
def secret_names(_repo_id) = raise(NotConfigured, MESSAGE)
|
|
def secret_set(_repo_id, name:, value:) = raise(NotConfigured, MESSAGE)
|
|
def secret_delete(_repo_id, _name) = raise(NotConfigured, MESSAGE)
|
|
|
|
def verify_config_request(_request) = false
|
|
def config_marker(_params) = nil
|
|
def pipeline_config(platform:, name:, update_server:) = nil
|
|
def config_response(platform:, config:) = {}
|
|
end
|
|
|
|
class << self
|
|
def adapter
|
|
configured = WarpEngine.config.ci_adapter
|
|
|
|
case configured
|
|
when nil, :woodpecker, "woodpecker" then woodpecker_adapter
|
|
when :none, "none", :null then null_adapter
|
|
else configured
|
|
end
|
|
end
|
|
|
|
def woodpecker? = adapter.is_a?(Woodpecker::Adapter)
|
|
|
|
def woodpecker_adapter
|
|
@woodpecker_adapter ||= Woodpecker::Adapter.new
|
|
end
|
|
|
|
def null_adapter
|
|
@null_adapter ||= Null.new
|
|
end
|
|
|
|
def reset!
|
|
@woodpecker_adapter = nil
|
|
@null_adapter = nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
require "warp_engine/ci/woodpecker"
|