The .zip of a Flutter project
What your Flutter archive must contain, what Releasely downloads for you during the build, and what you can leave out.
In short: zip your project folder as Flutter created it, keeping your configuration files and any private dependencies — and leaving out build folders and caches.
The quick check
Open your .zip: if you see pubspec.yaml right at the root, the archive is well formed. If
it's buried inside one or more folders, re-zip the contents of the project folder rather than
the folder itself.
What the archive must contain
pubspec.yaml— the project's manifest, at the root of the archive.pubspec.lock— recommended: it pins the exact versions of your dependencies, so the cloud build matches what you test locally.lib/— your Dart code.android/andios/— the platform folders Flutter generated (icons, native configuration, permissions…). The build needs them, even if you never touched them.- Your assets — images, fonts, and other files declared in
pubspec.yaml. - Any configuration files your app uses, if applicable:
google-services.json(Firebase Android),GoogleService-Info.plist(Firebase iOS),.envfiles read at build time, etc.
A well-formed archive looks like this:
my-app.zip
├── pubspec.yaml
├── pubspec.lock
├── lib/
├── android/
├── ios/
├── assets/
└── packages/ ← your local packages, if any (see below)Local and private dependencies: include them
We build only what's in the archive. The build machine has no access to your computer or your private git repositories. So:
path:dependencies (local packages) must be included in the.zip, with relative paths that stay valid inside the archive. If yourpubspec.yamlpoints to../my-package, that path escapes the archive: move the package into the project (e.g.packages/my-package) and update the path.- Dependencies coming from a private git or a private registry must be copied into the
project and referenced with
path:, because the build cannot reach them.
What Releasely downloads for you
No need to put these in the archive — they are fetched automatically during the build:
- pub.dev packages (
flutter pub getruns for you); - iOS CocoaPods (
pod installruns on the build Mac); - the Flutter SDK itself.
What you can leave out
These folders are regenerated at build time — including them only makes the upload heavier:
build/and.dart_tool/— build artifacts and caches;.git/— your repository history;ios/Pods/andandroid/.gradle/— native dependency caches;.idea/,*.iml,.vscode/— your editor's configuration.
On macOS or Linux, this command creates a clean archive from the project root:
zip -r my-app.zip . -x "build/*" ".dart_tool/*" ".git/*" "ios/Pods/*" "android/.gradle/*" ".idea/*" ".vscode/*"Signing: never in the .zip
Secrets go in Credentials
Do not put keystores, certificates, or API keys in the archive. Android signing (a keystore, if your app needs one) and the App Store connection are configured on your project's Credentials screen — Releasely signs the builds for you.
Size and build number
- 2 GB maximum per archive — plenty for a project without build folders.
- The build number auto-increments from the last known build; a field on the Upload screen lets you override it if you need to catch up with a number already used on the stores.
What's next?
Once the archive is uploaded, Releasely starts the cloud build (iOS and/or Android depending on your project) and the resulting binary automatically joins your next version.