Skip to content

Commit

Permalink
Merge branch 'ktorio:main' into issue/KTOR-7470
Browse files Browse the repository at this point in the history
  • Loading branch information
stokado authored Nov 10, 2024
2 parents 2831967 + 52e20f6 commit fc2a59e
Show file tree
Hide file tree
Showing 75 changed files with 2,021 additions and 611 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# 3.0.1
> Published 29 October 2024
### Bugfixes
* Remove space from the default client user agent ([KTOR-7655](https://youtrack.jetbrains.com/issue/KTOR-7655))
* `Url.segments` throws on URLs with root path ([KTOR-7625](https://youtrack.jetbrains.com/issue/KTOR-7625))
* Digest Auth does not implement nc parameter correctly according to RFC 7616 ([KTOR-4318](https://youtrack.jetbrains.com/issue/KTOR-4318))
* about:blank URL should be parsed correctly as about:blank ([KTOR-7410](https://youtrack.jetbrains.com/issue/KTOR-7410))
* ByteReadChannel.{readShort/readInt/readLong} could lead to CPU-bound indefinite loop since 3.0.0 ([KTOR-7571](https://youtrack.jetbrains.com/issue/KTOR-7571))
* CIO: Requests face connection timeouts when executed on the Android main dispatcher ([KTOR-6803](https://youtrack.jetbrains.com/issue/KTOR-6803))
* receiveMultipart fails with "IOException: Failed to parse multipart" when content-type is capitalized ([KTOR-7596](https://youtrack.jetbrains.com/issue/KTOR-7596))

### Improvements
* WebSockets logging: The plugin calls toString() unnecessarily on transformed response body ([KTOR-7623](https://youtrack.jetbrains.com/issue/KTOR-7623))
* INFO log message with all server interceptors on server startup ([KTOR-7326](https://youtrack.jetbrains.com/issue/KTOR-7326))
* Digest auth: `username` and `cnonce` parameters aren't surrounded with quotes ([KTOR-7561](https://youtrack.jetbrains.com/issue/KTOR-7561))
* ContentType.fromFilePath for newer file formats HEIC, AVIF, HEIF ([KTOR-7536](https://youtrack.jetbrains.com/issue/KTOR-7536))
* Support missing native targets in ktor-serialization-kotlinx-xml ([KTOR-7583](https://youtrack.jetbrains.com/issue/KTOR-7583))


# 3.0.0
> Published 9 October 2024
Expand Down
53 changes: 7 additions & 46 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,11 @@
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

import org.gradle.api.Project
import org.jetbrains.dokka.gradle.*
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.tasks.*
import org.jetbrains.kotlin.konan.target.*

buildscript {
/*
* These property group is used to build ktor against Kotlin compiler snapshot.
* How does it work:
* When build_snapshot_train is set to true, kotlin_version property is overridden with kotlin_snapshot_version,
* atomicfu_version, coroutines_version, serialization_version and kotlinx_io_version are overwritten by TeamCity environment.
* Additionally, mavenLocal and Sonatype snapshots are added to repository list and stress tests are disabled.
* DO NOT change the name of these properties without adapting kotlinx.train build chain.
*/
extra["build_snapshot_train"] = rootProject.properties["build_snapshot_train"]
val build_snapshot_train: String? by extra

if (build_snapshot_train.toBoolean()) {
extra["kotlin_version"] = rootProject.properties["kotlin_snapshot_version"]
val kotlin_version: String? by extra
if (kotlin_version == null) {
throw IllegalArgumentException(
"'kotlin_snapshot_version' should be defined when building with snapshot compiler",
)
}
repositories {
maven(url = "https://oss.sonatype.org/content/repositories/snapshots") {
mavenContent { snapshotsOnly() }
}
mavenLocal()
}

configurations.classpath {
resolutionStrategy.eachDependency {
if (requested.group == "org.jetbrains.kotlin") {
useVersion(kotlin_version!!)
}
}
}
}

repositories {
mavenCentral()
google()
gradlePluginPortal()
mavenLocal()
}
}

val releaseVersion: String? by extra
val eapVersion: String? by extra
val version = (project.version as String).let { if (it.endsWith("-SNAPSHOT")) it.dropLast("-SNAPSHOT".length) else it }
Expand Down Expand Up @@ -122,6 +77,7 @@ subprojects {
apply(plugin = "atomicfu-conventions")

configureTargets()
if (CI) configureTestTasksOnCi()

configurations {
maybeCreate("testOutput")
Expand All @@ -132,6 +88,11 @@ subprojects {

configureSourceSets()
setupJvmToolchain()

compilerOptions {
languageVersion = getKotlinLanguageVersion()
apiVersion = getKotlinApiVersion()
}
}

val skipPublish: List<String> by rootProject.extra
Expand All @@ -142,7 +103,7 @@ subprojects {
configureCodestyle()
}

println("Using Kotlin compiler version: ${org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION}")
println("Using Kotlin compiler version: ${libs.versions.kotlin.get()}")
filterSnapshotTests()

fun configureDokka() {
Expand Down
22 changes: 6 additions & 16 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,17 @@ plugins {
kotlin("plugin.serialization") version embeddedKotlinVersion
}

val buildSnapshotTrain = properties["build_snapshot_train"]?.toString().toBoolean()

repositories {
mavenCentral()
gradlePluginPortal()
maven("https://maven.pkg.jetbrains.space/public/p/ktor/eap")
if (buildSnapshotTrain) {
mavenLocal()
}
}

val ktor_version = "3.0.1-eap-1114"
val ktor_version = "3.1.0-eap-1130"

dependencies {
val kotlin_version = libs.versions.kotlin.get()
implementation(kotlin("gradle-plugin", kotlin_version))
implementation(kotlin("serialization", kotlin_version))
implementation(libs.kotlin.gradlePlugin)
implementation(libs.kotlin.serialization)

val ktlint_version = libs.versions.ktlint.get()
implementation("org.jmailen.gradle:kotlinter-gradle:$ktlint_version")

implementation(libs.develocity)

implementation("io.ktor:ktor-server-default-headers:$ktor_version")
implementation("io.ktor:ktor-server-netty:$ktor_version")
implementation("io.ktor:ktor-server-cio:$ktor_version")
Expand All @@ -48,7 +38,7 @@ dependencies {
implementation(libs.kotlinx.serialization.json)
implementation(libs.logback.classic)
implementation(libs.tomlj)
implementation("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${libs.versions.atomicfu.get()}")
implementation(libs.kotlinx.atomicfu.gradlePlugin)

// A hack to make version catalogs accessible from buildSrc sources
// https://github.com/gradle/gradle/issues/15383#issuecomment-779893192
Expand Down
27 changes: 16 additions & 11 deletions buildSrc/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
/*
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

pluginManagement {
val build_snapshot_train: String? by settings
repositories {
mavenCentral()
gradlePluginPortal()
if (build_snapshot_train.toBoolean()) {
mavenLocal()
}
}
includeBuild("../gradle-settings-conventions")
}

plugins {
id("conventions-dependency-resolution-management")
}

dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
// Additional repositories for buildSrc dependencies
@Suppress("UnstableApiUsage")
repositories {
gradlePluginPortal()

exclusiveContent {
forRepository {
maven("https://maven.pkg.jetbrains.space/public/p/ktor/eap") { name = "KtorEAP" }
}
filter { includeGroup("io.ktor") }
}
}
}
Expand Down
76 changes: 76 additions & 0 deletions buildSrc/src/main/kotlin/CI.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

import com.gradle.develocity.agent.gradle.test.*
import org.gradle.api.*
import org.gradle.api.tasks.testing.*
import org.gradle.kotlin.dsl.*
import org.jetbrains.kotlin.gradle.targets.jvm.tasks.*
import org.jetbrains.kotlin.gradle.tasks.*

val CI = System.getenv("TEAMCITY_VERSION") != null

/** Applies CI-specific configurations to test tasks. */
fun Project.configureTestTasksOnCi() {
// Don't fail build on the CI:
// 1. To distinct builds failed because of failed tests and because of compilation errors or anything else.
// TeamCity parses test results to define build status, so the build won't be green.
// 2. To run as many tests as possible while keeping fail-fast behavior locally.
tasks.withType<AbstractTestTask>().configureEach {
ignoreFailures = true
if (this is KotlinTest) ignoreRunFailures = true
}
// KotlinTestReport overwrites ignoreFailure values and fails build on test failure if this flag is disabled
extra["kotlin.tests.individualTaskReports"] = true

tasks.withType<KotlinJvmTest>().configureEach {
testRetry {
maxRetries = 1
maxFailures = 10
}

applyTestRetryCompatibilityWorkaround()
}
}

/**
* Test retry plugin is incompatible with test tasks that override the `createTestExecuter` method.
* This includes the [KotlinJvmTest] task which wraps the test executor with its own wrapper.
*
* This workaround heavily relies on the internal implementation details of the test-retry plugin and KGP.
*
* The test retry plugin adds a `doFirst` action, which:
* - Retrieves the test executer using `createTestExecuter` (KGP returns wrapped test executer here)
* - Wraps it with `RetryTestExecuter`
* - Sets the executer using `setTestExecuter`
*
* In the `doLast` action, it expects that `createTestExecuter` returns the previously created `RetryTestExecuter` instance.
* However, KGP wraps every result of `createTestExecutor` with its own wrapper, resulting in the following nesting:
* KotlinJvmTarget$Executer(RetryTestExecuter(KotlinJvmTarget$Executer(DefaultTestExecuter)))
*
* KGP wraps the executer only if `targetName` is present, as it is needed to add the target name suffix to the test name.
* The workaround sets `targetName` to `null` after the first KGP wrapper is created,
* so `createTestExecuter` returns the previously created executer:
* RetryTestExecuter(KotlinJvmTarget$Executer(DefaultTestExecuter))
*
* Issue: https://github.com/gradle/test-retry-gradle-plugin/issues/116 (KT-49155)
*/
private fun KotlinJvmTest.applyTestRetryCompatibilityWorkaround() {
if (targetName == null) return

val executeTestsActionIndex = taskActions.indexOfLast { it.displayName == "Execute executeTests" }
check(executeTestsActionIndex != -1) { "Action executeTests not found" }

// Add the workaround action and then move it to the correct position right before tests execution.
doFirst("workaround for compatibility with testRetry") {
targetName = null
}
val injectedAction = taskActions.removeFirst()
taskActions.add(executeTestsActionIndex, injectedAction)
}

// Docs: https://docs.gradle.com/develocity/gradle-plugin/current/#test_retry
private fun Test.testRetry(configure: TestRetryConfiguration.() -> Unit) {
extensions.getByName<DevelocityTestConfiguration>("develocity").testRetry(configure)
}
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/JvmConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fun Project.configureJvm() {
tasks.register<Jar>("jarTest") {
dependsOn(tasks.named("jvmTestClasses"))
archiveClassifier = "test"
from(kotlin.jvm().compilations.named("test").map { it.output })
from(kotlin.jvm().compilations["test"].output)
}

configurations {
Expand Down
2 changes: 0 additions & 2 deletions buildSrc/src/main/kotlin/KtorBuildProperties.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ val IDEA_ACTIVE: Boolean = System.getProperty("idea.active") == "true"

val OS_NAME = System.getProperty("os.name").lowercase()

val CI = System.getenv("TEAMCITY_VERSION") != null

val HOST_NAME = when {
OS_NAME.startsWith("linux") -> "linux"
OS_NAME.startsWith("windows") -> "windows"
Expand Down
3 changes: 1 addition & 2 deletions buildSrc/src/main/kotlin/NativeUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ fun Project.watchosTargets(): List<String> = with(kotlin) {
watchosArm64(),
watchosSimulatorArm64(),
// ktor-server-config-yaml: because of dependency on YAML library: https://github.com/Him188/yamlkt/issues/67
// ktor-serialization-kotlinx-xml: because of dependency on xmlutil library: https://repo.maven.apache.org/maven2/io/github/pdvrieze/xmlutil/ // ktlint-disable max-line-length
if ((project.name != "ktor-server-config-yaml") && (project.name != "ktor-serialization-kotlinx-xml")) {
if (project.name != "ktor-server-config-yaml") {
watchosDeviceArm64()
} else {
null
Expand Down
9 changes: 0 additions & 9 deletions buildSrc/src/main/kotlin/TargetsConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,6 @@ fun Project.configureTargets() {
}
}
}

// Don't fail build on the CI:
// 1. To distinct builds failed because of failed tests and because of compilation errors or anything else.
// TeamCity parses test results to define build status, so the build won't be green.
// 2. To run as many tests as possible while keeping fail-fast behavior locally.
if (CI) tasks.withType<AbstractTestTask>().configureEach {
ignoreFailures = true
if (this is KotlinTest) ignoreRunFailures = true
}
}

private val hierarchyTemplate = KotlinHierarchyTemplate {
Expand Down
Loading

0 comments on commit fc2a59e

Please sign in to comment.