Skip to content

Release to Production v2.9.24 - 2026-06-07#2154

Open
github-actions[bot] wants to merge 7 commits into
mainfrom
staging
Open

Release to Production v2.9.24 - 2026-06-07#2154
github-actions[bot] wants to merge 7 commits into
mainfrom
staging

Conversation

@github-actions

@github-actions github-actions Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

🎯 Production Release

Release Date: June 07, 2026
Commits ahead: 7

This automated PR promotes tested changes from staging to main for production deployment.

What's Included

All changes that have been verified in the staging environment.

Note: This PR is directly from staging, so new commits merged to staging will automatically appear here.

Pre-Deployment Checklist

  • All staging tests passed
  • QA sign-off received
  • Stakeholder approval obtained
  • Deployment plan reviewed
  • Rollback plan confirmed

Deployment Notes

Merging this PR will trigger production deployment.


This PR was automatically created by the Release Calendar workflow on June 07, 2026

github-actions Bot and others added 7 commits May 31, 2026 16:53
Update build numbers, platform build files, and deployment timestamps after successful deployment.

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* fix upload issue

* pr feedback

* update skill

* fixes

* fixeds

* pr feedback

* pr feedback rd2
Release to Staging v2.9.24 - 2026-05-31
)

* simplify deploy architecture

* update fastlane

* fixes

* pr feedback
Release to Staging v2.9.24 - 2026-06-01
Release to Staging v2.9.24 - 2026-06-02
@vercel

vercel Bot commented Jun 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
self-webview-app Ignored Ignored Jun 7, 2026 5:26pm

Request Review

@greptile-apps

greptile-apps Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This release overhauls the Android Play Store upload pipeline — moving from Fastlane's supply action to a custom Python script with resumable chunked uploads, explicit socket timeouts, pinned dependencies, and an idempotent retry mechanism — and adds App Store submission support for iOS production builds. It also bumps Android API/NDK (35→36, 27→28), narrows release builds to arm64-v8a, and upgrades fastlane to 2.235.

  • Android upload rewritten (upload_to_play_store.py): resumable uploads with 8 MiB chunks, 600 s socket timeout, per-chunk progress logging, a new query mode for pre-flight track inspection, and version-conflict detection on retries to handle lost commit responses idempotently.
  • iOS production path expanded (Fastfile, helpers/ios.rb): TestFlight uploads now use ios_upload_with_idempotent_retry to treat ITMS-4238 as success; a new IOS_SUBMIT_FOR_REVIEW-gated path submits the build for App Store review without manual intervention.
  • Infrastructure hardened: CocoaPods cache now requires an exact Podfile.lock match, Play Store upload timeout raised from 10 to 30 minutes, and Python deps pinned to fix a httplib2 redirect regression on GitHub runners.

Confidence Score: 4/5

Safe to merge for the bulk of the change; one path in the Play Store upload script leaves an uncommitted edit open which could block future uploads.

The idempotent-retry success branch in upload_to_play_store.py returns True without deleting the freshly created edit. Google Play enforces at most one active edit per app, so the lingering uncommitted edit would cause every subsequent CI run to fail at edits.insert() until Play auto-expires the edit (~7 days). The fix is a targeted cleanup call before returning True, mirroring what query_track already does. All other changes — resumable uploads, pinned deps, CocoaPods exact-match caching, iOS idempotent retry, App Store submission path — look well-reasoned and low risk.

app/scripts/upload_to_play_store.py — specifically the idempotent retry success path around line 268–272.

Important Files Changed

Filename Overview
app/scripts/upload_to_play_store.py Major rewrite adding resumable chunked uploads, explicit socket timeout, retry logic, and a new query mode — but the idempotent-retry success path leaves an uncommitted Play edit open, which can block all subsequent CI uploads for up to 7 days.
.github/workflows/mobile-deploy.yml Android API/NDK bumped (35→36, 27→28), architecture narrowed to arm64-v8a for release builds, timeouts extended to 30 min, pip deps pinned via requirements file, and a pre-upload track-query step added.
app/fastlane/Fastfile Android upload logic removed from Fastlane (now delegated to upload_to_play_store.py); iOS gains idempotent TestFlight upload retry and a new App Store submission path gated by IOS_SUBMIT_FOR_REVIEW.
app/fastlane/helpers/ios.rb New ios_build_already_uploaded? and ios_upload_with_idempotent_retry helpers correctly treat ITMS-4238 as success and rely on the existing with_retry/report_success infrastructure.
app/android/app/build.gradle Added parseArchitectures helper and selfAppArchitectures property hook so CI can override ABI filters without modifying the file.
app/scripts/requirements-play-store.txt New pinned requirements file; httplib2 pinned to 0.31.2 to work around the resumable-upload redirect regression in the system-installed 0.20.4.
app/ios/Self.xcodeproj/project.pbxproj CURRENT_PROJECT_VERSION bumped from 228 to 229 in both Debug and Release configs.
.github/actions/cache-pods/action.yml restore-keys removed so CocoaPods cache only reuses an exact Podfile.lock match, preventing hermes-engine skew on partial cache hits.

Sequence Diagram

sequenceDiagram
    participant CI as GitHub Actions
    participant FL as Fastlane (build_only)
    participant PY as upload_to_play_store.py
    participant PLAY as Google Play API

    CI->>FL: bundle exec fastlane android build_only
    FL->>FL: gradle clean bundleRelease
    FL-->>CI: app-release.aab

    CI->>PY: --mode query (pre-flight)
    PY->>PLAY: edits.insert()
    PLAY-->>PY: edit_id
    PY->>PLAY: edits.tracks.get(edit_id, track)
    PLAY-->>PY: current releases
    PY->>PLAY: edits.delete(edit_id)
    PY-->>CI: track state logged

    CI->>PY: --mode track --aab app-release.aab
    loop with_retry (up to 3 attempts)
        PY->>PLAY: edits.insert()
        PLAY-->>PY: edit_id
        PY->>PLAY: bundles.upload(edit_id) [resumable, 8 MiB chunks]
        alt Upload succeeds
            PLAY-->>PY: versionCode
            PY->>PLAY: tracks.update(edit_id, track)
            PY->>PLAY: edits.commit(edit_id)
            PLAY-->>PY: committed
            PY-->>CI: success
        else "Version already committed (retry attempt > 1)"
            PLAY-->>PY: HttpError 409/version conflict
            PY->>PLAY: tracks.get(edit_id, track)
            PLAY-->>PY: releases with versionCode
            Note over PY: edit_id left open (not deleted)
            PY-->>CI: success (idempotent)
        end
    end
Loading

Comments Outside Diff (1)

  1. .github/workflows/mobile-deploy.yml, line 94 (link)

    P2 x86_64 dropped from production Android builds

    Setting ANDROID_RELEASE_ARCHITECTURES: arm64-v8a means the Play Store AAB no longer includes x86_64 slices. Real-world physical devices are effectively all arm64, so this is likely intentional to cut AAB size, but it does prevent the app from being installed on x86_64 Android devices (Intel/AMD handsets, some ChromeOS configurations). Worth confirming this is deliberate before it reaches production.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Reviews (1): Last reviewed commit: "Merge pull request #2146 from selfxyz/re..." | Re-trigger Greptile

Comment on lines 256 to +277
try:
# Build the service
service = build('androidpublisher', 'v3', credentials=credentials)

# Create an edit
print("🚀 Creating edit transaction...")
edit_request = service.edits().insert(body={}, packageName=package_name)
edit = edit_request.execute()
edit_id = edit['id']
print(f"✅ Edit created: {edit_id}")

# Upload the AAB
print("📦 Uploading AAB file...")
media = MediaFileUpload(aab_path, mimetype='application/octet-stream')
upload_request = service.edits().bundles().upload(
bundle_response = execute_resumable_upload(upload_request, "Play Store AAB upload")
except HttpError as e:
if attempt > 1 and is_version_already_committed_error(e):
expected_version_code = (retry_state or {}).get('version_code')
if expected_version_code and track_contains_version_code(
service,
package_name,
edit_id,
track,
expected_version_code,
):
print("ℹ️ Play reports this version code as already used, and "
f"track {track} already contains version code "
f"{expected_version_code}. Treating this retry as a "
"successful release.")
return True
print("⚠️ Play reports this version code as already used, but the "
f"expected version code {expected_version_code or 'unknown'} "
f"was not found on track {track}. Failing instead of reporting "
"an unverified release as successful.")
raise

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Orphaned edit left open on idempotent-retry success path

When attempt > 1 detects is_version_already_committed_error and track_contains_version_code confirms the version landed, the function returns True — but edit_id (the fresh edit opened at the top of this retry) is never committed or deleted. Google Play allows only one active edit per app at a time, so this uncommitted edit will block every subsequent CI upload for up to 7 days (the Play Console auto-expiry window).

query_track avoids exactly this with a finally block that calls service.edits().delete(). The same cleanup is needed here before returning True.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant