Skip to content

Commit 6f0c71e

Browse files
authored
Merge pull request #43 from imagekit-developer/stainless/release
Release SDK updates
2 parents 2c6dc90 + 6ed1781 commit 6f0c71e

63 files changed

Lines changed: 521 additions & 143 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
lint:
1919
timeout-minutes: 15
2020
name: lint
21-
runs-on: ${{ github.repository == 'stainless-sdks/imagekit-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
21+
runs-on: ubuntu-latest
2222
if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
2323

2424
steps:
@@ -45,7 +45,7 @@ jobs:
4545
permissions:
4646
contents: read
4747
id-token: write
48-
runs-on: ${{ github.repository == 'stainless-sdks/imagekit-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
48+
runs-on: ubuntu-latest
4949
if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
5050

5151
steps:
@@ -66,44 +66,6 @@ jobs:
6666
- name: Build SDK
6767
run: ./scripts/build
6868

69-
- name: Get GitHub OIDC Token
70-
if: |-
71-
github.repository == 'stainless-sdks/imagekit-java' &&
72-
!startsWith(github.ref, 'refs/heads/stl/')
73-
id: github-oidc
74-
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
75-
with:
76-
script: core.setOutput('github_token', await core.getIDToken());
7769

78-
- name: Build and upload Maven artifacts
79-
if: |-
80-
github.repository == 'stainless-sdks/imagekit-java' &&
81-
!startsWith(github.ref, 'refs/heads/stl/')
82-
env:
83-
URL: https://pkg.stainless.com/s
84-
AUTH: ${{ steps.github-oidc.outputs.github_token }}
85-
SHA: ${{ github.sha }}
86-
PROJECT: imagekit-java
87-
run: ./scripts/upload-artifacts
88-
test:
89-
timeout-minutes: 15
90-
name: test
91-
runs-on: ${{ github.repository == 'stainless-sdks/imagekit-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
92-
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
93-
steps:
94-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
95-
96-
- name: Set up Java
97-
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
98-
with:
99-
distribution: temurin
100-
java-version: |
101-
8
102-
21
103-
cache: gradle
10470

105-
- name: Set up Gradle
106-
uses: gradle/gradle-build-action@a8f75513eafdebd8141bd1cd4e30fcd194af8dfa # v2.12.0
10771

108-
- name: Run tests
109-
run: ./scripts/test

.github/workflows/release-doctor.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ jobs:
1818
run: |
1919
bash ./bin/check-release-environment
2020
env:
21+
RELEASE_PLEASE_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN }}
2122
SONATYPE_USERNAME: ${{ secrets.IMAGE_KIT_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }}
2223
SONATYPE_PASSWORD: ${{ secrets.IMAGE_KIT_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }}
2324
GPG_SIGNING_KEY: ${{ secrets.IMAGE_KIT_SONATYPE_GPG_SIGNING_KEY || secrets.GPG_SIGNING_KEY }}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Release Please
2+
on:
3+
push:
4+
branches:
5+
- master
6+
7+
permissions:
8+
contents: write
9+
pull-requests: write
10+
11+
jobs:
12+
release-please:
13+
if: github.repository == 'imagekit-developer/imagekit-java'
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1
18+
id: release
19+
with:
20+
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}

.github/workflows/stlc-promote.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: Promote SDKs
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
promote:
12+
runs-on: ubuntu-latest
13+
env:
14+
PRODUCTION_REPO: imagekit-developer/imagekit-java
15+
PRODUCTION_BRANCH: master
16+
GH_TOKEN: ${{ secrets.SDK_WRITE_TOKEN }}
17+
steps:
18+
- name: Check out staging
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
persist-credentials: false
23+
24+
- name: Fetch production main
25+
run: |
26+
git remote add production \
27+
"https://x-access-token:${GH_TOKEN}@github.com/${PRODUCTION_REPO}.git"
28+
git fetch production "${PRODUCTION_BRANCH}"
29+
30+
- name: Check if production is already in sync
31+
id: diff
32+
run: |
33+
STAGING_SHA=$(git rev-parse origin/main)
34+
PRODUCTION_SHA=$(git rev-parse production/${PRODUCTION_BRANCH})
35+
if [ "$STAGING_SHA" = "$PRODUCTION_SHA" ]; then
36+
echo "Production is already at $STAGING_SHA. Nothing to release."
37+
echo "synced=true" >> "$GITHUB_OUTPUT"
38+
else
39+
echo "synced=false" >> "$GITHUB_OUTPUT"
40+
fi
41+
42+
- name: Push staging main to the release branch on production
43+
if: steps.diff.outputs.synced == 'false'
44+
run: |
45+
git push production origin/main:refs/heads/stainless/release --force
46+
47+
- name: Open or update the release PR on production
48+
if: steps.diff.outputs.synced == 'false'
49+
run: |
50+
EXISTING_PR=$(gh pr list \
51+
--repo "${PRODUCTION_REPO}" \
52+
--head stainless/release \
53+
--state open \
54+
--json number \
55+
--jq '.[0].number')
56+
if [ -z "${EXISTING_PR}" ]; then
57+
gh pr create \
58+
--repo "${PRODUCTION_REPO}" \
59+
--base "${PRODUCTION_BRANCH}" \
60+
--head stainless/release \
61+
--title "Release SDK updates" \
62+
--body "$(git log --oneline production/${PRODUCTION_BRANCH}..origin/main)"
63+
else
64+
echo "Release PR #${EXISTING_PR} already exists. Force-push has updated it."
65+
fi
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Sync Release-As from release PR title
2+
3+
on:
4+
pull_request:
5+
types: [edited]
6+
7+
permissions:
8+
contents: write
9+
10+
jobs:
11+
sync:
12+
if: >-
13+
github.event.pull_request.base.ref == 'master' &&
14+
startsWith(github.event.pull_request.head.ref, 'release-please--') &&
15+
github.event.changes.title != null
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Extract versions from old and new title
19+
id: parse
20+
env:
21+
NEW_TITLE: ${{ github.event.pull_request.title }}
22+
OLD_TITLE: ${{ github.event.changes.title.from }}
23+
run: |
24+
# Anchored on pull-request-title-pattern "release: ${version}" from release-please-config.json.
25+
extract() {
26+
echo "$1" | grep -oE '^release:[[:space:]]+v?[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?' \
27+
| sed -E 's/^release:[[:space:]]+v?//'
28+
}
29+
NEW_VERSION=$(extract "$NEW_TITLE")
30+
OLD_VERSION=$(extract "$OLD_TITLE")
31+
echo "old=$OLD_VERSION"
32+
echo "new=$NEW_VERSION"
33+
if [ -z "$NEW_VERSION" ]; then
34+
echo "::notice::No semver in new title; nothing to do."
35+
echo "skip=true" >> "$GITHUB_OUTPUT"
36+
exit 0
37+
fi
38+
if [ "$NEW_VERSION" = "$OLD_VERSION" ]; then
39+
echo "::notice::Version unchanged ($NEW_VERSION); not pushing."
40+
echo "skip=true" >> "$GITHUB_OUTPUT"
41+
exit 0
42+
fi
43+
echo "version=$NEW_VERSION" >> "$GITHUB_OUTPUT"
44+
45+
- name: Check out master
46+
if: steps.parse.outputs.skip != 'true'
47+
uses: actions/checkout@v6
48+
with:
49+
ref: master
50+
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
51+
fetch-depth: 1
52+
53+
- name: Push empty Release-As commit
54+
if: steps.parse.outputs.skip != 'true'
55+
env:
56+
VERSION: ${{ steps.parse.outputs.version }}
57+
run: |
58+
git config user.name "release-as-bot"
59+
git config user.email "release-as-bot@users.noreply.github.com"
60+
git commit --allow-empty -m "chore: pin next release
61+
62+
Release-As: ${VERSION}"
63+
git push origin master

.stats.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
11
configured_endpoints: 47
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/imagekit-inc/imagekit-01267e4c07ec30011b8445babed88fbd2133b65198f42d0310b7ab39c74751d4.yml
3-
openapi_spec_hash: 7c103e2dff0edcbeea82057e62f58d4d
4-
config_hash: 7ef70b333059ca21bef0f0a6d4cbb282

bin/check-release-environment

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
errors=()
44

5+
if [ -z "${RELEASE_PLEASE_TOKEN}" ]; then
6+
errors+=("The RELEASE_PLEASE_TOKEN secret has not been set. Create a fine-grained GitHub PAT and add it as a repository secret.")
7+
fi
8+
59
if [ -z "${SONATYPE_USERNAME}" ]; then
610
errors+=("The SONATYPE_USERNAME secret has not been set. Please set it in either this repository's secrets or your organization secrets")
711
fi

image-kit-java-client-okhttp/src/main/kotlin/io/imagekit/client/okhttp/ImageKitOkHttpClient.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ class ImageKitOkHttpClient private constructor() {
308308
* Your ImageKit webhook secret for verifying webhook signatures (starts with `whsec_`). You
309309
* can find this in the
310310
* [ImageKit dashboard](https://imagekit.io/dashboard/developer/webhooks). Only required if
311-
* you're using webhooks.
311+
* you are using webhooks.
312312
*/
313313
fun webhookSecret(webhookSecret: String?) = apply {
314314
clientOptions.webhookSecret(webhookSecret)

image-kit-java-client-okhttp/src/main/kotlin/io/imagekit/client/okhttp/ImageKitOkHttpClientAsync.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ class ImageKitOkHttpClientAsync private constructor() {
308308
* Your ImageKit webhook secret for verifying webhook signatures (starts with `whsec_`). You
309309
* can find this in the
310310
* [ImageKit dashboard](https://imagekit.io/dashboard/developer/webhooks). Only required if
311-
* you're using webhooks.
311+
* you are using webhooks.
312312
*/
313313
fun webhookSecret(webhookSecret: String?) = apply {
314314
clientOptions.webhookSecret(webhookSecret)

image-kit-java-core/src/main/kotlin/io/imagekit/core/Check.kt

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,45 +24,39 @@ internal fun <T : Any> checkKnown(name: String, value: MultipartField<T>): T =
2424
}
2525

2626
@JvmSynthetic
27-
internal fun checkLength(name: String, value: String, length: Int): String =
28-
value.also {
29-
check(it.length == length) { "`$name` must have length $length, but was ${it.length}" }
30-
}
27+
internal fun checkLength(name: String, value: String, length: Int): String = value.also {
28+
check(it.length == length) { "`$name` must have length $length, but was ${it.length}" }
29+
}
3130

3231
@JvmSynthetic
33-
internal fun checkMinLength(name: String, value: String, minLength: Int): String =
34-
value.also {
35-
check(it.length >= minLength) {
36-
if (minLength == 1) "`$name` must be non-empty, but was empty"
37-
else "`$name` must have at least length $minLength, but was ${it.length}"
38-
}
32+
internal fun checkMinLength(name: String, value: String, minLength: Int): String = value.also {
33+
check(it.length >= minLength) {
34+
if (minLength == 1) "`$name` must be non-empty, but was empty"
35+
else "`$name` must have at least length $minLength, but was ${it.length}"
3936
}
37+
}
4038

4139
@JvmSynthetic
42-
internal fun checkMaxLength(name: String, value: String, maxLength: Int): String =
43-
value.also {
44-
check(it.length <= maxLength) {
45-
"`$name` must have at most length $maxLength, but was ${it.length}"
46-
}
40+
internal fun checkMaxLength(name: String, value: String, maxLength: Int): String = value.also {
41+
check(it.length <= maxLength) {
42+
"`$name` must have at most length $maxLength, but was ${it.length}"
4743
}
44+
}
4845

4946
@JvmSynthetic
5047
internal fun checkJacksonVersionCompatibility() {
51-
val incompatibleJacksonVersions =
52-
RUNTIME_JACKSON_VERSIONS.mapNotNull {
53-
val badVersionReason = BAD_JACKSON_VERSIONS[it.toString()]
54-
when {
55-
it.majorVersion != MINIMUM_JACKSON_VERSION.majorVersion ->
56-
it to "incompatible major version"
57-
it.minorVersion < MINIMUM_JACKSON_VERSION.minorVersion ->
58-
it to "minor version too low"
59-
it.minorVersion == MINIMUM_JACKSON_VERSION.minorVersion &&
60-
it.patchLevel < MINIMUM_JACKSON_VERSION.patchLevel ->
61-
it to "patch version too low"
62-
badVersionReason != null -> it to badVersionReason
63-
else -> null
64-
}
48+
val incompatibleJacksonVersions = RUNTIME_JACKSON_VERSIONS.mapNotNull {
49+
val badVersionReason = BAD_JACKSON_VERSIONS[it.toString()]
50+
when {
51+
it.majorVersion != MINIMUM_JACKSON_VERSION.majorVersion ->
52+
it to "incompatible major version"
53+
it.minorVersion < MINIMUM_JACKSON_VERSION.minorVersion -> it to "minor version too low"
54+
it.minorVersion == MINIMUM_JACKSON_VERSION.minorVersion &&
55+
it.patchLevel < MINIMUM_JACKSON_VERSION.patchLevel -> it to "patch version too low"
56+
badVersionReason != null -> it to badVersionReason
57+
else -> null
6558
}
59+
}
6660
check(incompatibleJacksonVersions.isEmpty()) {
6761
"""
6862
This SDK requires a minimum Jackson version of $MINIMUM_JACKSON_VERSION, but the following incompatible Jackson versions were detected at runtime:

0 commit comments

Comments
 (0)