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
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:
- main

permissions:
contents: write
pull-requests: write

jobs:
release-please:
if: github.repository == 'sambanova/sambanova-python'
runs-on: ubuntu-latest

steps:
- uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1
id: release
with:
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
74 changes: 74 additions & 0 deletions .github/workflows/seal-dispatch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Seal custom code (dispatch)

# Optional, eager variant of the config repo's scheduled tracking-file sync.
#
# When genuine out-of-band custom code is merged to this SDK repo's `main`
# (a direct staging commit, or a contribution pulled back from production),
# notify the config repo to reseal so the custom-code tracking JSON absorbs it
# promptly instead of waiting for the config repo's poll. stlc-authored commits
# are skipped by the loop guards below, so the bot's own pushes (the "Build SDK"
# squash commit and any regen commit) cannot trigger a reseal loop.
#
# This workflow is itself custom code on the SDK repo: seal it once with
# `stlc build --commit` to bootstrap, after which scaffold preservation keeps it
# across regenerations. If you would rather keep things simple, drop this file
# and rely on the config repo's scheduled `stlc-sync-tracking.yml` poll alone.
#
# Lives in the STAGING repo. Requires CONFIG_DISPATCH_TOKEN — a token that can
# send a repository_dispatch to the config repo.
on:
push:
# main only. stlc preview/integrated/codegen branches never push to main.
branches: [main]

concurrency:
group: seal-dispatch-${{ github.ref }}
cancel-in-progress: false

permissions:
contents: read

jobs:
dispatch:
runs-on: ubuntu-latest
if: github.repository == 'sambanova/sambanova-python-staging'
env:
CONFIG_REPO: sambanova/sambanova-stlc-config
steps:
- name: Loop-guard and send reseal dispatch
env:
DISPATCH_TOKEN: ${{ secrets.CONFIG_DISPATCH_TOKEN }}
HEAD_MSG: ${{ github.event.head_commit.message }}
HEAD_AUTHOR_NAME: ${{ github.event.head_commit.author.name }}
SHA: ${{ github.sha }}
REPO: ${{ github.repository }}
run: |
set -euo pipefail

# Loop guard 1: skip the stlc "Build SDK" squash commit (it carries
# the Stainless-Generated-From trailer in its message).
if printf '%s' "$HEAD_MSG" | grep -q 'Stainless-Generated-From'; then
echo "Head commit is an stlc build — skipping reseal dispatch."
exit 0
fi

# Loop guard 2: skip stlc-bot commits (e.g. a regen commit).
if [ "$HEAD_AUTHOR_NAME" = "stlc-bot" ]; then
echo "Head commit authored by stlc-bot — skipping reseal dispatch."
exit 0
fi

[ -n "${DISPATCH_TOKEN:-}" ] || { echo "CONFIG_DISPATCH_TOKEN not set" >&2; exit 1; }
payload=$(jq -n --arg sha "$SHA" --arg repo "$REPO" \
'{event_type:"seal-custom-code",client_payload:{target:"all",sha:$sha,repo:$repo}}')
code=$(curl -sS -o /tmp/dispatch.txt -w '%{http_code}' -X POST \
-H "Authorization: Bearer ${DISPATCH_TOKEN}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${CONFIG_REPO}/dispatches" \
-d "$payload")
if [ "$code" = "204" ]; then
echo "Reseal dispatched to ${CONFIG_REPO}."
else
echo "Dispatch failed (HTTP $code)" >&2; cat /tmp/dispatch.txt >&2; exit 1
fi
88 changes: 88 additions & 0 deletions .github/workflows/stlc-promote.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: Promote SDKs

# Merge-commit PR promote — use this variant only when the PRODUCTION repo
# requires a pull request for changes to `main` (so the fast-forward direct
# push in examples/sdk-repo can't be used on that boundary). If production can
# take a direct push, use the fast-forward promote instead — it's simpler.
#
# This pushes staging `main` to a `stainless/release` branch on production and
# opens a PR. **Merge that PR with a MERGE COMMIT — never squash or rebase.**
# A merge commit keeps staging's commits reachable, so production stays a clean
# descendant of staging and the back-sync still fast-forwards; squash/rebase
# rewrite the SHAs and fork the two trunks apart.
#
# Lives in the STAGING repo. Requires PRODUCTION_REPO_TOKEN with Contents +
# Pull requests: write on the production repo.
on:
push:
branches: [main]

permissions:
contents: read

jobs:
promote:
runs-on: ubuntu-latest
if: github.repository == 'sambanova/sambanova-python-staging'
env:
PRODUCTION_REPO: sambanova/sambanova-python
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 whether production already has staging's content
id: diff
run: |
# Compare by CONTENT, not commit SHA. After a release, production
# carries release-please's version/changelog commits that staging
# lacks, so the SHAs always differ — a SHA check would re-open a
# spurious release PR on every push. Ask whether merging staging into
# production would change production's tree: if not, production
# already has everything on staging and there is nothing to release.
MERGED=$(git merge-tree --write-tree production/main origin/main) || MERGED=conflict
PRODUCTION_TREE=$(git rev-parse 'production/main^{tree}')
if [ "$MERGED" = "$PRODUCTION_TREE" ]; then
echo "Production already contains staging's content. 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 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
# Review and merge this PR with a MERGE COMMIT to cut a release. To
# land it automatically instead, enable auto-merge:
# gh pr merge stainless/release --repo "${PRODUCTION_REPO}" --merge --auto
# (--merge = merge commit; do NOT use --squash or --rebase here.)
89 changes: 89 additions & 0 deletions .github/workflows/stlc-sync-from-production.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Sync from production

# Merge-commit PR back-sync — use this variant only when the STAGING repo
# requires a pull request for changes to `main`. If staging can take a direct
# push, use the fast-forward back-sync in examples/sdk-repo instead.
#
# Pushes production `main` to a `stlc/from-prod` branch on staging and opens a
# PR, then auto-merges it **with a merge commit** (never squash or rebase) so
# staging stays a clean descendant of production and the next `stlc build`
# reseals against the released state.
#
# Lives in the STAGING repo. Reuses PRODUCTION_REPO_TOKEN to read production
# (only needed if production is private; a public repo reads with no token).
on:
schedule:
# A poll, not a release — the eager trigger is trigger-back-sync-on-release.
- cron: '17 */6 * * *'
workflow_dispatch: {}
repository_dispatch:
types: [prod-released]

permissions:
contents: write # push the back-sync branch on staging
pull-requests: write # open + auto-merge the back-sync PR on staging

concurrency:
group: stlc-sync-from-production
cancel-in-progress: true

jobs:
sync:
runs-on: ubuntu-latest
if: github.repository == 'sambanova/sambanova-python-staging'
env:
PRODUCTION_REPO: sambanova/sambanova-python
# The built-in token opens + merges the PR on this (staging) repo.
GH_TOKEN: ${{ github.token }}
steps:
- name: Check out staging
uses: actions/checkout@v6
with:
fetch-depth: 0
persist-credentials: false

- name: Fetch production main
run: |
# Production is public, so the built-in token reads it with no
# credential. If production is private, add the remote with
# PRODUCTION_REPO_TOKEN instead.
git remote add production "https://github.com/${PRODUCTION_REPO}.git"
git fetch production main

- name: Check whether production has content staging lacks
id: diff
run: |
MERGED=$(git merge-tree --write-tree origin/main production/main) || MERGED=conflict
STAGING_TREE=$(git rev-parse 'origin/main^{tree}')
if [ "$MERGED" = "$STAGING_TREE" ]; then
echo "Staging already has production's content. Nothing to pull back."
echo "behind=false" >> "$GITHUB_OUTPUT"
else
echo "behind=true" >> "$GITHUB_OUTPUT"
fi

- name: Push production main to the back-sync branch on staging
if: steps.diff.outputs.behind == 'true'
env:
STAGING_PUSH_TOKEN: ${{ secrets.PRODUCTION_REPO_TOKEN }}
run: |
git push "https://x-access-token:${STAGING_PUSH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" \
production/main:refs/heads/stlc/from-prod --force

- name: Open + auto-merge the back-sync PR (merge commit)
if: steps.diff.outputs.behind == 'true'
run: |
EXISTING_PR=$(gh pr list --head stlc/from-prod --base main --state open --json number --jq '.[0].number')
if [ -z "${EXISTING_PR}" ]; then
gh pr create \
--base main \
--head stlc/from-prod \
--title "Sync release changes from production" \
--body "Pulls production's release-please commits (and any merged contributions) back onto staging \`main\` so the next \`stlc build\` reseals against the released state. Bot-authored; safe to auto-merge."
fi
# --merge = MERGE COMMIT (preserves production's commits as ancestors).
# Never --squash or --rebase here: that would rewrite the SHAs and fork
# the trunks. If your repo gates main on `trunk-synced`, exclude the
# `stlc/from-prod` branch from that check so this PR isn't deadlocked.
gh pr merge stlc/from-prod --merge --auto \
|| echo "Auto-merge unavailable — merge the back-sync PR manually with a merge commit."
69 changes: 69 additions & 0 deletions .github/workflows/trunk-sync-lock.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Trunk sync lock

# Posts a `trunk-synced` commit status to open PRs targeting staging `main`:
# red while production is ahead of staging (a release hasn't been synced back
# yet), green once they are in sync.
#
# You should make `trunk-synced` a required status check on staging `main`
# to block merges onto a stale trunk during the release
# window.
#
# This only gates PRs, not direct pushes. The back-sync bypasses this check
# by pushing to staging `main` directly. If staging `main` also requires a pull
# request, give the back-sync's identity ruleset-bypass so it can push. Never
# route the back-sync through a PR gated by this check, or it deadlocks.
#
# First-run note: GitHub treats a status check as "required" only once it has
# been reported at least once. At setup time staging and production are
# identical, so trigger this workflow once (push a PR or use the Run workflow
# button) BEFORE adding `trunk-synced` to the required checks, so the first
# status is green rather than missing.
on:
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
workflow_run:
workflows: ["Sync from production"]
types: [completed]
repository_dispatch:
types: [prod-released]
workflow_dispatch: {}
schedule:
- cron: '*/30 * * * *'

permissions:
contents: read
statuses: write
pull-requests: read

jobs:
lock:
runs-on: ubuntu-latest
if: github.repository == 'sambanova/sambanova-python-staging'
env:
PRODUCTION_REPO: sambanova/sambanova-python
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
persist-credentials: false
- name: Evaluate sync state and post status to open main PRs
run: |
set -euo pipefail
# Production is public; the built-in token reads it with no credential.
git remote add production "https://github.com/${PRODUCTION_REPO}.git"
git fetch --no-tags production main
if git merge-base --is-ancestor production/main HEAD; then
state=success; desc="staging main is in sync with production"
else
state=failure; desc="production is ahead — wait for the back-sync before merging"
fi
echo "trunk-synced => $state ($desc)"
shas=$(gh pr list --repo "$GITHUB_REPOSITORY" --base main --state open --json headRefOid --jq '.[].headRefOid')
if [ -z "$shas" ]; then echo "no open PRs targeting main"; exit 0; fi
for sha in $shas; do
gh api -X POST "repos/$GITHUB_REPOSITORY/statuses/$sha" \
-f state="$state" -f context="trunk-synced" -f description="$desc" >/dev/null
echo "posted trunk-synced=$state to $sha"
done
3 changes: 0 additions & 3 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
configured_endpoints: 10
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/sambanova/sambanova-50fb2e3f57f67505e5e7230bf1191aaa021757640fd2c889fe30d5228a240f80.yml
openapi_spec_hash: 3f3793a97a88b742adf346745e57803d
config_hash: 0213fb1509c3d860435ee9a49477d86f
15 changes: 8 additions & 7 deletions scripts/mock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion scripts/utils/upload-artifact.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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/sambanova-python/$SHA/$FILENAME'\033[0m"
echo -e "\033[32mInstallation: pip install 'https://pkg.stainless.com/s/sambanova-python-staging/$SHA/$FILENAME'\033[0m"
else
echo -e "\033[31mFailed to upload artifact.\033[0m"
exit 1
Expand Down
Loading
Loading