DEV Community

Cover image for Introducing App Store Release Agent – Automating my App Store Pipeline
Dragos Roua
Dragos Roua

Posted on • Originally published at dragosroua.com

Introducing App Store Release Agent – Automating my App Store Pipeline

Publishing ten apps in four months sounds good.

And it is good. It means the bottleneck is no longer building the app. With AI-assisted coding, small utilities, focused experiments, and niche apps can go from idea to App Store submission in days, sometimes hours.

But there is a second part that can soon get really ugly. And messy. And time consuming.

After you publish the apps, you own them – not in the inspirational sense, in the annoying sense. Every app becomes a small surface that needs attention: metadata, screenshots, reviews, ratings, keywords, conversion, cross-promotion, build status, rejections, releases, privacy answers, promo text, support links. Ok, you can catch your breath now. We good?

Good, let’s move on.

One app is manageable as a pastime, but ten apps are already a small portfolio. And a small portfolio needs systems.

So I started building one.

The repo is called app-store-release-agent, and, for now, it’s a small Python toolkit for the release workflow itself. Eventually, this could evolve into a full ASO brain.

The Business Problem

The business problem is simple: maintenance does not scale linearly with motivation.

Building an app has a clear dopamine loop. Maintenance is fragmented: a review here, a screenshot there, a keyword set that probably needs work, a support email, a product page that now feels weak.

None of these tasks are hard in and by themselves. That is a real and very subtle trap, because they can easily get postponed, and then they pile up.

The benefit of an automation pipeline is not only speed. Speed is good, don’t get me wrong, but it’s secondary. The real benefit is lowering the activation energy.

If the agent can pull live App Store data, compare it with local metadata, inspect git history, and apply the next release action safely, I do not have to reconstruct the context from scratch every time.

A good pipeline should answer three questions quickly:

  1. What needs attention now?
  2. What can wait?
  3. What action has the highest leverage?

For a portfolio, this consistent and boring workflow is more important than shipping feature after feature into an app no ones uses.

A portfolio of apps has an order of magnitude impact, compared with a single app, but the portfolio compounds only if the apps inside stay alive.

The Release Agent

The repo currently has three scripts:

  • smoke_test.py connects to App Store Connect and lists the apps plus their current live versions.
  • fetch_metadata.py pulls live localized metadata into a local metadata/ folder.
  • patch_metadata.py patches metadata, attaches builds, or submits a version for App Review.

Everything you own stays in the local mirror. App Store Connect remains the canonical source for live state, but the local folder gives you something you can diff, review, and reason about before touching the public listing. That’s where you actually work and that’s what gets patched on top of the current App Store state.

Folder structure is easy:

metadata/
  app-name/
    app-id.txt
    bundle-id.txt
    live-version.txt
    1.0/
      version-id.txt
      en-US/
        title.txt
        subtitle.txt
        keywords.txt
        description.txt
        whats-new.txt
Enter fullscreen mode Exit fullscreen mode

Just plain text files, one per piece of information, nothing too fancy.

That makes it easy to have an agent draft a change, show me the diff, and then apply exactly one thing. I don’t do “improve the app page” as a vague command. More like: patch the keywords field for en-US on this in-flight version, using this file, dry-run first.

By the way, all scripts use dry-run by default. I highly recommend keeping it like this if you fork the repo. Any command that mutates App Store Connect needs an explicit --apply. The script prints the endpoint, the request body, and the current versus proposed values before sending anything.

The other important piece is the audit trail. Every real change gets written into a per-app changelog.md: why it happened, what changed, how it was applied, what the result was, and what should happen next.

That’s the actual brain of it – ok, more like the seed of a brain now, but you get the idea.

When you maintain one app, you can probably pretend you remember why a keyword changed. With ten apps, or more, that fantasy simply fades away. So that changelog is the place where future me can grep the actual reason for a specific change instead of hunting dead neurons in my brain.

The repo also documents one painful App Store Connect detail: submitting for review is no longer the old one-call endpoint. The working flow is the modern three-step reviewSubmissions path: create the submission shell, attach the version as an item, then patch submitted: true. The old appStoreVersionSubmissions endpoint can return a very misleading 403.

So this may look like a very tiny utility, but it’s something useful immediately. I am continuing to build it, so feel free to star the repo, subscribe to my newsletter and stay in touch.

The goal is to make release operations safe first.

Then make them smart.

Top comments (0)