From 6e8952864d48780e78700d116d8dbcd2e604cbf9 Mon Sep 17 00:00:00 2001 From: rogersXie Date: Thu, 28 May 2026 16:42:59 -0700 Subject: [PATCH 1/9] chore: add staging promote workflow --- .github/workflows/promote-to-production.yml | 99 +++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 .github/workflows/promote-to-production.yml diff --git a/.github/workflows/promote-to-production.yml b/.github/workflows/promote-to-production.yml new file mode 100644 index 00000000..61713232 --- /dev/null +++ b/.github/workflows/promote-to-production.yml @@ -0,0 +1,99 @@ +name: Promote to Production + +on: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: promote-to-production-${{ github.ref }} + cancel-in-progress: true + +jobs: + promote: + name: promote + runs-on: ubuntu-latest + timeout-minutes: 10 + if: github.repository == 'RetellAI/retell-python-sdk-staging' + + env: + PRODUCTION_REPO: RetellAI/retell-python-sdk + PROMOTE_BRANCH: stlc/sync-from-staging + + steps: + - name: Checkout staging + uses: actions/checkout@v4 + with: + path: staging + persist-credentials: false + + - name: Checkout production + uses: actions/checkout@v4 + with: + repository: ${{ env.PRODUCTION_REPO }} + ref: main + path: production + token: ${{ secrets.SDK_WRITE_TOKEN }} + persist-credentials: false + + - name: Prepare production branch + working-directory: production + run: git checkout -B "${PROMOTE_BRANCH}" + + - name: Sync staging into production branch + run: | + rsync -a --delete \ + --exclude ".git/" \ + --exclude ".github/workflows/promote-to-production.yml" \ + --exclude ".github/workflows/release-please.yml" \ + staging/ production/ + + - name: Open or update production PR + working-directory: production + env: + GH_TOKEN: ${{ secrets.SDK_WRITE_TOKEN }} + STAGING_SHA: ${{ github.sha }} + run: | + if git diff --quiet; then + echo "No production changes to promote." + exit 0 + fi + + git config user.name "stlc-bot" + git config user.email "stlc-bot@users.noreply.github.com" + git add -A + git commit -m "feat(api): api update" + git push --force "https://x-access-token:${GH_TOKEN}@github.com/${PRODUCTION_REPO}.git" "${PROMOTE_BRANCH}" + + pr_number="$(gh pr list \ + --repo "${PRODUCTION_REPO}" \ + --base main \ + --head "${PROMOTE_BRANCH}" \ + --json number \ + --jq '.[0].number')" + + pr_body="$(cat < Date: Thu, 28 May 2026 17:07:40 -0700 Subject: [PATCH 2/9] chore: align stlc promote workflow --- .github/workflows/promote-to-production.yml | 99 --------------------- .github/workflows/stlc-promote.yml | 64 +++++++++++++ 2 files changed, 64 insertions(+), 99 deletions(-) delete mode 100644 .github/workflows/promote-to-production.yml create mode 100644 .github/workflows/stlc-promote.yml diff --git a/.github/workflows/promote-to-production.yml b/.github/workflows/promote-to-production.yml deleted file mode 100644 index 61713232..00000000 --- a/.github/workflows/promote-to-production.yml +++ /dev/null @@ -1,99 +0,0 @@ -name: Promote to Production - -on: - push: - branches: - - main - workflow_dispatch: - -permissions: - contents: read - -concurrency: - group: promote-to-production-${{ github.ref }} - cancel-in-progress: true - -jobs: - promote: - name: promote - runs-on: ubuntu-latest - timeout-minutes: 10 - if: github.repository == 'RetellAI/retell-python-sdk-staging' - - env: - PRODUCTION_REPO: RetellAI/retell-python-sdk - PROMOTE_BRANCH: stlc/sync-from-staging - - steps: - - name: Checkout staging - uses: actions/checkout@v4 - with: - path: staging - persist-credentials: false - - - name: Checkout production - uses: actions/checkout@v4 - with: - repository: ${{ env.PRODUCTION_REPO }} - ref: main - path: production - token: ${{ secrets.SDK_WRITE_TOKEN }} - persist-credentials: false - - - name: Prepare production branch - working-directory: production - run: git checkout -B "${PROMOTE_BRANCH}" - - - name: Sync staging into production branch - run: | - rsync -a --delete \ - --exclude ".git/" \ - --exclude ".github/workflows/promote-to-production.yml" \ - --exclude ".github/workflows/release-please.yml" \ - staging/ production/ - - - name: Open or update production PR - working-directory: production - env: - GH_TOKEN: ${{ secrets.SDK_WRITE_TOKEN }} - STAGING_SHA: ${{ github.sha }} - run: | - if git diff --quiet; then - echo "No production changes to promote." - exit 0 - fi - - git config user.name "stlc-bot" - git config user.email "stlc-bot@users.noreply.github.com" - git add -A - git commit -m "feat(api): api update" - git push --force "https://x-access-token:${GH_TOKEN}@github.com/${PRODUCTION_REPO}.git" "${PROMOTE_BRANCH}" - - pr_number="$(gh pr list \ - --repo "${PRODUCTION_REPO}" \ - --base main \ - --head "${PROMOTE_BRANCH}" \ - --json number \ - --jq '.[0].number')" - - pr_body="$(cat <> "$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 main \ + --head stainless/release \ + --title "Release SDK updates" \ + --body "$(git log --oneline production/main..origin/main)" + else + echo "Release PR #${EXISTING_PR} already exists. Force-push has updated it." + fi From c98ec9d7855d20a9e3e1969bed281e054ec6dde3 Mon Sep 17 00:00:00 2001 From: rogersXie Date: Fri, 29 May 2026 12:25:44 -0700 Subject: [PATCH 3/9] ci: use non-conflicting stlc release branch --- .github/workflows/stlc-promote.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/stlc-promote.yml b/.github/workflows/stlc-promote.yml index fdb1698b..28b43827 100644 --- a/.github/workflows/stlc-promote.yml +++ b/.github/workflows/stlc-promote.yml @@ -41,14 +41,14 @@ jobs: - 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 + 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 \ + --head stainless-release \ --state open \ --json number \ --jq '.[0].number') @@ -56,7 +56,7 @@ jobs: gh pr create \ --repo "${PRODUCTION_REPO}" \ --base main \ - --head stainless/release \ + --head stainless-release \ --title "Release SDK updates" \ --body "$(git log --oneline production/main..origin/main)" else From f2c066e7ad555486f5fda40d0f2b3908affb1786 Mon Sep 17 00:00:00 2001 From: rogersXie Date: Fri, 29 May 2026 14:56:45 -0700 Subject: [PATCH 4/9] ci: preserve production workflows during promote --- .github/workflows/stlc-promote.yml | 32 +++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/.github/workflows/stlc-promote.yml b/.github/workflows/stlc-promote.yml index 28b43827..b1d8d143 100644 --- a/.github/workflows/stlc-promote.yml +++ b/.github/workflows/stlc-promote.yml @@ -39,9 +39,35 @@ jobs: echo "synced=false" >> "$GITHUB_OUTPUT" fi - - name: Push staging main to the release branch on production + - name: Preserve production-owned workflow files if: steps.diff.outputs.synced == 'false' - run: git push production origin/main:refs/heads/stainless-release --force + run: | + git switch --force-create stainless-release origin/main + + for path in \ + .github/workflows/ci.yml \ + .github/workflows/publish-pypi.yml \ + .github/workflows/release-doctor.yml \ + .github/workflows/release-please.yml \ + .github/workflows/stlc-auto-merge.yml + do + if git cat-file -e "production/main:${path}" 2>/dev/null; then + git checkout production/main -- "${path}" + else + git rm -f --ignore-unmatch "${path}" + fi + done + + git rm -f --ignore-unmatch .github/workflows/stlc-promote.yml + + if ! git diff --quiet; then + git add .github/workflows + git commit -m "chore: preserve production workflow files" + fi + + - name: Push release branch on production + if: steps.diff.outputs.synced == 'false' + run: git push production HEAD:refs/heads/stainless-release --force - name: Open or update the release PR on production if: steps.diff.outputs.synced == 'false' @@ -58,7 +84,7 @@ jobs: --base main \ --head stainless-release \ --title "Release SDK updates" \ - --body "$(git log --oneline production/main..origin/main)" + --body "$(git log --oneline production/main..HEAD)" else echo "Release PR #${EXISTING_PR} already exists. Force-push has updated it." fi From 2f12990411eddc2e1d584266b5787e9a38f54ae1 Mon Sep 17 00:00:00 2001 From: stlc-bot Date: Fri, 29 May 2026 21:18:13 +0000 Subject: [PATCH 5/9] feat(api): api update Stainless-Generated-From: 0e14722c121695a0a9d69dfc2842efdf0667f6b9 --- .github/workflows/release-please.yml | 20 ++++++++++++++++ src/retell/resources/conversation_flow.py | 4 ++-- src/retell/resources/phone_number.py | 24 +++++++++---------- .../conversation_flow_retrieve_params.py | 2 +- .../types/phone_number_create_params.py | 4 ++-- .../types/phone_number_import_params.py | 4 ++-- src/retell/types/phone_number_response.py | 4 ++-- .../types/phone_number_update_params.py | 4 ++-- 8 files changed, 43 insertions(+), 23 deletions(-) create mode 100644 .github/workflows/release-please.yml diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 00000000..16debdb2 --- /dev/null +++ b/.github/workflows/release-please.yml @@ -0,0 +1,20 @@ +name: Release Please +on: + push: + branches: + - main + +permissions: + contents: write + pull-requests: write + +jobs: + release-please: + if: github.repository == 'RetellAI/retell-python-sdk' + 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/src/retell/resources/conversation_flow.py b/src/retell/resources/conversation_flow.py index 655af4f6..ee490adf 100644 --- a/src/retell/resources/conversation_flow.py +++ b/src/retell/resources/conversation_flow.py @@ -182,7 +182,7 @@ def retrieve( Retrieve details of a specific Conversation Flow Args: - version: Optional version of the conversation flow to retrieve. Default to latest + version: Optional version of the conversation flow to retrieve. Defaults to the latest version. extra_headers: Send extra headers @@ -582,7 +582,7 @@ async def retrieve( Retrieve details of a specific Conversation Flow Args: - version: Optional version of the conversation flow to retrieve. Default to latest + version: Optional version of the conversation flow to retrieve. Defaults to the latest version. extra_headers: Send extra headers diff --git a/src/retell/resources/phone_number.py b/src/retell/resources/phone_number.py index d2022c46..22b0ae9a 100644 --- a/src/retell/resources/phone_number.py +++ b/src/retell/resources/phone_number.py @@ -99,8 +99,8 @@ def create( agent will be picked randomly for each inbound call, with probability proportional to the weight. Total weights must add up to 1. - inbound_webhook_url: If set, will send a webhook for inbound calls, where you can to override agent - id, set dynamic variables and other fields specific to that call. + inbound_webhook_url: If set, will send a webhook for inbound calls, where you can override agent id, + set dynamic variables and other fields specific to that call. nickname: Nickname of the number. This is for your reference only. @@ -245,8 +245,8 @@ def update( inbound_sms_webhook_url: If set, will send a webhook for inbound SMS, where you can override agent id, set dynamic variables and other fields specific to that chat. - inbound_webhook_url: If set, will send a webhook for inbound calls, where you can to override agent - id, set dynamic variables and other fields specific to that call. + inbound_webhook_url: If set, will send a webhook for inbound calls, where you can override agent id, + set dynamic variables and other fields specific to that call. nickname: Nickname of the number. This is for your reference only. @@ -435,8 +435,8 @@ def import_( agent will be picked randomly for each inbound call, with probability proportional to the weight. Total weights must add up to 1. - inbound_webhook_url: If set, will send a webhook for inbound calls, where you can to override agent - id, set dynamic variables and other fields specific to that call. + inbound_webhook_url: If set, will send a webhook for inbound calls, where you can override agent id, + set dynamic variables and other fields specific to that call. nickname: Nickname of the number. This is for your reference only. @@ -554,8 +554,8 @@ async def create( agent will be picked randomly for each inbound call, with probability proportional to the weight. Total weights must add up to 1. - inbound_webhook_url: If set, will send a webhook for inbound calls, where you can to override agent - id, set dynamic variables and other fields specific to that call. + inbound_webhook_url: If set, will send a webhook for inbound calls, where you can override agent id, + set dynamic variables and other fields specific to that call. nickname: Nickname of the number. This is for your reference only. @@ -700,8 +700,8 @@ async def update( inbound_sms_webhook_url: If set, will send a webhook for inbound SMS, where you can override agent id, set dynamic variables and other fields specific to that chat. - inbound_webhook_url: If set, will send a webhook for inbound calls, where you can to override agent - id, set dynamic variables and other fields specific to that call. + inbound_webhook_url: If set, will send a webhook for inbound calls, where you can override agent id, + set dynamic variables and other fields specific to that call. nickname: Nickname of the number. This is for your reference only. @@ -890,8 +890,8 @@ async def import_( agent will be picked randomly for each inbound call, with probability proportional to the weight. Total weights must add up to 1. - inbound_webhook_url: If set, will send a webhook for inbound calls, where you can to override agent - id, set dynamic variables and other fields specific to that call. + inbound_webhook_url: If set, will send a webhook for inbound calls, where you can override agent id, + set dynamic variables and other fields specific to that call. nickname: Nickname of the number. This is for your reference only. diff --git a/src/retell/types/conversation_flow_retrieve_params.py b/src/retell/types/conversation_flow_retrieve_params.py index 382fa504..c71b953e 100644 --- a/src/retell/types/conversation_flow_retrieve_params.py +++ b/src/retell/types/conversation_flow_retrieve_params.py @@ -11,5 +11,5 @@ class ConversationFlowRetrieveParams(TypedDict, total=False): version: int """Optional version of the conversation flow to retrieve. - Default to latest version. + Defaults to the latest version. """ diff --git a/src/retell/types/phone_number_create_params.py b/src/retell/types/phone_number_create_params.py index 3beaa387..a0e35e9c 100644 --- a/src/retell/types/phone_number_create_params.py +++ b/src/retell/types/phone_number_create_params.py @@ -54,8 +54,8 @@ class PhoneNumberCreateParams(TypedDict, total=False): inbound_webhook_url: Optional[str] """ - If set, will send a webhook for inbound calls, where you can to override agent - id, set dynamic variables and other fields specific to that call. + If set, will send a webhook for inbound calls, where you can override agent id, + set dynamic variables and other fields specific to that call. """ nickname: str diff --git a/src/retell/types/phone_number_import_params.py b/src/retell/types/phone_number_import_params.py index 9c076520..4e3014a1 100644 --- a/src/retell/types/phone_number_import_params.py +++ b/src/retell/types/phone_number_import_params.py @@ -54,8 +54,8 @@ class PhoneNumberImportParams(TypedDict, total=False): inbound_webhook_url: Optional[str] """ - If set, will send a webhook for inbound calls, where you can to override agent - id, set dynamic variables and other fields specific to that call. + If set, will send a webhook for inbound calls, where you can override agent id, + set dynamic variables and other fields specific to that call. """ nickname: str diff --git a/src/retell/types/phone_number_response.py b/src/retell/types/phone_number_response.py index a2cd41dd..a0f1a493 100644 --- a/src/retell/types/phone_number_response.py +++ b/src/retell/types/phone_number_response.py @@ -188,8 +188,8 @@ class PhoneNumberResponse(BaseModel): inbound_webhook_url: Optional[str] = None """ - If set, will send a webhook for inbound calls, where you can to override agent - id, set dynamic variables and other fields specific to that call. + If set, will send a webhook for inbound calls, where you can override agent id, + set dynamic variables and other fields specific to that call. """ nickname: Optional[str] = None diff --git a/src/retell/types/phone_number_update_params.py b/src/retell/types/phone_number_update_params.py index 2d1ac0d5..1af3a3d7 100644 --- a/src/retell/types/phone_number_update_params.py +++ b/src/retell/types/phone_number_update_params.py @@ -68,8 +68,8 @@ class PhoneNumberUpdateParams(TypedDict, total=False): inbound_webhook_url: Optional[str] """ - If set, will send a webhook for inbound calls, where you can to override agent - id, set dynamic variables and other fields specific to that call. + If set, will send a webhook for inbound calls, where you can override agent id, + set dynamic variables and other fields specific to that call. """ nickname: Optional[str] From ea94abc36b43f69487612c8e4302205e57f8b563 Mon Sep 17 00:00:00 2001 From: rogersXie Date: Fri, 29 May 2026 14:59:58 -0700 Subject: [PATCH 6/9] ci: configure promote commit author --- .github/workflows/stlc-promote.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/stlc-promote.yml b/.github/workflows/stlc-promote.yml index b1d8d143..34b058de 100644 --- a/.github/workflows/stlc-promote.yml +++ b/.github/workflows/stlc-promote.yml @@ -42,6 +42,8 @@ jobs: - name: Preserve production-owned workflow files if: steps.diff.outputs.synced == 'false' run: | + git config user.name "stlc-bot" + git config user.email "stlc-bot@users.noreply.github.com" git switch --force-create stainless-release origin/main for path in \ From 3fb74ffbf7641884578de4c233b000ff9883d019 Mon Sep 17 00:00:00 2001 From: rogersXie Date: Fri, 29 May 2026 15:01:55 -0700 Subject: [PATCH 7/9] ci: detect staged workflow preservation changes --- .github/workflows/stlc-promote.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stlc-promote.yml b/.github/workflows/stlc-promote.yml index 34b058de..0a3b46ff 100644 --- a/.github/workflows/stlc-promote.yml +++ b/.github/workflows/stlc-promote.yml @@ -62,7 +62,7 @@ jobs: git rm -f --ignore-unmatch .github/workflows/stlc-promote.yml - if ! git diff --quiet; then + if ! git diff --quiet HEAD -- .github/workflows; then git add .github/workflows git commit -m "chore: preserve production workflow files" fi From 26e31754745535ad34136b407fded6bfd456c36a Mon Sep 17 00:00:00 2001 From: rogersXie Date: Fri, 29 May 2026 15:07:15 -0700 Subject: [PATCH 8/9] ci: preserve production release metadata during promote --- .github/workflows/stlc-promote.yml | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/workflows/stlc-promote.yml b/.github/workflows/stlc-promote.yml index 0a3b46ff..bbf7ba4c 100644 --- a/.github/workflows/stlc-promote.yml +++ b/.github/workflows/stlc-promote.yml @@ -39,7 +39,7 @@ jobs: echo "synced=false" >> "$GITHUB_OUTPUT" fi - - name: Preserve production-owned workflow files + - name: Preserve production-owned files if: steps.diff.outputs.synced == 'false' run: | git config user.name "stlc-bot" @@ -62,8 +62,32 @@ jobs: git rm -f --ignore-unmatch .github/workflows/stlc-promote.yml - if ! git diff --quiet HEAD -- .github/workflows; then - git add .github/workflows + for release_path in \ + .release-please-manifest.json \ + CHANGELOG.md \ + pyproject.toml \ + src/retell/_version.py + do + if git cat-file -e "production/main:${release_path}" 2>/dev/null; then + git checkout production/main -- "${release_path}" + else + git rm -f --ignore-unmatch "${release_path}" + fi + done + + if ! git diff --quiet HEAD -- \ + .github/workflows \ + .release-please-manifest.json \ + CHANGELOG.md \ + pyproject.toml \ + src/retell/_version.py + then + git add \ + .github/workflows \ + .release-please-manifest.json \ + CHANGELOG.md \ + pyproject.toml \ + src/retell/_version.py git commit -m "chore: preserve production workflow files" fi From 8e839bae64ec3a2b4e61a196ca772c6695014dfc Mon Sep 17 00:00:00 2001 From: stlc-bot Date: Fri, 29 May 2026 22:09:49 +0000 Subject: [PATCH 9/9] chore: preserve production workflow files --- .github/workflows/ci.yml | 10 +-- .github/workflows/release-please.yml | 5 +- .github/workflows/stlc-auto-merge.yml | 105 +++++++++++++++++++++++ .github/workflows/stlc-promote.yml | 116 -------------------------- .release-please-manifest.json | 2 +- CHANGELOG.md | 31 +++++++ pyproject.toml | 2 +- src/retell/_version.py | 2 +- 8 files changed, 148 insertions(+), 125 deletions(-) create mode 100644 .github/workflows/stlc-auto-merge.yml delete mode 100644 .github/workflows/stlc-promote.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0b21c8f2..f0dbdd45 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/retell-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/retell-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: 'ubuntu-latest' steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -64,7 +64,7 @@ jobs: - name: Get GitHub OIDC Token if: |- - github.repository == 'stainless-sdks/retell-python' && + github.repository == 'RetellAI/retell-python-sdk-staging' && !startsWith(github.ref, 'refs/heads/stl/') id: github-oidc uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 @@ -73,7 +73,7 @@ jobs: - name: Upload tarball if: |- - github.repository == 'stainless-sdks/retell-python' && + github.repository == 'RetellAI/retell-python-sdk-staging' && !startsWith(github.ref, 'refs/heads/stl/') env: URL: https://pkg.stainless.com/s @@ -84,7 +84,7 @@ jobs: test: timeout-minutes: 10 name: test - runs-on: ${{ github.repository == 'stainless-sdks/retell-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: 'ubuntu-latest' if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 16debdb2..6dbc4dc6 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -1,8 +1,10 @@ name: Release Please + on: push: branches: - main + workflow_dispatch: permissions: contents: write @@ -10,8 +12,9 @@ permissions: jobs: release-please: - if: github.repository == 'RetellAI/retell-python-sdk' + name: release please runs-on: ubuntu-latest + if: github.repository == 'RetellAI/retell-python-sdk' steps: - uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1 diff --git a/.github/workflows/stlc-auto-merge.yml b/.github/workflows/stlc-auto-merge.yml new file mode 100644 index 00000000..fd58d774 --- /dev/null +++ b/.github/workflows/stlc-auto-merge.yml @@ -0,0 +1,105 @@ +name: Auto-merge SDK release PRs + +on: + pull_request_target: + types: [opened, synchronize, reopened, ready_for_review] + branches: [main] + workflow_run: + workflows: ['CI', 'Release Doctor'] + types: [completed] + workflow_dispatch: + inputs: + pr_number: + description: 'Optional PR number to evaluate' + required: false + +permissions: + contents: write + pull-requests: write + checks: read + statuses: read + actions: read + +jobs: + auto-merge: + if: github.repository == 'RetellAI/retell-python-sdk' + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN }} + REPO: ${{ github.repository }} + steps: + - name: Merge qualifying green PRs + shell: bash + run: | + set -euo pipefail + + pr_numbers=() + if [ "${{ github.event_name }}" = "pull_request_target" ]; then + pr_numbers+=("${{ github.event.pull_request.number }}") + elif [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ inputs.pr_number }}" ]; then + pr_numbers+=("${{ inputs.pr_number }}") + else + while IFS= read -r number; do + pr_numbers+=("$number") + done < <(gh pr list --repo "$REPO" --base main --state open --json number --jq '.[].number') + fi + + for pr in "${pr_numbers[@]}"; do + echo "Evaluating PR #$pr" + pr_json=$(gh pr view "$pr" --repo "$REPO" --json title,isDraft,headRefName,headRefOid,headRepository,isCrossRepository,baseRefName,mergeStateStatus) + title=$(jq -r '.title' <<<"$pr_json") + is_draft=$(jq -r '.isDraft' <<<"$pr_json") + head_ref=$(jq -r '.headRefName' <<<"$pr_json") + head_sha=$(jq -r '.headRefOid' <<<"$pr_json") + head_repo=$(jq -r '.headRepository.nameWithOwner // ""' <<<"$pr_json") + is_cross_repository=$(jq -r '.isCrossRepository' <<<"$pr_json") + base_ref=$(jq -r '.baseRefName' <<<"$pr_json") + + if [ "$base_ref" != "main" ] || [ "$is_draft" = "true" ]; then + echo "Skipping PR #$pr: not a ready PR to main." + continue + fi + + if [ "$is_cross_repository" = "true" ] || [ "$head_repo" != "$REPO" ]; then + echo "Skipping PR #$pr: head branch is not in $REPO." + continue + fi + + merge_flag="" + if [ "$head_ref" = "stainless-release" ] && [ "$title" = "Release SDK updates" ]; then + merge_flag="--merge" + elif [[ "$head_ref" == release-please--* ]] && [[ "$title" == release:* ]]; then + merge_flag="--squash" + else + echo "Skipping PR #$pr: not an automated SDK release PR." + continue + fi + + check_runs=$(gh api "/repos/$REPO/commits/$head_sha/check-runs?per_page=100") + check_count=$(jq '.total_count' <<<"$check_runs") + if [ "$check_count" -eq 0 ]; then + echo "Skipping PR #$pr: no check runs found yet." + continue + fi + + bad_checks=$(jq '[.check_runs[] | select(.status != "completed" or (.conclusion != "success" and .conclusion != "neutral" and .conclusion != "skipped"))] | length' <<<"$check_runs") + if [ "$bad_checks" -ne 0 ]; then + echo "Skipping PR #$pr: checks are pending or failed." + continue + fi + + statuses=$(gh api "/repos/$REPO/commits/$head_sha/status") + status_count=$(jq '.total_count' <<<"$statuses") + status_state=$(jq -r '.state' <<<"$statuses") + if [ "$status_count" -gt 0 ] && [ "$status_state" != "success" ]; then + echo "Skipping PR #$pr: commit statuses are $status_state." + continue + fi + + echo "Merging PR #$pr with ${merge_flag}." + if gh pr merge "$pr" --repo "$REPO" "$merge_flag" --delete-branch --match-head-commit "$head_sha"; then + echo "Merged PR #$pr." + else + echo "Skipping PR #$pr: GitHub did not consider it mergeable yet." + fi + done diff --git a/.github/workflows/stlc-promote.yml b/.github/workflows/stlc-promote.yml deleted file mode 100644 index bbf7ba4c..00000000 --- a/.github/workflows/stlc-promote.yml +++ /dev/null @@ -1,116 +0,0 @@ -name: Promote SDKs - -on: - push: - branches: [main] - -permissions: - contents: read - -jobs: - promote: - if: github.repository == 'RetellAI/retell-python-sdk-staging' - runs-on: ubuntu-latest - env: - PRODUCTION_REPO: RetellAI/retell-python-sdk - GH_TOKEN: ${{ secrets.PRODUCTION_REPO_TOKEN }} - steps: - - name: Check out staging - uses: actions/checkout@v6 - 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 main - - - name: Check if production is already in sync - id: diff - run: | - STAGING_SHA=$(git rev-parse origin/main) - PRODUCTION_SHA=$(git rev-parse production/main) - 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: Preserve production-owned files - if: steps.diff.outputs.synced == 'false' - run: | - git config user.name "stlc-bot" - git config user.email "stlc-bot@users.noreply.github.com" - git switch --force-create stainless-release origin/main - - for path in \ - .github/workflows/ci.yml \ - .github/workflows/publish-pypi.yml \ - .github/workflows/release-doctor.yml \ - .github/workflows/release-please.yml \ - .github/workflows/stlc-auto-merge.yml - do - if git cat-file -e "production/main:${path}" 2>/dev/null; then - git checkout production/main -- "${path}" - else - git rm -f --ignore-unmatch "${path}" - fi - done - - git rm -f --ignore-unmatch .github/workflows/stlc-promote.yml - - for release_path in \ - .release-please-manifest.json \ - CHANGELOG.md \ - pyproject.toml \ - src/retell/_version.py - do - if git cat-file -e "production/main:${release_path}" 2>/dev/null; then - git checkout production/main -- "${release_path}" - else - git rm -f --ignore-unmatch "${release_path}" - fi - done - - if ! git diff --quiet HEAD -- \ - .github/workflows \ - .release-please-manifest.json \ - CHANGELOG.md \ - pyproject.toml \ - src/retell/_version.py - then - git add \ - .github/workflows \ - .release-please-manifest.json \ - CHANGELOG.md \ - pyproject.toml \ - src/retell/_version.py - git commit -m "chore: preserve production workflow files" - fi - - - name: Push release branch on production - if: steps.diff.outputs.synced == 'false' - run: git push production HEAD: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 main \ - --head stainless-release \ - --title "Release SDK updates" \ - --body "$(git log --oneline production/main..HEAD)" - else - echo "Release PR #${EXISTING_PR} already exists. Force-push has updated it." - fi diff --git a/.release-please-manifest.json b/.release-please-manifest.json index e30834d7..dfb1d81a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "5.43.0" + ".": "5.44.1" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index e37f60a1..1935a66b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,36 @@ # Changelog +## [5.44.1](https://github.com/RetellAI/retell-python-sdk/compare/v5.44.0...v5.44.1) (2026-05-29) + + +### Chores + +* restore stlc auto-merge triggers ([5f38f95](https://github.com/RetellAI/retell-python-sdk/commit/5f38f95c5a65f79aedc16da6277c8800f4d05ffc)) + +## 5.44.0 (2026-05-29) + +Full Changelog: [v5.43.1...v5.44.0](https://github.com/RetellAI/retell-python-sdk/compare/v5.43.1...v5.44.0) + +### Features + +* **api:** api update ([a559d90](https://github.com/RetellAI/retell-python-sdk/commit/a559d9031cc2e111ae02a19ce988b8042c137526)) + + +### Chores + +* disable stlc auto-merge workflow ([83fc966](https://github.com/RetellAI/retell-python-sdk/commit/83fc96699b82d56652355396723f52caeb837842)) + +## 5.43.1 (2026-05-29) + +Full Changelog: [v5.43.0...v5.43.1](https://github.com/RetellAI/retell-python-sdk/compare/v5.43.0...v5.43.1) + +### Chores + +* add release-please workflow ([2ded49b](https://github.com/RetellAI/retell-python-sdk/commit/2ded49be02e1471bef0968f422c1cbf19314119b)) +* add SDK auto-merge workflow ([0966b89](https://github.com/RetellAI/retell-python-sdk/commit/0966b89b08dcb1ab507511b480270961bf8332b0)) +* harden SDK auto-merge workflow ([be57a3f](https://github.com/RetellAI/retell-python-sdk/commit/be57a3f70524d1f4bad69b37b73b383efb4c48d6)) +* restrict SDK auto-merge to same-repo branches ([4644075](https://github.com/RetellAI/retell-python-sdk/commit/4644075b17cc17443e67bc8fafa3ffe8e0e65e85)) + ## 5.43.0 (2026-05-28) Full Changelog: [v5.42.0...v5.43.0](https://github.com/RetellAI/retell-python-sdk/compare/v5.42.0...v5.43.0) diff --git a/pyproject.toml b/pyproject.toml index 0e3f0751..eb09a8e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "retell-sdk" -version = "5.43.0" +version = "5.44.1" description = "The official Python library for the retell API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/retell/_version.py b/src/retell/_version.py index a74ec2af..247924d2 100644 --- a/src/retell/_version.py +++ b/src/retell/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "retell" -__version__ = "5.43.0" # x-release-please-version +__version__ = "5.44.1" # x-release-please-version