Make docs optional in the tic80 updater

Older-style tic80 pipelines (bombexpert, mranderson) do not upload a
docs zip; the unconditional extraction raised and aborted the whole
update, so the new binary assets never got registered. Extract and
register docs only when the zip/dir exists. Covered by new
Tic80Service specs (optional docs + binary slug pickup).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-03 23:46:50 +02:00
co-authored by Claude Fable 5
parent 4b03b7bbc7
commit da37e39774
2 changed files with 82 additions and 4 deletions
@@ -0,0 +1,73 @@
require "rails_helper"
require "zip"
RSpec.describe SoftwareUpdater::Tic80Service do
let(:tmpdir) { Dir.mktmpdir }
let(:name) { "spectic" }
let(:version) { "9.9" }
let(:versioned) { "#{name}-#{version}" }
before do
allow(ENV).to receive(:fetch).and_call_original
allow(ENV).to receive(:fetch).with("FILE_CONTAINER_PATH", "/softwares").and_return(tmpdir)
write_zip("#{versioned}.html.zip", "index.html" => "<html></html>")
File.write(File.join(tmpdir, "#{versioned}.tic"), "TIC!")
File.write(File.join(tmpdir, "#{versioned}.lua"), <<~LUA)
-- title: Spec TIC
-- name: #{name}
-- author: RSpec
-- desc: spec fixture
-- version: #{version}
function TIC() end
LUA
end
after do
FileUtils.remove_entry(tmpdir)
Software.unscoped.where(name: name).each do |sw|
Release.unscoped.where(software_id: sw.id).each do |r|
ReleaseAsset.unscoped.where(release_id: r.id).delete_all
r.delete
end
ExternalLink.unscoped.where(software_id: sw.id).delete_all
sw.delete
end
end
def write_zip(filename, entries)
Zip::File.open(File.join(tmpdir, filename), create: true) do |zip|
entries.each do |entry_name, content|
zip.get_output_stream(entry_name) { |io| io.write(content) }
end
end
end
def asset_kinds(release)
ReleaseAsset.unscoped.where(release_id: release.id).pluck(:kind)
end
it "registers the release without a docs zip" do
release = described_class.new.update(name, version)
expect(asset_kinds(release)).to match_array(%w[cartridge source html])
end
it "registers docs when the docs zip is present" do
write_zip("#{versioned}-docs.zip", "index.html" => "docs")
release = described_class.new.update(name, version)
expect(asset_kinds(release)).to include("docs")
end
it "registers binary assets when slug zips are present" do
write_zip("#{versioned}-win-x64.zip", "game.exe" => "MZ")
write_zip("#{versioned}-mac-universal.zip", "game" => "bin")
release = described_class.new.update(name, version)
expect(asset_kinds(release)).to include("win_x64", "mac_universal")
expect(asset_kinds(release)).not_to include("linux_x64")
end
end