How I Use Codex and Antigravity to Update and Publish Flutter Apps?

If you maintain mobile apps on Google Play, you know the feeling.

Google sends that familiar warning banner:

“Update your target API level by November 1, 2026 to release updates to your app.”

You know how it goes.

Keeping apps alive on the Play Store is a constant cycle.

Update target SDKs. Fix broken dependencies. Bump version codes. Build signed bundles. Click through endless Google Play Console forms.

I had a few updates waiting for my Flutter apps.

Usually, this takes hours of manual clicking.

So I wanted to see if I could automate the whole thing using the tools I already use every day: Codex and Antigravity.

Here is the exact setup I used, how it works, and how I connect both tools to my real Chrome browser.

Note: To protect app and account confidentiality, all application names, package IDs, URLs, and signing credentials have been replaced with generic placeholders in this case study.


How I connect to my real browser?

This is the most important part of the whole setup.

Most automated browser scripts use headless Chrome.

If you try to open Google Play Console with a headless browser, it fails immediately. Google blocks it, asks for 2FA, or throws CAPTCHAs.

Instead, I use the browser features built into both tools:

  • In Antigravity, I use the /browser command.
  • In Codex, I use the @browser mention.

Both commands hook directly into my existing Chrome profile.

Because I am already logged into Google Play Console in Chrome, the agents do not need my password. They do not trigger 2FA. They do not need Google Cloud API service account keys.

They just see the open tabs and work directly on the page.

Here is what the flow looks like:

Codex (@browser)
   ↓ Updates Flutter code, bumps targetSdk to 36, fixes widgets
Local Device Testing (USB)
   ↓ Installs on physical phone, catches auto-rotation and contrast bugs
Antigravity Terminal
   ↓ Runs dart analyze, flutter test, builds signed release AAB
Antigravity (/browser)
   ↓ Inspects active Chrome tab, uploads AAB, fills release notes, submits

Why not just use Fastlane?

Most guides tell you to use Fastlane or GitHub Actions.

I have used them before. They work, but setting them up for solo projects is painful.

To get Fastlane working with Google Play:

  • You have to create a Google Cloud service account.
  • You have to grant it admin permissions in Play Console.
  • You have to download private JSON keys and store them safely.
  • You have to update your scripts every time Google changes the API.

And when Google adds a new required questionnaire or a warning banner in Play Console, the API scripts fail anyway.

Using @browser in Codex and /browser in Antigravity skips all of that. It works just like a human developer sitting in front of the screen.


Step 1: Updating the code with Codex

First, I had to fix the target SDK. Google required all updates to target at least Android 15/16 (API 36).

I opened the project in Codex and updated android/app/build.gradle.kts:

android {
    namespace = "com.myapp.production"
    compileSdk = 36
    ndkVersion = "28.2.13676358"

    defaultConfig {
        applicationId = "com.myapp.production"
        minSdk = flutter.minSdkVersion
        targetSdk = 36
        versionCode = flutterVersionCode
        versionName = flutterVersionName
    }
    // ...
}

Next, I bumped the version code in pubspec.yaml from 5 to 6.

Then I ran static analysis and tests in the terminal:

dart analyze
flutter test

One smoke test failed because of a timer in my splash screen. Antigravity added tester.pumpAndSettle() to let the animation finish. Then all tests passed.

Also, keeping your build clean here matters. Gradle caches grow fast on Windows, which I learned the hard way when I used Antigravity to clean 60+ GB off my C: drive.


Step 2: Testing on my real phone first?

Never build a release bundle straight from code without running it on a real device.

Emulators are fine for quick layout checks. But they miss real-world bugs.

Before building anything for release, I plug my physical Android phone into my PC via USB.

I have Antigravity install and run the app directly on the device:

flutter run -d <device_id>

Testing on my actual phone caught small issues that automated tests missed completely:

  1. Unwanted auto-rotation: When the app opened, it flipped sideways into landscape mode. The orientation was not locked. I had the agent lock the app strictly to portrait mode.

  2. Menu text visibility: In dark mode, the active menu text color was blending into the background. It looked fine in a simulated preview. But on an actual OLED screen under indoor light, the selected tab was unreadable. We fixed the contrast.

Fixing these small bugs on a plugged-in phone took two minutes.

Finding them after Google Play approves a production rollout takes days.

Once the app looked and felt right in my hands, we moved on to the release build.


Step 3: Checking the keystore before building

Here is a mistake I have made before:

You spend ten minutes building a 70MB app bundle.

You upload it to Google Play.

Then you see this error:

“Your Android App Bundle is signed with the wrong key. Expected SHA-256: 2B:15:… but found: 8C:4D:…”

I had recently reset the upload keystore for this app. I wanted to be completely sure the local key matched Google Play before building.

Instead of clicking around:

  1. I had Antigravity inspect the App Signing page in my open Chrome tab.
  2. It copied the active Upload Key Certificate SHA-256: 2B:15:CE:D7:...:D6:49:57:35:2C:33:66:3D
  3. Then it ran keytool on my local keystore file:
keytool -list -v -keystore upload-keystore.jks -alias upload

The hashes matched character for character.

Once that was verified, I ran the build command:

flutter build appbundle --release

The signed bundle was ready at build/app/outputs/bundle/release/app-release.aab.


Step 4: Uploading through the browser

Now came the release step.

I used /browser in Antigravity and pointed it to my open Google Play Console tab.

1. Opening the release page

It navigated to the Production track and clicked “Create new release”.

2. Uploading the bundle

It selected the new app-release.aab file.

Google Play takes about 40 to 60 seconds to process a 70MB bundle. Antigravity watched the progress bar and waited for Google to finish its checks.

Once done, Play Console confirmed:

  • Version code: 6 (2.0.0)
  • Target SDK: 36

3. Adding release notes

My app supports both English (en-US) and Arabic (ar).

Antigravity typed the release notes directly into the text box:

<en-US>
• Target API updated to Android 15/16 (API 36) for better performance.
• Modern UI updates and better dark mode support.
• General bug fixes and stability improvements.
</en-US>
<ar>
• تم تحديث واجهة برمجة التطبيقات المستهدفة إلى Android 15/16 (API 36) لتحسين الأداء.
• تحسينات عصرية على واجهة المستخدم ودعم أفضل للوضع الداكن.
• إصلاح الأخطاء وتحسين الاستقرار العام.
</ar>

Play Console accepted both languages immediately.


Step 5: Handling the dropped devices warning

When Antigravity clicked “Next”, Google Play showed a yellow warning box:

“This release no longer supports 999 devices that were supported in your previous release.”

This happens because newer Flutter releases raise the minimum SDK to Android 7.0 (API 24), dropping very old phones from 2015.

A regular script would crash here.

Antigravity looked at the popup dialog, read the warning, and clicked “Proceed”.

That unlocked the “Save” button. It saved the draft and clicked “Go to overview”.


Step 6: Submitting for review

On the Publishing Overview page, the release was ready:

  • Production: 6 (2.0.0)

Antigravity clicked “Submit 1 change for review”, confirmed the prompt, and verified the final status:

“1 change sent for review”

That was it. The update was sent to Google for review.

No manual forms. No copy-pasting release notes. No key mismatch surprises.


What I learned?

After running this across my apps, here are the main things I noticed:

1. Connecting to an active browser saves hours

Using @browser in Codex and /browser in Antigravity means you never deal with API keys, cookies, or 2FA. The agents just use your active Chrome profile.

2. Real websites have surprises

Google Play Console changes constantly. Modal popups appear. Warnings require confirmation. An AI agent that can read the page and click the right button handles these changes easily. Hardcoded scripts break.

3. Verify your keys first

Always run keytool against your local keystore before building. Checking the hash against Google Play takes 10 seconds. Rebuilding an app bundle takes 10 minutes.

This setup makes app updates easy. Codex handles the code, and Antigravity handles the terminal and the browser.

Just like cleaning up internal links on a website, removing friction from your release process lets you spend your time building things instead of filling out web forms.

Want my posts to show up more often on Google?

One click and Google will surface this site in your Top Stories.

Add as preferred source
Suraj Katwal
Written by

Suraj Katwal

Digital marketer, data enthusiast, and developer based in Melbourne, originally from Nepal. I build web platforms, Flutter apps, and digital marketing campaigns. On the data side, I work with SQL and Python while growing into dbt and data pipeline tools.