Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 2 additions & 40 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
lint:
timeout-minutes: 15
name: lint
runs-on: ${{ github.repository == 'stainless-sdks/imagekit-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
runs-on: ubuntu-latest
if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')

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

steps:
Expand All @@ -66,44 +66,6 @@ jobs:
- name: Build SDK
run: ./scripts/build

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

- name: Build and upload Maven artifacts
if: |-
github.repository == 'stainless-sdks/imagekit-java' &&
!startsWith(github.ref, 'refs/heads/stl/')
env:
URL: https://pkg.stainless.com/s
AUTH: ${{ steps.github-oidc.outputs.github_token }}
SHA: ${{ github.sha }}
PROJECT: imagekit-java
run: ./scripts/upload-artifacts
test:
timeout-minutes: 15
name: test
runs-on: ${{ github.repository == 'stainless-sdks/imagekit-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Set up Java
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: temurin
java-version: |
8
21
cache: gradle

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

- name: Run tests
run: ./scripts/test
1 change: 1 addition & 0 deletions .github/workflows/release-doctor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jobs:
run: |
bash ./bin/check-release-environment
env:
RELEASE_PLEASE_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN }}
SONATYPE_USERNAME: ${{ secrets.IMAGE_KIT_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }}
SONATYPE_PASSWORD: ${{ secrets.IMAGE_KIT_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }}
GPG_SIGNING_KEY: ${{ secrets.IMAGE_KIT_SONATYPE_GPG_SIGNING_KEY || secrets.GPG_SIGNING_KEY }}
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Release Please
on:
push:
branches:
- master

permissions:
contents: write
pull-requests: write

jobs:
release-please:
if: github.repository == 'imagekit-developer/imagekit-java'
runs-on: ubuntu-latest

steps:
- uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1
id: release
with:
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
65 changes: 65 additions & 0 deletions .github/workflows/stlc-promote.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Promote SDKs

on:
push:
branches: [main]

permissions:
contents: read

jobs:
promote:
runs-on: ubuntu-latest
env:
PRODUCTION_REPO: imagekit-developer/imagekit-java
PRODUCTION_BRANCH: master
GH_TOKEN: ${{ secrets.SDK_WRITE_TOKEN }}
steps:
- name: Check out staging
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false

- name: Fetch production main
run: |
git remote add production \
"https://x-access-token:${GH_TOKEN}@github.com/${PRODUCTION_REPO}.git"
git fetch production "${PRODUCTION_BRANCH}"

- name: Check if production is already in sync
id: diff
run: |
STAGING_SHA=$(git rev-parse origin/main)
PRODUCTION_SHA=$(git rev-parse production/${PRODUCTION_BRANCH})
if [ "$STAGING_SHA" = "$PRODUCTION_SHA" ]; then
echo "Production is already at $STAGING_SHA. Nothing to release."
echo "synced=true" >> "$GITHUB_OUTPUT"
else
echo "synced=false" >> "$GITHUB_OUTPUT"
fi

- name: Push staging main to the release branch on production
if: steps.diff.outputs.synced == 'false'
run: |
git push production origin/main:refs/heads/stainless/release --force

- name: Open or update the release PR on production
if: steps.diff.outputs.synced == 'false'
run: |
EXISTING_PR=$(gh pr list \
--repo "${PRODUCTION_REPO}" \
--head stainless/release \
--state open \
--json number \
--jq '.[0].number')
if [ -z "${EXISTING_PR}" ]; then
gh pr create \
--repo "${PRODUCTION_REPO}" \
--base "${PRODUCTION_BRANCH}" \
--head stainless/release \
--title "Release SDK updates" \
--body "$(git log --oneline production/${PRODUCTION_BRANCH}..origin/main)"
else
echo "Release PR #${EXISTING_PR} already exists. Force-push has updated it."
fi
63 changes: 63 additions & 0 deletions .github/workflows/sync-release-as.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Sync Release-As from release PR title

on:
pull_request:
types: [edited]

permissions:
contents: write

jobs:
sync:
if: >-
github.event.pull_request.base.ref == 'master' &&
startsWith(github.event.pull_request.head.ref, 'release-please--') &&
github.event.changes.title != null
runs-on: ubuntu-latest
steps:
- name: Extract versions from old and new title
id: parse
env:
NEW_TITLE: ${{ github.event.pull_request.title }}
OLD_TITLE: ${{ github.event.changes.title.from }}
run: |
# Anchored on pull-request-title-pattern "release: ${version}" from release-please-config.json.
extract() {
echo "$1" | grep -oE '^release:[[:space:]]+v?[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?' \
| sed -E 's/^release:[[:space:]]+v?//'
}
NEW_VERSION=$(extract "$NEW_TITLE")
OLD_VERSION=$(extract "$OLD_TITLE")
echo "old=$OLD_VERSION"
echo "new=$NEW_VERSION"
if [ -z "$NEW_VERSION" ]; then
echo "::notice::No semver in new title; nothing to do."
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
if [ "$NEW_VERSION" = "$OLD_VERSION" ]; then
echo "::notice::Version unchanged ($NEW_VERSION); not pushing."
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "version=$NEW_VERSION" >> "$GITHUB_OUTPUT"

- name: Check out master
if: steps.parse.outputs.skip != 'true'
uses: actions/checkout@v6
with:
ref: master
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
fetch-depth: 1

- name: Push empty Release-As commit
if: steps.parse.outputs.skip != 'true'
env:
VERSION: ${{ steps.parse.outputs.version }}
run: |
git config user.name "release-as-bot"
git config user.email "release-as-bot@users.noreply.github.com"
git commit --allow-empty -m "chore: pin next release

Release-As: ${VERSION}"
git push origin master
3 changes: 0 additions & 3 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
configured_endpoints: 47
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/imagekit-inc/imagekit-01267e4c07ec30011b8445babed88fbd2133b65198f42d0310b7ab39c74751d4.yml
openapi_spec_hash: 7c103e2dff0edcbeea82057e62f58d4d
config_hash: 7ef70b333059ca21bef0f0a6d4cbb282
4 changes: 4 additions & 0 deletions bin/check-release-environment
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

errors=()

if [ -z "${RELEASE_PLEASE_TOKEN}" ]; then
errors+=("The RELEASE_PLEASE_TOKEN secret has not been set. Create a fine-grained GitHub PAT and add it as a repository secret.")
fi

if [ -z "${SONATYPE_USERNAME}" ]; then
errors+=("The SONATYPE_USERNAME secret has not been set. Please set it in either this repository's secrets or your organization secrets")
fi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ class ImageKitOkHttpClient private constructor() {
* Your ImageKit webhook secret for verifying webhook signatures (starts with `whsec_`). You
* can find this in the
* [ImageKit dashboard](https://imagekit.io/dashboard/developer/webhooks). Only required if
* you're using webhooks.
* you are using webhooks.
*/
fun webhookSecret(webhookSecret: String?) = apply {
clientOptions.webhookSecret(webhookSecret)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ class ImageKitOkHttpClientAsync private constructor() {
* Your ImageKit webhook secret for verifying webhook signatures (starts with `whsec_`). You
* can find this in the
* [ImageKit dashboard](https://imagekit.io/dashboard/developer/webhooks). Only required if
* you're using webhooks.
* you are using webhooks.
*/
fun webhookSecret(webhookSecret: String?) = apply {
clientOptions.webhookSecret(webhookSecret)
Expand Down
52 changes: 23 additions & 29 deletions image-kit-java-core/src/main/kotlin/io/imagekit/core/Check.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,45 +24,39 @@ internal fun <T : Any> checkKnown(name: String, value: MultipartField<T>): T =
}

@JvmSynthetic
internal fun checkLength(name: String, value: String, length: Int): String =
value.also {
check(it.length == length) { "`$name` must have length $length, but was ${it.length}" }
}
internal fun checkLength(name: String, value: String, length: Int): String = value.also {
check(it.length == length) { "`$name` must have length $length, but was ${it.length}" }
}

@JvmSynthetic
internal fun checkMinLength(name: String, value: String, minLength: Int): String =
value.also {
check(it.length >= minLength) {
if (minLength == 1) "`$name` must be non-empty, but was empty"
else "`$name` must have at least length $minLength, but was ${it.length}"
}
internal fun checkMinLength(name: String, value: String, minLength: Int): String = value.also {
check(it.length >= minLength) {
if (minLength == 1) "`$name` must be non-empty, but was empty"
else "`$name` must have at least length $minLength, but was ${it.length}"
}
}

@JvmSynthetic
internal fun checkMaxLength(name: String, value: String, maxLength: Int): String =
value.also {
check(it.length <= maxLength) {
"`$name` must have at most length $maxLength, but was ${it.length}"
}
internal fun checkMaxLength(name: String, value: String, maxLength: Int): String = value.also {
check(it.length <= maxLength) {
"`$name` must have at most length $maxLength, but was ${it.length}"
}
}

@JvmSynthetic
internal fun checkJacksonVersionCompatibility() {
val incompatibleJacksonVersions =
RUNTIME_JACKSON_VERSIONS.mapNotNull {
val badVersionReason = BAD_JACKSON_VERSIONS[it.toString()]
when {
it.majorVersion != MINIMUM_JACKSON_VERSION.majorVersion ->
it to "incompatible major version"
it.minorVersion < MINIMUM_JACKSON_VERSION.minorVersion ->
it to "minor version too low"
it.minorVersion == MINIMUM_JACKSON_VERSION.minorVersion &&
it.patchLevel < MINIMUM_JACKSON_VERSION.patchLevel ->
it to "patch version too low"
badVersionReason != null -> it to badVersionReason
else -> null
}
val incompatibleJacksonVersions = RUNTIME_JACKSON_VERSIONS.mapNotNull {
val badVersionReason = BAD_JACKSON_VERSIONS[it.toString()]
when {
it.majorVersion != MINIMUM_JACKSON_VERSION.majorVersion ->
it to "incompatible major version"
it.minorVersion < MINIMUM_JACKSON_VERSION.minorVersion -> it to "minor version too low"
it.minorVersion == MINIMUM_JACKSON_VERSION.minorVersion &&
it.patchLevel < MINIMUM_JACKSON_VERSION.patchLevel -> it to "patch version too low"
badVersionReason != null -> it to badVersionReason
else -> null
}
}
check(incompatibleJacksonVersions.isEmpty()) {
"""
This SDK requires a minimum Jackson version of $MINIMUM_JACKSON_VERSION, but the following incompatible Jackson versions were detected at runtime:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ private constructor(
/**
* Your ImageKit webhook secret for verifying webhook signatures (starts with `whsec_`). You can
* find this in the [ImageKit dashboard](https://imagekit.io/dashboard/developer/webhooks). Only
* required if you're using webhooks.
* required if you are using webhooks.
*/
fun webhookSecret(): Optional<String> = Optional.ofNullable(webhookSecret)

Expand Down Expand Up @@ -345,7 +345,7 @@ private constructor(
* Your ImageKit webhook secret for verifying webhook signatures (starts with `whsec_`). You
* can find this in the
* [ImageKit dashboard](https://imagekit.io/dashboard/developer/webhooks). Only required if
* you're using webhooks.
* you are using webhooks.
*/
fun webhookSecret(webhookSecret: String?) = apply { this.webhookSecret = webhookSecret }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,11 @@ private constructor(
* An enum containing [LayerMode]'s known values, as well as an [_UNKNOWN] member.
*
* An instance of [LayerMode] can contain an unknown value in a couple of cases:
*
* - It was deserialized from data that doesn't match any known member. For example, if the
* SDK is on an older version than the API, then the API may respond with new members that
* the SDK is unaware of.
*
* - It was constructed with an arbitrary value using the [of] method.
*/
enum class Value {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ private constructor(
* Used for best match union deserialization.
*/
@JvmSynthetic
internal fun validity(): Int =
additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() }
internal fun validity(): Int = additionalProperties.count { (_, value) ->
!value.isNull() && !value.isMissing()
}

override fun equals(other: Any?): Boolean {
if (this === other) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@ private constructor(
* Used for best match union deserialization.
*/
@JvmSynthetic
internal fun validity(): Int =
additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() }
internal fun validity(): Int = additionalProperties.count { (_, value) ->
!value.isNull() && !value.isMissing()
}

override fun equals(other: Any?): Boolean {
if (this === other) {
Expand Down
Loading