build: only upload changed graphics, fix changelog slicing

This commit is contained in:
2026-04-12 00:01:06 +03:00
parent a656f73bf0
commit e69625e8af
3 changed files with 85 additions and 2 deletions

1
.gitignore vendored
View File

@@ -55,6 +55,7 @@ android/app/*.keystore
# Fastlane
android/fastlane/play-store-key.json
android/fastlane/.image_hashes.json
ios/fastlane/report.xml
android/fastlane/report.xml
/.envrc

View File

@@ -1,3 +1,6 @@
require "digest"
require "json"
default_platform(:android)
platform :android do
@@ -13,17 +16,24 @@ platform :android do
"#{v[:build]} (#{v[:name]})"
end
# Google Play enforces a 500-char limit on release notes per language.
PLAY_NOTES_MAX = 500
PLAY_NOTES_TRAILER = "\n\n… see full notes on GitHub."
def changelog_notes
version = version_info[:name]
changelog_path = File.expand_path("../../CHANGELOG.md", __dir__)
return "Release #{version}" unless File.exist?(changelog_path)
changelog = File.read(changelog_path)
pattern = /^## \[#{Regexp.escape(version)}\].*?\n(.*?)(?=^## \[|\z)/m
# Match the release heading (both `## [x.y.z]...` and `## x.y.z ...` forms),
# capture until the next `## ` heading (any form) or EOF.
escaped = Regexp.escape(version)
pattern = /^## (?:\[#{escaped}\]|#{escaped}[\s(]).*?\n(.*?)(?=^## |\z)/m
match = changelog.match(pattern)
return "Release #{version}" unless match
match[1].strip
notes = match[1].strip
.gsub(/\s*\(\[[\da-f]+\]\([^)]+\)\)/, "")
.gsub(/^\*\s+\*\*[^*]+:\*\*\s*/m, "- ")
.gsub(/^\*\s+/, "- ")
@@ -31,6 +41,56 @@ platform :android do
.gsub(/\n{3,}/, "\n\n")
.strip
.then { |n| n.empty? ? "Release #{version}" : n }
truncate_for_play(notes)
end
# Truncate release notes to fit within the Play Store limit. If the
# notes exceed the limit, trim to a line boundary and append a trailer
# so the total stays under [PLAY_NOTES_MAX].
def truncate_for_play(notes)
return notes if notes.length <= PLAY_NOTES_MAX
budget = PLAY_NOTES_MAX - PLAY_NOTES_TRAILER.length
truncated = notes[0, budget]
# Cut at the last newline so we don't chop a bullet mid-word.
last_newline = truncated.rindex("\n")
truncated = truncated[0, last_newline] if last_newline && last_newline > budget / 2
truncated.rstrip + PLAY_NOTES_TRAILER
end
# -- Image change detection --
# We hash every file under metadata/android/*/images/ and compare to a
# cache file. If nothing changed, we skip image uploads entirely.
IMAGE_HASH_CACHE = File.expand_path(".image_hashes.json", __dir__)
def current_image_hashes
root = File.expand_path("metadata/android", __dir__)
return {} unless Dir.exist?(root)
files = Dir.glob(File.join(root, "**/images/**/*")).select { |f| File.file?(f) }
files.sort.each_with_object({}) do |path, acc|
rel = path.sub("#{root}/", "")
acc[rel] = Digest::SHA256.file(path).hexdigest
end
end
def cached_image_hashes
return {} unless File.exist?(IMAGE_HASH_CACHE)
JSON.parse(File.read(IMAGE_HASH_CACHE))
rescue StandardError
{}
end
def images_changed?
current_image_hashes != cached_image_hashes
end
def save_image_hashes
File.write(IMAGE_HASH_CACHE, JSON.pretty_generate(current_image_hashes))
end
desc "Upload AAB to Google Play"
@@ -42,22 +102,36 @@ platform :android do
FileUtils.mkdir_p(changelog_dir)
File.write(File.join(changelog_dir, "#{version_code}.txt"), changelog_notes)
changed = images_changed?
UI.message(changed ? "Images changed — uploading." : "Images unchanged — skipping.")
upload_to_play_store(
aab: File.expand_path("../../build/app/outputs/bundle/release/app-release.aab", __dir__),
track: options[:track] || "internal",
release_status: options[:status] || "draft",
version_name: version_name,
metadata_path: File.expand_path("metadata/android", __dir__),
skip_upload_images: !changed,
skip_upload_screenshots: !changed,
)
save_image_hashes if changed
end
desc "Sync metadata and screenshots only (no AAB upload)"
lane :metadata do
changed = images_changed?
UI.message(changed ? "Images changed — uploading." : "Images unchanged — skipping.")
upload_to_play_store(
skip_upload_aab: true,
skip_upload_apk: true,
metadata_path: File.expand_path("metadata/android", __dir__),
skip_upload_images: !changed,
skip_upload_screenshots: !changed,
)
save_image_hashes if changed
end
desc "Promote a release from one track to another"

View File

@@ -0,0 +1,8 @@
Features
- add sorting by category for checklist
- notifications support
Bug Fixes
- add bottom padding to accomodate fab