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>
33 lines
992 B
Ruby
33 lines
992 B
Ruby
class Image < ApplicationRecord
|
|
def self.upload_path
|
|
ENV.fetch("IMAGE_CONTAINER_PATH", "/images")
|
|
end
|
|
|
|
has_many :software_images, class_name: "WarpEngine::SoftwareImage", dependent: :restrict_with_error
|
|
|
|
default_scope { where(deleted_at: nil) }
|
|
|
|
attr_accessor :file_upload
|
|
|
|
before_save :process_upload, if: -> { file_upload.present? }
|
|
|
|
def self.ransackable_attributes(auth_object = nil)
|
|
%w[content_type created_at deleted_at filename id original_filename updated_at]
|
|
end
|
|
|
|
def file_path
|
|
File.join(self.class.upload_path, filename.to_s)
|
|
end
|
|
|
|
private
|
|
|
|
def process_upload
|
|
FileUtils.mkdir_p(self.class.upload_path)
|
|
self.original_filename = file_upload.original_filename
|
|
self.content_type = file_upload.content_type.presence || "application/octet-stream"
|
|
ext = File.extname(file_upload.original_filename)
|
|
self.filename = "#{SecureRandom.uuid}#{ext}"
|
|
IO.copy_stream(file_upload.to_io, file_path)
|
|
end
|
|
end
|