# `mix mob.republish`
[🔗](https://github.com/genericjam/mob_dev/blob/main/lib/mix/tasks/mob.republish.ex#L1)

Convenience wrapper around the per-release flow. Bumps the platform's
build number, rebuilds the release artifact, and uploads to the store.

    mix mob.republish --ios                         # bump CFBundleVersion, mob.release, mob.publish --ios
    mix mob.republish --ios --no-bump               # skip the bump (Apple will reject same build #; mostly for testing)
    mix mob.republish --android                     # bump versionCode, gradlew bundleRelease, mob.publish --android
    mix mob.republish --android --track production  # publish to a specific track

Platform flag is **required** — Mob is intentionally platform-agnostic
and refuses to default to either side.

## What --ios does (under the hood)

Three steps. Each is a standalone command if you'd rather run them
separately or need to troubleshoot one in isolation:

  1. Bump `CFBundleVersion` in `ios/Info.plist` by 1:

         CURRENT=$(/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" ios/Info.plist)
         /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $((CURRENT + 1))" ios/Info.plist

     Apple rejects re-uploads with the same `CFBundleVersion`. The bump
     only touches `CFBundleVersion` (the integer build number); your
     `CFBundleShortVersionString` (the public semver) stays put.

  2. `mix mob.release` — builds `_build/mob_release/<App>.ipa`. See
     `Mix.Tasks.Mob.Release` for what this produces. Bump-then-release
     order matters: the build number is baked into the binary, not
     inferred at upload time.

  3. `mix mob.publish --ios` — uploads via `xcrun altool` with App
     Store Connect API key auth. See `Mix.Tasks.Mob.Publish`.

## Failure handling

If the bump itself fails (e.g. `CFBundleVersion` isn't an integer —
someone wrote `"1.0"` which actually belongs in `CFBundleShortVersionString`),
you get a clear error before anything else runs.

If `mix mob.release` fails, `mix mob.publish` is not invoked. The
build-number bump is NOT rolled back — you'll see a gap in your
uploaded versions, which Apple is fine with (gaps are allowed; going
backward isn't). Re-run after fixing whatever broke the build.

If `mix mob.publish` itself fails (network, Apple API error, etc.),
you may need to bump the version *again* before retrying — Apple
considers the build number "consumed" once they see it, even on
upload failure. Use `--no-bump` is rarely the right call; usually
the right move is just `mix mob.republish --ios` again.

# `bump_android_version_code!`

```elixir
@spec bump_android_version_code!(Path.t()) :: {String.t(), String.t()}
```

Read `versionCode` from the given `build.gradle`, integer-bump it, and
write back. Returns `{old, new}` strings.

Raises with a clear message if no `versionCode` line is found.

# `bump_ios_build_number!`

```elixir
@spec bump_ios_build_number!(String.t()) :: {String.t(), String.t()}
```

Read `CFBundleVersion` from the given Info.plist, integer-bump it, and
write back. Returns `{old, new}` strings.

Raises with a clear message if the current value isn't a clean integer
— typically that means someone put a semver-style version
(`"1.0.0"`) where Apple expects an integer build counter; the semver
belongs in `CFBundleShortVersionString` instead.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
