App-Store-Connect-CLI: asc: The Go CLI Making App Store Connect Machine-Readable

A JSON-first automation layer for Apple’s release pipeline, built for CI, AI agents, and the messy realities of 2FA, uploads, metadata, and submissions.

8 min read • View on GitHub • More from rudrankriyam

A terminal console acts like a control tower while structured release packets move into an Apple-shaped machine. The scene explains how asc turns App Store Connect from a human-shaped process into a machine-readable release pipeline.
asc is not trying to make App Store Connect friendlier. It is trying to make it legible to software agents.

It has been a month of working on the App Store Connect CLI and it has grown beyond my imagination!

Rudrank Riyam, Author · Post on Threads
Key Takeaways

The first thing to understand about asc is what it is not. It is not another terminal convenience layer for a developer tapping through menus. It is a release system shaped for agents, CI, and other callers that need the same answer every time.

That shift matters because App Store Connect is full of brittle human assumptions. Sessions expire. 2FA mutates. Uploads are large, stateful, and easy to mess up. Metadata lives in a maze of app info states, version states, and submission paths.

Why this CLI exists at all

A hedcut-style portrait of Rudrank Riyam on a white background. It anchors the project in a real maintainer while the article explains the design choices behind asc.

Rudrank Riyam’s public framing makes the intent plain. The project is not pitched as a side utility. It is a release tool meant to be put into pipelines and used repeatedly without drama.

That is why the README language, the command behavior, and even the repository extras point toward a machine audience. The tool favors JSON, non-interactive flows, and explicit outcomes. Humans can still use it, but they are not the center of the design.

The core idea is simple: a command enters asc, gets normalized, executed through specialized handlers, and returns a meaning-rich result that automation can trust.

DimensionascWhat that means
InterfaceJSON-first CLIMachines can parse it without guessing
Command styleNon-interactivePipelines do not stall on prompts
ScopeApp Store Connect focusedNarrower than a full release suite
RuntimeGo single binaryEasy to ship and easy to script
AudienceAgents, CI, developersBuilt for repeatable automation

Built for machines, not menu navigation

The architecture starts with the command layer and then gets out of the way. The repo uses ffcli for composable routing, which fits a tool that has many subcommands but wants clean, predictable execution. Root help and version checks are fast paths, not afterthoughts.

That matters because a machine-friendly CLI has to be boring in the best way. It should fail clearly, exit cleanly, and avoid ambiguous interaction. asc treats the terminal as an API surface, not a conversational UI.

// simplified from cmd/exit_codes.go
func ExitCodeFromError(err error) int {
    var apiErr *asc.APIError
    if errors.As(err, &apiErr) {
        if apiErr.StatusCode >= 400 && apiErr.StatusCode < 500 {
            return 10 + (apiErr.StatusCode - 400)
        }
        if apiErr.StatusCode >= 500 && apiErr.StatusCode < 600 {
            return 60 + (apiErr.StatusCode - 500)
        }
    }
    return 1
}

That tiny mapping is a product feature. A pipeline can tell the difference between a bad request, a missing resource, and a service outage without scraping a stack trace. In automation, that is the difference between retrying intelligently and guessing.

How asc survives Apple’s complexity

A close-up of a file being split into precise byte-range slices while one channel stays open and another path is blocked. The image explains how asc streams uploads safely and guards against dangerous file handling.
The implementation is careful because Apple’s release surface is careful in all the wrong ways. asc has to be disciplined to stay reliable.

The best engineering in asc is not flashy. It is defensive. Asset uploads are streamed in slices with io.NewSectionReader, which avoids loading huge files into memory. Symlinks are refused. Oversized assets are blocked before they become operational problems.

The same pattern shows up in Apple ID handling. The auth layer has to deal with session state, trusted devices, and two-factor flows that do not behave like ordinary web logins. asc turns that mess into explicit state handling instead of burying it under generic failure.

App info resolution is another example. Apple can expose multiple metadata states for what looks like the same app, so the code maps version state to the correct app info target. That is not just convenience. It prevents edits from landing in the wrong place.

The quiet superpower: exit codes that mean something

Many tools collapse everything into a single non-zero exit. asc does not. It translates API failures into ranges that encode meaning, which makes the tool easier to compose in CI and easier to debug in logs.

Failure typeGeneric CLIasc
404 Not Foundexit 1distinct 4xx-derived code
429 or 422 style client errorexit 1separate client-side signal
500 service errorexit 1distinct 5xx-derived code
Successexit 0exit 0

This is a small implementation detail with a large behavioral payoff. A pipeline can branch on specific failure classes without parsing text, and an agent can decide whether to retry, escalate, or stop. That is machine readability in its most practical form.

Why the Wails Studio matters

The Studio is the surprise. A CLI project does not usually ship with a desktop front end, especially one built in Wails. But here the GUI is not a separate product. It is another shell around the same Go core.

That choice says something important about the codebase. The business logic is not trapped inside the terminal. It is portable enough to support a different interface without being rewritten. For infrastructure software, that is a serious design signal.

Thank you to everyone who starred, contributed, filed issues, and are putting asc cli in their pipelines. This is just the beginning.

Rudrank Riyam, Author · Post on Threads

How it compares to fastlane and Apple’s own tools

ToolLanguage / runtimeStrengthTrade-off
ascGoLightweight, JSON-first, agent-friendlyNarrower scope than a full release suite
fastlaneRubyBroad ecosystem and many lanesHeavier mental model and more moving parts
altoolApple native toolingOfficial baseline for some uploadsMore limited and less expressive for complex automation

The comparison is not really about feature counts. It is about interface philosophy. fastlane is the broad automation platform. Apple’s tools are native but constrained. asc is narrower, faster to reason about, and better aligned with the way CI and agents actually consume tools.

That is why the project feels timely. It takes a messy, high-friction platform and expresses it as something software can trust. In the age of agents, that may be the most valuable feature of all.