1
- import co.touchlab.faktory.KmmBridgeExtension
2
- import co.touchlab.faktory.artifactmanager.ArtifactManager
3
- import co.touchlab.faktory.capitalized
4
1
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
5
- import java.security.MessageDigest
2
+ import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework
6
3
7
4
plugins {
8
5
alias(libs.plugins.kotlinMultiplatform)
9
- alias(libs.plugins.kmmbridge)
10
6
alias(libs.plugins.skie)
11
- alias(libs.plugins.mavenPublishPlugin)
12
7
alias(libs.plugins.kotlinter)
13
- id(" com.powersync.plugins.sonatype" )
14
8
}
15
9
16
10
kotlin {
11
+ val xcf = XCFramework ()
12
+
17
13
listOf (
18
14
iosX64(),
19
15
iosArm64(),
@@ -22,8 +18,14 @@ kotlin {
22
18
macosX64(),
23
19
).forEach {
24
20
it.binaries.framework {
21
+ baseName = " PowerSyncKotlin"
22
+ xcf.add(this )
23
+
25
24
export(project(" :core" ))
26
25
isStatic = true
26
+
27
+ binaryOption(" bundleId" , " PowerSyncKotlin" )
28
+ binaryOption(" bundleVersion" , project.version.toString())
27
29
}
28
30
}
29
31
@@ -64,180 +66,22 @@ configurations.all {
64
66
}
65
67
}
66
68
67
- kmmbridge {
68
- artifactManager.set(SonatypePortalPublishArtifactManager (project, repositoryName = null ))
69
- artifactManager.finalizeValue()
70
- spm()
71
- }
72
-
73
- // We need this so that when a user includes the package in XCode they are able to
74
- // import the package using Github
75
- if (System .getenv().containsKey(" CI" )) {
76
- // Setup github publishing based on GitHub action variables
77
- addGithubPackagesRepository()
78
- }
79
-
80
- // This is required for KMMBridge zip to be uploaded to Sonatype (Maven Central)
81
- // Since this will only ever be used in this build file it does not make sense to make a
82
- // plugin to use this.
83
- class SonatypePortalPublishArtifactManager (
84
- val project : Project ,
85
- private val publicationName : String = " KMMBridgeFramework" ,
86
- artifactSuffix : String = " kmmbridge" ,
87
- private val repositoryName : String?
88
- ) : ArtifactManager {
89
- private val group: String = project.group.toString().replace(" ." , " /" )
90
- private val kmmbridgeArtifactId =
91
- " ${project.name} -$artifactSuffix "
92
- private val zipName = " powersync-$artifactSuffix "
93
- private val LIBRARY_VERSION : String by project
94
-
95
- // This is the URL that will be added to Package.swift in Github package so that
96
- // KMMBridge is downloaded when a user includes the package in XCode
97
- private val MAVEN_CENTRAL_PACKAGE_ZIP_URL = " https://repo1.maven.org/maven2/com/powersync/${zipName} /${LIBRARY_VERSION } /${zipName} -${LIBRARY_VERSION } .zip"
98
-
99
- override fun deployArtifact (
100
- project : Project ,
101
- zipFilePath : File ,
102
- version : String
103
- ): String = MAVEN_CENTRAL_PACKAGE_ZIP_URL
104
-
105
- override fun configure (
106
- project : Project ,
107
- version : String ,
108
- uploadTask : TaskProvider <Task >,
109
- kmmPublishTask : TaskProvider <Task >
110
- ) {
111
- val zipXCFramework = project.tasks.named<Zip >(" zipXCFramework" )
112
- zipXCFramework.configure {
113
- // KMMBridge uses the Gradle Zip tasks to create XCFramework archives, but Gradle
114
- // doesn't support symlinks. XCFrameworks for macOS need to use symlinks though, so we
115
- // patch the task to generate zip files properly.
116
- doLast {
117
- val bridge = project.extensions.getByName<KmmBridgeExtension >(" kmmbridge" )
118
- val source = project.layout.buildDirectory.map { it.dir(" XCFrameworks/${bridge.buildType.get().name} " ) }.get().asFile
119
-
120
- val out = archiveFile.get().asFile
121
- out .delete()
69
+ listOf (" Debug" , " Release" ).forEach { buildType ->
70
+ tasks.register<Exec >(" build$buildType " ) {
71
+ group = " build"
72
+ description = " Create an XCFramework archive for $buildType "
122
73
123
- providers.exec {
124
- executable = " zip"
125
- args(" -r" , " --symlinks" , out .absolutePath, " PowerSyncKotlin.xcframework" )
126
- workingDir(source)
127
- }.result.get().assertNormalExitValue()
128
- }
129
- }
130
-
131
- project.extensions.getByType<PublishingExtension >().publications.create(
132
- publicationName,
133
- MavenPublication ::class .java,
134
- ) {
135
- this .version = version
136
- val archiveProvider = zipXCFramework.flatMap {
137
- it.archiveFile
138
- }
139
- artifact(archiveProvider) {
140
- extension = " zip"
141
- }
142
- artifactId = kmmbridgeArtifactId
143
- }
144
-
145
- // Register the task
146
- project.tasks.register<UpdatePackageSwiftChecksumTask >(" updatePackageSwiftChecksum" ) {
147
- artifactId.set(kmmbridgeArtifactId)
148
- zipUrl.set(MAVEN_CENTRAL_PACKAGE_ZIP_URL )
149
- dependsOn(" updatePackageSwift" )
150
- }
151
-
152
- // Make sure this task runs after updatePackageSwift
153
- project.tasks.named(" kmmBridgePublish" ) {
154
- dependsOn(" updatePackageSwiftChecksum" )
155
- }
74
+ val originalFramework = tasks.getByName(" assemblePowerSyncKotlin${buildType} XCFramework" )
75
+ dependsOn(originalFramework)
156
76
157
- publishingTasks().forEach {
158
- uploadTask.configure {
159
- dependsOn(it)
160
- }
161
- }
162
- try {
163
- project.tasks.named(" publish" ).also { task ->
164
- task.configure {
165
- dependsOn(kmmPublishTask)
166
- }
167
- }
168
- } catch (_: UnknownTaskException ) {
169
- project.logger.warn(" Gradle publish task not found" )
170
- }
171
- }
172
-
173
- private fun publishingTasks (): List <TaskProvider <Task >> {
174
- val publishingExtension = project.extensions.getByType<PublishingExtension >()
175
-
176
- // Either the user has supplied a correct name, or we use the default. If neither is found, fail.
177
- val publicationNameCap =
178
- publishingExtension.publications
179
- .getByName(
180
- publicationName,
181
- ).name
182
- .capitalized()
183
-
184
- return publishingExtension.repositories
185
- .filterIsInstance<MavenArtifactRepository >()
186
- .map { repo ->
187
- val repositoryName = repo.name.capitalized()
188
- val publishTaskName =
189
- " publish${publicationNameCap} PublicationTo${repositoryName} Repository"
190
- // Verify that the "publish" task exists before collecting
191
- project.tasks.named(publishTaskName)
192
- }
193
- }
194
- }
195
-
196
- // This task is used to update Package.swift with the checksum of the zip file
197
- // located on maven central.
198
- abstract class UpdatePackageSwiftChecksumTask : DefaultTask () {
199
- @get:Input
200
- abstract val artifactId: Property <String >
201
-
202
- @get:Input
203
- abstract val zipUrl: Property <String >
204
-
205
- @TaskAction
206
- fun updateChecksum () {
207
- val LIBRARY_VERSION : String by project
208
-
209
- val zipFile = project.file(" ${project.layout.buildDirectory.get()} /tmp/${artifactId.get().lowercase()} -$LIBRARY_VERSION .zip" )
210
-
211
- // Download the zip file
212
- zipFile.parentFile.mkdirs()
213
- project.uri(zipUrl.get()).toURL().openStream().use { input ->
214
- zipFile.outputStream().use { output ->
215
- input.copyTo(output)
216
- }
217
- }
218
-
219
- // Compute the checksum
220
- val checksum =
221
- zipFile.inputStream().use { input ->
222
- val digest = MessageDigest .getInstance(" SHA-256" )
223
- val buffer = ByteArray (8192 )
224
- var bytes = input.read(buffer)
225
- while (bytes >= 0 ) {
226
- digest.update(buffer, 0 , bytes)
227
- bytes = input.read(buffer)
228
- }
229
- digest.digest().joinToString(" " ) { " %02x" .format(it) }
230
- }
77
+ val source = project.layout.buildDirectory.map { it.dir(" XCFrameworks/${buildType.lowercase()} " ) }.get().asFile
78
+ val archiveFile = project.layout.buildDirectory.map { it.file(" FrameworkArchives/PowersyncKotlin$buildType .zip" ) }.get().asFile
231
79
232
- // Update Package.swift
233
- val packageSwiftFile = project.rootProject.file(" Package.swift" )
234
- val updatedContent =
235
- packageSwiftFile.readText().replace(
236
- Regex (" let remoteKotlinChecksum = \" [a-f0-9]+\" " ),
237
- " let remoteKotlinChecksum = \" $checksum \" " ,
238
- )
239
- packageSwiftFile.writeText(updatedContent)
80
+ archiveFile.parentFile.mkdirs()
81
+ archiveFile.delete()
240
82
241
- println (" Updated Package.swift with new checksum: $checksum " )
83
+ executable = " zip"
84
+ args(" -r" , " --symlinks" , archiveFile.absolutePath, " PowerSyncKotlin.xcframework" )
85
+ workingDir(source)
242
86
}
243
87
}
0 commit comments