Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions .github/workflows/publish-shared-core.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Publish SharedCore

# Cuts a release of the `:kmp:shared-core` XCFramework into
# code-payments/flipcash-shared-core-spm, which is the repo iOS depends on. The
# Kotlin stays here; that repo only ever holds the generated `Package.swift` and
# the release assets it points at.
on:
workflow_dispatch:
inputs:
version:
description: 'Version to publish, e.g. 0.1.0 — also the Swift Package tag'
required: true

concurrency:
# Two publishes at once would race on the same tag and release.
group: publish-shared-core
cancel-in-progress: false

env:
CI: true
SPM_REPO: code-payments/flipcash-shared-core-spm

jobs:
publish:
name: Publish SharedCore ${{ inputs.version }}
# Apple targets and `swift package compute-checksum` both need Xcode, so this
# lane can't share the Ubuntu runners the rest of CI uses.
runs-on: macos-15
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@v4

- name: Setup Java env
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'corretto'
cache: 'gradle'

# A fine-grained PAT with Contents: read & write on the Swift Package repo.
# The job's own GITHUB_TOKEN can't reach another repository, and a deploy
# key can only push git — it can't create the GitHub release the
# XCFramework is uploaded to — so one PAT covers both halves.
- name: Check out the Swift Package repo
uses: actions/checkout@v4
with:
repository: ${{ env.SPM_REPO }}
path: spm-repo
token: ${{ secrets.SHARED_CORE_PUBLISH_TOKEN }}

- name: Build the XCFramework, upload it, and update Package.swift
env:
# Gradle reads ORG_GRADLE_PROJECT_-prefixed vars as project properties,
# which keeps the token out of the command line.
ORG_GRADLE_PROJECT_GITHUB_PUBLISH_TOKEN: ${{ secrets.SHARED_CORE_PUBLISH_TOKEN }}
run: |
./gradlew :kmp:shared-core:kmmBridgePublish \
-PENABLE_PUBLISHING=true \
-PsharedCoreVersion=${{ inputs.version }} \
-PspmRepoDir=$GITHUB_WORKSPACE/spm-repo

- name: Commit and tag the Swift Package
working-directory: spm-repo
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

git add Package.swift
if git diff --cached --quiet; then
echo "Package.swift is unchanged — the upload produced the same URL and checksum."
exit 1
fi
git commit -m "SharedCore ${{ inputs.version }}"
git push origin HEAD:main

# The release upload already created this tag, pointing at whatever
# main was before the commit above — i.e. at a Package.swift that
# doesn't mention this release. Move it onto the commit that does, or
# SPM resolves the version to the previous binary.
git tag -f "${{ inputs.version }}"
git push -f origin "${{ inputs.version }}"

- name: Summary
run: |
{
echo "### SharedCore ${{ inputs.version }} published"
echo
echo "- Release: https://github.com/${SPM_REPO}/releases/tag/${{ inputs.version }}"
echo '- Consume: `.package(url: "https://github.com/'"${SPM_REPO}"'", from: "${{ inputs.version }}")`'
} >> "$GITHUB_STEP_SUMMARY"
20 changes: 17 additions & 3 deletions kmp/shared-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,17 @@ plugins {
}

group = "com.flipcash"
version = "0.1.0"

// The published version, and the tag the Swift Package repo gets. CI passes the
// release version in; the fallback only matters for local builds.
version = findProperty("sharedCoreVersion") as String? ?: "0.1.0"

// Where `Package.swift` is written. CI points this at a checkout of
// `code-payments/flipcash-shared-core-spm`; locally it lands under the root
// build directory so `spmDevBuild` has somewhere to write without dirtying the
// repo. Left unset, KMMBridge would write it to this repo's root.
val spmPackageDir = findProperty("spmRepoDir") as String?
?: rootProject.layout.buildDirectory.dir("spm").get().asFile.path

kotlin {
android {
Expand Down Expand Up @@ -44,8 +54,12 @@ kotlin {
}

kmmbridge {
gitHubReleaseArtifacts()
spm(swiftToolVersion = "5.9") {
// Both halves point at the Swift Package repo rather than this one: the
// XCFramework zip is uploaded as a release asset there, and the generated
// `Package.swift` that references it is committed there. iOS then depends on
// a small public repo instead of the whole Android app.
gitHubReleaseArtifacts(repository = "code-payments/flipcash-shared-core-spm")
spm(spmDirectory = spmPackageDir, swiftToolVersion = "5.9") {
iOS { v("15") }
}
}
Loading