Skip to content
Draft
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
107 changes: 96 additions & 11 deletions .github/workflows/sdk_publish.yaml
Original file line number Diff line number Diff line change
@@ -1,23 +1,108 @@
name: Publish

# Publishes the openrouter package to PyPI and creates the matching GitHub
# release when a Speakeasy regen lands on main (gen.lock changes). Generation
# still runs through speakeasy-api/sdk-generation-action; publishing is done
# here directly rather than through its sdk-publish.yaml reusable workflow.
#
# Both steps are idempotent so a failed run can simply be re-run: a PyPI
# version that already exists is not re-uploaded, and an existing release is
# left alone.

permissions:
checks: write
contents: write
pull-requests: write
statuses: write
id-token: write
id-token: write # allows switching to PyPI trusted publishing without workflow changes

"on":
push:
branches:
- main
paths:
- .speakeasy/gen.lock
workflow_dispatch: {}

concurrency:
group: publish
cancel-in-progress: false

jobs:
publish:
uses: speakeasy-api/sdk-generation-action/.github/workflows/sdk-publish.yaml@68f3bfefb79354d39358bf4699863dabd2cea0f6 # v15.60.11
with:
target: open-router
secrets:
github_access_token: ${{ secrets.GITHUB_TOKEN }}
pypi_token: ${{ secrets.PYPI_TOKEN }}
speakeasy_api_key: ${{ secrets.SPEAKEASY_API_KEY }}
name: Publish to PyPI
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0

- name: Resolve release version
id: version
run: |
VERSION=$(yq '.management.releaseVersion' .speakeasy/gen.lock)
PKG_VERSION=$(yq -p toml -oy '.project.version' pyproject.toml)
PKG_NAME=$(yq -p toml -oy '.project.name' pyproject.toml)
if [ "$VERSION" != "$PKG_VERSION" ]; then
echo "::error::gen.lock releaseVersion ($VERSION) does not match pyproject.toml version ($PKG_VERSION)"
exit 1
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "name=$PKG_NAME" >> "$GITHUB_OUTPUT"
echo "Resolved $PKG_NAME==$VERSION"

- name: Check PyPI for existing version
id: pypi
env:
PKG_NAME: ${{ steps.version.outputs.name }}
VERSION: ${{ steps.version.outputs.version }}
run: |
STATUS=$(curl -s -o /dev/null -w '%{http_code}' "https://pypi.org/pypi/$PKG_NAME/$VERSION/json")
if [ "$STATUS" = "200" ]; then
echo "$PKG_NAME==$VERSION is already on PyPI — skipping publish"
echo "published=true" >> "$GITHUB_OUTPUT"
elif [ "$STATUS" = "404" ]; then
echo "published=false" >> "$GITHUB_OUTPUT"
else
echo "::error::Unexpected HTTP $STATUS from PyPI while checking $PKG_NAME==$VERSION"
exit 1
fi

- name: Install uv
if: steps.pypi.outputs.published == 'false'
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2

- name: Build
if: steps.pypi.outputs.published == 'false'
run: |
uv run python scripts/prepare_readme.py
uv build

- name: Publish
if: steps.pypi.outputs.published == 'false'
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
run: uv publish

- name: Create GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ steps.version.outputs.version }}
PKG_NAME: ${{ steps.version.outputs.name }}
run: |
TAG="v$VERSION"
if gh release view "$TAG" >/dev/null 2>&1; then
echo "Release $TAG already exists — nothing to do"
exit 0
fi

{
echo "[$PKG_NAME $VERSION](https://pypi.org/project/$PKG_NAME/$VERSION)"
yq '.releaseNotes // ""' .speakeasy/gen.lock
echo "Generated with [Speakeasy CLI $(yq '.management.speakeasyVersion' .speakeasy/gen.lock)](https://github.com/speakeasy-api/speakeasy/releases)"
} > "$RUNNER_TEMP/notes.md"

ARGS=()
if [[ "$VERSION" == *"-"* ]]; then
ARGS+=(--prerelease --latest=false)
fi
gh release create "$TAG" \
--target "$GITHUB_SHA" \
--title "python - $TAG - $(date -u '+%Y-%m-%d %H:%M:%S')" \
--notes-file "$RUNNER_TEMP/notes.md" \
"${ARGS[@]}"
Loading