touchlab / KMMBridge

KMMBridge is a set of Gradle tooling that facilitates publishing and consuming pre-built KMM (Kotlin Multiplatform Mobile) Xcode Framework binaries. See https://kmmbridge.touchlab.co/docs to get started.
https://kmmbridge.touchlab.co/
Apache License 2.0
339 stars 20 forks source link

Package file for multiple modules #168

Open russhwolf opened 1 year ago

russhwolf commented 1 year ago

This will need some experimentation. Probably it looks like a single top-level file which declares multiple artifacts, but need to do some testing and understand how it works.

samhill303 commented 1 year ago

We likely don't want to code actual package file generator. We want to test whether we can write a package file which can then reference packages for multiple modules

russhwolf commented 1 year ago

When consuming a remote package file from a url, it's not possible for it to reference packages at other file paths in the repo, so we can't just use our existing package file generation with a static parent package file.

kpgalligan commented 1 year ago

Played around with some ideas, but yeah, the original plan won't work. We can chat about some alternative ideas. While you can't reference sub-module Package.swift files in the way we were thinking, you can have more than one products in the main Package.swift file. For example, I did a little copy/paste:

// swift-tools-version:5.3
import PackageDescription

let remoteKotlinUrl = "https://maven.pkg.github.com/kpgalligan/KMMRules/kpgalligan/github/kmmrules/lessshared-kmmbridge/0.9.3/lessshared-kmmbridge-0.9.3.zip"
let remoteKotlinChecksum = "b2e0d6a24b8676f740153da82beabb258df72264c82c1e21718921db547314e1"
let packageName = "lessshared"

let remoteKotlinUrl2 = "https://maven.pkg.github.com/kpgalligan/KMMRules/kpgalligan/github/kmmrules/allshared-kmmbridge/0.9.3/allshared-kmmbridge-0.9.3.zip"
let remoteKotlinChecksum2 = "60ce4c9626926ada1e3a2d526151065790307829824353412a87e925a0f96aec"
let packageName2 = "allshared"

let package = Package(
    name: "moreshared",
    platforms: [
        .iOS(.v13)
    ],
    products: [
        .library(
            name: packageName,
            targets: [packageName]
        ),
        .library(
            name: packageName2,
            targets: [packageName2]
        ),
    ],
    targets: [
        .binaryTarget(
            name: packageName,
            url: remoteKotlinUrl,
            checksum: remoteKotlinChecksum
        )
        ,
        .binaryTarget(
            name: packageName2,
            url: remoteKotlinUrl2,
            checksum: remoteKotlinChecksum2
        )
        ,
    ]
)

When you add that, it'll ask which libraries you want to add:

Screen Shot 2023-01-10 at 8 31 20 PM

We're writing metadata to the build dir now (url, version, etc). In theory, we could write out package name and the checksum. Then, say, in the root dir, add an SPM config that points at each module we want to add to it. Then it could build the Package.swift file in one place, from the module builds. As I think about it, there's complications with how to make those module builds dependencies of the main build. Will need to think through it a bit.

I'm reluctant to try anything really "weird", with Package.swift files in module folders, and trying to get around the git management of SPM. From the official docs

Simply put: a package is a git repository with semantically versioned tags, that contains Swift sources and a Package.swift manifest file at its root.

That's the first thing it says about creating packages. I do believe they mean it!

Can think through maybe adding those other modules as module dependencies, but I have no idea how that intersects with task order. Can also look at settings plugins, but that seems like a whole different world.

Third option, treat it as a really special case. Implement the extra metadata discussed above, then change the current plugin to run even if it doesn't have a dependency manager. It'll make the metadata and upload the zips. Then, run a completely different plugin that we point at modules to collect and build the Package.swift file. Fairly hacky, but can be managed in CI, and would be an interim solution.

hanrw commented 4 months ago

same issue may related to this - build -> https://github.com/tddworks/openai-kotlin/actions/runs/7867481586/job/21463248748#step:8:1

Run touchlab/autoversion-finishrelease@main
  with:
    commitMessage: KMM SPM package release for 0.1.0
    tagMessage: KMM release version 0.1.0
    tagVersion: 0.1.0
    branchName: build-0.1.0
  env:
    PODSPEC_SSH_KEY_EXISTS: false
    MODULE: 
    JAVA_HOME: /Users/runner/hostedtoolcache/Java_Adopt_jdk/17.0.10-7/x6[4](https://github.com/tddworks/openai-kotlin/actions/runs/7867481586/job/21463248748#step:16:4)/Contents/Home
Error: fatal: pathspec './Package.swift' did not match any files
hanrw commented 2 months ago

Hi @kpgalligan, is this issue fixed? i couldn't find any docs for this.

kpgalligan commented 2 months ago

No. I was closing old issues. I'll reopen it, but we're crushed with regular Touchlab work and other OSS stuff we're doing, so I don't think this will get any thought anytime soon. There's a new version of KMMBridge coming out pretty soon, but it's focused on other things. If there's some extra time, I'll put some thought into this again, but I wouldn't say there's much "extra time" till later in the year (I.E. after KotlinConf).

hanrw commented 2 months ago

I am just trying to figure out how to fix this issue. and there are may two options:

  1. which you mention early like: we can get the sub-modules that support - kmmbridge
    
    val kmmbridgeProjects = project.subprojects.filter {
        it.plugins.hasPlugin("co.touchlab.kmmbridge:touchlab-kmmbridge")
    }

```kotlin
products: [
        .library(
            name: packageName,
            targets: [packageName]
        ),
        .library(
            name: packageName2,
            targets: [packageName2]
        ),
    ],
    targets: [
        .binaryTarget(
            name: packageName,
            url: remoteKotlinUrl,
            checksum: remoteKotlinChecksum
        )
        ,
        .binaryTarget(
            name: packageName2,
            url: remoteKotlinUrl2,
            checksum: remoteKotlinChecksum2
        )
        ,
    ]
  1. create a different tag for it(sub-module which with KMMBridge)