Skip to content

[deliver] Initial App Preview (video) upload support for iPhone and iPad#29831

Merged
iBotPeaches merged 7 commits into
fastlane:masterfrom
ccaruceru:feature/upload-appstoreconect-app-preview-videos
Mar 19, 2026
Merged

[deliver] Initial App Preview (video) upload support for iPhone and iPad#29831
iBotPeaches merged 7 commits into
fastlane:masterfrom
ccaruceru:feature/upload-appstoreconect-app-preview-videos

Conversation

@ccaruceru

@ccaruceru ccaruceru commented Dec 26, 2025

Copy link
Copy Markdown
Contributor

Checklist

  • I've run bundle exec rspec from the root directory to see all new and existing tests pass
  • I've followed the fastlane code style and run bundle exec rubocop -a to ensure the code style is valid
  • I see several green ci/circleci builds in the "All checks have passed" section of my PR (connect CircleCI to GitHub if not)
  • I've read the Contribution Guidelines
  • I've updated the documentation if necessary.
  • I've added or updated relevant unit tests.

Motivation and Context

This adds initial support for uploading localized App Preview videos with deliver for iPad and iPhone, which includes validation, ordering, and overwrite handling.

Related to #19948, #15515, #15879, #14535, #9775

Description

In this PR:

  • new options for deliver
    • app_previews_path to point to localized App Preview videos.
    • preview_frame_time_code to set the still frame (default: 00:00:05:00 like on ASC).
    • overwrite_preview_videos to clear existing previews before upload.
  • new uploader: Deliver::SyncAppPreviews
    • discovers videos under app-previews/<locale>/.
    • supports .mp4, .mov, .m4v.
    • infers device preview type from filename (e.g., IPHONE_67_*.mp4).
    • validates the following constraints from ASC:
      • size <= 500MB.
      • duration between 15s and 30s (if can be detected).
      • resolution matches accepted ASC sizes (if it can be detected). Currently for iPhone and iPad.
    • skips upload by calculating the checksum if the same file was already uploaded.
    • uploads up to 3 videos per locale and per device type (max allowed by ASC) using FastlaneCore::QueueWorker.
    • waits for the upload to be completed and orders videos within each set by filename.
    • supports to overwrite existing (deletes existing videos first).
  • fastlane_core
    • new FastlaneCore::VideoUtils: pure Ruby parsing of MP4/MOV container headers to read resolution and duration.
  • spaceship
    • AppPreviewSet:
      • add missing PreviewType::IPHONE_61.
      • add validate_video_resolution(width, height) for accepted portrait resolutions. Currently for iPhone and iPad.
      • add preview_type_from_filename(name) to infer preview type from a filename token. Currently for iPhone and iPad.
  • updat deliver docs to include App Preview uploads, usage, and folder structure.
  • add new tests and adapt existing

Future work

  • insert the videos to the HTML Preview
  • add support for downloading existing app preview videos (currently broken. api returns an m3u playlist instead of the original video)
  • add fastlane deliver download app-previews command and support for fastlane deliver init
  • add support for the rest of the platforms (macOS, tvOS and visionOS)
  • poll the upload status (see api doc)

Testing Steps

  • mkdir -p fastlane/app-previews/en-US
  • place a couple of videos in en-US folder that have the device type in their filename (see AppPreviewSet)
    • if needed, use the command below to generate video files
generate video
ffmpeg -y -loglevel error \
  -f lavfi -i "nullsrc=s=1200x1600:d=15,geq=r='X/W*255':g='Y/H*255*sin(T)':b='255-X/W*255'" \
  -f lavfi -i "anoisesrc=color=white:amplitude=0.03:sample_rate=48000:d=15" \
  -ar 48000 -ac 2 -profile:a aac_low -b:a 128k \
  -c:v libx264 -pix_fmt yuv420p \
  -c:a aac \
  -shortest \
  IPAD_105.mp4
  • run fastlane to upload the videos:
    • [bundle exec] fastlane deliver [...] - should upload videos and skip existing on second run
    • [bundle exec] fastlane deliver [...] --overwrite_preview_videos true - should always upload from scratch
    • [bundle exec] fastlane deliver [...] --preview_frame_time_code 00:00:10:00 - should additionally set the preview frame to 10s

ccaruceru and others added 3 commits December 24, 2025 23:47
- add missing IPHONE_61 preview type
- add video parsing util
- rspec tests, deliver options
- update docs and screenshots
- add missing IPHONE_61 preview type
- add video parsing util
- rspec tests, deliver options
- update docs and screenshots

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find an existing good gem that parses video data and didn't want to add ffmpeg as a (transitive) dependency to fastlane, therefore we have this video parser code. I'm open for suggestions if you can find something better than this 🙂
(the code is working, it's just that people might find is scary and hard to maintain)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this loosely follows the structure of sync_screenshots.rb

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if needed, we can further reduce the size of these mock videos with gzip. But then we won't be able to directly play/preview them anymore (in Finder or any other player).

@iBotPeaches

Copy link
Copy Markdown
Member

Nice! I don't think I have the day to day usage to test this, but I'll add Copilot to help with code review and see if I can recruit someone that works more with deliver to review this.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds initial support for uploading localized App Preview videos for iPhone and iPad devices to App Store Connect via the deliver tool. The implementation includes video file validation, concurrent upload handling, ordering, and overwrite capabilities.

Key Changes

  • New Deliver::SyncAppPreviews uploader with validation for size (≤500MB), duration (15-30s), and resolution
  • New FastlaneCore::VideoUtils pure Ruby MP4/MOV parser for reading video metadata without external dependencies
  • Extended AppPreviewSet model with resolution validation and filename-based device type inference
  • Three new CLI options: app_previews_path, preview_frame_time_code, and overwrite_preview_videos

Reviewed changes

Copilot reviewed 11 out of 20 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
spaceship/lib/spaceship/connect_api/models/app_preview_set.rb Added IPHONE_61 constant, validation methods for video resolution, and filename-based preview type inference
fastlane_core/lib/fastlane_core/video_utils.rb New pure Ruby MP4/MOV container parser for reading video resolution and duration
deliver/lib/deliver/sync_app_previews.rb New uploader class handling video discovery, validation, concurrent upload, and ordering
deliver/lib/deliver/runner.rb Integration of app preview uploads into the delivery workflow
deliver/lib/deliver/options.rb Added three new configuration options for app preview uploads
deliver/lib/deliver/detect_values.rb Extended folder detection to include app-previews directory
fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb Updated documentation to describe app preview upload feature
deliver/spec/* Comprehensive test coverage for new functionality including edge cases

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread deliver/lib/deliver/sync_app_previews.rb
Comment thread deliver/lib/deliver/sync_app_previews.rb Outdated
Comment thread spaceship/lib/spaceship/connect_api/models/app_preview_set.rb
Comment thread spaceship/lib/spaceship/connect_api/models/app_preview_set.rb Outdated
Comment thread fastlane_core/lib/fastlane_core/video_utils.rb Outdated
Comment thread deliver/spec/sync_app_previews_spec.rb Outdated
Comment thread deliver/spec/sync_app_previews_spec.rb Outdated
@ccaruceru

Copy link
Copy Markdown
Contributor Author

Nice! I don't think I have the day to day usage to test this, but I'll add Copilot to help with code review and see if I can recruit someone that works more with deliver to review this.

Thanks for checking this out! The PR is ready for review if you can find someone willing to have a look 🙂

@ccaruceru

Copy link
Copy Markdown
Contributor Author

Hey @iBotPeaches, any news on adding this on someones review radar?

@iBotPeaches

Copy link
Copy Markdown
Member

Apologies - I've had no bites. I was trying to get eyes for both this and the other larger app clips PR - #29738

@victorgson

Copy link
Copy Markdown

I would love for this to be merged 👀

@ccaruceru

Copy link
Copy Markdown
Contributor Author

hey @iBotPeaches, any chance that you or one of our fastlane friends can have a look at this? (I checked #29738 and that's tackling a different problem)

@iBotPeaches

Copy link
Copy Markdown
Member

So here is my plan. I want to review this again a bit more slowly and figure out how isolated this change is. If we are pretty confident that these changes are isolated to the people opting into this new feature - that would be swell. At that point, much like some other tools, we evolve it in releases as folks opt in. So we could merge as-is.

My fear is some cross contamination breaks something else so need to confirm that.

@iBotPeaches iBotPeaches left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this + Copilot. Its opt-in, and no code paths seem to cross for those not opting into it. Managing our own tiny video code is probably a pita, but better than requiring ffmpeg.

Going forward with merge.

@iBotPeaches iBotPeaches merged commit b9911aa into fastlane:master Mar 19, 2026
9 checks passed

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @ccaruceru 👋

Thank you for your contribution to fastlane and congrats on getting this pull request merged 🎉
The code change now lives in the master branch, however it wasn't released to RubyGems yet.
We usually ship about once a month, and your PR will be included in the next one.

Please let us know if this change requires an immediate release by adding a comment here 👍
We'll notify you once we shipped a new release with your changes 🚀"

@ccaruceru

Copy link
Copy Markdown
Contributor Author

Thanks a lot for the speedy review! I'll start using the master (or next release) version and keep an eye on this feature, but after I come back from holiday (2-3 weeks).

@ccaruceru ccaruceru deleted the feature/upload-appstoreconect-app-preview-videos branch March 20, 2026 19:58

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congratulations! 🎉 This was released as part of fastlane 2.233.0 🚀

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants