Skip to content

chore: update SDK from production OpenAPI (#246) #203

chore: update SDK from production OpenAPI (#246)

chore: update SDK from production OpenAPI (#246) #203

Workflow file for this run

name: release
on:
push:
branches:
- main
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
jobs:
# Scheduled or manually triggered release lane: if main has commits since the
# last version tag, this publishes commit-specific canaries and opens one PR
# containing only the lockstep package versions and lockfile bump. An existing
# PR for that version is left in place while newer main commits receive fresh
# canaries.
version-pr:
if: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
pull-requests: write
id-token: write
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
ref: main
fetch-depth: 0
- name: Check commits since last version
id: changes
run: |
LAST_VERSION=$(git describe --tags --abbrev=0 --match 'v[0-9]*' --match 'v0-sdk@*' 2>/dev/null || true)
if [ -z "$LAST_VERSION" ]; then
echo "No version tag found; continuing with release PR."
echo "skip=false" >> "$GITHUB_OUTPUT"
exit 0
fi
COMMITS=$(git rev-list "${LAST_VERSION}..HEAD" --count)
echo "last_version=${LAST_VERSION}" >> "$GITHUB_OUTPUT"
echo "commits=${COMMITS}" >> "$GITHUB_OUTPUT"
if [ "$COMMITS" -eq 0 ]; then
echo "No commits since ${LAST_VERSION}; skipping release PR."
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "${COMMITS} commits since ${LAST_VERSION}; continuing with release PR."
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
if: steps.changes.outputs.skip != 'true'
with:
node-version: '24'
registry-url: 'https://registry.npmjs.org'
package-manager-cache: false
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
if: steps.changes.outputs.skip != 'true'
- if: steps.changes.outputs.skip != 'true'
run: bun install --frozen-lockfile
- name: Bump package versions
id: bump
if: steps.changes.outputs.skip != 'true'
env:
BUMP: patch
run: |
cd packages/v0-sdk
bun pm version "$BUMP" --no-git-tag-version
SDK_NAME=$(bun pm pkg get name | tr -d '"')
VERSION=$(bun pm pkg get version | tr -d '"')
cd ../ai-tools
AI_TOOLS_NAME=$(bun pm pkg get name | tr -d '"')
bun pm pkg set "version=${VERSION}" "dependencies.v0=${VERSION}"
cd ../react
REACT_NAME=$(bun pm pkg get name | tr -d '"')
bun pm pkg set "version=${VERSION}" "dependencies.v0=${VERSION}"
cd ../create-v0-sdk-app
CREATE_APP_NAME=$(bun pm pkg get name | tr -d '"')
bun pm pkg set "version=${VERSION}"
cd ../..
bun install --lockfile-only
echo "sdk_name=${SDK_NAME}" >> "$GITHUB_OUTPUT"
echo "ai_tools_name=${AI_TOOLS_NAME}" >> "$GITHUB_OUTPUT"
echo "react_name=${REACT_NAME}" >> "$GITHUB_OUTPUT"
echo "create_app_name=${CREATE_APP_NAME}" >> "$GITHUB_OUTPUT"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
- name: Check published latest
id: published
if: steps.changes.outputs.skip != 'true'
run: |
SDK_PUBLISHED=false
AI_TOOLS_PUBLISHED=false
REACT_PUBLISHED=false
CREATE_APP_PUBLISHED=false
if npm view "${{ steps.bump.outputs.sdk_name }}@${{ steps.bump.outputs.version }}" version --silent > /dev/null 2>&1; then
SDK_PUBLISHED=true
fi
if npm view "${{ steps.bump.outputs.ai_tools_name }}@${{ steps.bump.outputs.version }}" version --silent > /dev/null 2>&1; then
AI_TOOLS_PUBLISHED=true
fi
if npm view "${{ steps.bump.outputs.react_name }}@${{ steps.bump.outputs.version }}" version --silent > /dev/null 2>&1; then
REACT_PUBLISHED=true
fi
if npm view "${{ steps.bump.outputs.create_app_name }}@${{ steps.bump.outputs.version }}" version --silent > /dev/null 2>&1; then
CREATE_APP_PUBLISHED=true
fi
if [ "$SDK_PUBLISHED" = true ] && [ "$AI_TOOLS_PUBLISHED" = true ] && [ "$REACT_PUBLISHED" = true ] && [ "$CREATE_APP_PUBLISHED" = true ]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Resolve nightly canary version
id: canary
if: steps.changes.outputs.skip != 'true' && steps.published.outputs.skip != 'true'
run: |
SHA=$(git rev-parse --short HEAD)
echo "version=${{ steps.bump.outputs.version }}-canary.${SHA}" >> "$GITHUB_OUTPUT"
- name: Set nightly canary versions
if: steps.changes.outputs.skip != 'true' && steps.published.outputs.skip != 'true'
run: |
CANARY_VERSION="${{ steps.canary.outputs.version }}"
(cd packages/v0-sdk && bun pm pkg set "version=${CANARY_VERSION}")
(cd packages/ai-tools && bun pm pkg set "version=${CANARY_VERSION}" "dependencies.v0=${CANARY_VERSION}")
(cd packages/react && bun pm pkg set "version=${CANARY_VERSION}" "dependencies.v0=${CANARY_VERSION}")
(cd packages/create-v0-sdk-app && bun pm pkg set "version=${CANARY_VERSION}")
- name: Ensure nightly canary tag
if: steps.changes.outputs.skip != 'true' && steps.published.outputs.skip != 'true'
run: |
TAG="v${{ steps.canary.outputs.version }}"
COMMIT=$(git rev-parse HEAD)
REMOTE_COMMIT=$(git ls-remote --tags origin "refs/tags/${TAG}" | awk '{print $1}')
if [ -z "$REMOTE_COMMIT" ]; then
git tag "$TAG" "$COMMIT"
git push origin "$TAG"
elif [ "$REMOTE_COMMIT" != "$COMMIT" ]; then
echo "::error::Tag ${TAG} points to ${REMOTE_COMMIT}, expected ${COMMIT}."
exit 1
fi
- name: Publish nightly canaries
if: steps.changes.outputs.skip != 'true' && steps.published.outputs.skip != 'true'
run: |
publish_if_needed() {
NAME="$1"
WORKSPACE="$2"
VERSION="${{ steps.canary.outputs.version }}"
if npm view "${NAME}@${VERSION}" version --silent > /dev/null 2>&1; then
echo "${NAME}@${VERSION} is already published; skipping."
else
npm publish --tag canary --workspace "${WORKSPACE}"
fi
}
publish_if_needed "${{ steps.bump.outputs.sdk_name }}" packages/v0-sdk
publish_if_needed "${{ steps.bump.outputs.ai_tools_name }}" packages/ai-tools
publish_if_needed "${{ steps.bump.outputs.react_name }}" packages/react
publish_if_needed "${{ steps.bump.outputs.create_app_name }}" packages/create-v0-sdk-app
- name: Restore stable release candidate versions
if: steps.changes.outputs.skip != 'true' && steps.published.outputs.skip != 'true'
run: |
VERSION="${{ steps.bump.outputs.version }}"
(cd packages/v0-sdk && bun pm pkg set "version=${VERSION}")
(cd packages/ai-tools && bun pm pkg set "version=${VERSION}" "dependencies.v0=${VERSION}")
(cd packages/react && bun pm pkg set "version=${VERSION}" "dependencies.v0=${VERSION}")
(cd packages/create-v0-sdk-app && bun pm pkg set "version=${VERSION}")
- name: Check for existing release PR
id: existing
if: steps.changes.outputs.skip != 'true' && steps.published.outputs.skip != 'true'
env:
GH_TOKEN: ${{ secrets.RELEASE_PR_TOKEN || secrets.GITHUB_TOKEN }}
run: |
PR=$(gh pr list --state open --search "Release v${{ steps.bump.outputs.version }} in:title" --json number --jq '.[0].number // ""')
if [ -n "$PR" ]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Open release PR
if: steps.changes.outputs.skip != 'true' && steps.published.outputs.skip != 'true' && steps.existing.outputs.skip != 'true'
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with:
token: ${{ secrets.RELEASE_PR_TOKEN || secrets.GITHUB_TOKEN }}
branch-token: ${{ secrets.GITHUB_TOKEN }}
sign-commits: true
add-paths: |
packages/v0-sdk/package.json
packages/ai-tools/package.json
packages/react/package.json
packages/create-v0-sdk-app/package.json
bun.lock
base: main
branch: release/v${{ steps.bump.outputs.version }}-${{ github.run_id }}
delete-branch: true
commit-message: Release v${{ steps.bump.outputs.version }}
title: Release v${{ steps.bump.outputs.version }}
body: Bumps ${{ steps.bump.outputs.sdk_name }}, ${{ steps.bump.outputs.ai_tools_name }}, ${{ steps.bump.outputs.react_name }}, and ${{ steps.bump.outputs.create_app_name }} to v${{ steps.bump.outputs.version }}. Merge this PR to publish them from main.
# Stable publish lane: when a release PR is manually merged to main, the bumped
# package versions are unpublished, so this publishes them to npm as latest and
# creates the GitHub release. Other main pushes with already-published versions
# skip release side effects.
latest:
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
id-token: write
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
ref: ${{ github.sha }}
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
with:
node-version: '24'
registry-url: 'https://registry.npmjs.org'
package-manager-cache: false
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
- run: bun install --frozen-lockfile
- name: Resolve shared latest version
id: version
run: |
SDK_NAME=$(cd packages/v0-sdk && bun pm pkg get name | tr -d '"')
AI_TOOLS_NAME=$(cd packages/ai-tools && bun pm pkg get name | tr -d '"')
REACT_NAME=$(cd packages/react && bun pm pkg get name | tr -d '"')
CREATE_APP_NAME=$(cd packages/create-v0-sdk-app && bun pm pkg get name | tr -d '"')
SDK_VERSION=$(cd packages/v0-sdk && bun pm pkg get version | tr -d '"')
AI_TOOLS_VERSION=$(cd packages/ai-tools && bun pm pkg get version | tr -d '"')
REACT_VERSION=$(cd packages/react && bun pm pkg get version | tr -d '"')
CREATE_APP_VERSION=$(cd packages/create-v0-sdk-app && bun pm pkg get version | tr -d '"')
if [ "$SDK_VERSION" != "$AI_TOOLS_VERSION" ] || [ "$SDK_VERSION" != "$REACT_VERSION" ] || [ "$SDK_VERSION" != "$CREATE_APP_VERSION" ]; then
echo "::error::${SDK_NAME}, ${AI_TOOLS_NAME}, ${REACT_NAME}, and ${CREATE_APP_NAME} versions must match (${SDK_VERSION}, ${AI_TOOLS_VERSION}, ${REACT_VERSION}, ${CREATE_APP_VERSION})."
exit 1
fi
COMMIT=$(git rev-parse HEAD)
echo "sdk_name=${SDK_NAME}" >> "$GITHUB_OUTPUT"
echo "ai_tools_name=${AI_TOOLS_NAME}" >> "$GITHUB_OUTPUT"
echo "react_name=${REACT_NAME}" >> "$GITHUB_OUTPUT"
echo "create_app_name=${CREATE_APP_NAME}" >> "$GITHUB_OUTPUT"
echo "version=${SDK_VERSION}" >> "$GITHUB_OUTPUT"
echo "commit=${COMMIT}" >> "$GITHUB_OUTPUT"
if [[ "$SDK_VERSION" == *-* ]]; then
echo "prerelease=true" >> "$GITHUB_OUTPUT"
else
echo "prerelease=false" >> "$GITHUB_OUTPUT"
fi
- name: Check published latest
id: published
if: steps.version.outputs.prerelease != 'true'
run: |
SDK_SKIP=false
AI_TOOLS_SKIP=false
REACT_SKIP=false
CREATE_APP_SKIP=false
if npm view "${{ steps.version.outputs.sdk_name }}@${{ steps.version.outputs.version }}" version --silent > /dev/null 2>&1; then
SDK_SKIP=true
fi
if npm view "${{ steps.version.outputs.ai_tools_name }}@${{ steps.version.outputs.version }}" version --silent > /dev/null 2>&1; then
AI_TOOLS_SKIP=true
fi
if npm view "${{ steps.version.outputs.react_name }}@${{ steps.version.outputs.version }}" version --silent > /dev/null 2>&1; then
REACT_SKIP=true
fi
if npm view "${{ steps.version.outputs.create_app_name }}@${{ steps.version.outputs.version }}" version --silent > /dev/null 2>&1; then
CREATE_APP_SKIP=true
fi
echo "sdk_skip=${SDK_SKIP}" >> "$GITHUB_OUTPUT"
echo "ai_tools_skip=${AI_TOOLS_SKIP}" >> "$GITHUB_OUTPUT"
echo "react_skip=${REACT_SKIP}" >> "$GITHUB_OUTPUT"
echo "create_app_skip=${CREATE_APP_SKIP}" >> "$GITHUB_OUTPUT"
if [ "$SDK_SKIP" = true ] && [ "$AI_TOOLS_SKIP" = true ] && [ "$REACT_SKIP" = true ] && [ "$CREATE_APP_SKIP" = true ]; then
echo "all_skip=true" >> "$GITHUB_OUTPUT"
else
echo "all_skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Ensure stable release tag
if: steps.version.outputs.prerelease != 'true' && steps.published.outputs.all_skip != 'true'
run: |
TAG="v${{ steps.version.outputs.version }}"
COMMIT="${{ steps.version.outputs.commit }}"
REMOTE_COMMIT=$(git ls-remote --tags origin "refs/tags/${TAG}" | awk '{print $1}')
if [ -z "$REMOTE_COMMIT" ]; then
git tag "$TAG" "$COMMIT"
git push origin "$TAG"
elif [ "$REMOTE_COMMIT" != "$COMMIT" ]; then
echo "::error::Tag ${TAG} points to ${REMOTE_COMMIT}, expected ${COMMIT}."
exit 1
fi
- if: steps.version.outputs.prerelease != 'true' && steps.published.outputs.sdk_skip != 'true'
run: npm publish --tag latest --workspace packages/v0-sdk
- if: steps.version.outputs.prerelease != 'true' && steps.published.outputs.ai_tools_skip != 'true'
run: npm publish --tag latest --workspace packages/ai-tools
- if: steps.version.outputs.prerelease != 'true' && steps.published.outputs.react_skip != 'true'
run: npm publish --tag latest --workspace packages/react
- if: steps.version.outputs.prerelease != 'true' && steps.published.outputs.create_app_skip != 'true'
run: npm publish --tag latest --workspace packages/create-v0-sdk-app
- name: Check GitHub release
id: release
if: steps.version.outputs.prerelease != 'true' && steps.published.outputs.all_skip != 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if gh release view "v${{ steps.version.outputs.version }}" > /dev/null 2>&1; then
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- if: steps.version.outputs.prerelease != 'true' && steps.published.outputs.all_skip != 'true' && steps.release.outputs.skip != 'true'
run: gh release create "v${{ steps.version.outputs.version }}" --verify-tag --generate-notes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}