How to Generate AppStoreInfo.plist on Windows / Linux / Mac: Get the Resource Description File for App Store Submission Without Installing Xcode
One command generates AppStoreInfo.plist from an IPA on any system:
appuploader-cli info -u dev@example.com Payload.ipa -o AppStoreInfo.plist
appuploader-cli is the command-line tool bundled with AppUploader. The info command only reads your package locally and generates the resource description file used in Apple's App Store submission flow. It does not upload anything over the network, and it does not require Xcode.
First, What This File Is Actually For
AppStoreInfo.plist is not a configuration in your project — it is a manifest that describes the package when you deliver a build. Apple states its purpose right at the beginning of the file:
This App Store Information can be used with iTMSTransporter and App Store Connect Developer API.
In other words, when you hand a package to Apple through iTMSTransporter or a similar route instead of clicking "Distribute App" in Xcode, you usually need to attach this description along with the package.
The problem is that this file is normally generated by a tool in the Xcode toolchain — one that only runs on macOS. This is where many people get stuck: the package is already built and signed on Windows, yet this one manifest is missing, and buying a Mac or renting a cloud Mac just for it isn't worth it.
appuploader-cli info solves exactly this step: it generates the file on Windows, Linux, and macOS alike, and the output format is identical.
Install the Tool and Locate the Command
Install AppUploader first; the command-line tool is installed along with it, with no separate download needed:
| System | Location |
|---|---|
| Windows |
appuploader-cli.exe in the same directory as the main program AppUploader.exe
|
| macOS | AppUploader.app/Contents/Resources/appuploader-cli |
| Linux |
appuploader-cli in the same directory as the main program AppUploader
|
Open a terminal in that directory and you can use it directly. If you want to run it from any directory, add it to PATH:
- Windows: Settings → System → About → Advanced system settings → Environment Variables → select Path → Edit → New, paste this directory, then reopen a terminal for it to take effect.
-
macOS / Linux: add
export PATH="$PATH:/your/install/directory"to~/.zshrcor~/.bashrc.
Verify it:
appuploader-cli info --help
Generating AppStoreInfo.plist
The most common invocation:
appuploader-cli info -u dev@example.com Payload.ipa -o AppStoreInfo.plist
-
-utakes your Apple ID email; - The package path can go directly at the end of the command (you can also write it as
-f Payload.ipa); -
-ospecifies the output file. Without-o, the result is printed straight to the terminal, which is convenient for piping.
When it finishes, it prints one line of output containing the generated file name, size, and the package's Bundle ID:
asset description written to AppStoreInfo.plist (93613 bytes, xml plist, bundle id com.example.app)
A quick look at that Bundle ID immediately confirms whether you're shipping the package you intended — in CI, mixing up build artifacts is more common than you'd think.
The supported inputs go beyond IPA: .pkg (macOS apps) and .zip can also be analyzed.
If You Need the Binary Format
The default output is an XML plist — readable and easy to diff. Some downstream tools require a binary plist:
appuploader-cli info -u dev@example.com Payload.ipa --format binary -o AppStoreInfo.plist
--format accepts only xml (the default) and binary.
Using It in CI
Two typical use cases.
First, a self-check before uploading. The generation step actually unpacks the package and reads through it layer by layer, so structural problems in the package itself surface here — much faster than being rejected by Apple halfway through an upload:
appuploader-cli info -u "$APPLE_ID" -f build/App.ipa -o build/AppStoreInfo.plist || exit 1
Second, pairing it with another upload tool. If your pipeline already uses iTMSTransporter or a custom delivery script and only this description file is missing, info fills exactly that gap — just pass the generated plist to the downstream tool.
There is also a --deterministic switch, which pins down fields that differ on every run, such as UUIDs, process IDs, and timestamps:
appuploader-cli info -u "$APPLE_ID" --deterministic -f build/App.ipa -o out.plist
Its purpose is quite specific: if you want to verify "whether two builds produce exactly the same package," turning this on lets the two plists be compared byte by byte; otherwise the timestamps alone will never match. You don't need it for everyday submissions.
One last note: this plist describes one specific package, so a different build requires regenerating it. Don't cache it in your pipeline — just generate a fresh one right after building. If your goal is simply to upload the package, the same tool's upload command does it in one go, with no need to generate this file first.
I once almost rented a cloud Mac for this one file that's only a few dozen KB, and later found this command was all I needed. It's the command-line tool bundled with AppUploader, and the same toolkit can also sign certificates, create Bundle IDs, generate provisioning profiles, and upload IPAs on Windows.
Top comments (0)