Skip to content

Automate the App Store screenshot upload - #136

Merged
evandhoffman merged 3 commits into
mainfrom
ci/appstore-screenshot-upload
Oct 12, 2026
Merged

evandhoffman merged 3 commits into
mainfrom
ci/appstore-screenshot-upload

Conversation

@evandhoffman

Copy link
Copy Markdown
Collaborator

Summary

This PR automates the App Store screenshot upload. It is item 2 of #132, the screenshot part.

  • ci/appstore-screenshots.txt: the approved set, in store order. This file is the one place where the set is chosen.
  • appstore-screenshots.yml: a dispatch-only workflow on the Linux runner. Inputs: version, run_id (optional) and dry_run (default true).
    • It takes the screenshots artifact of the newest successful TestFlight run on v<version>, or of the run you name.
    • It checks the set, and it uploads only when dry_run=false.
  • scripts/upload_appstore_screenshots.py: ported from StationCast, with 60 new tests.
    • It refuses before any write when:
      • a name has no file;
      • an image's size has no App Store slot;
      • an image has an alpha channel;
      • the images span more than one display type;
      • the set has more than 10 images;
      • the version is missing or cannot be edited;
      • the locale has no localization.
    • Otherwise it replaces the 6.9-inch set in manifest order, waits until Apple marks each image delivered, then sets the order.
  • release-testflight.yml: it now uploads the screenshots artifact too, so each release tag's run holds images that show that release's version number.
  • Settings screenshots: they hide the simulator-only "Testing" section, which the shipped app does not have. SettingsView.showsTestingTools is read only in simulator builds.
  • httpx logging: all three App Store Connect scripts keep httpx and httpcore logging at WARNING, so the pre-signed upload URLs stay out of the logs.

Verification

  • actionlint: no findings.
  • ruff, mypy --strict and pytest -rs: 202 passed, 0 skipped.
  • ci/lint_swift.sh: 0 violations.
  • pre-commit run --all-files: all hooks pass.
  • Compile-only build-for-testing: 0 errors and 0 Swift warnings.
  • The real images:
    • The 18 images from run 38284188110 are all 1320 × 2868 with no alpha. The plan builds in the approved order.
    • The 18 older images are 1206 × 2622 with alpha, and they are refused.
  • Not run: the workflow and any App Store Connect call. The first live check is a dry run after the merge.

Release

skip-release. CI and tooling only. The app change exists only in simulator builds.

evan-agent Bot added 3 commits October 12, 2026 13:51
SettingsView takes showsTestingTools (default true), read only in
simulator builds. ScreenshotTests passes false, so 03-settings-* shows
the shipped app. Device builds do not change.
ci/appstore-screenshots.txt holds the approved set in store order.
scripts/upload_appstore_screenshots.py checks every image before any
write, then replaces the version's 6.9-inch iPhone set in that order.
The ASC scripts now share asc_api.configure_logging, which keeps httpx
and httpcore at WARNING: the upload URLs are pre-signed.
appstore-screenshots.yml downloads the screenshots artifact of a CI
run and runs the upload script, as a dry run unless dry_run=false.
release-testflight.yml now uploads the screenshots artifact too, so
the release tag's run holds images with the right version number.
@evandhoffman evandhoffman added the skip-release Docs, CI or tooling only: the merge cuts no release and no TestFlight upload label Oct 12, 2026
@evandhoffman
evandhoffman merged commit 4fc2f9c into main Oct 12, 2026
7 of 8 checks passed
@evandhoffman
evandhoffman deleted the ci/appstore-screenshot-upload branch October 12, 2026 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-release Docs, CI or tooling only: the merge cuts no release and no TestFlight upload

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant