Publishing KMM swift package using GitHub actions.

Piotr Prus
Google for Developers Europe
3 min readNov 5, 2021
Photo by Jackie Zhao on Unsplash

When you use Kotlin Multiplatform Mobile, there are two ways you can use the shared module. The first method is to have the shared module within the one repository with client apps(android and iOS), and the second one is to have all the parts separately, each in a different git repository. The second option scales better for bigger apps and distributed teams. This is the one that we choose for a recent project and I will write about its configuration n this blog post.

Swift package

To use shared module code in swift, we need to distribute/publish a framework that can be consumed by the Xcode. My iOS teammates asked specifically about Swift Package, which is a relatively new technology. Thankfully, I found this article by John O’Reilly that sheds light on the matter.

To make a swift package, I will use the Multiplatform swift package Gradle plugin. After setting this up, we can run the command:

./gradlew createSwiftPackage

that will create the framework, ready to use in our iOS project. Let’s jump into the CD setup to never worry about this again and just focus more on development 💻.

Publishing the framework

This should be fairly easy , I told myself and start looking into documentation and examples. I found this article, with a very promising title: GitHub Package Registry will support Swift package. Although, the post is from June 2019, the support for Swift Package is not here yet. There is an ongoing discussion on this forum if you would like to learn more.

One of the methods for publishing the swift package is the separate repository. Adding package dependency to Xcode is well supported and described on the Apple developer site. Let’s see how to do it using GitHub actions.

The above workflow will build the Swift Package in shared/swiftpackage. To send all the files from that directory to a separate repository we will use action from the GitHub marketplace. It has a very descriptive name: Push to another repository. There are a few requirements to meet:

  • The destination repository needs to exist already
  • The destination branch needs to exist already
  • We need to provide a GitHub token that has permission to write to the destination repository
  • The action runs only on a Linux server. macOS is not supported / issue

To fulfill the first three requirements, we can create the repository with the main branch and copy the token to GitHub secrets. We will automate it later, but now let’s deal with the last requirement.

The Linux server does not have an access to MacOS outputs, so we need to upload our artifacts and download these on another server. Hopefully, there are two perfect actions that do exactly that, upload and download.

Now, with Swift Package in place, on right server, we can upload it to other repository.

Push to a specific custom-named branch

The above-presented solution works smoothly but supports only main branch. It is good to have a history of the packages and the ability to make alpha and release branches.

To automatically create a branch on different repo we can use this action: Clone GitHub repo. The action allows us to create a new branch and the only requirement to do that is providing the GitHub token that we already use for previous actions.

Now, we just need to make a variable that will be used to name all the new branches. I thought that name of the event that triggers the build will be just perfect. We can trigger the workflow for each tag with a specific prefix and use its name to create our branch.

Firstly, add the trigger:

# Trigger on every tag creation
on:
push:
tags:
- 'release-*'

Now, let's access the tag name during the workflow.

- name: Access tag name of current workflow        
run: echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV

👆 above snippet will write the tag name into env variable called TAG

Putting all together

This workflow will build a swift package and push the artifacts to a separate repo, using the tag name as a new branch name. To make an alpha build, you can modify this workflow, change the tag name or trigger it on each successful merch to develop. There are a lot of options and useful actions with GitHub actions.

Happy coding! 💻

Big thanks to John(twitter) for reviewing this 👍

--

--

Piotr Prus
Google for Developers Europe

Android Developer @Tilt, Enthusiast of kotlin, jetpack compose and clean architecture. Currently Composing and KMMing all the things ❤️