koin-annotations icon indicating copy to clipboard operation
koin-annotations copied to clipboard

The order of module block generation impacts the reproducibility of F-Droid builds.

Open darriousliu opened this issue 3 weeks ago • 0 comments
trafficstars

Describe the bug Within Module blocks generated using the @Module and @ComponentScan annotations, the order of declarations varies across different environments, resulting in failed reproducible builds for F-Droid.

package com.mrl.pixiv

import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Module

@Module
@ComponentScan
object FeatureModule

To Reproduce Steps to reproduce the behavior: Project URL: https://github.com/darriousliu/PiPixiv

  1. macOS local build project, generated file FeatureModuleGencom$mrl$pixiv.kt
package org.koin.ksp.generated

import org.koin.core.module.Module
import org.koin.dsl.*
import org.koin.core.module.dsl.viewModel

public val com_mrl_pixiv_FeatureModule : Module get() = module {
	viewModel() { _ -> com.mrl.pixiv.home.HomeViewModel()} binds(arrayOf(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class,org.koin.core.component.KoinComponent::class))
	viewModel() { _ -> com.mrl.pixiv.collection.CollectionViewModel(uid=get())} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.follow.FollowingViewModel(uid=get())} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.picture.PictureViewModel(illust=getOrNull(),illustId=getOrNull())} binds(arrayOf(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class,org.koin.core.component.KoinComponent::class))
	viewModel() { _ -> com.mrl.pixiv.latest.LatestViewModel()} 
	viewModel() { _ -> com.mrl.pixiv.search.result.SearchResultViewModel(searchWords=get())} binds(arrayOf(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class,org.koin.core.component.KoinComponent::class))
	viewModel() { _ -> com.mrl.pixiv.search.SearchViewModel()} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.search.preview.SearchPreviewViewModel()} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.profile.ProfileViewModel()} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.profile.detail.ProfileDetailViewModel(uid=getOrNull())} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.history.HistoryViewModel()} binds(arrayOf(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class,org.koin.core.component.KoinComponent::class))
	viewModel() { _ -> com.mrl.pixiv.setting.SettingViewModel()} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.login.oauth.OAuthLoginViewModel()} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.login.LoginViewModel()} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
}
public val com.mrl.pixiv.FeatureModule.module : org.koin.core.module.Module get() = com_mrl_pixiv_FeatureModule
  1. Github Action generated file FeatureModuleGencom$mrl$pixiv.kt
package org.koin.ksp.generated

import org.koin.core.module.Module
import org.koin.dsl.*
import org.koin.core.module.dsl.viewModel

public val com_mrl_pixiv_FeatureModule : Module get() = module {
	viewModel() { _ -> com.mrl.pixiv.picture.PictureViewModel(illust=getOrNull(),illustId=getOrNull())} binds(arrayOf(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class,org.koin.core.component.KoinComponent::class))
	viewModel() { _ -> com.mrl.pixiv.collection.CollectionViewModel(uid=get())} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.login.oauth.OAuthLoginViewModel()} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.login.LoginViewModel()} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.profile.ProfileViewModel()} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.profile.detail.ProfileDetailViewModel(uid=getOrNull())} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.follow.FollowingViewModel(uid=get())} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.search.result.SearchResultViewModel(searchWords=get())} binds(arrayOf(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class,org.koin.core.component.KoinComponent::class))
	viewModel() { _ -> com.mrl.pixiv.search.preview.SearchPreviewViewModel()} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.search.SearchViewModel()} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.home.HomeViewModel()} binds(arrayOf(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class,org.koin.core.component.KoinComponent::class))
	viewModel() { _ -> com.mrl.pixiv.setting.SettingViewModel()} bind(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class)
	viewModel() { _ -> com.mrl.pixiv.latest.LatestViewModel()} 
	viewModel() { _ -> com.mrl.pixiv.history.HistoryViewModel()} binds(arrayOf(com.mrl.pixiv.common.viewmodel.BaseMviViewModel::class,org.koin.core.component.KoinComponent::class))
}
public val com.mrl.pixiv.FeatureModule.module : org.koin.core.module.Module get() = com_mrl_pixiv_FeatureModule

Expected behavior The order within the generated module block remains consistent across different environments. Whether R8 obfuscation is enabled or not directly impacts reproducible builds (F-Droid).

Koin project used and used version (please complete the following information):

koin = "4.1.1"
koinAnnotation = "2.2.0"

Additional moduleDefinition Add any other moduleDefinition about the problem here.

darriousliu avatar Oct 31 '25 06:10 darriousliu