The publishing pipeline: from app settings to a store build

The idea in one sentence

When you click Submit on the Publish Your App page, you are not uploading a build. You are asking the Tiny Screen Labs build service (WPMAM) to start one — and the actual build runs later, on someone else’s machines, pulling your settings back from your site when it is ready.

That one shift — from “I am building an app” to “I am queuing a build request” — explains almost everything about how the page behaves: why submit returns instantly, why there is no progress bar, why status appears minutes later, and why a forgotten build-number bump shows up as a store rejection half an hour after you walked away.

This article walks through that pipeline so the page’s behavior makes sense to you. For the click-by-click procedure, see Recipe: Publish your app to iOS and Android.


Why MAM works this way

Building a native iOS or Android app is heavy lifting: it takes Xcode and the Android toolchain, signing certificates, provisioning profiles, and a long chain of Fastlane steps that compile, sign, package, and upload to App Store Connect and Google Play Console. None of that can — or should — run inside your WordPress site.

So MAM Suite splits the work across two systems:

  • Your site owns the settings: the app name, bundle ids, version and build numbers, permission strings, icon and launch screens, and integration keys. These are the inputs to a build.
  • WPMAM owns the build: it runs the Fastlane CI that turns those settings into a signed binary and submits it to the stores.

The publish page sits right on the seam between them. Its whole job is to collect good inputs from your side and hand off a build request to WPMAM — the actual build stays deliberately out of your site’s hands.


The three stages

Stage 1 — Settings become saved options

Everything you type on Mobile App Manager → Publish Your App gets stored as WordPress options — on your own site, nowhere else. Saving the form writes roughly twenty options in total: app identity, versioning, permission strings, branding, and integration keys. That’s the only thing saving does — it doesn’t contact WPMAM, and it doesn’t start anything.

Here’s why that matters: the saved options are the durable source of truth. A build that runs an hour from now reads whatever is saved at the moment it actually runs — not whatever happened to be on screen when you clicked submit. Some of these option keys are frozen: the iOS and Android bundle ids, for instance, predate MAM’s current naming convention, and renaming them now would orphan a customer’s existing store submissions. Treat your saved publishing settings as a stable contract, not a scratch pad.

Stage 2 — Submit sends a request, not a build

Saving and submitting are two separate, deliberate actions on this page. Save writes your options and hands you back “Draft Saved” — no build is requested. Only Submit Publish Request actually sends anything outbound, and what it sends is smaller than you’d think. Here’s what happens on submit:

  1. Confirms your account code is present and that the site is actually connected to an account — a localhost or sentinel site counts as not connected, and can’t publish.
  2. Figures out which platform you’re submitting — iOS or Android.
  3. Sends a lightweight publish request to WPMAM, carrying just enough to identify and reach you: your account code, the platform, the submitting admin’s email, and a callback URL that points back at your site’s admin-ajax endpoint.

That’s the whole outbound message. Notice what it doesn’t carry: no full settings payload, no icon, no build numbers. Think of it as a doorbell, not a delivery. The site then jots down a local note — something like “Publish requested on <date>” — and returns immediately.

This is what “fire-and-forget” means in practice: the submit call succeeds the moment WPMAM acknowledges the request. Success here means “your request was accepted” — not “your app was built.”

Stage 3 — WPMAM pulls your settings and runs Fastlane

Once WPMAM has your request, the build runs on its own CI, on its own schedule. When the Fastlane pipeline reaches the point where it actually needs your configuration, it calls back to your site and pulls the full settings down — the reverse of what most people assume happens.

That pull is where the complete Fastlane payload comes together: app name, bundle ids, team id, version and build numbers, permission usage strings, icon and splash URLs, integration keys (Firebase plist, Google Places, Facebook, Branch), the API endpoint, the account id, and feature flags derived from your role settings (for example, whether any role uses GPS, camera, or push notifications). That pull is protected by a one-time fetch token: the request has to present a valid, unexpired token, which then gets consumed so it can’t be replayed. That’s what keeps a customer’s signing-relevant configuration from being readable by anyone who merely knows the site URL.

Just before that payload ships out, MAM fires a filter — mam_fastlane_settings — the single, intended extension point for the build. Sibling plugins that need to inject build-time configuration (a third-party SDK key, a custom Info.plist entry, a deep-link domain) add their values right here. There’s no other supported way to influence the build payload: you can’t intercept the request, and editing the options after the fact simply won’t land.


What “submit” really means

Put the three stages together, and here’s the full lifecycle of a single submit:

You save settings           → ~20 options written on your site
You click Submit            → small publish request sent to WPMAM
                              (account code, platform, email, callback URL)
WPMAM acknowledges          → page returns instantly ("Publish requested")
        … minutes pass, build runs on WPMAM CI …
WPMAM's Fastlane pulls back → token-gated fetch of full settings from your site
                              mam_fastlane_settings filter runs here
Fastlane builds + signs     → uploads to App Store Connect / Google Play

So “submit” really means: validate that I’m connected, and ask WPMAM to build this platform. That’s it — deliberately cheap, deliberately non-blocking. The heavy, fallible work — compiling, signing, uploading — happens later, and elsewhere.


How you learn what happened: status is polled

Because the build runs asynchronously, there’s no live result to show you the moment you submit. Instead, the publish page finds out what’s happening by polling WPMAM separately.

Your site periodically asks WPMAM for your subscription and publish status, then caches the answer for a short while. From that response, it learns whether your license permits publishing, whether each platform is connected, and a per-platform publish state that WPMAM sets — for iOS, states like “Submitted to Apple for Review” or “Uploaded to TestFlight”; for Android, states like closed testing or publishing. An empty state just means nothing has published yet. That same response also carries server-managed identifiers (bundle ids, team id, version and build numbers) that WPMAM may write back so the two systems stay in sync.

In practice, that’s why refreshing the publish page is how you see progress, and why a freshly submitted build feels stuck “in progress” for a while before a real state shows up. You’re looking at a cached snapshot of WPMAM’s truth, not watching a live build.

Before any of that, the page runs a readiness check of its own: shared content like the app name, description, and a large-enough app icon (at least 1024×1024) all need to be in place, the license needs to permit publishing, and at least one platform needs to be connected. Miss a requirement, and the page tells you exactly what’s blocking you — rather than letting you submit a build that’s only going to fail downstream.


Consequences worth internalizing

A handful of things follow directly from this design — and they’re behind most of the real-world confusion:

  • Submit success ≠ build success. The instant confirmation only means your request was accepted. A build can still fail later for reasons your site never sees in the moment — a signing problem, a rejected permission string, a bad asset.
  • Build numbers must increment, and that’s on you. Apple and Google both reject duplicate build numbers within a release train, and the page won’t bump them for you. Forget, and it typically surfaces as a store-side rejection roughly half an hour after submit — long after the page has already told you “requested.”
  • Account-code verification is a guard, not a fix. The page checks that your account code matches what WPMAM has on file for your URL, and it’ll warn you on a mismatch — but it won’t repair the drift for you. A mismatch calls for a support conversation, not another retry.
  • Saved settings are the real input. Because WPMAM pulls your settings at build time, what actually gets built is whatever’s saved — not whatever happened to be on screen last. Save before you submit.

How this connects to the rest of MAM Suite

This is where the no-code promise of MAM Suite actually cashes out. Everything else in the Codex — configuring app settings, building tabs and menus, wiring up push notifications, adding a contact form — produces configuration that lives as options and role settings on your site. The publish pipeline is what carries all of that accumulated configuration across the seam, into a real, signed, store-submitted app.

If you’re extending the build yourself, mam_fastlane_settings is the one hook that participates in this flow — see Hook: mam_fastlane_settings. For the operational walkthrough, see Recipe: Publish your app to iOS and Android. And for the enrollment and account-code groundwork that has to be in place before any of this works, see Recipe: Customer enrollment and account code.


  • Recipe: Publish your app to iOS and Android
  • Recipe: Customer enrollment and account code
  • Hook: mam_fastlane_settings
  • Integration: WPMAM publishing pipeline (developer-facing reference)
  • Frozen public contracts reference
Was this article helpful?
Contents

    Need Support?

    Can't find the answer you're looking for? Don't worry we're here to help!