From 8274740b92f67c625694f84b50ac3f044ec45a1f Mon Sep 17 00:00:00 2001 From: Manu Chaudhary Date: Sun, 24 May 2026 17:59:14 +0530 Subject: [PATCH 1/4] feat: initial stlc build Stainless-Generated-From: 8ca1a32ff0527a7574b4493f6d77513f329f5b06 --- .github/workflows/ci.yml | 45 ++-------------------------- .github/workflows/publish-pypi.yml | 8 ++--- .github/workflows/release-doctor.yml | 1 + .stats.yml | 3 -- bin/check-release-environment | 4 +++ release-please-config.json | 2 +- scripts/utils/upload-artifact.sh | 2 +- src/imagekit/lib/.keep | 4 --- 8 files changed, 11 insertions(+), 58 deletions(-) delete mode 100644 src/imagekit/lib/.keep diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed433ce0..7bcc0a32 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: lint: timeout-minutes: 10 name: lint - runs-on: ${{ github.repository == 'stainless-sdks/imagekit-python' && '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: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -44,7 +44,7 @@ jobs: permissions: contents: read id-token: write - runs-on: ${{ github.repository == 'stainless-sdks/imagekit-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: ubuntu-latest steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -61,44 +61,3 @@ jobs: - name: Run build run: rye build - - - name: Get GitHub OIDC Token - if: |- - github.repository == 'stainless-sdks/imagekit-python' && - !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: Upload tarball - if: |- - github.repository == 'stainless-sdks/imagekit-python' && - !startsWith(github.ref, 'refs/heads/stl/') - env: - URL: https://pkg.stainless.com/s - AUTH: ${{ steps.github-oidc.outputs.github_token }} - SHA: ${{ github.sha }} - run: ./scripts/utils/upload-artifact.sh - - test: - timeout-minutes: 10 - name: test - runs-on: ${{ github.repository == 'stainless-sdks/imagekit-python' && '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: Install Rye - run: | - curl -sSf https://rye.astral.sh/get | bash - echo "$HOME/.rye/shims" >> $GITHUB_PATH - env: - RYE_VERSION: '0.44.0' - RYE_INSTALL_OPTION: '--yes' - - - name: Bootstrap - run: ./scripts/bootstrap - - - name: Run tests - run: ./scripts/test diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 7317a1d3..d27e3bda 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -1,13 +1,9 @@ -# This workflow is triggered when a GitHub release is created. -# It can also be run manually to re-publish to PyPI in case it failed for some reason. -# You can run this workflow by navigating to https://www.github.com/imagekit-developer/imagekit-python/actions/workflows/publish-pypi.yml +# workflow for re-running publishing to PyPI in case it fails for some reason +# you can run this workflow by navigating to https://www.github.com/imagekit-developer/imagekit-python/actions/workflows/publish-pypi.yml name: Publish PyPI on: workflow_dispatch: - release: - types: [published] - jobs: publish: name: publish diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index a52ac7fb..a6374d9d 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -18,4 +18,5 @@ jobs: run: | bash ./bin/check-release-environment env: + RELEASE_PLEASE_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN }} PYPI_TOKEN: ${{ secrets.IMAGE_KIT_PYPI_TOKEN || secrets.PYPI_TOKEN }} diff --git a/.stats.yml b/.stats.yml index 45327aad..58526a77 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1 @@ configured_endpoints: 48 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/imagekit-inc/imagekit-01267e4c07ec30011b8445babed88fbd2133b65198f42d0310b7ab39c74751d4.yml -openapi_spec_hash: 7c103e2dff0edcbeea82057e62f58d4d -config_hash: 7ef70b333059ca21bef0f0a6d4cbb282 diff --git a/bin/check-release-environment b/bin/check-release-environment index b845b0f4..98d98fbc 100644 --- a/bin/check-release-environment +++ b/bin/check-release-environment @@ -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 "${PYPI_TOKEN}" ]; then errors+=("The PYPI_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets.") fi diff --git a/release-please-config.json b/release-please-config.json index cd36a977..546a6997 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -2,7 +2,7 @@ "packages": { ".": {} }, - "$schema": "https://raw.githubusercontent.com/stainless-api/release-please/main/schemas/config.json", + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", "include-v-in-tag": true, "include-component-in-tag": false, "versioning": "prerelease", diff --git a/scripts/utils/upload-artifact.sh b/scripts/utils/upload-artifact.sh index ace7ffbf..f6c63024 100755 --- a/scripts/utils/upload-artifact.sh +++ b/scripts/utils/upload-artifact.sh @@ -20,7 +20,7 @@ UPLOAD_RESPONSE=$(curl -v -X PUT \ if echo "$UPLOAD_RESPONSE" | grep -q "HTTP/[0-9.]* 200"; then echo -e "\033[32mUploaded build to Stainless storage.\033[0m" - echo -e "\033[32mInstallation: pip install 'https://pkg.stainless.com/s/imagekit-python/$SHA/$FILENAME'\033[0m" + echo -e "\033[32mInstallation: pip install 'https://pkg.stainless.com/s/imagekit-python-staging/$SHA/$FILENAME'\033[0m" else echo -e "\033[31mFailed to upload artifact.\033[0m" exit 1 diff --git a/src/imagekit/lib/.keep b/src/imagekit/lib/.keep deleted file mode 100644 index 5e2c99fd..00000000 --- a/src/imagekit/lib/.keep +++ /dev/null @@ -1,4 +0,0 @@ -File generated from our OpenAPI spec by Stainless. - -This directory can be used to store custom files to expand the SDK. -It is ignored by Stainless code generation and its content (other than this keep file) won't be touched. \ No newline at end of file From 2cc624d80aa7703d97f55db1d4efff2ec21d8631 Mon Sep 17 00:00:00 2001 From: Manu Chaudhary Date: Mon, 25 May 2026 12:13:44 +0530 Subject: [PATCH 2/4] Promote SDKs from staging to production Stainless-Generated-From: d2d0774ba59ebd52d23fcc9436657725bd9fca41 --- .github/workflows/stlc-promote.yml | 65 ++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .github/workflows/stlc-promote.yml diff --git a/.github/workflows/stlc-promote.yml b/.github/workflows/stlc-promote.yml new file mode 100644 index 00000000..69e80f0a --- /dev/null +++ b/.github/workflows/stlc-promote.yml @@ -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-python + 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 From dbef859766aea7534d00598c1b9acaaba2580708 Mon Sep 17 00:00:00 2001 From: Manu Chaudhary Date: Mon, 25 May 2026 13:18:55 +0530 Subject: [PATCH 3/4] Add release configuration Stainless-Generated-From: b84e10c69c65b03b8be25dec90d9c3fe58d05b92 --- .github/workflows/publish-pypi.yml | 8 ++++++-- .github/workflows/release-please.yml | 20 ++++++++++++++++++++ release-please-config.json | 2 +- 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/release-please.yml diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index d27e3bda..7317a1d3 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -1,9 +1,13 @@ -# workflow for re-running publishing to PyPI in case it fails for some reason -# you can run this workflow by navigating to https://www.github.com/imagekit-developer/imagekit-python/actions/workflows/publish-pypi.yml +# This workflow is triggered when a GitHub release is created. +# It can also be run manually to re-publish to PyPI in case it failed for some reason. +# You can run this workflow by navigating to https://www.github.com/imagekit-developer/imagekit-python/actions/workflows/publish-pypi.yml name: Publish PyPI on: workflow_dispatch: + release: + types: [published] + jobs: publish: name: publish diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 00000000..a922d704 --- /dev/null +++ b/.github/workflows/release-please.yml @@ -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-python' + runs-on: ubuntu-latest + + steps: + - uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1 + id: release + with: + token: ${{ secrets.RELEASE_PLEASE_TOKEN }} diff --git a/release-please-config.json b/release-please-config.json index 546a6997..d93f3fea 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -6,7 +6,7 @@ "include-v-in-tag": true, "include-component-in-tag": false, "versioning": "prerelease", - "prerelease": true, + "prerelease": false, "bump-minor-pre-major": true, "bump-patch-for-minor-pre-major": false, "pull-request-header": "Automated Release PR", From 9d94fb4f6e473cde3b7c23c5b1b8eb3c45fb82e1 Mon Sep 17 00:00:00 2001 From: Manu Chaudhary Date: Mon, 25 May 2026 15:03:08 +0530 Subject: [PATCH 4/4] ci: add sync-release-as workflow to mirror release PR title version Stainless-Generated-From: 08dcb7fc788d6a179c7e84af990c28f3cfef5e43 --- .github/workflows/sync-release-as.yml | 63 +++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 .github/workflows/sync-release-as.yml diff --git a/.github/workflows/sync-release-as.yml b/.github/workflows/sync-release-as.yml new file mode 100644 index 00000000..99150044 --- /dev/null +++ b/.github/workflows/sync-release-as.yml @@ -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