diff --git a/.claude/skills/release/SKILL.md b/.claude/skills/release/SKILL.md index ab6e45a..e4d9fdb 100644 --- a/.claude/skills/release/SKILL.md +++ b/.claude/skills/release/SKILL.md @@ -149,8 +149,17 @@ subdirectories, and it ends by reconciling the screenshots — wait for the checksums, delete duplicates, sort by filename, fail if live still differs from disk. Two more traps sit outside our code: **App Review Information must exist before deliver will run at all** (it reads it without a rescue and an app that -has never had it gets `No data`), and **What's New shows as a difference until -the second release**, because App Store Connect refuses it for a first version. +has never had it gets `No data`), and **What's New does not exist until the +second release on a platform**, because the field belongs to an update: deliver +says so and moves on (`Skipping 'release_notes'... this is the first version of +the app`), so text written there cannot reach the store however many times it +is pushed, and `metadata_diff` reports it every run instead. Two permanent +phantom lines is how a diff people read becomes a diff people skip, so +`appstore/metadata-visionos/*/release_notes.txt` is deliberately **empty** and +`MetadataCheck::MAY_BE_EMPTY` allows that one field in that one directory. +**Write the notes and delete the exemption together**, when visionOS takes its +second version — an update with no What's New is refused, and by then it is the +exemption that would be hiding the empty file. One more vocabulary mismatch to remember: deliver says `osx`, the Connect API says `MAC_OS`, and passing the former to spaceship reports a missing version that plainly exists. diff --git a/appstore/metadata-visionos/en-US/release_notes.txt b/appstore/metadata-visionos/en-US/release_notes.txt index 421a20b..e69de29 100644 --- a/appstore/metadata-visionos/en-US/release_notes.txt +++ b/appstore/metadata-visionos/en-US/release_notes.txt @@ -1 +0,0 @@ -Tortoise Blocks comes to Apple Vision Pro, as a viewer for the drawings you make on iPad and Mac. Open one and it goes on the table in front of you, at whatever size you like, with the tortoise walking across the paper as the picture appears. The blocks it was made from and the Swift code behind it open in two more windows, both at once. diff --git a/appstore/metadata-visionos/ja/release_notes.txt b/appstore/metadata-visionos/ja/release_notes.txt index 8bbd467..e69de29 100644 --- a/appstore/metadata-visionos/ja/release_notes.txt +++ b/appstore/metadata-visionos/ja/release_notes.txt @@ -1 +0,0 @@ -Apple Vision Pro に対応しました。iPad と Mac で作った絵を見るためのビューワーです。開くと目の前の机の上に好きな大きさで紙が広がり、その上をカメが歩きながら絵を描いていきます。もとになったブロックと、その Swift のコードは、それぞれ別のウィンドウで同時に開けます。 diff --git a/fastlane/metadata_check.rb b/fastlane/metadata_check.rb index 6d72fcf..16e626e 100755 --- a/fastlane/metadata_check.rb +++ b/fastlane/metadata_check.rb @@ -39,6 +39,19 @@ module MetadataCheck # app's name depend on lane order, silently. They have to match. SHARED = ["name.txt", "subtitle.txt", "privacy_url.txt"].freeze + # Empty is a problem everywhere except here, and only because App Store + # Connect has no field to fill: "What's New" belongs to an *update*, and + # visionOS 1.1.0 is the app's first version on that platform. deliver says so + # and moves on — `Skipping 'release_notes'... this is the first version of + # the app` — so text written here cannot reach the store however many times + # it is pushed, and shows up in every `metadata_diff` instead. Two permanent + # phantom lines is how a diff people read becomes a diff people skip. + # + # **Delete this the moment visionOS takes a second version**, which is also + # when the notes have to be written: an update with no What's New is refused, + # and by then it is this exemption that would be hiding the empty file. + MAY_BE_EMPTY = { "metadata-visionos" => ["release_notes.txt"] }.freeze + # Sizes Apple accepts for the display types this app ships. An unexpected # size is a mistake worth stopping on, not a shape to guess at. A platform # missing from this table is not checked at all, so a new screenshots @@ -96,7 +109,9 @@ def text_problems(root) METADATA_DIRECTORIES.flat_map do |metadata| locale_directories(root / metadata).flat_map do |directory| locale = directory.basename.to_s - REQUIRED.flat_map { |name| field_problems(directory / name, "#{metadata}/#{locale}/#{name}") } + REQUIRED.flat_map do |name| + field_problems(directory / name, "#{metadata}/#{locale}/#{name}", metadata) + end end end end @@ -125,12 +140,13 @@ def shared_problems(root) end end - def field_problems(path, where) + def field_problems(path, where, metadata) return [[where, "missing"]] unless path.exist? text = path.read(encoding: "UTF-8").strip found = [] - found << [where, "empty"] if text.empty? + may_be_empty = MAY_BE_EMPTY.fetch(metadata, []).include?(path.basename.to_s) + found << [where, "empty"] if text.empty? && !may_be_empty limit = LIMITS[path.basename.to_s] found << [where, "#{text.length} characters, limit is #{limit}"] if limit && text.length > limit if URLS.include?(path.basename.to_s) && !text.start_with?("http")