App Store Submissions

Desktop apps can be distributed as downloads from your website or GitHub releases. Mobile apps are usually distributed through Apple’s App Store or Google Play. The shared daybrite/actions GitHub workflows can build, test, sign and upload your app when you tag a release. Store account setup and review still take place in each store’s console.

This page covers iOS and Android submissions through your own accounts. For desktop downloads, see Packaging & distribution. For the build workflow, see GitHub Actions.

Prepare the listing

Edit store/storefront.toml. If the project has no listing, create it with day store init. Provide the app name, descriptions, release notes, privacy and support URLs, review contact, and translations for the locales you publish. Store-specific fields belong under that store’s table; for example:

[storefront.ios-uikit.apple-app-store.submission-info]
apple-category = "PRODUCTIVITY"

[storefront.ios-uikit.apple-app-store.screenshots]
iphone = ["home", "editor", "search"]
ipad = ["home", "editor", "search"]

[storefront.android-mdc.google-play-store.screenshots]
default = ["home", "editor", "search"]

Screenshot names refer to captures in your dayscript tests. Run the tests on the required phone and tablet profiles, then check the listing and captures:

day lint
day store screenshots build/day/screenshots/gallery.json

The second command needs the gallery.json produced by day screenshot index or downloaded from CI. It checks screenshot sizes and locale/device coverage. These checks catch submission errors; they do not guarantee store approval. See the store listing reference for the schema and screenshot selection rules.

Create the store records

Keep each app identifier consistent between Day.toml, the signing configuration and its store record. Do not change an identifier when releasing an update.

StoreOne-time setup
App Store ConnectCreate the app record for the iOS bundle ID. Configure privacy, age rating, export compliance and availability. Create an App Store Connect API key with access to the app, an Apple distribution certificate, and an App Store provisioning profile.
Google PlayCreate the app in Play Console and complete its content rating, data safety and audience settings. Enable the publishing API and grant a service account access. Configure Play App Signing and retain the upload keystore.

Upload the first Android bundle through Play Console before using the API. This is a fastlane supply prerequisite. Complete any testing or account-verification requirements shown in the console before requesting production access.

Configure CI credentials

Add the following repository secrets under Settings → Secrets and variables → Actions. Configure only the stores you use.

PurposeSecrets
Apple teamDAY_APPLE_TEAM — team ID
App Store Connect APIDAY_ASC_KEY_ID, DAY_ASC_ISSUER, DAY_ASC_KEY_B64 — key ID, issuer ID and base64-encoded .p8 key
iOS signingDAY_APPLE_CERT_P12, DAY_APPLE_CERT_PASSWORD, DAY_IOS_PROFILE_B64 — base64-encoded distribution certificate, its password and base64-encoded provisioning profile
Android signingDAY_ANDROID_KEYSTORE_B64, DAY_ANDROID_KEY_ALIAS, DAY_KS_PASS, DAY_KEY_PASS — base64-encoded upload keystore, alias, keystore password and key password
Google Play APIDAY_PLAY_JSON_KEY — service-account JSON contents
HarmonyOS signingDAY_OHOS_KEYSTORE_B64, DAY_OHOS_CERT_B64, DAY_OHOS_PROFILE_B64, DAY_OHOS_KEY_ALIAS, DAY_OHOS_KS_PASS, DAY_OHOS_KEY_PASS — base64-encoded keystore, certificate and profile, the key alias and the two passwords

The workflow signs after it builds. The job that compiles the app and runs its walkthroughs packs every store package unsigned and never sees a key; a separate sign job, which checks out no code, signs each package with day sign apply and replaces the artifact. The signing secrets therefore need no [signing] table in Day.toml, though one still serves local release packs. An API key authorizes uploads; it does not replace the signing certificate or upload key. Unsigned iOS packages and Android packages signed with the development key cannot be uploaded to these stores.

Enable store uploads

Add these inputs to the app job in the CI workflow:

with:
  targets: ios-uikit, android-mdc
  scripts: auto
  locales: all
  themes: light dark
  upload-ios: "true"
  upload-play: "true"
  store-screenshots: true

Keep the job’s uses and secrets: inherit entries. Include any desktop or web targets your existing workflow builds. Remove an upload input, or set it to "false", for a store you do not use. When omitted, the upload inputs auto-enable only if the listing or matching Fastfile and the store’s API credentials are present.

On a version tag, CI signs the packages and runs the generated fastlane lanes. The default lanes upload without publishing to production:

LaneResult
ios uploadUploads the build and listing to App Store Connect without submitting for review.
ios submitSubmits a previously uploaded build for review; does not upload the binary again.
ios releaseUploads and submits for review. An approved version releases automatically unless the listing sets apple-release = "manual".
android uploadUploads to the internal track as a draft.
android releaseUploads a completed production release, subject to Google Play review and publishing settings.

To submit for review on each release tag, add:

  ios-upload-lane: ios release
  play-upload-lane: android release

With store-screenshots: true, uploads replace the store screenshots with the captures selected by the listing. Its default is false, which retains the existing screenshots.

Release and update

Update version in Cargo.toml, increment [app] build in Day.toml, and revise the release notes. Account for platform or flavor overrides. Commit those changes, then push a version tag. Inspect the workflow’s upload jobs and the status in each store console.

A GitHub release and a store release are separate. GitHub’s draft or pre-release setting does not disable store uploads. Set the workflow’s upload-* inputs explicitly when staging a build that should not reach the stores.

After publication, add the listing IDs to Day.toml so the generated website links to them:

[store]
apple-app-id = "6802801331"
google-play-id = "com.example.app"

Local uploads and custom lanes

day pack builds the packages; day store stage writes fastlane projects under build/day/store/<target>/. For local validation and upload commands, see Uploading.

A project with its own fastlane/Fastfile uses those lanes instead of generated ones. It must handle metadata, screenshots and submission policy itself. The generated iOS submission lanes assume no advertising identifier and exempt encryption; use custom lanes if those declarations do not describe your app.

Mac App Store uploads also require a custom lane. The workflow supplies macOS build products; the lane must produce the package signed for Mac App Store distribution. See store-upload inputs and limitations.