eas-release
Skill0 starsChanged 35 days agoMITView on GitHub
Build, upload and update Expo / React Native apps with EAS - first-time project and credential setup, eas.json profiles and environments, cloud builds, TestFlight uploads, and over-the-air (OTA) updates with rollouts and rollbacks - from a machine with no Mac. Use this whenever the user mentions EAS, an Expo build, TestFlight, "make a build", "production build", a staging build, build numbers, runtime versions, channels, eas update, OTA or over-the-air updates, a hotfix without a store release, or a build that failed, and whenever the app-launch skill reaches its build phase. Sending a build to App Review is the app-store-connect skill; this one stops at TestFlight.
In this repository8 other files it gives its agents.
- app-launchSkill
- app-localizationSkill
- app-review-readinessSkill
- app-store-connectSkill
- aso-researchSkill
- revenuecat-setupSkill
- store-listingSkill
- store-screenshotsSkill
The file
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 3 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 22
Ask before anything that costs money: a paid plan, a larger build machine, builds beyond the free quota.
- Very specific: line 33
When the installed CLI is too old for a command you need, run that command with npx eas-cli@latest <command> rather than upgrading the …
- Very specific: line 37
Read eas.json, the app config (version, runtimeVersion, updates, ios.bundleIdentifier, extra.eas.projectId, plugins) and the scripts in …
- Very specific: line 56
Use the profile set in section 4 of the reference: development, preview, production, and staging (a store build on its own channel that …
- Very specific: line 74
After the upload Apple processes the build for some minutes.
- Very specific: line 75
When a build fails, read the log before changing anything (build:view --json gives error.message and logFiles).
- Distinctive: line 80
Only with the owner's go-ahead for this update.
- Distinctive: line 92
Keep the update group id from the output.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
EAS: build, upload, update
Three different things get called "a release", and mixing them up is how production breaks:
- a build is a native binary (needs Apple's processing, and review before the public sees it);
- a submission in EAS's words is only an upload to TestFlight, never App Review;
- an update (OTA) replaces the JavaScript inside binaries people already have, within minutes and with no review.
references/eas-reference.md is the full, sourced reference (checked October 2026): exact commands, which CLI version has which command, credential routes, failure table, limits. Read the section you are about to act on. This file is the order of work and the rules.
Rules that outrank the task
- Never run
eas updateon any branch or channel unless the owner said so for that update. This includes staging. An update reaches real devices in minutes and cannot be recalled, only superseded. - A build may be started when the task asks for a build. It spends quota and appears to testers, so do not start extra ones to "check something"; prove the bundle locally first.
- Nothing here submits to App Review, and nothing should.
--auto-submituploads to TestFlight. - Never delete or revoke credentials (certificates, push key, API keys). Revoking a push key stops notifications in every app that uses it.
- Ask before anything that costs money: a paid plan, a larger build machine, builds beyond the free quota.
The complete list is section 11 of the reference.
First: look at what exists
npx eas --version # docs describe the newest CLI; older ones lack commands (reference, section 2)
npx eas whoami # is there a session or EXPO_TOKEN?When the installed CLI is too old for a command you need, run that command with npx eas-cli@latest <command> rather than upgrading the owner's global install, whose version their own scripts were written for. Mention the gap in your report.
Paths such as ../app-store-connect/scripts/asc.mjs are relative to this skill's folder; run commands from the app's repository root with the script's absolute path.
Read eas.json, the app config (version, runtimeVersion, updates, ios.bundleIdentifier, extra.eas.projectId, plugins) and the scripts in package.json. Existing scripts encode the owner's habits, and sometimes their old mistakes: check that every update script names a branch and an environment that belong together before trusting it.
A brand-new app
The order matters: each step needs the one before it. The owner's steps are requested through ../app-launch/references/owner-inputs.md (the credentials command in the day-one message, the app record once the name is approved).
| # | Step | Who |
| 1 | Expo session: npx eas whoami works, or an access token set as EXPO_TOKEN | Owner, once per machine |
| 2 | eas init; bundle identifier, owner and extra.eas.projectId in the app config | Agent |
| 3 | First iOS credentials: eas credentials:configure-build --platform ios --profile production in a real terminal. This also registers the bundle identifier with Apple. In the same sitting: push key, app groups (widgets, Live Activities), which need an Apple ID login and not the API key. | Owner. A non-interactive first build stops with "Credentials are not set up". One command, once per app. |
| 4 | The app record in App Store Connect (Apps, +, New App), choosing that bundle identifier | Owner, after the name is approved. No API creates it. If only the bundle identifier is missing, asc.mjs bundle-id <id> "<name>" registers it without waiting for step 3. |
| 5 | ascAppId in submit.production.ios (asc.mjs apps prints it), environment variables, profiles | Agent |
| 6 | First build | Agent |
A build can be made after step 3; uploading it to TestFlight needs step 4.
Profiles and environments
Use the profile set in section 4 of the reference: development, preview, production, and staging (a store build on its own channel that talks to the staging API). Two rules prevent the classic accidents:
- One channel, one environment. A channel whose binaries were built with production variables must only ever receive updates bundled with production variables. An update's
--branchdecides who gets it;--environmentdecides which API URL is baked in. They are independent flags, and a mismatch once pointed production testers at a staging server and logged them all out. runtimeVersion: { policy: "appVersion" }with a version bump on every native change. The version string is then the only thing keeping new JavaScript away from old binaries. A new native module, an SDK upgrade, a config plugin change, a permission or an entitlement means: bumpversionfirst.
Set ios.config.usesNonExemptEncryption: false (when the app only uses HTTPS) so builds do not wait in TestFlight for the export question.
Build and upload
npx expo-doctor
npx expo export --platform ios # the bundle compiles; free, local
eas build --platform ios --profile <profile> --auto-submit --non-interactive --no-wait --json
eas build:view <BUILD_ID> --json # poll every minute or two- Say which profile you are building and what it points at: "production profile, production API, channel production".
- Queues are not predictable. A free-plan upload has waited over two hours. Do not promise a time; poll, and use the wait for other launch work.
- After the upload Apple processes the build for some minutes.
../app-store-connect/scripts/asc.mjs wait-build <number>waits for it. - When a build fails, read the log before changing anything (
build:view --jsongiveserror.messageandlogFiles); the failure table in section 5 of the reference covers the usual causes. - A build made with the staging profile must never be attached to an App Store version. Check the profile of the build you attach.
Updates (OTA)
Only with the owner's go-ahead for this update. Then, in this order:
- The change is JavaScript and assets only. Anything native needs a build.
eas fingerprint:compare --build-id <live build> --environment <env>reports no native difference.- Publish to the staging or preview branch first, with that channel's own environment.
- A real device on that channel loads it: cold start twice (the first launch downloads, the second runs it), then walk sign-in and navigation. Navigation and routing changes are the ones that break on device while looking fine in review. This step needs the owner's phone; ask.
- Owner approves. Publish to production, as a rollout when the change is risky:
eas update --branch production --environment production --platform ios --message "…" --rollout-percentage 10 --non-interactive --jsonKeep the update group id from the output; rollouts and rollbacks need it. Upload source maps afterwards if the project uses Sentry.
Apple allows updates that fix and adjust; it does not allow an update that changes what the app is for, or that adds a feature the reviewer never saw (guideline 2.5.2 and the licence agreement, quoted in section 6 of the reference). While a version is in review, do not publish an update to the channel the reviewer's build reads.
Report
State what was built or published, the profile, channel, environment, version and build number, where it is now (queued, processing, in TestFlight), and what nobody has tested yet. "Uploaded" is not "works": a build that no one has opened on a device is unverified, and the report says so.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

