Skip to content

Commit 5c7e4e1

Browse files
authored
Merge branch 'main' into remove-deprecated-headers-standardize-readme
2 parents 9947cea + d61f7a4 commit 5c7e4e1

31 files changed

+242
-1414
lines changed

.github/workflows/ci.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ jobs:
4040
build:
4141
timeout-minutes: 15
4242
name: build
43+
permissions:
44+
contents: read
45+
id-token: write
4346
runs-on: ${{ github.repository == 'stainless-sdks/stagehand-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
4447
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
4548

@@ -61,6 +64,21 @@ jobs:
6164
- name: Build SDK
6265
run: ./scripts/build
6366

67+
- name: Get GitHub OIDC Token
68+
if: github.repository == 'stainless-sdks/stagehand-java'
69+
id: github-oidc
70+
uses: actions/github-script@v6
71+
with:
72+
script: core.setOutput('github_token', await core.getIDToken());
73+
74+
- name: Build and upload Maven artifacts
75+
if: github.repository == 'stainless-sdks/stagehand-java'
76+
env:
77+
URL: https://pkg.stainless.com/s
78+
AUTH: ${{ steps.github-oidc.outputs.github_token }}
79+
SHA: ${{ github.sha }}
80+
PROJECT: stagehand-java
81+
run: ./scripts/upload-artifacts
6482
test:
6583
timeout-minutes: 15
6684
name: test

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.5.0"
2+
".": "0.6.0"
33
}

.stats.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 7
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-39cd9547d16412cf0568f6ce2ad8d43805dffe65bde830beeff630b903ae3b38.yml
3-
openapi_spec_hash: 9cd7c9fefa686f9711392782d948470f
4-
config_hash: 3c21550e2c94cad4339d3093d794beb0
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-419940ce988c43313660d30a5bb5b5c2d89b3b19a0f80fe050331e0f4e8c58d2.yml
3+
openapi_spec_hash: a621ca69697ebba7286cbf9e475c46ad
4+
config_hash: 74111faa0876db6b053526281c444498

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# Changelog
22

3+
## 0.6.0 (2026-01-13)
4+
5+
Full Changelog: [v0.5.0...v0.6.0](https://github.com/browserbase/stagehand-java/compare/v0.5.0...v0.6.0)
6+
7+
### Features
8+
9+
* **client:** allow configuring dispatcher executor service ([b67a0d6](https://github.com/browserbase/stagehand-java/commit/b67a0d62fe7f2e15a73bc033c0a421daf88e6915))
10+
* Removed requiring x-language and x-sdk-version from openapi spec ([2690cf4](https://github.com/browserbase/stagehand-java/commit/2690cf4d826f3a356f6049a5640fd15bf6e962ee))
11+
* Using provider/model syntax in modelName examples within openapi spec ([aae3dce](https://github.com/browserbase/stagehand-java/commit/aae3dce8134b19c0bb3d24b848a73dd8a523aaec))
12+
13+
14+
### Chores
15+
16+
* **internal:** support uploading Maven repo artifacts to stainless package server ([32f6329](https://github.com/browserbase/stagehand-java/commit/32f6329e2ec8e30b1b2f701e9ed2f039e934fd49))
17+
318
## 0.5.0 (2026-01-07)
419

520
Full Changelog: [v0.4.0...v0.5.0](https://github.com/browserbase/stagehand-java/compare/v0.4.0...v0.5.0)

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ Most existing browser automation tools either require you to write low-level cod
7070
### Gradle
7171

7272
```kotlin
73-
implementation("com.browserbase.api:stagehand-java:0.5.0")
73+
implementation("com.browserbase.api:stagehand-java:0.6.0")
7474
```
7575

7676
### Maven
@@ -79,7 +79,7 @@ implementation("com.browserbase.api:stagehand-java:0.5.0")
7979
<dependency>
8080
<groupId>com.browserbase.api</groupId>
8181
<artifactId>stagehand-java</artifactId>
82-
<version>0.5.0</version>
82+
<version>0.6.0</version>
8383
</dependency>
8484
```
8585

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ repositories {
99

1010
allprojects {
1111
group = "com.browserbase.api"
12-
version = "0.5.0" // x-release-please-version
12+
version = "0.6.0" // x-release-please-version
1313
}
1414

1515
subprojects {

buildSrc/src/main/kotlin/stagehand.publish.gradle.kts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ configure<PublishingExtension> {
3939
}
4040
}
4141
}
42+
repositories {
43+
if (project.hasProperty("publishLocal")) {
44+
maven {
45+
name = "LocalFileSystem"
46+
url = uri("${rootProject.layout.buildDirectory.get()}/local-maven-repo")
47+
}
48+
}
49+
}
4250
}
4351

4452
signing {

scripts/upload-artifacts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
# ANSI Color Codes
6+
GREEN='\033[32m'
7+
RED='\033[31m'
8+
NC='\033[0m' # No Color
9+
10+
log_error() {
11+
local msg="$1"
12+
local headers="$2"
13+
local body="$3"
14+
echo -e "${RED}${msg}${NC}"
15+
[[ -f "$headers" ]] && echo -e "${RED}Headers:$(cat "$headers")${NC}"
16+
echo -e "${RED}Body: ${body}${NC}"
17+
exit 1
18+
}
19+
20+
upload_file() {
21+
local file_name="$1"
22+
local tmp_headers
23+
tmp_headers=$(mktemp)
24+
25+
if [ -f "$file_name" ]; then
26+
echo -e "${GREEN}Processing file: $file_name${NC}"
27+
pkg_file_name="mvn${file_name#./build/local-maven-repo}"
28+
29+
# Get signed URL for uploading artifact file
30+
signed_url_response=$(curl -X POST -G "$URL" \
31+
-sS --retry 5 \
32+
-D "$tmp_headers" \
33+
--data-urlencode "filename=$pkg_file_name" \
34+
-H "Authorization: Bearer $AUTH" \
35+
-H "Content-Type: application/json")
36+
37+
# Validate JSON and extract URL
38+
if ! signed_url=$(echo "$signed_url_response" | jq -e -r '.url' 2>/dev/null) || [[ "$signed_url" == "null" ]]; then
39+
log_error "Failed to get valid signed URL" "$tmp_headers" "$signed_url_response"
40+
fi
41+
42+
# Set content-type based on file extension
43+
local extension="${file_name##*.}"
44+
local content_type
45+
case "$extension" in
46+
jar) content_type="application/java-archive" ;;
47+
md5|sha1|sha256|sha512) content_type="text/plain" ;;
48+
module) content_type="application/json" ;;
49+
pom|xml) content_type="application/xml" ;;
50+
*) content_type="application/octet-stream" ;;
51+
esac
52+
53+
# Upload file
54+
upload_response=$(curl -v -X PUT \
55+
--retry 5 \
56+
-D "$tmp_headers" \
57+
-H "Content-Type: $content_type" \
58+
--data-binary "@${file_name}" "$signed_url" 2>&1)
59+
60+
if ! echo "$upload_response" | grep -q "HTTP/[0-9.]* 200"; then
61+
log_error "Failed upload artifact file" "$tmp_headers" "$upload_response"
62+
fi
63+
64+
# Insert small throttle to reduce rate limiting risk
65+
sleep 0.1
66+
fi
67+
}
68+
69+
walk_tree() {
70+
local current_dir="$1"
71+
72+
for entry in "$current_dir"/*; do
73+
# Check that entry is valid
74+
[ -e "$entry" ] || [ -h "$entry" ] || continue
75+
76+
if [ -d "$entry" ]; then
77+
walk_tree "$entry"
78+
else
79+
upload_file "$entry"
80+
fi
81+
done
82+
}
83+
84+
cd "$(dirname "$0")/.."
85+
86+
echo "::group::Creating local Maven content"
87+
./gradlew publishMavenPublicationToLocalFileSystemRepository -PpublishLocal
88+
echo "::endgroup::"
89+
90+
echo "::group::Uploading to pkg.stainless.com"
91+
walk_tree "./build/local-maven-repo"
92+
echo "::endgroup::"
93+
94+
echo "::group::Generating instructions"
95+
echo "Configure maven or gradle to use the repo located at 'https://pkg.stainless.com/s/${PROJECT}/${SHA}/mvn'"
96+
echo "::endgroup::"

stagehand-java-client-okhttp/src/main/kotlin/com/browserbase/api/client/okhttp/OkHttpClient.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ import java.net.Proxy
1515
import java.time.Duration
1616
import java.util.concurrent.CancellationException
1717
import java.util.concurrent.CompletableFuture
18+
import java.util.concurrent.ExecutorService
1819
import javax.net.ssl.HostnameVerifier
1920
import javax.net.ssl.SSLSocketFactory
2021
import javax.net.ssl.X509TrustManager
2122
import okhttp3.Call
2223
import okhttp3.Callback
24+
import okhttp3.Dispatcher
2325
import okhttp3.HttpUrl.Companion.toHttpUrl
2426
import okhttp3.MediaType
2527
import okhttp3.MediaType.Companion.toMediaType
@@ -202,6 +204,7 @@ private constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClien
202204

203205
private var timeout: Timeout = Timeout.default()
204206
private var proxy: Proxy? = null
207+
private var dispatcherExecutorService: ExecutorService? = null
205208
private var sslSocketFactory: SSLSocketFactory? = null
206209
private var trustManager: X509TrustManager? = null
207210
private var hostnameVerifier: HostnameVerifier? = null
@@ -212,6 +215,10 @@ private constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClien
212215

213216
fun proxy(proxy: Proxy?) = apply { this.proxy = proxy }
214217

218+
fun dispatcherExecutorService(dispatcherExecutorService: ExecutorService?) = apply {
219+
this.dispatcherExecutorService = dispatcherExecutorService
220+
}
221+
215222
fun sslSocketFactory(sslSocketFactory: SSLSocketFactory?) = apply {
216223
this.sslSocketFactory = sslSocketFactory
217224
}
@@ -233,6 +240,8 @@ private constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClien
233240
.callTimeout(timeout.request())
234241
.proxy(proxy)
235242
.apply {
243+
dispatcherExecutorService?.let { dispatcher(Dispatcher(it)) }
244+
236245
val sslSocketFactory = sslSocketFactory
237246
val trustManager = trustManager
238247
if (sslSocketFactory != null && trustManager != null) {

stagehand-java-client-okhttp/src/main/kotlin/com/browserbase/api/client/okhttp/StagehandOkHttpClient.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import java.time.Clock
1818
import java.time.Duration
1919
import java.util.Optional
2020
import java.util.concurrent.Executor
21+
import java.util.concurrent.ExecutorService
2122
import javax.net.ssl.HostnameVerifier
2223
import javax.net.ssl.SSLSocketFactory
2324
import javax.net.ssl.X509TrustManager
@@ -46,11 +47,31 @@ class StagehandOkHttpClient private constructor() {
4647
class Builder internal constructor() {
4748

4849
private var clientOptions: ClientOptions.Builder = ClientOptions.builder()
50+
private var dispatcherExecutorService: ExecutorService? = null
4951
private var proxy: Proxy? = null
5052
private var sslSocketFactory: SSLSocketFactory? = null
5153
private var trustManager: X509TrustManager? = null
5254
private var hostnameVerifier: HostnameVerifier? = null
5355

56+
/**
57+
* The executor service to use for running HTTP requests.
58+
*
59+
* Defaults to OkHttp's
60+
* [default executor service](https://github.com/square/okhttp/blob/ace792f443b2ffb17974f5c0d1cecdf589309f26/okhttp/src/commonJvmAndroid/kotlin/okhttp3/Dispatcher.kt#L98-L104).
61+
*
62+
* This class takes ownership of the executor service and shuts it down when closed.
63+
*/
64+
fun dispatcherExecutorService(dispatcherExecutorService: ExecutorService?) = apply {
65+
this.dispatcherExecutorService = dispatcherExecutorService
66+
}
67+
68+
/**
69+
* Alias for calling [Builder.dispatcherExecutorService] with
70+
* `dispatcherExecutorService.orElse(null)`.
71+
*/
72+
fun dispatcherExecutorService(dispatcherExecutorService: Optional<ExecutorService>) =
73+
dispatcherExecutorService(dispatcherExecutorService.getOrNull())
74+
5475
fun proxy(proxy: Proxy?) = apply { this.proxy = proxy }
5576

5677
/** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */
@@ -320,6 +341,7 @@ class StagehandOkHttpClient private constructor() {
320341
OkHttpClient.builder()
321342
.timeout(clientOptions.timeout())
322343
.proxy(proxy)
344+
.dispatcherExecutorService(dispatcherExecutorService)
323345
.sslSocketFactory(sslSocketFactory)
324346
.trustManager(trustManager)
325347
.hostnameVerifier(hostnameVerifier)

0 commit comments

Comments
 (0)