Subwave App Ios Release logo

Subwave App Ios Release

CommunityPopular
perminder-klair
subwave-app-ios-release

Cut a NEW iOS build of the SUB/WAVE app (the Expo project in `app/`) and ship it via EAS — to TestFlight, and on to the live App Store. The app is LIVE in production on the App Store, so a release is build+submit (one command) then a manual "promote to production" step in App Store Connect. Use this skill whenever the user wants to "submit a build", "release iOS again", "push a new TestFlight build", "ship the iOS app", "release to the App Store", "cut an iOS release", "build and submit for iOS", "send a new build to testers", "deploy the iOS app", "bump the iOS build", or any equivalent phrasing aimed at getting a fresh iOS build out. Trigger it even when the user doesn't say "EAS" or "TestFlight" by name — if they want a new iOS build out, this is the path. The one-time pieces (EAS project link, signing certs, App Store Connect app record, eas.json) already exist, so the build is essentially one command. Do NOT use this for the Android app (that's `subwave-app-android`), for running on a simulator/dev (`expo run:ios`), or for first-time EAS/Apple account setup.

Overview

Publisherperminder-klair
Repositorysubwave
Skill namesubwave-app-ios-release
Stars
1.4K
Forks
122
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by perminder-klair on GitHub. Read the source before you install it.

Installation

Install the Subwave App Ios Release AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/perminder-klair/subwave/tree/develop/.claude/skills/subwave-app-ios-release
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/perminder-klair/subwave.git /tmp/subwave
mkdir -p .claude/skills
cp -r /tmp/subwave/.claude/skills/subwave-app-ios-release .claude/skills/subwave-app-ios-release
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Subwave App Ios Release in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Subwave App Ios Release on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Subwave App Ios Release is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

SUB/WAVE iOS release → TestFlight

Build a fresh iOS binary in the cloud and push it to TestFlight. All the painful one-time setup is already done — signing credentials live on EAS, the App Store Connect app record exists, and eas.json is wired — so a normal release is a single command. This skill is about doing it again, reliably, and knowing what to check.

Why this is now easy

The first release required interactive setup (creating a distribution certificate, registering the App Store Connect app). That's finished. EAS stores the credentials server-side and app/eas.json pins the submit target, so repeat builds run non-interactively — no Xcode, no Apple login prompts, no TTY.

First: does this even need a new build? (OTA)

The app ships expo-updates (OTA). If the change is JS/TS only — components, hooks, styles, copy, logic, Metro-bundled assets — you do not need a TestFlight build at all. Push it over-the-air to the binaries already out there:

bash
cd "$APP"
eas update --channel production --message "fix: …"   # testers first: --channel preview

It reaches every installed build whose runtime version (fingerprint) matches — i.e. any build with the same native code. Testers see it on the next cold start (it fetches in the background; fallbackToCacheTimeout: 0 keeps launch instant, so killing + relaunching twice is how you confirm it applied).

A new binary is only required when native inputs changed: a dependency add/upgrade, anything under app/patches/, a config plugin, or app.json's ios/infoPlist/plugins sections. The fingerprint policy guarantees an OTA can't land on a binary with mismatched native code, so you can't break a build this way. Rule of thumb: ran npx expo install or touched patches/? → build a binary. Otherwise → OTA. Full decision table + fingerprint debugging: app/docs/RELEASE.md.

The rest of this skill is the binary path (native change, or a store release).

Fixed facts about this app

Derive the repo root once; don't hardcode it. The Expo project and eas.json live in app/, and every eas command must run from there.

bash
REPO=$(git -C "<this skill's base directory>" rev-parse --show-toplevel)
APP="$REPO/app"   # eas.json lives here — cd into it before any eas command
ThingValue
EAS project@pinku1/subwave (Expo account pinku1)
Bundle identifiercom.getsubwave.app
App Store Connect App ID6778786696
Apple TeamBU9RD766GN (Individual)
Build profileproduction (store distribution, autoIncrement on)
OTA channelproduction — JS-only updates via eas update (see OTA section above)
Runtime versionfingerprint policy — hashes native deps + patches/ so OTAs only reach matching binaries
Version sourceremote — EAS owns the build number; never bump it by hand
TestFlight pagehttps://appstoreconnect.apple.com/apps/6778786696/testflight/ios

eas.json → submit.production.ios already carries ascAppId + appleTeamId, which is what makes submit non-interactive. Leave it intact.

Preflight (10 seconds)

bash
cd "$APP"
eas whoami        # expect: pinku1   (if not logged in: eas login)

If eas isn't found, install it: npm i -g eas-cli.

The release — one command

Build in the cloud and auto-submit to TestFlight when the binary is ready:

bash
cd "$APP"
eas build --platform ios --profile production --auto-submit --non-interactive

That's the whole thing. It:

  1. Increments the build number on EAS (because autoIncrement + remote versions), so each release is a distinct TestFlight build.
  2. Builds the .ipa on EAS servers (~7–15 min) using the stored distribution cert + provisioning profile.
  3. On success, submits straight to App Store Connect using the pinned ascAppId + EAS-stored App Store Connect API key.

The command stays attached and streams progress. If you'd rather not hold the session, add --no-wait and monitor separately (see below) — but then submit won't auto-chain, so you'd submit by build id afterwards.

Detached variant (don't block the session on a 15-min build)

bash
cd "$APP"
# Queue the build, return immediately
eas build --platform ios --profile production --no-wait --non-interactive
# Grab the build id from the output, then watch it:
eas build:view <BUILD_ID>          # Status: new → in queue → in progress → finished
# Once finished, submit that build:
eas submit --platform ios --profile production --id <BUILD_ID> --non-interactive

Poll to completion without babysitting:

bash
BID=<BUILD_ID>
until eas build:view "$BID" --json 2>/dev/null \
      | grep -qiE '"status":[[:space:]]*"(finished|errored|canceled)"'; do sleep 60; done
eas build:view "$BID" | grep -iE "Status|Application Archive"

After it submits

The binary uploads to App Store Connect, then Apple processes it (~5–15 min) before it shows in TestFlight — that part is out of our hands. Apple emails when processing finishes. Internal testers (already in a TestFlight group) can install as soon as it clears; external testers need Beta App Review first.

Confirm/track at the TestFlight page above, or https://expo.dev/accounts/pinku1/projects/subwave/builds.

--auto-submit lands the build in TestFlight, NOT on the public App Store. That's the right default — the build burns in with testers first. Releasing to the public store is a deliberate, manual step (next section), so don't tell the user the App Store is updated just because the build submitted.

Promoting to the public App Store (live app)

SUB/WAVE is live in production on the App Store. EAS only gets the binary into App Store Connect; pushing it to real users is a manual App Store Connect step — EAS doesn't do App Store release (only TestFlight delivery). Once the processed build appears under TestFlight:

  1. App Store Connect → SUB/WAVE → Distribution / App Store tab.
  2. Create a new version if this is a new marketing version (e.g. 1.0.1) — the number must match expo.version in app.json. For a same-version resubmission, edit the existing version.
  3. Under Build, attach the processed build (the one EAS just submitted).
  4. Fill "What's New", then Add for Review → Submit. Apple review for an update is typically hours-to-a-day.
  5. Choose phased release or immediate; it goes live when Apple approves.

So a full public release = run the build command below, wait for processing, then do this promotion. A TestFlight-only push (testers only, no store change) stops after the build submits.

Bumping the version vs. just the build number

Decide which kind of release this is:

  • Another TestFlight build of a version Apple hasn't released yet (a fix, a tweak still in beta): change nothing. autoIncrement gives it a fresh build number under the same expo.version. Just run the release command.
  • A new public App Store release (the live-app case): you must bump expo.version in app/app.json first (e.g. 1.0.0 → 1.1.0), commit, then release. The build number still auto-increments under it.

A version bump is four fields, not one: expo.version in app/app.json, version in app/package.json, and both version fields in app/package-lock.json (top-level .version and .packages[""].version — npm writes the same number twice). app is deliberately outside release-please-config.json, since its marketing version tracks store submissions rather than the monorepo's release train, so nothing bumps these for you. Edit the lockfile's two lines by hand; do not run npm install to do it, which rewrites unrelated entries.

Live-app gotcha — once a marketing version is released on the App Store, you can't ship to the public store again under that same version. --auto-submit (or eas submit) will fail at the submission step with:

You've already submitted this version of the app.
Versions are identified by CFBundleShortVersionString (expo.version)…

The build still succeeds — only the submit is rejected — so the fix is: bump expo.version, commit, rebuild. SUB/WAVE is live on the App Store, so treat a version bump as mandatory for every public release, not optional. (TestFlight alone would take another build under the same version; the public store will not.) Don't query/guess the current version — read expo.version from app/app.json and the released version from App Store Connect.

You only hand-edit app.json's version. You never set buildNumber — appVersionSource: "remote" means EAS is the source of truth for it, and setting it locally would fight EAS. The current build number isn't worth recording here either — it auto-increments every build; check eas build:list for the live value.

When something needs Apple auth again (rare)

Stored credentials cover normal releases. EAS may need to re-touch Apple only on edge cases — the distribution certificate expiring (this one lasts until 2027-06-10), adding a device, or regenerating a profile. If a command starts asking to "log in to your Apple account" or for an "App Store Connect API Key", feed it the API key instead of an interactive login:

Keep the App Store Connect API key (.p8) outside the repo and never commit it — the .p8, its Key ID, and Issuer ID are the credential. Point the env vars at wherever you store it:

bash
export EXPO_ASC_API_KEY_PATH=/path/to/your/AuthKey_<KEYID>.p8
export EXPO_ASC_KEY_ID=<KEY_ID>
export EXPO_ASC_ISSUER_ID=<ISSUER_ID>
export EXPO_APPLE_TEAM_ID=BU9RD766GN   # already in eas.json; non-secret
# then re-run the eas command

Creating a brand-new distribution certificate is the one thing EAS refuses to do headlessly — it needs a real interactive terminal. If you hit that, have the user run the same eas build command via ! (so it gets a TTY) and answer the cert/profile prompts (Yes), then it proceeds.

Things that bite

  • Wrong directory. eas reads eas.json, which is in app/. Run from anywhere else and it won't find the project config. Always cd "$APP" first.
  • Don't hand-edit the build number. appVersionSource: remote owns it.
  • Export compliance is already handled — ITSAppUsesNonExemptEncryption is set to false in app.json, so TestFlight won't block on the encryption question. (The app only uses standard HTTPS.)
  • --auto-submit vs --no-wait are mutually exclusive in spirit: auto-submit waits for the build then submits; no-wait returns early and skips the submit. Pick based on whether you want to hold the session.
  • A failed build still bumps the build number. That's fine — build numbers are cheap and monotonic; a gap doesn't matter.

Quick reference

WantDo
Ship a JS-only change (no new build)cd "$APP" && eas update --channel production --message "…"
Ship a new build to TestFlightcd "$APP" && eas build -p ios --profile production --auto-submit --non-interactive
Release to the public App Storebuild+submit (above), wait for processing, then promote the build in App Store Connect (manual)
New app version firstedit expo.version in app/app.json, commit, then ship
Queue without waitingadd --no-wait, then eas submit -p ios --profile production --id <id>
Check a buildeas build:view <id> / list: eas build:list
See it in TestFlighthttps://appstoreconnect.apple.com/apps/6778786696/testflight/ios
Confirm logineas whoami (expect pinku1)

Frequently asked questions

What does the Subwave App Ios Release AI skill do?

Cut a NEW iOS build of the SUB/WAVE app (the Expo project in `app/`) and ship it via EAS — to TestFlight, and on to the live App Store. The app is LIVE in production on the App Store, so a release is build+submit (one command) then a manual "promote to production" step in App Store Connect. Use this skill whenever the user wants to "submit a build", "release iOS again", "push a new TestFlight build", "ship the iOS app", "release to the App Store", "cut an iOS release", "build and submit for iOS", "send a new build to testers", "deploy the iOS app", "bump the iOS build", or any equivalent ph...

Why use Subwave App Ios Release on TypingMind?

Because you install it once and use it with any model. Subwave App Ios Release is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Subwave App Ios Release in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/perminder-klair/subwave/tree/develop/.claude/skills/subwave-app-ios-release. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Subwave App Ios Release?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Subwave App Ios Release?

As many as you like. As long as a model supports skills, you can use Subwave App Ios Release with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Subwave App Ios Release AI skill free?

Yes. It is published on GitHub by perminder-klair under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇