mr.zero ec43d2ae46
ci/woodpecker/push/woodpecker Pipeline was successful
warp_engine 0.2.0: pluggable storage adapter and publish notifications
Two seams the hosts needed, both backward compatible.

Storage: artifacts are served through WarpEngine::Storage.adapter instead of
raw filesystem calls. The default :local adapter keeps the previous behaviour
byte for byte, including the path traversal guard. A host can now set
config.storage_adapter to any object answering file?/directory?/locate and
serve builds from an object store - FileService and /api/download both honour
a Location.redirect, so a signing adapter turns them into redirects.
DownloadService#create still returns an absolute path (nil when missing) for
existing callers; #locate is the new entry point that can also return a
redirect. Ingestion (upload, extraction, file manager) stays local for now.

Publish: PublishService emits ActiveSupport::Notifications
("warp_engine.publish") with platform/name/version/software/release, so hosts
can react to a new build without hanging callbacks on the models.
WarpEngine.instruments_publish? lets a host feature-detect and keep its
fallback for older engine versions.
2026-08-10 11:16:17 +02:00
2026-08-09 17:57:08 +02:00
2026-05-06 20:15:52 +02:00
2026-08-06 16:05:07 +02:00
2026-02-19 12:35:43 +01:00
2026-08-05 20:12:35 +02:00
2026-01-27 20:01:25 +01:00

Teletype Games

Monorepo for the Teletype Games portal: a Vue 3 frontend, a Rails 8 API host app, and the reusable WarpEngine software-catalog engine.

Project structure

apps/
  frontend/            # Vue 3 + Vite + TypeScript + Tailwind SPA
  api/                 # Rails 8 host app: TTG-specific API + ActiveAdmin shell
libs/
  ruby/warp_engine/    # WarpEngine: mountable Rails engine (catalog, updater, admin resources)

The API is split in two layers:

  • WarpEngine (libs/ruby/warp_engine) owns the software catalog: models (softwares, releases, release assets, images, platform links, download stats), the CI-callable /build/* publishing endpoints, the public read-only JSON API (/api/software*, /api/builds*, /api/image, /api/download, /file/*) and the catalog ActiveAdmin resources. See its README.
  • The host app (apps/api) owns everything TTG-specific: members, events, wiki proxy, RSS feeds, Devise/ActiveAdmin authentication, theming and assets. It consumes WarpEngine as a path gem and mounts it at /.

Development environment

docker compose up -d
Service URL
Frontend http://${WEBAPP_DOMAIN}
API http://${WEBAPP_DOMAIN}/api
Admin http://${WEBAPP_DOMAIN}/admin
API docs http://${WEBAPP_DOMAIN}/api/swagger

The api image is built from the repo root (so the libs/ path gems are visible during bundle install) and mounts ./libs at runtime. After changing the compose file or the Gemfile, rebuild with docker compose up -d --build api.

Testing

make api-test

Runs the host suite (apps/api, softwares_test DB), the WarpEngine suite (dummy app, warp_engine_test DB) and a production-mode zeitwerk:check. Individually:

docker exec -e RAILS_ENV=test api bundle exec rspec                                # host
docker exec -w /libs/ruby/warp_engine -e RAILS_ENV=test api bundle exec rspec     # engine

JSON contract baselines for /api/software and /api/builds live in apps/api/spec/snapshots/ — diff against them after refactors.

Linting

Backend (RuboCop)

docker compose run --rm --no-deps api bundle exec rubocop        # check
docker compose run --rm --no-deps api bundle exec rubocop -A     # autofix

Config: apps/api/.rubocop.yml (rubocop-rails-omakase preset)

Frontend (ESLint)

docker compose run --rm --no-deps frontend npm run lint          # check
docker compose run --rm --no-deps frontend npm run lint:fix      # autofix

Config: apps/frontend/eslint.config.js (ESLint 9 flat config, Vue + TypeScript)

S
Description
No description provided
Readme
9.6 MiB
Languages
Ruby 59.4%
Vue 12.6%
TypeScript 12.5%
HTML 10.6%
CSS 2.1%
Other 2.6%