Skip to content

fix(release): repair + automate Android + iOS store-metadata push from #644#646

Merged
TaprootFreak merged 8 commits into
stagingfrom
fix/android-play-changelog-version-code
Jun 2, 2026
Merged

fix(release): repair + automate Android + iOS store-metadata push from #644#646
TaprootFreak merged 8 commits into
stagingfrom
fix/android-play-changelog-version-code

Conversation

@TaprootFreak
Copy link
Copy Markdown
Contributor

@TaprootFreak TaprootFreak commented Jun 2, 2026

Problem

The first real store release after #644 (internal release v1.0.76) failed on both platforms — two regressions in the metadata-push that #644 added but that only run on a tag push (never in PR CI):

  • Android upload_to_play_store: Cannot find changelog because no version code given — a metadata-only call (skip_upload_aab: true) still had skip_upload_changelogs: false; supply needs a version code (from a binary) to attach a changelog.
  • iOS deliver: Cannot update languages - could not find an editable version for 'IOS' — deliver writes to an editable App Store version, which a TestFlight-only app has none of, and skip_app_version_update: true never creates one.

Fix

Android (android/fastlane/Fastfile) — clean separation:

  • binary call uploads binary + changelog only (skip_upload_metadata/images/screenshots: true);
  • listing call pushes metadata + images with skip_upload_changelogs: true;
  • store_metadata lane likewise, pinned to internal.

iOS (ios/fastlane/Fastfile) — keep the listing git-driven and automated (no permanent manual step), by letting deliver self-bootstrap the App Store version:

  • beta lane: deliver runs with app_version: marketing_version + skip_app_version_update: false, so it creates/selects the editable App Store version itself and stages the listing on every tag-driven release;
  • store_metadata lane: skip_app_version_update: false for the binary-less metadata sync.
  • Safeguards unchanged (ios/fastlane/Deliverfile): force (no CI prompts), submit_for_review false, automatic_release false → deliver only stages the listing; a human still clicks Submit, and it never auto-releases to the public.

README updated: both beta lanes push the listing again (iOS staged via a self-created version).

Validation

  • ruby -c passes for both Fastfiles (syntax + config shape).
  • Android: changelog uploaded exactly once (binary, version-code-bound); listing exactly once; no skip_upload_changelogs: false remains.
  • iOS: beta ends with a deliver that can create the version; store_metadata mirrors it; safeguards intact.

⚠️ Validation limitation (transparent)

App Store Connect / Play Console are not reachable from PR CI, so whether deliver actually creates the editable App Store version (skip_app_version_update: false) can only be verified on the next tag push (the v1.0.77 internal release). This PR is validated at the syntax/config level only; the end-to-end console behavior is verified post-merge on that release run.

Meta

  • Base branch: staging (per CONTRIBUTING.md — feature/fix PRs target staging, then auto-promote to developmain).

Refs #634

Promote: staging -> develop
## Automatic Staging PR

This PR was automatically created after changes were pushed to staging.

**Commits:** 1 new commit(s)

### Checklist
- [ ] Review all changes
- [ ] Verify CI passes
- [ ] Approve and merge to promote into develop

Co-authored-by: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com>
Promote: staging -> develop
## Automatic Staging PR

This PR was automatically created after changes were pushed to staging.

**Commits:** 1 new commit(s)

### Checklist
- [ ] Review all changes
- [ ] Verify CI passes
- [ ] Approve and merge to promote into develop

Co-authored-by: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com>
## Automatic Staging PR

This PR was automatically created after changes were pushed to staging.

**Commits:** 1 new commit(s)

### Checklist
- [ ] Review all changes
- [ ] Verify CI passes
- [ ] Approve and merge to promote into develop

Co-authored-by: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com>
The release `beta` lane added a metadata-only upload_to_play_store call
(skip_upload_aab: true) that still had skip_upload_changelogs: false.
supply can only attach a changelog to a version code, which only a
binary upload provides, so the call aborts with "Cannot find changelog
because no version code given" and fails the whole Android release
(first seen on the v1.0.76 internal release).

Separate the two concerns cleanly:
- The binary upload_to_play_store now uploads the binary + changelog
  only (skip metadata/images/screenshots), owning the version-code-bound
  changelog.
- The listing upload_to_play_store pushes metadata + images with
  skip_upload_changelogs: true (no duplicate metadata upload either).
- The metadata-only store_metadata lane likewise skips the changelog
  (no binary => no version code) and stays pinned to the internal track.

Refs #634
@TaprootFreak TaprootFreak marked this pull request as ready for review June 2, 2026 20:56
The release `beta` lane's `deliver` call (added in #644) aborts with
"Cannot update languages - could not find an editable version for 'IOS'":
deliver can only write metadata/screenshots to an editable App Store
version, which a TestFlight-only app does not have, and
skip_app_version_update: true means it never creates one. This failed
the iOS leg of the v1.0.76 release (~20 min of retries).

Decouple the App Store listing from the TestFlight binary: the iOS beta
lane now ships only the TestFlight build. The App Store listing stays
git-driven via the dedicated store_metadata lane / store-metadata.yaml,
to be run once an editable App Store version exists (see PR discussion).
Unlike Play — where the listing is global and ships with the AAB — the
App Store listing is a separate, human-gated submission surface, so
coupling it to every internal TestFlight tag was both broken and wrong.

README updated to describe the per-platform behavior.

Refs #634
@TaprootFreak TaprootFreak changed the title fix(android): don't upload Play changelog without a version code fix(release): repair Android + iOS store-metadata push from #644 Jun 2, 2026
@TaprootFreak TaprootFreak changed the base branch from develop to staging June 2, 2026 21:34
…ated

Reverts the earlier decoupling, which broke the git-driven App Store
listing for iOS. Instead of removing deliver, make it work when no
editable App Store version exists yet (TestFlight-only app):

- beta lane: restore the deliver call with app_version: marketing_version
  and skip_app_version_update: false, so deliver creates/selects the
  editable App Store version itself and stages the listing on every
  tag-driven release.
- store_metadata lane: skip_app_version_update: false for the same reason
  on the binary-less metadata sync.

Safeguards are unchanged and load-bearing (Deliverfile): force (no CI
prompts), submit_for_review false, automatic_release false — deliver only
stages the listing; a human still clicks Submit, and it never auto-
releases to the public.

README updated: both beta lanes push the listing again (iOS staged via a
self-created version).

Note: real verification that deliver creates the App Store version can
only happen on the next tag push (App Store Connect is not reachable from
PR CI); ruby -c validates syntax only. See PR body.

Refs #634
@TaprootFreak TaprootFreak marked this pull request as draft June 2, 2026 21:44
@TaprootFreak TaprootFreak changed the title fix(release): repair Android + iOS store-metadata push from #644 fix(release): repair + automate Android + iOS store-metadata push from #644 Jun 2, 2026
@TaprootFreak TaprootFreak marked this pull request as ready for review June 2, 2026 21:47
@TaprootFreak TaprootFreak merged commit bf2a331 into staging Jun 2, 2026
8 of 10 checks passed
@TaprootFreak TaprootFreak deleted the fix/android-play-changelog-version-code branch June 2, 2026 22:04
TaprootFreak added a commit that referenced this pull request Jun 2, 2026
…#648)

## Problem

The iOS leg of release **v1.0.77** failed at `deliver` (the App Store
listing push). gym + `upload_to_testflight` succeeded (the TestFlight
binary shipped), then `deliver` aborted:

```
app_version: 1.0.77, skip_app_version_update: false
The provided entity includes a relationship with an invalid value
- You cannot create a new version of the App in the current state. - /data/relationships/app
```

The earlier `#646` fix (`skip_app_version_update: false`) correctly
makes deliver *attempt* to create the App Store version (the old "could
not find an editable version" error is gone). But Apple's API refuses to
create the **first** App Store version for an app that is still
TestFlight-only — an **App Store Connect bootstrap prerequisite**, not a
repo problem. The additive listing push then hard-failed the whole iOS
release even though the binary uploaded fine.

## Fix — best-effort listing push (Option B, owner-approved)

`ios/fastlane/Fastfile`: wrap the `deliver` call (both the `beta` lane
and the `store_metadata` lane) in a new `deliver_best_effort` helper:

```ruby
def deliver_best_effort(**options)
  deliver(**options)
rescue => e
  UI.error(...); UI.important("ACTION: create the first App Store version once in App Store Connect ...")
end
```

- The `rescue` wraps **only the single `deliver` call**, so a deliver
failure is logged loudly and the lane exit stays **0**.
- **A failure of any other action (gym, signing, `upload_to_testflight`,
…) still hard-fails** — they are outside the rescue.
- Android path **unchanged**.
- README updated to document the best-effort behavior + the one-time ASC
bootstrap.

Once the first App Store version is created once in App Store Connect,
the next tag-driven release's `deliver` writes the listing automatically
— no further manual step. (Owner will do the ASC bootstrap later.)

## What is swallowed vs. what still hard-fails
- **Swallowed (logged WARNING, exit 0):** any failure of the `deliver`
call in the `beta` / `store_metadata` lanes — i.e. the App Store listing
push, including the "cannot create a new version in the current state"
bootstrap error.
- **Still hard-fails:** `gym` (build/archive), code signing,
`upload_to_testflight` (the release-critical TestFlight upload), and
every other action — none are wrapped.

## Validation
- `ruby -c ios/fastlane/Fastfile` passes.
- Isolated rescue test: the helper swallows the deliver exception
(returns, no re-raise → exit 0); a non-deliver error propagates and
hard-fails.
- The error stays clearly visible in the build log (`UI.error` banner +
`UI.important` ACTION line) so the pending ASC bootstrap is never
silently lost.

Base branch: **`staging`** (per `CONTRIBUTING.md`).

Refs #634
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant