Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
skiko
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
liuqiang
skiko
Commits
2bc9c86e
Unverified
Commit
2bc9c86e
authored
Nov 08, 2021
by
Alexey Tsvetkov
Committed by
GitHub
Nov 08, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use published build helper module for publishing (#350)
parent
d9b136ef
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
23 additions
and
660 deletions
+23
-660
build.gradle.kts
skiko/build.gradle.kts
+5
-3
build.gradle.kts
skiko/buildSrc/build.gradle.kts
+0
-2
build.gradle.kts
skiko/buildSrc/publishing/build.gradle.kts
+0
-23
DownloadFromSpaceTask.kt
...mpose/internal/gradle/publishing/DownloadFromSpaceTask.kt
+0
-69
ModuleToUpload.kt
...ains/compose/internal/gradle/publishing/ModuleToUpload.kt
+0
-16
UploadToSonatypeTask.kt
...ompose/internal/gradle/publishing/UploadToSonatypeTask.kt
+0
-100
AbstractRestApiClient.kt
...ernal/gradle/publishing/sonatype/AbstractRestApiClient.kt
+0
-72
ModuleValidator.kt
...se/internal/gradle/publishing/sonatype/ModuleValidator.kt
+0
-113
RequestError.kt
...mpose/internal/gradle/publishing/sonatype/RequestError.kt
+0
-23
SonatypeApi.kt
...ompose/internal/gradle/publishing/sonatype/SonatypeApi.kt
+0
-46
SonatypeRestApiClient.kt
...ernal/gradle/publishing/sonatype/SonatypeRestApiClient.kt
+0
-97
Xml.kt
...brains/compose/internal/gradle/publishing/sonatype/Xml.kt
+0
-26
settings.gradle.kts
skiko/buildSrc/settings.gradle.kts
+0
-1
properties.kt
skiko/buildSrc/src/main/kotlin/properties.kt
+0
-56
build.gradle.kts
skiko/ci/build.gradle.kts
+9
-9
settings.gradle.kts
skiko/settings.gradle.kts
+9
-4
No files found.
skiko/build.gradle.kts
View file @
2bc9c86e
...
@@ -2,13 +2,14 @@ import de.undercouch.gradle.tasks.download.Download
...
@@ -2,13 +2,14 @@ import de.undercouch.gradle.tasks.download.Download
import
org.gradle.crypto.checksum.Checksum
import
org.gradle.crypto.checksum.Checksum
import
org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import
org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import
org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
import
org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
import
org.jetbrains.compose.internal.publishing.MavenCentralProperties
plugins
{
plugins
{
kotlin
(
"multiplatform"
)
version
"1.5.31"
kotlin
(
"multiplatform"
)
version
"1.5.31"
`
maven
-
publish
`
`
maven
-
publish
`
signing
signing
id
(
"org.gradle.crypto.checksum"
)
version
"1.1.0"
id
(
"org.gradle.crypto.checksum"
)
version
"1.1.0"
id
(
"de.undercouch.download"
)
id
(
"de.undercouch.download"
)
version
"4.1.2"
}
}
val
coroutinesVersion
=
"1.5.2"
val
coroutinesVersion
=
"1.5.2"
...
@@ -1102,10 +1103,11 @@ publishing {
...
@@ -1102,10 +1103,11 @@ publishing {
}
}
}
}
if
(
skiko
.
isCIBuild
||
skiko
.
signArtifacts
)
{
val
mavenCentral
=
MavenCentralProperties
(
project
)
if
(
skiko
.
isCIBuild
||
mavenCentral
.
signArtifacts
)
{
signing
{
signing
{
sign
(
publishing
.
publications
)
sign
(
publishing
.
publications
)
useInMemoryPgpKeys
(
skiko
.
signArtifactsKey
,
skiko
.
signArtifactsPassword
)
useInMemoryPgpKeys
(
mavenCentral
.
signArtifactsKey
.
get
(),
mavenCentral
.
signArtifactsPassword
.
get
()
)
}
}
}
}
...
...
skiko/buildSrc/build.gradle.kts
View file @
2bc9c86e
...
@@ -9,6 +9,4 @@ repositories {
...
@@ -9,6 +9,4 @@ repositories {
dependencies
{
dependencies
{
implementation
(
kotlin
(
"stdlib"
))
implementation
(
kotlin
(
"stdlib"
))
compileOnly
(
gradleApi
())
compileOnly
(
gradleApi
())
api
(
project
(
":publishing"
))
}
}
skiko/buildSrc/publishing/build.gradle.kts
deleted
100644 → 0
View file @
d9b136ef
import
org.gradle.kotlin.dsl.gradleKotlinDsl
plugins
{
id
(
"org.jetbrains.kotlin.jvm"
)
}
repositories
{
mavenCentral
()
}
dependencies
{
compileOnly
(
gradleApi
())
compileOnly
(
gradleKotlinDsl
())
compileOnly
(
kotlin
(
"stdlib"
))
val
jacksonVersion
=
"2.12.5"
implementation
(
"com.fasterxml.jackson.dataformat:jackson-dataformat-xml:$jacksonVersion"
)
implementation
(
"com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion"
)
implementation
(
"io.ktor:ktor-client-okhttp:1.6.2"
)
implementation
(
"org.apache.tika:tika-parsers:1.24.1"
)
implementation
(
"org.jsoup:jsoup:1.14.3"
)
implementation
(
"de.undercouch:gradle-download-task:4.1.2"
)
}
skiko/buildSrc/publishing/src/main/kotlin/org/jetbrains/compose/internal/gradle/publishing/DownloadFromSpaceTask.kt
deleted
100644 → 0
View file @
d9b136ef
package
org.jetbrains.compose.internal.gradle.publishing
import
de.undercouch.gradle.tasks.download.DownloadAction
import
org.gradle.api.DefaultTask
import
org.gradle.api.provider.ListProperty
import
org.gradle.api.provider.Property
import
org.gradle.api.tasks.Internal
import
org.gradle.api.tasks.TaskAction
import
org.jsoup.Jsoup
import
java.net.URL
abstract
class
DownloadFromSpaceMavenRepoTask
:
DefaultTask
()
{
@get
:
Internal
abstract
val
modulesToDownload
:
ListProperty
<
ModuleToUpload
>
@get
:
Internal
abstract
val
spaceRepoUrl
:
Property
<
String
>
@TaskAction
fun
run
()
{
for
(
module
in
modulesToDownload
.
get
())
{
downloadArtifactsFromComposeDev
(
module
)
}
}
private
fun
downloadArtifactsFromComposeDev
(
module
:
ModuleToUpload
)
{
val
groupUrl
=
module
.
groupId
.
replace
(
"."
,
"/"
)
val
filesListingDocument
=
Jsoup
.
connect
(
"${spaceRepoUrl.get()}/$groupUrl/${module.artifactId}/${module.version}/"
).
get
()
val
downloadableFiles
=
HashMap
<
String
,
URL
>()
for
(
a
in
filesListingDocument
.
select
(
"#contents > a"
))
{
val
href
=
a
.
attributes
().
get
(
"href"
)
val
lastPart
=
href
.
substringAfterLast
(
"/"
,
""
)
// check if URL points to a file
if
(
lastPart
.
isNotEmpty
()
&&
lastPart
.
contains
(
"."
))
{
downloadableFiles
[
lastPart
]
=
URL
(
href
)
}
}
val
destinationDir
=
module
.
localDir
if
(
destinationDir
.
exists
())
{
if
(
module
.
version
.
endsWith
(
"-SNAPSHOT"
))
{
destinationDir
.
deleteRecursively
()
}
else
{
// delete existing files, that are not downloadable
val
existingFiles
=
(
destinationDir
.
list
()
?:
emptyArray
()).
toSet
()
for
(
existingFileName
in
existingFiles
)
{
if
(
existingFileName
!
in
downloadableFiles
)
{
destinationDir
.
resolve
(
existingFileName
).
delete
()
}
}
// don't re-download all files for non-snapshot version
val
it
=
downloadableFiles
.
entries
.
iterator
()
while
(
it
.
hasNext
())
{
val
(
fileName
,
_
)
=
it
.
next
()
if
(
fileName
in
existingFiles
)
{
it
.
remove
()
}
}
}
}
DownloadAction
(
project
,
this
).
apply
{
src
(
downloadableFiles
.
values
)
dest
(
destinationDir
)
}.
execute
()
}
}
\ No newline at end of file
skiko/buildSrc/publishing/src/main/kotlin/org/jetbrains/compose/internal/gradle/publishing/ModuleToUpload.kt
deleted
100644 → 0
View file @
d9b136ef
package
org.jetbrains.compose.internal.gradle.publishing
import
java.io.File
data class
ModuleToUpload
(
val
groupId
:
String
,
val
artifactId
:
String
,
val
version
:
String
,
val
localDir
:
File
)
{
internal
fun
listFiles
():
Array
<
File
>
=
localDir
.
listFiles
()
?:
emptyArray
()
internal
val
coordinate
:
String
get
()
=
"$groupId:$artifactId:$version"
}
\ No newline at end of file
skiko/buildSrc/publishing/src/main/kotlin/org/jetbrains/compose/internal/gradle/publishing/UploadToSonatypeTask.kt
deleted
100644 → 0
View file @
d9b136ef
package
org.jetbrains.compose.internal.gradle.publishing
import
org.gradle.api.DefaultTask
import
org.gradle.api.provider.ListProperty
import
org.gradle.api.provider.Property
import
org.gradle.api.tasks.Internal
import
org.gradle.api.tasks.TaskAction
import
org.jetbrains.compose.internal.gradle.publishing.sonatype.ModuleValidator
import
org.jetbrains.compose.internal.gradle.publishing.sonatype.SonatypeApi
import
org.jetbrains.compose.internal.gradle.publishing.sonatype.SonatypeRestApiClient
import
org.jetbrains.compose.internal.gradle.publishing.sonatype.StagingProfile
abstract
class
UploadToSonatypeTask
:
DefaultTask
()
{
// the task must always re-run anyway, so all inputs can be declared Internal
@get
:
Internal
abstract
val
sonatypeServer
:
Property
<
String
>
@get
:
Internal
abstract
val
user
:
Property
<
String
>
@get
:
Internal
abstract
val
password
:
Property
<
String
>
@get
:
Internal
abstract
val
stagingProfileName
:
Property
<
String
>
@get
:
Internal
abstract
val
autoCommitOnSuccess
:
Property
<
Boolean
>
@get
:
Internal
abstract
val
autoDropOnError
:
Property
<
Boolean
>
@get
:
Internal
abstract
val
version
:
Property
<
String
>
@get
:
Internal
abstract
val
modulesToUpload
:
ListProperty
<
ModuleToUpload
>
@TaskAction
fun
run
()
{
SonatypeRestApiClient
(
sonatypeServer
=
sonatypeServer
.
get
(),
user
=
user
.
get
(),
password
=
password
.
get
(),
logger
=
logger
).
use
{
client
->
run
(
client
)
}
}
private
fun
run
(
sonatype
:
SonatypeApi
)
{
val
stagingProfiles
=
sonatype
.
stagingProfiles
()
val
stagingProfileName
=
stagingProfileName
.
get
()
val
stagingProfile
=
stagingProfiles
.
data
.
firstOrNull
{
it
.
name
==
stagingProfileName
}
?:
error
(
"Cannot find staging profile '$stagingProfileName' among existing staging profiles: "
+
stagingProfiles
.
data
.
joinToString
{
"'${it.name}'"
}
)
val
modules
=
modulesToUpload
.
get
()
validate
(
stagingProfile
,
modules
)
val
stagingRepo
=
sonatype
.
createStagingRepo
(
stagingProfile
,
"Staging repo for '${stagingProfile.name}' release '${version.get()}'"
)
try
{
for
(
module
in
modules
)
{
sonatype
.
upload
(
stagingRepo
,
module
)
}
if
(
autoCommitOnSuccess
.
get
())
{
sonatype
.
closeStagingRepo
(
stagingRepo
)
}
}
catch
(
e
:
Exception
)
{
if
(
autoDropOnError
.
get
())
{
sonatype
.
dropStagingRepo
(
stagingRepo
)
}
throw
e
}
}
private
fun
validate
(
stagingProfile
:
StagingProfile
,
modules
:
List
<
ModuleToUpload
>)
{
val
validationIssues
=
arrayListOf
<
Pair
<
ModuleToUpload
,
ModuleValidator
.
Status
.
Error
>>()
for
(
module
in
modules
)
{
val
status
=
ModuleValidator
(
stagingProfile
,
module
,
version
.
get
()).
validate
()
if
(
status
is
ModuleValidator
.
Status
.
Error
)
{
validationIssues
.
add
(
module
to
status
)
}
}
if
(
validationIssues
.
isNotEmpty
())
{
val
message
=
buildString
{
appendLine
(
"Some modules violate Maven Central requirements:"
)
for
((
module
,
status
)
in
validationIssues
)
{
appendLine
(
"* ${module.coordinate} (files: ${module.localDir})"
)
for
(
error
in
status
.
errors
)
{
appendLine
(
" * $error"
)
}
}
}
error
(
message
)
}
}
}
\ No newline at end of file
skiko/buildSrc/publishing/src/main/kotlin/org/jetbrains/compose/internal/gradle/publishing/sonatype/AbstractRestApiClient.kt
deleted
100644 → 0
View file @
d9b136ef
package
org.jetbrains.compose.internal.gradle.publishing.sonatype
import
okhttp3.*
import
okhttp3.internal.http.RealResponseBody
import
okio.Buffer
import
org.gradle.api.logging.Logger
import
java.net.URL
import
java.time.Duration
import
java.util.concurrent.atomic.AtomicLong
internal
class
RestApiClient
(
private
val
serverUrl
:
String
,
private
val
user
:
String
,
private
val
password
:
String
,
private
val
logger
:
Logger
,
)
:
AutoCloseable
{
private
val
okClient
by
lazy
{
OkHttpClient
.
Builder
()
.
readTimeout
(
Duration
.
ofMinutes
(
1
))
.
build
()
}
fun
buildRequest
(
urlPath
:
String
,
configure
:
Request
.
Builder
.()
->
Unit
):
Request
=
Request
.
Builder
().
apply
{
addHeader
(
"Authorization"
,
Credentials
.
basic
(
user
,
password
))
url
(
URL
(
"$serverUrl/$urlPath"
))
configure
()
}.
build
()
fun
<
T
>
execute
(
request
:
Request
,
retries
:
Int
=
5
,
delaySec
:
Long
=
10
,
processResponse
:
(
ResponseBody
)
->
T
):
T
{
val
message
=
"Remote request #${globalRequestCounter.incrementAndGet()}"
val
startTimeNs
=
System
.
nanoTime
()
logger
.
info
(
"$message: ${request.method} '${request.url}'"
)
val
delayMs
=
delaySec
*
1000
for
(
i
in
1
..
retries
)
{
try
{
return
okClient
.
newCall
(
request
).
execute
().
use
{
response
->
val
endTimeNs
=
System
.
nanoTime
()
logger
.
info
(
"$message: finished in ${(endTimeNs - startTimeNs)/1_000_000} ms"
)
if
(!
response
.
isSuccessful
)
throw
RequestError
(
request
,
response
)
val
responseBody
=
response
.
body
?:
RealResponseBody
(
null
,
0
,
Buffer
())
processResponse
(
responseBody
)
}
}
catch
(
e
:
Exception
)
{
if
(
i
==
retries
)
{
throw
RuntimeException
(
"$message: failed all $retries attempts, see nested exception for details"
,
e
)
}
logger
.
info
(
"$message: retry #$i of $retries failed. Retrying in $delayMs ms\n${e.message}"
)
Thread
.
sleep
(
delayMs
)
}
}
error
(
"Unreachable"
)
}
override
fun
close
()
{
okClient
.
connectionPool
.
evictAll
()
}
companion
object
{
private
val
globalRequestCounter
=
AtomicLong
()
}
}
skiko/buildSrc/publishing/src/main/kotlin/org/jetbrains/compose/internal/gradle/publishing/sonatype/ModuleValidator.kt
deleted
100644 → 0
View file @
d9b136ef
package
org.jetbrains.compose.internal.gradle.publishing.sonatype
import
com.fasterxml.jackson.annotation.JsonRootName
import
org.jetbrains.compose.internal.gradle.publishing.ModuleToUpload
import
java.io.File
internal
class
ModuleValidator
(
private
val
stagingProfile
:
StagingProfile
,
private
val
module
:
ModuleToUpload
,
private
val
version
:
String
)
{
private
val
errors
=
arrayListOf
<
String
>()
private
var
status
:
Status
?
=
null
sealed
class
Status
{
object
OK
:
Status
()
class
Error
(
val
errors
:
List
<
String
>)
:
Status
()
}
fun
validate
():
Status
{
if
(
status
==
null
)
{
validateImpl
()
status
=
if
(
errors
.
isEmpty
())
Status
.
OK
else
Status
.
Error
(
errors
)
}
return
status
!!
}
private
fun
validateImpl
()
{
if
(!
module
.
groupId
.
startsWith
(
stagingProfile
.
name
))
{
errors
.
add
(
"Module's group id '${module.groupId}' does not match staging repo '${stagingProfile.name}'"
)
}
if
(
module
.
version
!=
version
)
{
errors
.
add
(
"Unexpected version '${module.version}' (expected: '$version')"
)
}
val
pomFile
=
artifactFile
(
extension
=
"pom"
)
val
pom
=
when
{
pomFile
.
exists
()
->
try
{
// todo: validate POM
Xml
.
deserialize
<
Pom
>(
pomFile
.
readText
())
}
catch
(
e
:
Exception
)
{
errors
.
add
(
"Cannot deserialize $pomFile: $e"
)
null
}
else
->
null
}
val
packageFile
=
artifactFile
(
extension
=
pom
?.
packaging
?:
"jar"
)
val
sourcesJar
=
artifactFile
(
extension
=
"jar"
,
classifier
=
"sources"
)
val
javadocJar
=
artifactFile
(
extension
=
"jar"
,
classifier
=
"javadoc"
)
val
nonExistingFiles
=
listOf
(
pomFile
,
packageFile
,
sourcesJar
,
javadocJar
)
.
filter
{
!
it
.
exists
()
}
if
(
nonExistingFiles
.
isNotEmpty
())
{
errors
.
add
(
"Some necessary files do not exist: [${nonExistingFiles.map { it.name }.joinToString()}]"
)
}
// signatures and checksums should not be signed themselves
val
skipSignatureCheckExtensions
=
setOf
(
"asc"
,
"md5"
,
"sha1"
,
"sha256"
,
"sha512"
)
val
unsignedFiles
=
module
.
listFiles
()
.
filter
{
it
.
extension
!
in
skipSignatureCheckExtensions
&&
!
it
.
resolveSibling
(
it
.
name
+
".asc"
).
exists
()
}
if
(
unsignedFiles
.
isNotEmpty
())
{
errors
.
add
(
"Some files are not signed: [${unsignedFiles.map { it.name }.joinToString()}]"
)
}
}
private
fun
artifactFile
(
extension
:
String
,
classifier
:
String
?
=
null
):
File
{
val
fileName
=
buildString
{
append
(
"${module.artifactId}-${module.version}"
)
if
(
classifier
!=
null
)
append
(
"-$classifier"
)
append
(
".$extension"
)
}
return
module
.
localDir
.
resolve
(
fileName
)
}
}
@JsonRootName
(
"project"
)
private
data class
Pom
(
var
groupId
:
String
?
=
null
,
var
artifactId
:
String
?
=
null
,
var
packaging
:
String
?
=
null
,
var
name
:
String
?
=
null
,
var
description
:
String
?
=
null
,
var
url
:
String
?
=
null
,
var
scm
:
Scm
?
=
null
,
var
licenses
:
List
<
License
>?
=
null
,
var
developers
:
List
<
Developer
>?
=
null
,
)
{
internal
data class
Scm
(
var
connection
:
String
?,
var
developerConnection
:
String
?,
var
url
:
String
?,
)
internal
data class
License
(
var
name
:
String
?
=
null
,
var
url
:
String
?
=
null
)
internal
data class
Developer
(
var
name
:
String
?
=
null
,
var
organization
:
String
?
=
null
,
var
organizationUrl
:
String
?
=
null
)
}
skiko/buildSrc/publishing/src/main/kotlin/org/jetbrains/compose/internal/gradle/publishing/sonatype/RequestError.kt
deleted
100644 → 0
View file @
d9b136ef
package
org.jetbrains.compose.internal.gradle.publishing.sonatype
import
okhttp3.Request
import
okhttp3.Response
internal
class
RequestError
(
val
request
:
Request
,
val
response
:
Response
,
responseBody
:
String
)
:
RuntimeException
(
"${request.url}: returned ${response.code}\n${responseBody.trim()}"
)
internal
fun
RequestError
(
request
:
Request
,
response
:
Response
):
RequestError
{
var
responseBodyException
:
Throwable
?
=
null
val
responseBody
=
try
{
response
.
body
?.
string
()
?:
""
}
catch
(
t
:
Throwable
)
{
responseBodyException
=
t
""
}
return
RequestError
(
request
,
response
,
responseBody
).
apply
{
if
(
responseBodyException
!=
null
)
addSuppressed
(
responseBodyException
)
}
}
\ No newline at end of file
skiko/buildSrc/publishing/src/main/kotlin/org/jetbrains/compose/internal/gradle/publishing/sonatype/SonatypeApi.kt
deleted
100644 → 0
View file @
d9b136ef
package
org.jetbrains.compose.internal.gradle.publishing.sonatype
import
com.fasterxml.jackson.annotation.JsonRootName
import
com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper
import
org.jetbrains.compose.internal.gradle.publishing.ModuleToUpload
interface
SonatypeApi
{
fun
upload
(
repo
:
StagingRepo
,
module
:
ModuleToUpload
)
fun
stagingProfiles
():
StagingProfiles
fun
createStagingRepo
(
profile
:
StagingProfile
,
description
:
String
):
StagingRepo
fun
dropStagingRepo
(
repo
:
StagingRepo
)
fun
closeStagingRepo
(
repo
:
StagingRepo
)
}
@JsonRootName
(
"stagingProfile"
)
data class
StagingProfile
(
var
id
:
String
=
""
,
var
name
:
String
=
""
,
)
@JsonRootName
(
"stagingProfiles"
)
class
StagingProfiles
(
@JacksonXmlElementWrapper
var
data
:
List
<
StagingProfile
>
)
data class
StagingRepo
(
val
id
:
String
,
val
description
:
String
,
val
profile
:
StagingProfile
)
{
constructor
(
response
:
PromoteResponse
,
profile
:
StagingProfile
)
:
this
(
id
=
response
.
data
.
stagedRepositoryId
!!
,
description
=
response
.
data
.
description
,
profile
=
profile
)
@JsonRootName
(
"promoteRequest"
)
data class
PromoteRequest
(
var
data
:
PromoteData
)
@JsonRootName
(
"promoteResponse"
)
data class
PromoteResponse
(
var
data
:
PromoteData
)
data class
PromoteData
(
var
stagedRepositoryId
:
String
?
=
null
,
var
description
:
String
)
}
skiko/buildSrc/publishing/src/main/kotlin/org/jetbrains/compose/internal/gradle/publishing/sonatype/SonatypeRestApiClient.kt
deleted
100644 → 0
View file @
d9b136ef
package
org.jetbrains.compose.internal.gradle.publishing.sonatype
import
okhttp3.MediaType.Companion.toMediaTypeOrNull
import
okhttp3.Request
import
okhttp3.RequestBody.Companion.asRequestBody
import
okhttp3.RequestBody.Companion.toRequestBody
import
okhttp3.ResponseBody
import
org.apache.tika.Tika
import
org.gradle.api.logging.Logger
import
org.jetbrains.compose.internal.gradle.publishing.ModuleToUpload
import
java.io.Closeable
import
java.io.File
// https://support.sonatype.com/hc/en-us/articles/213465868-Uploading-to-a-Staging-Repository-via-REST-API
class
SonatypeRestApiClient
(
sonatypeServer
:
String
,
user
:
String
,
password
:
String
,
private
val
logger
:
Logger
,
)
:
SonatypeApi
,
Closeable
{
private
val
client
=
RestApiClient
(
sonatypeServer
,
user
,
password
,
logger
)
private
fun
buildRequest
(
urlPath
:
String
,
builder
:
Request
.
Builder
.()
->
Unit
):
Request
=
client
.
buildRequest
(
urlPath
,
builder
)
private
fun
<
T
>
Request
.
execute
(
processResponse
:
(
ResponseBody
)
->
T
):
T
=
client
.
execute
(
this
,
processResponse
=
processResponse
)
override
fun
close
()
{
client
.
close
()
}
override
fun
upload
(
repo
:
StagingRepo
,
module
:
ModuleToUpload
)
{
for
(
file
in
module
.
localDir
.
listFiles
()
!!
)
{
uploadFile
(
repo
,
module
,
file
)
}
}
private
fun
uploadFile
(
repo
:
StagingRepo
,
module
:
ModuleToUpload
,
file
:
File
)
{
val
fileType
=
Tika
().
detect
(
file
.
name
)
logger
.
info
(
"Uploading $file (detected type='$fileType', length=${file.length()})"
)
val
deployUrl
=
"service/local/staging/deployByRepositoryId/${repo.id}"
val
groupUrl
=
module
.
groupId
.
replace
(
"."
,
"/"
)
val
coordinateUrl
=
"$groupUrl/${module.artifactId}/${module.version}"
val
uploadUrlPath
=
"$deployUrl/$coordinateUrl/${file.name}"
buildRequest
(
uploadUrlPath
)
{
header
(
"Content-type"
,
fileType
)
put
(
file
.
asRequestBody
(
fileType
.
toMediaTypeOrNull
()))
}.
execute
{
}
}
override
fun
stagingProfiles
():
StagingProfiles
=
buildRequest
(
"service/local/staging/profiles"
)
{
get
()
}.
execute
{
responseBody
->
Xml
.
deserialize
(
responseBody
.
string
())
}
override
fun
createStagingRepo
(
profile
:
StagingProfile
,
description
:
String
):
StagingRepo
{
logger
.
info
(
"Creating sonatype staging repository for `${profile.id}` with description `$description`"
)
val
response
=
buildRequest
(
"service/local/staging/profiles/${profile.id}/start"
)
{
val
promoteRequest
=
StagingRepo
.
PromoteRequest
(
StagingRepo
.
PromoteData
(
description
=
description
)
)
post
(
Xml
.
serialize
(
promoteRequest
).
toRequestBody
(
Xml
.
mediaType
))
}.
execute
{
responseBody
->
Xml
.
deserialize
<
StagingRepo
.
PromoteResponse
>(
responseBody
.
string
())
}
return
StagingRepo
(
response
,
profile
)
}
override
fun
dropStagingRepo
(
repo
:
StagingRepo
)
{
stagingRepoAction
(
"drop"
,
repo
)
}
override
fun
closeStagingRepo
(
repo
:
StagingRepo
)
{
stagingRepoAction
(
"finish"
,
repo
)
}
private
fun
stagingRepoAction
(
action
:
String
,
repo
:
StagingRepo
)
{
val
logRepoDescription
=
"profileId='${repo.profile.id}', repoId='${repo.id}', description='${repo.description}'"
logger
.
info
(
"Starting '$action': $logRepoDescription"
)
buildRequest
(
"service/local/staging/${repo.profile.id}/$action"
)
{
val
promoteRequest
=
StagingRepo
.
PromoteRequest
(
StagingRepo
.
PromoteData
(
stagedRepositoryId
=
repo
.
id
,
description
=
repo
.
description
)
)
post
(
Xml
.
serialize
(
promoteRequest
).
toRequestBody
(
Xml
.
mediaType
))
}.
execute
{
responseBody
->
logger
.
info
(
"Finished '$action': $logRepoDescription"
)
logger
.
info
(
"Response: '${responseBody.string()}'"
)
}
}
}
skiko/buildSrc/publishing/src/main/kotlin/org/jetbrains/compose/internal/gradle/publishing/sonatype/Xml.kt
deleted
100644 → 0
View file @
d9b136ef
package
org.jetbrains.compose.internal.gradle.publishing.sonatype
import
com.fasterxml.jackson.databind.DeserializationFeature
import
com.fasterxml.jackson.databind.MapperFeature
import
com.fasterxml.jackson.databind.ObjectMapper
import
com.fasterxml.jackson.dataformat.xml.JacksonXmlModule
import
com.fasterxml.jackson.dataformat.xml.XmlMapper
import
com.fasterxml.jackson.module.kotlin.registerKotlinModule
import
okhttp3.MediaType.Companion.toMediaType
internal
object
Xml
{
val
mediaType
=
"application/xml"
.
toMediaType
()
fun
serialize
(
value
:
Any
):
String
=
kotlinXmlMapper
.
writeValueAsString
(
value
)
inline
fun
<
reified
T
>
deserialize
(
xml
:
String
):
T
=
kotlinXmlMapper
.
readValue
(
xml
,
T
::
class
.
java
)
private
val
kotlinXmlMapper
:
ObjectMapper
=
XmlMapper
(
JacksonXmlModule
().
apply
{
setDefaultUseWrapper
(
false
)
}).
registerKotlinModule
()
.
configure
(
MapperFeature
.
ACCEPT_CASE_INSENSITIVE_PROPERTIES
,
true
)
.
configure
(
DeserializationFeature
.
FAIL_ON_UNKNOWN_PROPERTIES
,
false
)
}
skiko/buildSrc/settings.gradle.kts
View file @
2bc9c86e
include
(
":publishing"
)
\ No newline at end of file
skiko/buildSrc/src/main/kotlin/properties.kt
View file @
2bc9c86e
...
@@ -128,17 +128,6 @@ class SkikoProperties(private val myProject: Project) {
...
@@ -128,17 +128,6 @@ class SkikoProperties(private val myProject: Project) {
val
isRelease
:
Boolean
val
isRelease
:
Boolean
get
()
=
myProject
.
findProperty
(
"deploy.release"
)
==
"true"
get
()
=
myProject
.
findProperty
(
"deploy.release"
)
==
"true"
val
signArtifacts
:
Boolean
get
()
=
myProject
.
findProperty
(
"deploy.sign"
)
==
"true"
val
signArtifactsKey
:
String
get
()
=
System
.
getenv
(
"MAVEN_ARTIFACTS_SIGN_KEY"
)
?:
error
(
"Environment variable 'MAVEN_ARTIFACTS_SIGN_KEY' is not specified"
)
val
signArtifactsPassword
:
String
get
()
=
System
.
getenv
(
"MAVEN_ARTIFACTS_SIGN_PASSWORD"
)
?:
error
(
"Environment variable 'MAVEN_ARTIFACTS_SIGN_PASSWORD' is not specified"
)
val
buildType
:
SkiaBuildType
val
buildType
:
SkiaBuildType
get
()
=
if
(
myProject
.
findProperty
(
"skiko.debug"
)
==
"true"
)
SkiaBuildType
.
DEBUG
else
SkiaBuildType
.
RELEASE
get
()
=
if
(
myProject
.
findProperty
(
"skiko.debug"
)
==
"true"
)
SkiaBuildType
.
DEBUG
else
SkiaBuildType
.
RELEASE
...
@@ -189,51 +178,6 @@ class SkikoProperties(private val myProject: Project) {
...
@@ -189,51 +178,6 @@ class SkikoProperties(private val myProject: Project) {
val
dependenciesDir
:
File
val
dependenciesDir
:
File
get
()
=
myProject
.
rootProject
.
projectDir
.
resolve
(
"dependencies"
)
get
()
=
myProject
.
rootProject
.
projectDir
.
resolve
(
"dependencies"
)
val
mavenCentral
=
MavenCentralProperties
(
myProject
)
}
class
MavenCentralProperties
(
private
val
myProject
:
Project
)
{
private
fun
propertyProvider
(
property
:
String
,
envVar
:
String
?
=
null
,
defaultValue
:
String
?
=
null
):
Provider
<
String
>
{
val
providers
=
myProject
.
providers
var
result
=
providers
.
gradleProperty
(
property
)
if
(
envVar
!=
null
)
{
result
=
result
.
orElse
(
providers
.
environmentVariable
(
envVar
))
}
if
(
defaultValue
!=
null
)
{
result
=
result
.
orElse
(
defaultValue
)
}
else
{
result
=
result
.
orElse
(
providers
.
provider
{
val
envVarMessage
=
if
(
envVar
!=
null
)
" or '$envVar' environment variable"
else
""
error
(
"Provide value for '$property' Gradle property$envVarMessage"
)
})
}
return
result
}
private
fun
environmentVariable
(
variable
:
String
)
=
myProject
.
providers
.
environmentVariable
(
variable
)
val
version
:
Provider
<
String
>
=
propertyProvider
(
"maven.central.version"
)
val
user
:
Provider
<
String
>
=
propertyProvider
(
"maven.central.user"
,
envVar
=
"MAVEN_CENTRAL_USER"
)
val
password
:
Provider
<
String
>
=
propertyProvider
(
"maven.central.password"
,
envVar
=
"MAVEN_CENTRAL_PASSWORD"
)
val
autoCommitOnSuccess
:
Provider
<
Boolean
>
=
propertyProvider
(
"maven.central.staging.auto.commit"
,
defaultValue
=
"false"
)
.
map
{
it
.
toBoolean
()
}
val
autoDropOnError
:
Provider
<
Boolean
>
=
propertyProvider
(
"maven.central.staging.auto.drop"
,
defaultValue
=
"false"
)
.
map
{
it
.
toBoolean
()
}
}
}
object
SkikoArtifacts
{
object
SkikoArtifacts
{
...
...
skiko/ci/build.gradle.kts
View file @
2bc9c86e
import
org.kohsuke.github.*
import
org.kohsuke.github.*
import
org.jetbrains.compose.internal.
gradle.
publishing.*
import
org.jetbrains.compose.internal.publishing.*
val
skiko
=
SkikoProperties
(
project
)
val
skiko
=
SkikoProperties
(
project
)
val
GITHUB_REPO
=
"JetBrains/skiko"
val
GITHUB_REPO
=
"JetBrains/skiko"
...
@@ -73,22 +73,22 @@ fun skikoMavenModules(version: Provider<String>): Provider<List<ModuleToUpload>>
...
@@ -73,22 +73,22 @@ fun skikoMavenModules(version: Provider<String>): Provider<List<ModuleToUpload>>
}
}
}
}
val
mavenCentral
=
MavenCentralProperties
(
project
)
val
downloadSkikoArtifactsFromComposeDev
by
tasks
.
registering
(
DownloadFromSpaceMavenRepoTask
::
class
)
{
val
downloadSkikoArtifactsFromComposeDev
by
tasks
.
registering
(
DownloadFromSpaceMavenRepoTask
::
class
)
{
modulesToDownload
.
set
(
skikoMavenModules
(
skiko
.
mavenCentral
.
version
))
modulesToDownload
.
set
(
skikoMavenModules
(
mavenCentral
.
version
))
spaceRepoUrl
.
set
(
"https://maven.pkg.jetbrains.space/public/p/compose/dev"
)
spaceRepoUrl
.
set
(
"https://maven.pkg.jetbrains.space/public/p/compose/dev"
)
}
}
val
uploadSkikoArtifactsToMavenCentral
by
tasks
.
registering
(
UploadToSonatypeTask
::
class
)
{
val
uploadSkikoArtifactsToMavenCentral
by
tasks
.
registering
(
UploadToSonatypeTask
::
class
)
{
dependsOn
(
downloadSkikoArtifactsFromComposeDev
)
dependsOn
(
downloadSkikoArtifactsFromComposeDev
)
val
central
=
skiko
.
mavenCentral
version
.
set
(
mavenCentral
.
version
)
version
.
set
(
central
.
version
)
modulesToUpload
.
set
(
skikoMavenModules
(
mavenCentral
.
version
))
modulesToUpload
.
set
(
skikoMavenModules
(
central
.
version
))
sonatypeServer
.
set
(
"https://oss.sonatype.org"
)
sonatypeServer
.
set
(
"https://oss.sonatype.org"
)
user
.
set
(
c
entral
.
user
)
user
.
set
(
mavenC
entral
.
user
)
password
.
set
(
c
entral
.
password
)
password
.
set
(
mavenC
entral
.
password
)
autoCommitOnSuccess
.
set
(
c
entral
.
autoCommitOnSuccess
)
autoCommitOnSuccess
.
set
(
mavenC
entral
.
autoCommitOnSuccess
)
autoDropOnError
.
set
(
c
entral
.
autoDropOnError
)
autoDropOnError
.
set
(
mavenC
entral
.
autoDropOnError
)
stagingProfileName
.
set
(
"org.jetbrains.skiko"
)
stagingProfileName
.
set
(
"org.jetbrains.skiko"
)
}
}
skiko/settings.gradle.kts
View file @
2bc9c86e
pluginManagement
{
pluginManagement
{
repositories
{
repositories
{
mavenCentral
()
gradlePluginPortal
()
gradlePluginPortal
()
maven
{
}
url
=
uri
(
"https://dl.bintray.com/kotlin/kotlin-eap"
)
buildscript
{
repositories
{
mavenCentral
()
maven
(
"https://maven.pkg.jetbrains.space/public/p/compose/internal"
)
maven
(
"https://maven.pkg.jetbrains.space/public/p/space/maven"
)
}
dependencies
{
classpath
(
"org.jetbrains.compose.internal.build-helpers:publishing:0.0.2"
)
}
}
}
}
}
}
rootProject
.
name
=
"skiko"
rootProject
.
name
=
"skiko"
include
(
"ci"
)
include
(
"ci"
)
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment