From dc228a9a1fa6813c92946b1bfbcb4f01c870b95e Mon Sep 17 00:00:00 2001 From: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com> Date: Thu, 22 Jan 2026 08:46:52 -0800 Subject: [PATCH 1/5] chore: Move to release-please for publishing. --- .github/actions/ci/action.yml | 42 +++++++++++++++ .github/actions/publish/action.yml | 39 ++++++++++++++ .github/actions/publish/publish.sh | 22 ++++++++ .github/workflows/publish.yml | 78 ++++++++++++++++++++++++++++ .github/workflows/release-please.yml | 34 ++++++++++++ .ldrelease/config.yml | 21 -------- .ldrelease/publish.sh | 12 ----- .release-please-manifest.json | 3 ++ build.gradle.kts | 20 +++---- gradle.properties | 2 + release-please-config.json | 14 +++++ scripts/release.sh | 20 ------- 12 files changed, 240 insertions(+), 67 deletions(-) create mode 100644 .github/actions/ci/action.yml create mode 100644 .github/actions/publish/action.yml create mode 100755 .github/actions/publish/publish.sh create mode 100644 .github/workflows/publish.yml create mode 100644 .github/workflows/release-please.yml delete mode 100644 .ldrelease/config.yml delete mode 100755 .ldrelease/publish.sh create mode 100644 .release-please-manifest.json create mode 100644 release-please-config.json delete mode 100755 scripts/release.sh diff --git a/.github/actions/ci/action.yml b/.github/actions/ci/action.yml new file mode 100644 index 0000000..8211be0 --- /dev/null +++ b/.github/actions/ci/action.yml @@ -0,0 +1,42 @@ +name: CI Workflow +description: 'Shared CI workflow.' +inputs: + run_tests: + description: 'If true, run unit tests, otherwise skip them.' + required: false + default: 'true' + java_version: + description: 'The Java version to use.' + required: true + java_distribution: + description: 'The Java distribution to use.' + required: false + default: 'temurin' + +runs: + using: composite + steps: + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: ${{ inputs.java_distribution }} + java-version: ${{ inputs.java_version }} + + - name: Restore dependencies + shell: bash + id: restore + run: ./gradlew dependencies + + - name: Build + shell: bash + id: build + run: ./gradlew jar + + - name: Run Tests + if: steps.build.outcome == 'success' && inputs.run_tests == 'true' + shell: bash + run: ./gradlew test + + - name: Build Documentation + shell: bash + run: ./gradlew javadoc diff --git a/.github/actions/publish/action.yml b/.github/actions/publish/action.yml new file mode 100644 index 0000000..ce2fbe2 --- /dev/null +++ b/.github/actions/publish/action.yml @@ -0,0 +1,39 @@ +name: Publish Package +description: 'Publish the package to Sonatype' +inputs: + dry_run: + description: 'Is this a dry run. If so no package will be published.' + required: true + prerelease: + description: 'Is this a prerelease. If so then it will be published to the staging repository only.' + required: true + signing_key_id: + description: 'Signing key ID' + required: true + signing_key_passphrase: + description: 'Signing key passphrase' + required: true + code_signing_keyring: + description: 'The path of the code signing keyring.' + required: true + sonatype_username: + description: 'Sonatype repo username.' + required: true + sonatype_password: + description: 'Sonatype repo password.' + required: true + +runs: + using: composite + steps: + - name: Publish Library + shell: bash + env: + LD_RELEASE_IS_PRERELEASE: ${{ inputs.prerelease }} + LD_RELEASE_IS_DRYRUN: ${{ inputs.dry_run }} + SIGNING_KEY_ID: ${{ inputs.signing_key_id }} + SIGNING_KEY_PASSPHRASE: ${{ inputs.signing_key_passphrase }} + SIGNING_SECRET_KEY_RING_FILE: ${{ inputs.code_signing_keyring }} + SONATYPE_USER_NAME: ${{ inputs.sonatype_username }} + SONATYPE_PASSWORD: ${{ inputs.sonatype_password }} + run: source $GITHUB_ACTION_PATH/publish.sh diff --git a/.github/actions/publish/publish.sh b/.github/actions/publish/publish.sh new file mode 100755 index 0000000..a954c4e --- /dev/null +++ b/.github/actions/publish/publish.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -ue + +if $LD_RELEASE_IS_DRYRUN ; then + echo "Doing a dry run of publishing." +else + echo "Publishing to Sonatype" + if [ "${LD_RELEASE_IS_PRERELEASE}" == "true" ]; then + echo "PRERELEASE" + ./gradlew publishToSonatype -Psigning.keyId="${SIGNING_KEY_ID}" -Psigning.password="${SIGNING_KEY_PASSPHRASE}" -Psigning.secretKeyRingFile="${SIGNING_SECRET_KEY_RING_FILE}" -PsonatypeUsername="${SONATYPE_USER_NAME}" -PsonatypePassword="${SONATYPE_PASSWORD}" || { + echo "Gradle publish/release failed" >&2 + exit 1 + } + else + echo "RELEASE" + ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository -Psigning.keyId="${SIGNING_KEY_ID}" -Psigning.password="${SIGNING_KEY_PASSPHRASE}" -Psigning.secretKeyRingFile="${SIGNING_SECRET_KEY_RING_FILE}" -PsonatypeUsername="${SONATYPE_USER_NAME}" -PsonatypePassword="${SONATYPE_PASSWORD}" || { + echo "Gradle publish/release failed" >&2 + exit 1 + } + fi +fi diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..fce5663 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,78 @@ +name: Publish Package +on: + workflow_dispatch: + inputs: + run_tests: + description: 'If true, run unit tests, otherwise skip them.' + type: boolean + default: true + dry_run: + description: 'Is this a dry run. If so no package will be published.' + type: boolean + required: true + prerelease: + description: 'If true, then this is a prerelease and should be published to the staging repository only.' + type: boolean + required: true + workflow_call: + inputs: + run_tests: + description: 'If true, run unit tests, otherwise skip them.' + required: false + type: boolean + default: true + dry_run: + description: 'Is this a dry run. If so no package will be published.' + type: boolean + required: true + prerelease: + description: 'If true, then this is a prerelease and should be published to the staging repository only.' + type: boolean + required: true + +jobs: + build-and-publish: + runs-on: ubuntu-latest + permissions: + id-token: write + contents: write # For publishing documentation. + steps: + - uses: actions/checkout@v4 + + - name: CI check + uses: ./.github/actions/ci + with: + run_tests: ${{ inputs.run_tests }} + java_version: '11' + + - uses: launchdarkly/gh-actions/actions/release-secrets@release-secrets-v1.1.0 + name: Get secrets + with: + aws_assume_role: ${{ vars.AWS_ROLE_ARN }} + ssm_parameter_pairs: '/production/common/releasing/sonatype/username = SONATYPE_USER_NAME, + /production/common/releasing/sonatype/password = SONATYPE_PASSWORD, + /production/common/releasing/java/keyId = SIGNING_KEY_ID' + s3_path_pairs: 'launchdarkly-releaser/java/code-signing-keyring.gpg = code-signing-keyring.gpg' + + - name: Publish + uses: ./.github/actions/publish + with: + dry_run: ${{ inputs.dry_run }} + prerelease: ${{ inputs.prerelease }} + signing_key_id: ${{ env.SIGNING_KEY_ID }} + signing_key_passphrase: '' + code_signing_keyring: 'code-signing-keyring.gpg' + sonatype_username: ${{ env.SONATYPE_USER_NAME }} + sonatype_password: ${{ env.SONATYPE_PASSWORD }} + + - uses: launchdarkly/gh-actions/actions/publish-pages@publish-pages-v1.0.1 + name: 'Publish to Github pages' + if: ${{ inputs.dry_run == false }} + with: + docs_path: build/docs/javadoc + github_token: ${{ secrets.GITHUB_TOKEN }} + + - name: Dry Run Publish Docs + shell: bash + if: ${{ inputs.dry_run == true }} + run: echo "Dry run. Not publishing docs." diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 0000000..4cb365d --- /dev/null +++ b/.github/workflows/release-please.yml @@ -0,0 +1,34 @@ +name: Run Release Please + +on: + push: + branches: + - main + +jobs: + release-please: + runs-on: ubuntu-latest + + permissions: + id-token: write # Needed for OIDC to get release secrets. + contents: write # Contents and pull-requests are for release-please to make releases. + pull-requests: write + + outputs: + releases_created: ${{ steps.release.outputs.releases_created }} + + steps: + - uses: google-github-actions/release-please-action@v4 + id: release + with: + token: ${{ secrets.GITHUB_TOKEN }} + target-branch: ${{ github.ref_name }} + + call-workflow-publish: + needs: release-please + uses: ./.github/workflows/publish.yml + if: ${{ needs.release-please.outputs.releases_created == 'true' }} + with: + run_tests: true + dry_run: false + prerelease: false diff --git a/.ldrelease/config.yml b/.ldrelease/config.yml deleted file mode 100644 index 210fbba..0000000 --- a/.ldrelease/config.yml +++ /dev/null @@ -1,21 +0,0 @@ -version: 2 - -jobs: - - docker: - image: gradle:7.6-jdk11 - template: - name: gradle - -branches: - - name: main - - name: 2.x - - name: 1.x - -publications: - - url: https://oss.sonatype.org/content/groups/public/com/launchdarkly/okhttp-eventsource/ - description: Sonatype - - url: https://javadoc.io/doc/com.launchdarkly/okhttp-eventsource - description: documentation (javadoc.io) - -documentation: - gitHubPages: true diff --git a/.ldrelease/publish.sh b/.ldrelease/publish.sh deleted file mode 100755 index 677f638..0000000 --- a/.ldrelease/publish.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -set -ue - -# Publish to Sonatype -echo "Publishing to Sonatype" -if [[ -n "${LD_RELEASE_IS_PRERELEASE}" ]]; then - ./gradlew publishToSonatype || { echo "Gradle publish/release failed" >&2; exit 1; } -else - ./gradlew publishToSonatype closeAndReleaseRepository || { echo "Gradle publish/release failed" >&2; exit 1; } -fi - diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..9965c41 --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "4.1.1" +} diff --git a/build.gradle.kts b/build.gradle.kts index 4c5f75f..7f7ccff 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,9 +3,9 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.external.javadoc.CoreJavadocOptions import org.gradle.external.javadoc.StandardJavadocDocletOptions -// These values come from gradle.properties -val ossrhUsername: String by project -val ossrhPassword: String by project +// These values come from gradle.properties or command line +val ossrhUsername: String? by project +val ossrhPassword: String? by project buildscript { repositories { @@ -23,8 +23,7 @@ plugins { "maven-publish" idea id("org.jetbrains.kotlin.jvm") version "1.6.10" - id("de.marcphilipp.nexus-publish") version "0.4.0" - id("io.codearte.nexus-staging") version "0.30.0" + id("io.github.gradle-nexus.publish-plugin") version "1.3.0" } // Note about org.jetbrains.kotlin.jvm in the plugins block: @@ -179,11 +178,6 @@ idea { } } -nexusStaging { - packageGroup = "com.launchdarkly" - numberOfRetries = 40 // we've seen extremely long delays in closing repositories -} - publishing { publications { create("mavenJava") { @@ -224,13 +218,11 @@ publishing { nexusPublishing { clientTimeout.set(Duration.ofMinutes(2)) // we've seen extremely long delays in creating repositories repositories { - sonatype { - username.set(ossrhUsername) - password.set(ossrhPassword) - } + sonatype() } } signing { + setRequired({ findProperty("skipSigning") != "true" }) sign(publishing.publications["mavenJava"]) } diff --git a/gradle.properties b/gradle.properties index ed90211..a9d4507 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,6 @@ +# x-release-please-start-version version=4.1.1 +# x-release-please-end ossrhUsername= ossrhPassword= diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 0000000..392c98e --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,14 @@ +{ + "bootstrap-sha": "7cccc52e3859f8884b203fc80b52ad12c2203b08", + "packages": { + ".": { + "release-type": "simple", + "versioning": "default", + "include-v-in-tag": false, + "include-component-in-tag": false, + "extra-files": [ + "gradle.properties" + ] + } + } +} diff --git a/scripts/release.sh b/scripts/release.sh deleted file mode 100755 index 52b6f92..0000000 --- a/scripts/release.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -# This script updates the version for the okhttp-eventsource library and releases the artifact + javadoc -# It will only work if you have the proper credentials set up in ~/.gradle/gradle.properties - -# It takes exactly one argument: the new version. -# It should be run from the root of this git repo like this: -# ./scripts/release.sh 4.0.9 - -# When done you should commit and push the changes made. - -set -uxe -echo "Starting okhttp-eventsource release." - -VERSION=$1 - -#Update version in gradle.properties file: -sed -i '' "s/^version.*$/version=${VERSION}/" gradle.properties - -./gradlew clean test install sourcesJar javadocJar uploadArchives closeAndReleaseRepository -echo "Finished okhttp-eventsource release." From ed7c25d6970851571b1f6dc6486096e99df1f8d4 Mon Sep 17 00:00:00 2001 From: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:21:24 -0800 Subject: [PATCH 2/5] Pin SHAs. --- .github/actions/ci/action.yml | 42 ---------------------------- .github/workflows/publish.yml | 15 ++++------ .github/workflows/release-please.yml | 3 +- 3 files changed, 8 insertions(+), 52 deletions(-) delete mode 100644 .github/actions/ci/action.yml diff --git a/.github/actions/ci/action.yml b/.github/actions/ci/action.yml deleted file mode 100644 index 8211be0..0000000 --- a/.github/actions/ci/action.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: CI Workflow -description: 'Shared CI workflow.' -inputs: - run_tests: - description: 'If true, run unit tests, otherwise skip them.' - required: false - default: 'true' - java_version: - description: 'The Java version to use.' - required: true - java_distribution: - description: 'The Java distribution to use.' - required: false - default: 'temurin' - -runs: - using: composite - steps: - - name: Setup Java - uses: actions/setup-java@v4 - with: - distribution: ${{ inputs.java_distribution }} - java-version: ${{ inputs.java_version }} - - - name: Restore dependencies - shell: bash - id: restore - run: ./gradlew dependencies - - - name: Build - shell: bash - id: build - run: ./gradlew jar - - - name: Run Tests - if: steps.build.outcome == 'success' && inputs.run_tests == 'true' - shell: bash - run: ./gradlew test - - - name: Build Documentation - shell: bash - run: ./gradlew javadoc diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index fce5663..d5ecf5f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -37,15 +37,11 @@ jobs: id-token: write contents: write # For publishing documentation. steps: - - uses: actions/checkout@v4 + # https://github.com/actions/checkout/releases/tag/v4.3.1 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - - name: CI check - uses: ./.github/actions/ci - with: - run_tests: ${{ inputs.run_tests }} - java_version: '11' - - - uses: launchdarkly/gh-actions/actions/release-secrets@release-secrets-v1.1.0 + # https://github.com/launchdarkly/gh-actions/releases/tag/release-secrets-v1.1.0 + - uses: launchdarkly/gh-actions/actions/release-secrets@dfe04d7415f4bb5f7529c9208abb0a9c13cfaa4e # release-secrets-v1.1.0 name: Get secrets with: aws_assume_role: ${{ vars.AWS_ROLE_ARN }} @@ -65,7 +61,8 @@ jobs: sonatype_username: ${{ env.SONATYPE_USER_NAME }} sonatype_password: ${{ env.SONATYPE_PASSWORD }} - - uses: launchdarkly/gh-actions/actions/publish-pages@publish-pages-v1.0.1 + # https://github.com/launchdarkly/gh-actions/releases/tag/publish-pages-v1.0.1 + - uses: launchdarkly/gh-actions/actions/publish-pages@d73db5e96be542144389c8c4b094844ab0f373bc # publish-pages-v1.0.1 name: 'Publish to Github pages' if: ${{ inputs.dry_run == false }} with: diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 4cb365d..6a12a7d 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -18,7 +18,8 @@ jobs: releases_created: ${{ steps.release.outputs.releases_created }} steps: - - uses: google-github-actions/release-please-action@v4 + # https://github.com/google-github-actions/release-please-action/releases/tag/v4.1.1 + - uses: google-github-actions/release-please-action@e4dc86ba9405554aeba3c6bb2d169500e7d3b4ee # v4.1.1 id: release with: token: ${{ secrets.GITHUB_TOKEN }} From 043f579ec09a9f0c81e2323fb733d7f43ae66d41 Mon Sep 17 00:00:00 2001 From: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:30:03 -0800 Subject: [PATCH 3/5] fix: Use backticks for plugin names in Kotlin DSL The string notation ("java-library", "maven-publish") was causing Gradle configuration errors. The correct Kotlin DSL syntax uses backticks for built-in plugin names. --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7f7ccff..c9a7aaa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,11 +16,11 @@ buildscript { plugins { java - "java-library" + `java-library` checkstyle jacoco signing - "maven-publish" + `maven-publish` idea id("org.jetbrains.kotlin.jvm") version "1.6.10" id("io.github.gradle-nexus.publish-plugin") version "1.3.0" From 9ac6ff20abb5314f8ac4e058097a705c2a4cb5b7 Mon Sep 17 00:00:00 2001 From: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:41:10 -0800 Subject: [PATCH 4/5] fix: Apply nexus-publish plugin only to root project The contract tests use a multi-project build where the main project becomes a subproject called :eventsource. The nexus-publish plugin must only be applied to root projects, so we conditionally apply it and configure it only when project == rootProject. --- build.gradle.kts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index c9a7aaa..b51c1b4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -23,7 +23,7 @@ plugins { `maven-publish` idea id("org.jetbrains.kotlin.jvm") version "1.6.10" - id("io.github.gradle-nexus.publish-plugin") version "1.3.0" + id("io.github.gradle-nexus.publish-plugin") version "1.3.0" apply false } // Note about org.jetbrains.kotlin.jvm in the plugins block: @@ -46,6 +46,12 @@ repositories { mavenCentral() } +// Apply nexus-publish plugin only when this is the root project +// (contract tests include this as a subproject, which would fail) +if (project == rootProject) { + apply(plugin = "io.github.gradle-nexus.publish-plugin") +} + base { group = "com.launchdarkly" archivesBaseName = "okhttp-eventsource" @@ -215,10 +221,13 @@ publishing { } } -nexusPublishing { - clientTimeout.set(Duration.ofMinutes(2)) // we've seen extremely long delays in creating repositories - repositories { - sonatype() +// Only configure nexus publishing when this is the root project +if (project == rootProject) { + configure { + clientTimeout.set(Duration.ofMinutes(2)) // we've seen extremely long delays in creating repositories + repositories { + sonatype() + } } } From e7560db7fb8286a9ef25fb67752ec95f560525d1 Mon Sep 17 00:00:00 2001 From: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:42:35 -0800 Subject: [PATCH 5/5] Build docs before publishing them, --- .github/workflows/publish.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d5ecf5f..e67e2a7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -61,6 +61,10 @@ jobs: sonatype_username: ${{ env.SONATYPE_USER_NAME }} sonatype_password: ${{ env.SONATYPE_PASSWORD }} + - name: Build Documentation + shell: bash + run: ./gradlew javadoc + # https://github.com/launchdarkly/gh-actions/releases/tag/publish-pages-v1.0.1 - uses: launchdarkly/gh-actions/actions/publish-pages@d73db5e96be542144389c8c4b094844ab0f373bc # publish-pages-v1.0.1 name: 'Publish to Github pages'