diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 03623ab..c71b847 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,7 +67,7 @@ jobs: - name: Get GitHub OIDC Token if: github.repository == 'stainless-sdks/open-transit-java' id: github-oidc - uses: actions/github-script@v6 + uses: actions/github-script@v8 with: script: core.setOutput('github_token', await core.getIDToken()); diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 21a705e..1916b02 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.0-alpha.48" + ".": "0.1.0-alpha.49" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 2764806..c330700 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 0.1.0-alpha.49 (2026-01-24) + +Full Changelog: [v0.1.0-alpha.48...v0.1.0-alpha.49](https://github.com/OneBusAway/java-sdk/compare/v0.1.0-alpha.48...v0.1.0-alpha.49) + +### Bug Fixes + +* **client:** preserve time zone in lenient date-time parsing ([99572e3](https://github.com/OneBusAway/java-sdk/commit/99572e3a8c05fb5d37d5ba1ed63aae58a49326d6)) + + +### Chores + +* **ci:** upgrade `actions/github-script` ([7501fdc](https://github.com/OneBusAway/java-sdk/commit/7501fdca0669d7c6492620d8ab92206357fd142b)) +* **internal:** correct cache invalidation for `SKIP_MOCK_TESTS` ([2625cdd](https://github.com/OneBusAway/java-sdk/commit/2625cddb2178d4c800e97f12440f51d96cc22a97)) + ## 0.1.0-alpha.48 (2026-01-22) Full Changelog: [v0.1.0-alpha.47...v0.1.0-alpha.48](https://github.com/OneBusAway/java-sdk/compare/v0.1.0-alpha.47...v0.1.0-alpha.48) diff --git a/README.md b/README.md index 97849e0..e595a78 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/org.onebusaway/onebusaway-sdk-java)](https://central.sonatype.com/artifact/org.onebusaway/onebusaway-sdk-java/0.1.0-alpha.48) -[![javadoc](https://javadoc.io/badge2/org.onebusaway/onebusaway-sdk-java/0.1.0-alpha.48/javadoc.svg)](https://javadoc.io/doc/org.onebusaway/onebusaway-sdk-java/0.1.0-alpha.48) +[![Maven Central](https://img.shields.io/maven-central/v/org.onebusaway/onebusaway-sdk-java)](https://central.sonatype.com/artifact/org.onebusaway/onebusaway-sdk-java/0.1.0-alpha.49) +[![javadoc](https://javadoc.io/badge2/org.onebusaway/onebusaway-sdk-java/0.1.0-alpha.49/javadoc.svg)](https://javadoc.io/doc/org.onebusaway/onebusaway-sdk-java/0.1.0-alpha.49) @@ -15,7 +15,7 @@ It is generated with [Stainless](https://www.stainless.com/). -The REST API documentation can be found on [developer.onebusaway.org](https://developer.onebusaway.org). Javadocs are available on [javadoc.io](https://javadoc.io/doc/org.onebusaway/onebusaway-sdk-java/0.1.0-alpha.48). +The REST API documentation can be found on [developer.onebusaway.org](https://developer.onebusaway.org). Javadocs are available on [javadoc.io](https://javadoc.io/doc/org.onebusaway/onebusaway-sdk-java/0.1.0-alpha.49). @@ -26,7 +26,7 @@ The REST API documentation can be found on [developer.onebusaway.org](https://de ### Gradle ```kotlin -implementation("org.onebusaway:onebusaway-sdk-java:0.1.0-alpha.48") +implementation("org.onebusaway:onebusaway-sdk-java:0.1.0-alpha.49") ``` ### Maven @@ -35,7 +35,7 @@ implementation("org.onebusaway:onebusaway-sdk-java:0.1.0-alpha.48") org.onebusaway onebusaway-sdk-java - 0.1.0-alpha.48 + 0.1.0-alpha.49 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 00aed79..d50e87e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "org.onebusaway" - version = "0.1.0-alpha.48" // x-release-please-version + version = "0.1.0-alpha.49" // x-release-please-version } subprojects { diff --git a/buildSrc/src/main/kotlin/onebusaway-sdk.kotlin.gradle.kts b/buildSrc/src/main/kotlin/onebusaway-sdk.kotlin.gradle.kts index 5fab5a6..fbd8fe3 100644 --- a/buildSrc/src/main/kotlin/onebusaway-sdk.kotlin.gradle.kts +++ b/buildSrc/src/main/kotlin/onebusaway-sdk.kotlin.gradle.kts @@ -33,6 +33,9 @@ kotlin { tasks.withType().configureEach { systemProperty("junit.jupiter.execution.parallel.enabled", true) systemProperty("junit.jupiter.execution.parallel.mode.default", "concurrent") + + // `SKIP_MOCK_TESTS` affects which tests run so it must be added as input for proper cache invalidation. + inputs.property("skipMockTests", System.getenv("SKIP_MOCK_TESTS")).optional(true) } val ktfmt by configurations.creating diff --git a/onebusaway-sdk-java-core/src/main/kotlin/org/onebusaway/core/ObjectMappers.kt b/onebusaway-sdk-java-core/src/main/kotlin/org/onebusaway/core/ObjectMappers.kt index 8b9c59d..ab3f530 100644 --- a/onebusaway-sdk-java-core/src/main/kotlin/org/onebusaway/core/ObjectMappers.kt +++ b/onebusaway-sdk-java-core/src/main/kotlin/org/onebusaway/core/ObjectMappers.kt @@ -25,7 +25,7 @@ import java.time.DateTimeException import java.time.LocalDate import java.time.LocalDateTime import java.time.OffsetDateTime -import java.time.ZonedDateTime +import java.time.ZoneId import java.time.format.DateTimeFormatter import java.time.temporal.ChronoField @@ -157,14 +157,15 @@ private class LenientOffsetDateTimeDeserializer : val temporal = formatter.parse(p.text) return when { - !temporal.isSupported(ChronoField.HOUR_OF_DAY) -> - LocalDate.from(temporal).atStartOfDay() - !temporal.isSupported(ChronoField.OFFSET_SECONDS) -> - LocalDateTime.from(temporal) - else -> ZonedDateTime.from(temporal).toLocalDateTime() - } - .atZone(context.timeZone.toZoneId()) - .toOffsetDateTime() + !temporal.isSupported(ChronoField.HOUR_OF_DAY) -> + LocalDate.from(temporal) + .atStartOfDay() + .atZone(ZoneId.of("UTC")) + .toOffsetDateTime() + !temporal.isSupported(ChronoField.OFFSET_SECONDS) -> + LocalDateTime.from(temporal).atZone(ZoneId.of("UTC")).toOffsetDateTime() + else -> OffsetDateTime.from(temporal) + } } catch (e: DateTimeException) { exceptions.add(e) } diff --git a/onebusaway-sdk-java-core/src/test/kotlin/org/onebusaway/core/ObjectMappersTest.kt b/onebusaway-sdk-java-core/src/test/kotlin/org/onebusaway/core/ObjectMappersTest.kt index 332f645..51f5969 100644 --- a/onebusaway-sdk-java-core/src/test/kotlin/org/onebusaway/core/ObjectMappersTest.kt +++ b/onebusaway-sdk-java-core/src/test/kotlin/org/onebusaway/core/ObjectMappersTest.kt @@ -3,12 +3,14 @@ package org.onebusaway.core import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.databind.exc.MismatchedInputException import com.fasterxml.jackson.module.kotlin.readValue +import java.time.LocalDate +import java.time.LocalTime import java.time.OffsetDateTime +import java.time.ZoneOffset import kotlin.reflect.KClass import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.catchThrowable import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.EnumSource import org.junitpioneer.jupiter.cartesian.CartesianTest @@ -72,11 +74,34 @@ internal class ObjectMappersTest { } } - enum class LenientOffsetDateTimeTestCase(val string: String) { - DATE("1998-04-21"), - DATE_TIME("1998-04-21T04:00:00"), - ZONED_DATE_TIME_1("1998-04-21T04:00:00+03:00"), - ZONED_DATE_TIME_2("1998-04-21T04:00:00Z"), + enum class LenientOffsetDateTimeTestCase( + val string: String, + val expectedOffsetDateTime: OffsetDateTime, + ) { + DATE( + "1998-04-21", + expectedOffsetDateTime = + OffsetDateTime.of(LocalDate.of(1998, 4, 21), LocalTime.of(0, 0), ZoneOffset.UTC), + ), + DATE_TIME( + "1998-04-21T04:00:00", + expectedOffsetDateTime = + OffsetDateTime.of(LocalDate.of(1998, 4, 21), LocalTime.of(4, 0), ZoneOffset.UTC), + ), + ZONED_DATE_TIME_1( + "1998-04-21T04:00:00+03:00", + expectedOffsetDateTime = + OffsetDateTime.of( + LocalDate.of(1998, 4, 21), + LocalTime.of(4, 0), + ZoneOffset.ofHours(3), + ), + ), + ZONED_DATE_TIME_2( + "1998-04-21T04:00:00Z", + expectedOffsetDateTime = + OffsetDateTime.of(LocalDate.of(1998, 4, 21), LocalTime.of(4, 0), ZoneOffset.UTC), + ), } @ParameterizedTest @@ -85,6 +110,8 @@ internal class ObjectMappersTest { val jsonMapper = jsonMapper() val json = jsonMapper.writeValueAsString(testCase.string) - assertDoesNotThrow { jsonMapper().readValue(json) } + val offsetDateTime = jsonMapper().readValue(json) + + assertThat(offsetDateTime).isEqualTo(testCase.expectedOffsetDateTime) } }