Hello all, I'm trying to learn how KMMBridge works...
# touchlab-tools
d
Hello all, I'm trying to learn how KMMBridge works but cannot figure it out yet. I have a KMM library and I would like to offer this lib to iOS and Android hosted on Github, but without sharing the code, just the binaries. How is this supposed to work, do I just need the Github Actions?
k
You'd need to publish your binaries to a different repo. It's possible but not documented in any central place. There is a POC around somewhere, but I don't know where off hand. The config is certainly more complicated. It's on the task list to do, but not done yet. The outside repo needs to be pointed to both by the action and in the call to gradle. In GitHub, you need to add "deploy keys" and run ssh config so the GA script can talk to the other repo.
d
Thanks, I will try it out and let you know later on.
What I'm missing in the quick start is which parts of https://github.com/touchlab/KMMBridgeSPMQuickStart do I need to copy to my own repo for the action to run?
k
The private repo? If just iOS, then the iOS publish GA workflow, but you need to modify the gradle call to pass in the target repo, and the
update-release-tag
(params) step to specify the target repo, and configure deploy keys. I don't remember off-hand if there were any other issues.
d
* What went wrong: 2871 Task 'publishAndroidDebugPublicationToGitHubPackagesRepository ' not found in root project 'MyProject' and its subprojects. what am I missing?
k
publishAndroidDebugPublicationToGitHubPackagesRepository
the Android publishing command doesn't have the GitHub Packages repo defined. The docs need a bit of a reorg as that part is buried a bit: https://touchlab.co/kmmbridge/artifacts/mavenrepoartifacts#github-packages.
d
I#m still confused, do I even need that in the action? or can I remove it?
k
It specifically publishes the Android binary. If you want to publish for Android, you need to tell Gradle to publish your Android binaries in some way. That's all in Gradle land, though. There are several options for telling Gradle to publish. We used specific tasks to avoid Gradle sending all targets. So, to answer your question, yes and no. You need something that triggers Android publishing, and in the case of the sample, it's actually these three that are relevant:
publishKotlinMultiplatformPublicationToGitHubPackagesRepository publishAndroidDebugPublicationToGitHubPackagesRepository publishAndroidReleasePublicationToGitHubPackagesRepository
You could also just try
publish
. However, if that specific task is failing, that presumably means the GitHub Packages repo isn't set up, so Gradle won't have anywhere to publish to.
d
"presumably means the GitHub Packages repo isn't set up" I don't understand what this means
I mean, I checked all the gradle files from the template and added all I did not have, still I'm getting that error "not found in root project", so I'm blocked
k
"presumably means the GitHub Packages repo isn't set up"
KMMBridge has nothing to do with Gradle and Android publishing. The sample template has Android publishing configured, but only because that's what somebody using the sample would likely want.
addGithubPackagesRepository()
exists as a convenience function to set up the publishing target Maven repo. If that's confusing, then you can try setting up your publishing Maven repo manually. If Android publishing with Gradle is confusing, that's a whole different topic.
To break down the target `publishAndroidDebugPublicationToGitHubPackagesRepository`: •
publishAndroidDebugPublication
- publish the android debug build •
ToGitHubPackagesRepository
- to the GitHub Packages repository If the task doesn't exist, then that repo isn't configured.
Or, you possibly don't have the Gradle publishing plugin
I would probably start debugging this by forgetting iOS and just get Android publishing working. First to the same repo, then worry about a separate repo.
d
ok, I will try it, thanks
I was able to publish now in a separate repo, I can forward you the minor needed changes once I'm done if you wish
the only issue I'm encountering is, that I cannot publish in my own repo AND on the other one at the same time, maven repos with the same name cannot exist twice. It would be ideal if you could define the artifact name via a variable in the CI as it's already possible with some other data.
k
I was able to publish now in a separate repo, I can forward you the minor needed changes once I'm done if you wish
I'm curious how you push
Package.swift
to your external repo by way of a minor change, unless by the context of the following message you mean "maven repo"
d
"Package.swift
to your external repo" you mean in the tag, right?
ok, I'm getting the release with the assets, the maven packages, and also tags being created, but pushing the changes to the tag is not working yet
k
I was thinking it would be simpler, but there's more git stuff that needs to be done. As I was sitting down to work on that, I found the work I had done previously. Got it to work: https://github.com/kpgalligan/KMPPublic Build published from a private repo. Drafting quick docs. The process is hacky in parts. Specifically, you need to set up deploy keys and create a PAT. git cli needs the deploy key, but the github rest api can't use deploy keys, so you need a token. Should have a draft doc later today.
Ah, damn. Spoke too soon. Something else needs to change. URL generation, specifically.
Shouldn't be too bad, though.
d
oh nice. The only thing, I'm an Android Dev, my iOS colleague does not like using the zip because you must add they key to the keychain on MacOS and he says it's a pain to request that, so he is preferring to unzip and push the contents to the distribution repo, referencing this folder in Package.swift. Would be nice if we could optionally push the unziped content to the distribution repo main branch and then create the tag
side note: publishing to the dist repo did not work with a fine-grained token, but it works with a classic token
k
Would be nice if we could optionally push the unziped content to the distribution repo main branch and then create the tag
definitely out of scope for KMMBridge. Certainly in the near term. That's a very different process, and as mentioned, you'll run out of releases pretty quickly because the repo size will get quite large.
As mentioned, a dev on the team claimed they were able to avoid auth for public binaries using a different url format, but that will need verification. I never got that to work.
d
that size thing is something I did not understand yet, I mean you build freshly each time, what grows in size? our case is a small lib, zip has 900Kb
k
It seems like you have a really special use case. Dev teams publishing builds for their iOS users would do so fairly often, and uncompressed builds are bigger. The KMMBridge quick start template project is small, and even that results in ~42m of binary (10m zipped). 25 releases, and you'll be over 1g for the repo size. Our first SPM project a few years ago started by putting builds in the repo, and it didn't take long for it to be unusable. If your binary zip is 900k, that's pretty darn small. Since you're only using this repo for publishing your library, if you only publish a few versions, that might be OK. That's up to you. Since your ios dev/team doesn't want to deal with auth, I assume this is for public users. Keep in mind, when a user adds your dependency, that repo has to be downloaded and stored on their drive.
I mean you build freshly each time, what grows in size?
The repo. Each fresh build lives in the repo. You don't see it, but it exists. If your XCFramework zip is 900k, which seems rather small, but OK, then uncompressed, it's, say 4m. If it's a year from now and you've done 25 point releases, your "small" dependency will be a 100m git repo. Something like that anyway. Having said that, in your case, write a build script that does some git tricks. Build the framework, pull the public as an alternate remote, create a worktree, copy your built framework into the worktree, commit and push. See this for ideas on how that would work: https://github.com/touchlab/ga-push-remote-swift-package/blob/main/src/main.ts#L46. KMMBridge itself is just a different use case than yours.
d
ahhhhh, you were referring to the needed space to host all diferent releases over time, now I get you!
Our current use case is a private lib, for paying customers. But these are our first KMM steps. What worries me is the binary size you mention, not over time, but is that like the drawback of relying on KMM? Because that may be a dealbreaker for some, nobody wants big apps.
k
No. The size of the binary build in the repo is much bigger than the binary that's actually included in a published app. KMP will add some overhead vs writing everything in Swift, but after an initial "tax" the increase is proportional to Swift code. Assuming you understand how to minimize KMP binary size.
d
I'm not aware of KMP binary size minimization mechanisms, I only know what Android can minimize in general