Flutter build: Unexpected version/version code in output

Hi. I’m trying to publish a Flutter app, but I’m having a problem while testing build metadata:

ERROR: Could not build app io.github.mimoguz.tripeaksneue: Unexpected version/version code in output; APK: ‘0.8.0’ / ‘2001’, Expected: ‘0.8.0’ / ‘1’

Version code in pubspec.yml is 0.8.0+1, and local.properties picks up this version code:

sdk.dir=/opt/android-sdk
flutter.sdk=/build/build/srclib/flutter
flutter.buildMode=release
flutter.versionName=0.8.0
flutter.versionCode=1

This is my current build metadata file: https://gitlab.com/m.oguz.tas/fdroiddata/-/blob/io.github.mimoguz.tripeaksneue/metadata/io.github.mimoguz.tripeaksneue.yml

Both versionCode for the build and CurrentVersionCode fields are set to 1. Commit codes of the release and metadata match. When I build locally outside of the test container, I get the correct version code. I have no idea where that 2001 comes from.

Can anyone guide me to the source of the problem?

Thanks.

That’s the default version code scheme of flutter for different abi. You will got the same version code locally if you run the same commands.

I built the APK locally and checked it using aapt, and it was 1. But now I’m not sure if I used the exact same commands. I’ll check when I get back home.

Do you happen to have a link for documentation of this behaviour?

Thanks.

No, but you can read the source code directly. flutter/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy at 082497087c082e6b4f35eea5fd90636c999df020 · flutter/flutter · GitHub

Undocumented behaviour then? Awesome.

Yeah, I missed --split-per--abi when testing locally. So for ARCH_ARM64 it is 2 * 1000 + my_version_code. Got it.

Thanks.

Follow up: Adding

VercodeOperation:
    - 2000 + %c

seems to solve the issue. But I’ll probably just remove --split-per-abi flag.

Thanks again.

why remove it? don’t you want the app split in smaller packages ?

Because:

  • I would need to figure out how to create multiple apks per build. Does F-Droid even support this? I read build metadata of a few Flutter apps, none of them used split apks.
  • More importantly, I would need to handle a seemingly undocumented behaviour of Flutter build tooling.

I sure would like to do it. But how?

Anyhow, I’m still experimenting.

not sure what you’ve read but it’s supported just fine: metadata/tech.lolli.toolbox.yml · master · F-Droid / Data · GitLab

Not this one, obviously :grin:

I’m adding this to my bucket list. Thanks.

Add this to change the version code

ext.abiCodes = [ "armeabi-v7a": 1, "arm64-v8a": 2, "x86_64": 3 ]
import com.android.build.OutputFile
android.applicationVariants.all { variant ->
  variant.outputs.each { output ->
    def abiVersionCode = project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))
    if (abiVersionCode != null) {
      output.versionCodeOverride = variant.versionCode * 10 + abiVersionCode
    }
  }
}

Yes, the app Licaon_Kter linked has this too. It’s a nice workaround.

Below is Kotlin DSL equivalet that I could come up with (untested):

val abiCodes = mapOf(
    "armeabi-v7a" to 1,
    "arm64-v8a" to 2,
    "x86_64" to 3,
)

applicationVariants.configureEach {
    outputs.configureEach {
        val abiCode = abiCodes[filters.find { it.filterType == OutputFile.ABI }?.identifier] ?: 0
        (this as? ApkVariantOutputImpl)?.versionCodeOverride = versionCode * 10 + abiCode
    }
}

But, please bear with me, I’m asking as a non-developer trying to do this right:
ApkVariantOutputImpl is internal api and OutputFile and its parent interface (where that ABI constant is defined) are depreciated. Is this better than just using the Flutter tooling already does (can I?)? After all, It seems to me I would be replacing something undocumented with something unsupported/internal.

Sorry if I’m being too annoying :slight_smile:

The default version code scheme doesn’t work with F-Droid becuase F-Droid only keeps the versions with the highest version codes.

You’re adapting it to your (our) needs :slight_smile:

The default version code scheme doesn’t work with F-Droid becuase F-Droid only keeps the versions with the highest version codes.

So it’s not per-platform? Ok, thanks.

You’re adapting it to your (our) needs :slight_smile:

:grinning: