
Automating Screenshot Uploads to App Store Connect with GitHub Actions
Got a project?
Let's discuss your project
Introduction
In iOS development, building an app and manually capturing screenshots for multiple devices can be a tedious and time-consuming task. Automating these processes using GitHub Actions helps streamline the workflow, especially when dealing with multiple screen sizes and languages.
This blog post demonstrates how to automate the entire process-building the app, launching it in an iOS Simulator, capturing screenshots, and uploading them to App Store Connect. Leveraging App Store Connect’s API, this CI/CD pipeline can save time, ensure consistency, and improve efficiency during app release.
Why Automate?
Manually building apps, launching them in simulators, and capturing screenshots can be tedious. This becomes even more challenging when managing multiple devices and scenarios. GitHub Actions provides a platform to automate these tasks by creating a workflow that does everything from setting up dependencies to building, launching, and taking screenshots of your app.
Step-by-Step Guide
Here’s how I built this automation pipeline:
1. Setting Up the Workflow
We start by defining the GitHub Actions workflow file (iOS_Screenshot_Upload.yml). This file outlines the steps the workflow will take whenever changes are pushed to a specific branch (e.g., ScreenshotBuild).

This ensures that the workflow triggers when code is pushed to the ScreenshotBuild branch.
2. Environment Setup
Setting up the environment is the next critical step. We need Python, Ruby (for CocoaPods), and Node.js for React Native dependencies.

We also use CocoaPods for dependency management in iOS and cache them to speed up subsequent builds.

3. Installing and Updating Pods
We integrate CocoaPods with our project by updating and installing the necessary dependencies:

4. Building the App
To simulate the app on a specific device, we build the app for the iOS Simulator (in this case, using the iPhone 14). Before building, we clean the build folder and Derived Data:

This step compiles the app and prepares it for installation on the simulator.
5. Booting the Simulator and Launching the App
After successfully building the app, we find the UUID of the desired simulator, boot it, and install the app.

The app is launched using its Bundle ID.
6. Capturing the Screenshots
Screenshots are captured using UUID of emulator and path defined to save screenshot as desired place.

7. Uploading and Downloading Screenshots
The screenshots are uploaded as artifacts so that they can be easily accessed:

To download them later, we use the download-artifact action:

8. Create Screenshot Set
The first API request is responsible for creating a new screenshot set associated with a specific app version on App Store Connect. A screenshot set groups screenshots that are specific to a particular display type, like for iPhones, iPads, or other devices.
Let's Build Something Great Together
Ready to transform your idea into a powerful software solution? Talk to our experts and get a free consultation.
Contact Us- URL: /v1/appScreenshotSets
- Request Type: POST
- Description: This API creates a screenshot set for a specific app version localization.
- Payload: It includes details such as screenshotDisplayType, which specifies the type of screenshots (e.g., iPhone 6.7″ display), and the ID of the app’s version localization.
- Response: The API returns an ID for the newly created screenshot set, which is later used to upload screenshots to this set.

9. Upload Screenshots to App Store Connect
Once the screenshot set is created, this API request uploads screenshots to the App Store Connect. The process is divided into two steps: creating an entity for each screenshot and uploading the actual image file.
- URL: /v1/appScreenshots
- Request Type: POST
- Description: This API request initiates the upload process by creating an app screenshot entity. It defines the filename, file size, and links it to the appScreenshotSet.
- Response: The response contains details like the upload URL and Content-Type headersneeded for the next step, along with the screenshotId, which uniquely identifies the screenshot.

10. Upload Screenshot File
After creating the screenshot entity, the next API call uploads the actual image file to the provided URL.
- URL: The URL is dynamically provided in the previous response (uploadUrl).
- Request Type: PUT
- Description: This API uploads the screenshot image to the App Store Connect servers. It uses the Content-Type header specified earlier, and the image file itself is uploaded to the provided URL.
- Response: This step confirms the upload of the screenshot file to the server.

11. Commit Screenshot Reservation
Finally, after uploading the screenshot, the reservation for the uploaded screenshot needs to be committed to App Store Connect. This ensures the screenshot is marked as uploaded and ready for review.
- URL: /v1/appScreenshots/{screenshotId}
- Request Type: PATCH
- Description: This API marks the screenshot upload as complete by committing the reservation. The payload includes the MD5 checksum of the uploaded file to verify its integrity.
- Response: The API responds with the status of the screenshot reservation, confirming that the screenshot is now available for the app version on the App Store.


Conclusion
By automating the iOS app testing and screenshot capture process, developers can avoid repetitive manual tasks and focus more on enhancing app features. This GitHub Actions workflow demonstrates how to build, launch, and capture screenshots on an iOS Simulator, followed by uploading those screenshots directly to App Store Connect. With this setup, you can easily extend automation to cover additional devices and screen variations, or even other App Store Connect tasks such as submitting apps for review.
Integrating automation into your development process can enhance productivity, minimize errors, and streamline app store submissions, making your iOS development lifecycle much smoother.

How to Add LiveKit Video Calling to a Next.js App
Add embedded video & audio calling to Next.js with LiveKit Cloud. Compared vs Twilio, Daily, Agora, Zoom — plus token auth, guests & recording.
Read More
We chose ECS over EKS: what we gained and what we gave up
An honest comparison of ECS vs EKS the costs, tradeoffs, and real-world reasoning behind choosing ECS for a production platform on AWS.
Read More
Upgrading Legacy Systems: From Outdated Technology to Competitive Advantage
Learn how to upgrade legacy systems through application modernization, API integration, cloud migration, security improvements, and incremental system upgrades without disrupting business operations.
Read More
Building Distributed Tracing and Observability with AWS X-Ray
A practical guide to correlating requests across a multi-tier application using correlation IDs, AWS X-Ray segments, and structured logging for faster incident debugging.
Read More
Designing Before and After AI: What Really Changed
A look at how AI has transformed UI/UX design from manual wireframes and slow research to AI-assisted prototyping, design-to-code, and personalization at scale.
Read More
Beyond Prompting: Managing Context and Tokens in AI Coding Tools
Ever wondered why your AI coding agent starts losing context or hits a hard limit mid-task? The answer lies in tokens and the context window. Good AI coding is not about giving the model the most information. It is about giving it the right information at the right time.
Read More
What Is llms.txt? How It Helps Google, AI Search, and Agentic Browsing Find Your Website
Learn what llms.txt is, how it differs from sitemap.xml and robots.txt, and how it can help your site get found by Google, AI search tools, and AI agents.
Read More
Build an Automated Image Compression Script with Sharp and SVGO
Compress images from the terminal with a Node.js script powered by Sharp and SVGO a safe, two-step workflow that keeps your site fast without bloating your repo.
Read More
The Right Way to Migrate from MySQL to AWS Aurora DSQL
Migrating a production database is one of the highest-risk changes you can make to an application. Moving from MySQL to AWS Aurora DSQL raises the stakes further...
Read More