Add screenshot generator

This commit is contained in:
世界
2026-01-08 16:13:20 +08:00
parent 264c4eed81
commit 6b589cb771
57 changed files with 1931 additions and 109 deletions
+261
View File
@@ -0,0 +1,261 @@
default_platform(:ios)
ENV["FASTLANE_XCODEBUILD_SETTINGS_RETRIES"] = "0"
ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "30"
SCREENSHOT_LANGUAGES = ["en-US", "zh-Hans"].freeze
SCREENSHOT_LOCALES = {
"zh-Hans" => "zh_CN"
}.freeze
def reset_dir(path)
FileUtils.rm_rf(path)
FileUtils.mkdir_p(path)
end
def screenshot_locale(language)
SCREENSHOT_LOCALES[language]
end
def write_screenshot_language_files(dir, language, locale)
FileUtils.mkdir_p(dir)
File.write(File.join(dir, "language.txt"), language)
if locale
File.write(File.join(dir, "locale.txt"), locale)
else
FileUtils.rm_f(File.join(dir, "locale.txt"))
end
end
def shutdown_simulator(name)
sh("xcrun simctl shutdown \"#{name}\" || true")
end
platform :ios do
desc "Generate iOS screenshots"
lane :screenshots do
ENV["SNAPSHOT_SIMULATOR_WAIT_FOR_BOOT_TIMEOUT"] = "10"
screenshots_cache = File.expand_path("~/Library/Caches/tools.fastlane/screenshots")
reset_dir(screenshots_cache)
capture_screenshots
shutdown_simulator("iPhone 11 Pro Max")
shutdown_simulator("iPad Pro 13-inch (M4)")
end
end
platform :mac do
desc "Generate macOS screenshots"
lane :screenshots do
output_base_dir = File.expand_path("../screenshots/macos", __dir__)
screenshots_cache_candidates = [
File.expand_path("~/Library/Caches/tools.fastlane/screenshots"),
File.expand_path("~/Library/Containers/io.nekohasekai.sfavt.SFMUITests.xctrunner/Data/Library/Caches/tools.fastlane/screenshots")
].uniq
ENV["DISABLE_SWIFTLINT"] = "1"
ENV["SCREENSHOT_WINDOW_PIXEL_HEIGHT"] = "1000"
reset_dir(output_base_dir)
SCREENSHOT_LANGUAGES.each do |language|
output_dir = File.join(output_base_dir, language)
ENV["SCREENSHOT_LANGUAGE"] = language
locale = screenshot_locale(language)
if locale
ENV["SCREENSHOT_LOCALE"] = locale
else
ENV.delete("SCREENSHOT_LOCALE")
end
reset_dir(output_dir)
screenshots_cache_candidates.each do |dir|
reset_dir(dir)
write_screenshot_language_files(dir, language, locale)
end
run_tests(
project: "sing-box.xcodeproj",
scheme: "SFM",
destination: "platform=macOS",
result_bundle: false,
reinstall_app: false,
app_identifier: "io.nekohasekai.sfavt",
only_testing: ["SFMUITests/SnapshotTests"],
number_of_retries: 0
)
copied = {}
screenshots_cache_candidates.each do |dir|
Dir.glob("#{dir}/Mac-*.png").each do |file|
basename = File.basename(file)
next if copied[basename]
FileUtils.cp(file, output_dir)
copied[basename] = true
end
end
padded_files = Dir.glob("#{output_dir}/*.png")
magick_bin = `which magick 2>/dev/null`.strip
magick_bin = `which convert 2>/dev/null`.strip if magick_bin.empty?
if magick_bin.empty?
UI.user_error!("ImageMagick not found. Install it (magick/convert) to add shadow.")
end
canvas_width = 2880
canvas_height = 1800
target_width = 2620
target_height = 1620
shadow_opacity = 26
padded_files.each do |file|
size_output = sh(
magick_bin,
file,
"-format",
"%w %h",
"info:",
log: false
).strip
opaque_output = sh(
magick_bin,
file,
"-format",
"%[opaque]",
"info:",
log: false
).strip
width, height = size_output.split.map(&:to_i)
has_transparency = opaque_output != "True"
tmp_file = "#{file}.tmp.png"
if has_transparency
shadow_sigma = 24
shadow_offset = 8
shadow = "#{shadow_opacity}x#{shadow_sigma}+0+#{shadow_offset}"
sh(
magick_bin,
file,
"-alpha", "set",
"-background", "none",
"-trim",
"+repage",
"-resize",
"#{target_width}x#{target_height}",
"(",
"+clone",
"-background",
"black",
"-shadow",
shadow,
")",
"+swap",
"-background",
"white",
"-layers",
"merge",
"+repage",
"-gravity",
"center",
"-extent",
"#{canvas_width}x#{canvas_height}",
tmp_file
)
else
scale = [
target_width.to_f / width,
target_height.to_f / height
].min
scaled_width = (width * scale).round
scaled_height = (height * scale).round
mask_width = [scaled_width - 1, 1].max
mask_height = [scaled_height - 1, 1].max
corner_radius = [(28 * scale).round, 28].max
shadow_sigma = [(16 * scale).round, 1].max
shadow_offset = [(5 * scale).round, 1].max
shadow = "#{shadow_opacity}x#{shadow_sigma}+0+#{shadow_offset}"
sh(
magick_bin,
file,
"-resize",
"#{scaled_width}x#{scaled_height}",
"-alpha",
"set",
"(",
"-size",
"#{scaled_width}x#{scaled_height}",
"xc:none",
"-fill",
"white",
"-draw",
"roundrectangle 0,0 #{mask_width},#{mask_height},#{corner_radius},#{corner_radius}",
")",
"-compose",
"DstIn",
"-composite",
"-compose",
"over",
"(",
"+clone",
"-background",
"black",
"-shadow",
shadow,
")",
"+swap",
"-background",
"white",
"-layers",
"merge",
"+repage",
"-gravity",
"center",
"-extent",
"#{canvas_width}x#{canvas_height}",
tmp_file
)
end
FileUtils.mv(tmp_file, file, force: true)
end
end
end
end
platform :tvos do
desc "Generate tvOS screenshots"
lane :screenshots do
output_base_dir = File.expand_path("../screenshots/tvos", __dir__)
screenshots_cache = File.expand_path("~/Library/Caches/tools.fastlane/screenshots")
reset_dir(output_base_dir)
SCREENSHOT_LANGUAGES.each do |language|
output_dir = File.join(output_base_dir, language)
ENV["SCREENSHOT_LANGUAGE"] = language
locale = screenshot_locale(language)
if locale
ENV["SCREENSHOT_LOCALE"] = locale
else
ENV.delete("SCREENSHOT_LOCALE")
end
reset_dir(output_dir)
reset_dir(screenshots_cache)
write_screenshot_language_files(screenshots_cache, language, locale)
run_tests(
project: "sing-box.xcodeproj",
scheme: "SFT",
devices: ["Apple TV 4K (3rd generation)"],
result_bundle: false,
reinstall_app: true,
app_identifier: "io.nekohasekai.sfavt",
only_testing: ["SFTUITests/SnapshotTests"],
number_of_retries: 0,
cloned_source_packages_path: "/tmp/fastlane_source_packages",
derived_data_path: "/tmp/fastlane_derived_data"
)
Dir.glob("#{screenshots_cache}/*.png").each do |file|
FileUtils.cp(file, output_dir)
end
end
shutdown_simulator("Apple TV 4K (3rd generation)")
end
end
+58
View File
@@ -0,0 +1,58 @@
fastlane documentation
----
# Installation
Make sure you have the latest version of the Xcode command line tools installed:
```sh
xcode-select --install
```
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
# Available Actions
## iOS
### ios screenshots
```sh
[bundle exec] fastlane ios screenshots
```
Generate iOS screenshots
----
## Mac
### mac screenshots
```sh
[bundle exec] fastlane mac screenshots
```
Generate macOS screenshots
----
## tvos
### tvos screenshots
```sh
[bundle exec] fastlane tvos screenshots
```
Generate tvOS screenshots
----
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
+30
View File
@@ -0,0 +1,30 @@
# iOS Screenshots
# App Store requirements:
# - iPhone 6.5" Display
# - iPad 13" Display
devices([
"iPhone 11 Pro Max",
"iPad Pro 13-inch (M4)"
])
languages([
"en-US",
"zh-Hans"
])
project("./sing-box.xcodeproj")
scheme("SFI")
app_identifier("io.nekohasekai.sfavt")
output_directory("./screenshots/ios")
clear_previous_screenshots(true)
reinstall_app(true)
skip_helper_version_check(true)
override_status_bar(true)
dark_mode(true)
number_of_retries(0)
stop_after_first_error(true)
skip_package_dependencies_resolution(true)
disable_package_automatic_updates(true)
cloned_source_packages_path("/tmp/fastlane_source_packages")
derived_data_path("/tmp/fastlane_derived_data")
localize_simulator(true)