Repository navigation
fix(dspy): render PEP 604 unions like typing.Union in get_annotation_… #138
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| name: Publish Python 🐍 distributions 📦 to PyPI | |
| on: | |
| push: | |
| tags: | |
| - "*" | |
| permissions: {} | |
| jobs: | |
| extract-tag: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| outputs: | |
| version: ${{ steps.extract_tag.outputs.tag }} | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| persist-credentials: false | |
| - id: extract_tag | |
| name: Extract tag name | |
| run: echo "tag=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT" | |
| build-and-publish-test-pypi: | |
| needs: extract-tag | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: testpypi | |
| permissions: | |
| contents: read | |
| id-token: write # IMPORTANT: mandatory for trusted publishing | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: "3.11" | |
| - name: Install dependencies | |
| run: python3 -m pip install --upgrade setuptools wheel twine build semver packaging | |
| - name: Install Deno | |
| uses: denoland/setup-deno@22d081ff2d3a40755e97629de92e3bcbfa7cf2ed # v2.0.5 | |
| with: | |
| deno-version: v2.7.7 | |
| - name: Get correct version for TestPyPI release | |
| id: check_version | |
| env: | |
| VERSION: ${{ needs.extract-tag.outputs.version }} | |
| run: | | |
| PACKAGE_NAME="dspy-ai-test-isaac" | |
| echo "Checking if $VERSION for $PACKAGE_NAME exists on TestPyPI" | |
| NEW_VERSION=$(python3 .github/workflows/build_utils/test_version.py "$PACKAGE_NAME" "$VERSION") | |
| echo "Version to be used for TestPyPI release: $NEW_VERSION" | |
| echo "version=$NEW_VERSION" >> "$GITHUB_OUTPUT" | |
| - name: Update version in pyproject.toml | |
| env: | |
| VERSION: ${{ steps.check_version.outputs.version }} | |
| run: sed -i "/#replace_package_version_marker/{n;s/version=\"[^\"]*\"/version=\"$VERSION\"/;}" pyproject.toml | |
| - name: Update package name in pyproject.toml | |
| run: sed -i '/#replace_package_name_marker/{n;s/name="[^"]*"/name="dspy-ai-test-isaac"/;}' pyproject.toml | |
| - name: Build a binary wheel | |
| run: python3 -m build | |
| - name: Validate built distributions | |
| run: python3 -m twine check --strict dist/* | |
| # Test the locally built wheel | |
| - name: Create test environment | |
| run: python -m venv test_before_testpypi | |
| - name: Test package installation and functionality | |
| run: | | |
| source test_before_testpypi/bin/activate | |
| # Install the locally built wheel and testing dependencies | |
| pip install dist/*.whl pytest pytest-asyncio pytest-mock | |
| pytest tests/metadata/test_metadata.py tests/predict | |
| (cd "$RUNNER_TEMP" && python -c 'import dspy; assert dspy.PythonInterpreter().execute("6 * 7") == 42') | |
| deactivate | |
| # Publish to test-PyPI | |
| - name: Publish distribution 📦 to test-PyPI | |
| uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1 # This requires a trusted publisher to be setup in pypi/testpypi | |
| with: | |
| repository-url: https://test.pypi.org/legacy/ | |
| # TODO: Add tests using dspy-ai-test | |
| build-and-publish-pypi: | |
| needs: [extract-tag, build-and-publish-test-pypi] | |
| # Only publish to PyPI if the repository owner is stanfordnlp | |
| if: github.repository_owner == 'stanfordnlp' | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: pypi | |
| permissions: | |
| contents: read | |
| id-token: write # IMPORTANT: mandatory for trusted publishing | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: "3.11" | |
| - name: Install dependencies | |
| run: python3 -m pip install --upgrade setuptools wheel twine build | |
| - name: Install Deno | |
| uses: denoland/setup-deno@22d081ff2d3a40755e97629de92e3bcbfa7cf2ed # v2.0.5 | |
| with: | |
| deno-version: v2.7.7 | |
| - name: Update version in pyproject.toml | |
| env: | |
| VERSION: ${{ needs.extract-tag.outputs.version }} | |
| run: sed -i "/#replace_package_version_marker/{n;s/version *= *\"[^\"]*\"/version=\"$VERSION\"/;}" pyproject.toml | |
| - name: Update version in __metadata__.py | |
| env: | |
| VERSION: ${{ needs.extract-tag.outputs.version }} | |
| run: sed -i "/#replace_package_version_marker/{n;s/__version__ *= *\"[^\"]*\"/__version__=\"$VERSION\"/;}" ./dspy/__metadata__.py | |
| # Publish to dspy | |
| - name: Update package name in pyproject.toml | |
| run: sed -i '/#replace_package_name_marker/{n;s/name *= *"[^"]*"/name="dspy"/;}' pyproject.toml | |
| - name: Update package name in metadata.py | |
| run: sed -i '/#replace_package_name_marker/{n;s/__name__ *= *"[^"]*"/__name__="dspy"/;}' ./dspy/__metadata__.py | |
| - name: Build a binary wheel | |
| run: python3 -m build | |
| - name: Validate built distributions | |
| run: python3 -m twine check --strict dist/* | |
| # Test the locally built wheel before publishing to pypi | |
| - name: Create test environment | |
| run: python -m venv test_before_pypi | |
| - name: Test package installation and functionality | |
| run: | | |
| source test_before_pypi/bin/activate | |
| # Install the locally built wheel and testing dependencies | |
| pip install dist/*.whl pytest pytest-asyncio pytest-mock | |
| pytest tests/metadata/test_metadata.py tests/predict | |
| (cd "$RUNNER_TEMP" && python -c 'import dspy; assert dspy.PythonInterpreter().execute("6 * 7") == 42') | |
| deactivate | |
| rm -r test_before_pypi | |
| - name: Preserve the exact release wheel for documentation | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: dspy-release-wheel | |
| path: dist/*.whl | |
| if-no-files-found: error | |
| - name: Publish distribution 📦 to PyPI (dspy) | |
| uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1 | |
| with: | |
| attestations: false | |
| # Publish to dspy-ai | |
| - name: Update package name in pyproject.toml | |
| run: sed -i '/#replace_package_name_marker/{n;s/name *= *"[^"]*"/name="dspy-ai"/;}' .github/.internal_dspyai/pyproject.toml | |
| - name: Update version for dspy-ai release | |
| env: | |
| VERSION: ${{ needs.extract-tag.outputs.version }} | |
| run: sed -i "/#replace_package_version_marker/{n;s/version *= *\"[^\"]*\"/version=\"$VERSION\"/;}" .github/.internal_dspyai/pyproject.toml | |
| - name: Update dspy dependency for dspy-ai release | |
| env: | |
| VERSION: ${{ needs.extract-tag.outputs.version }} | |
| run: sed -i "/#replace_dspy_version_marker/{n;s/dspy>=[^\"]*/dspy>=$VERSION/;}" .github/.internal_dspyai/pyproject.toml | |
| - name: Build a binary wheel (dspy-ai) | |
| run: python3 -m build .github/.internal_dspyai/ | |
| - name: Validate built distributions (dspy-ai) | |
| run: python3 -m twine check --strict .github/.internal_dspyai/dist/* | |
| - name: Publish distribution 📦 to PyPI (dspy-ai) | |
| uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1 | |
| with: | |
| attestations: false | |
| packages-dir: .github/.internal_dspyai/dist/ | |
| release-docs: | |
| needs: [extract-tag, build-and-publish-pypi] | |
| if: github.repository_owner == 'stanfordnlp' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| persist-credentials: false | |
| fetch-depth: 0 | |
| - name: Check whether this is a documentation release | |
| id: publishable | |
| env: | |
| VERSION: ${{ needs.extract-tag.outputs.version }} | |
| run: | | |
| if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+((a|b|rc)[0-9]+)?$ ]] && (( ${VERSION%%.*} >= 3 )); then | |
| echo "publish=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "publish=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Set up Python 3.11 | |
| if: steps.publishable.outputs.publish == 'true' | |
| uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 | |
| with: | |
| python-version: "3.11" | |
| - name: Download exact production wheel | |
| if: steps.publishable.outputs.publish == 'true' | |
| uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0 | |
| with: | |
| name: dspy-release-wheel | |
| path: release-wheel | |
| - name: Install documentation dependencies and release wheel | |
| if: steps.publishable.outputs.publish == 'true' | |
| run: python -m pip install -r docs/requirements.txt release-wheel/*.whl | |
| - name: Verify API introspection uses the release wheel | |
| if: steps.publishable.outputs.publish == 'true' | |
| run: | | |
| cd "$RUNNER_TEMP" | |
| env -u PYTHONPATH PYTHONSAFEPATH=1 python -P - <<'PY' | |
| import site | |
| from pathlib import Path | |
| import dspy | |
| module = Path(dspy.__file__).resolve() | |
| site_packages = [Path(root).resolve() for root in site.getsitepackages()] | |
| if not any(module.is_relative_to(root) for root in site_packages): | |
| raise SystemExit(f"DSPy resolved outside site-packages: {module}") | |
| print(f"DSPy API source: {module}") | |
| PY | |
| - name: Build immutable release documentation | |
| if: steps.publishable.outputs.publish == 'true' | |
| env: | |
| VERSION: ${{ needs.extract-tag.outputs.version }} | |
| run: | | |
| cd "$RUNNER_TEMP" | |
| env PYTHONPATH="$GITHUB_WORKSPACE/docs/scripts" PYTHONSAFEPATH=1 python -P \ | |
| "$GITHUB_WORKSPACE/docs/scripts/build_docs.py" release \ | |
| --config "$GITHUB_WORKSPACE/docs/mkdocs.yml" \ | |
| --output "$GITHUB_WORKSPACE/release-site" \ | |
| --version "$VERSION" \ | |
| --artifact "$GITHUB_WORKSPACE"/release-wheel/*.whl \ | |
| --package-source workflow-wheel | |
| - name: Check out documentation deployment | |
| if: steps.publishable.outputs.publish == 'true' | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| repository: krypticmouse/dspy-docs | |
| ref: master | |
| path: docs-deployment | |
| persist-credentials: false | |
| token: ${{ secrets.GH_PAT }} # zizmor: ignore[secrets-outside-env] | |
| - name: Publish immutable release documentation | |
| if: steps.publishable.outputs.publish == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.GH_PAT }} | |
| VERSION: ${{ needs.extract-tag.outputs.version }} | |
| run: | | |
| gh auth setup-git | |
| git -C docs-deployment config user.name github-actions | |
| git -C docs-deployment config user.email github-actions@github.com | |
| aliases=() | |
| if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| aliases=(--alias "${VERSION%.*}") | |
| fi | |
| for attempt in 1 2 3; do | |
| git -C docs-deployment fetch origin master | |
| git -C docs-deployment reset --hard origin/master | |
| python docs/scripts/publish_versioned_docs.py \ | |
| --repository docs-deployment \ | |
| --site release-site \ | |
| --identifier "$VERSION" \ | |
| "${aliases[@]}" \ | |
| --package-source workflow-wheel \ | |
| --branch master \ | |
| --require-current-renderer zensical | |
| if git -C docs-deployment push origin master; then | |
| exit 0 | |
| fi | |
| sleep $((2 ** attempt + RANDOM % 5)) | |
| done | |
| echo "::error::Documentation deployment changed repeatedly; rerun this release job" | |
| exit 1 | |
| open-main-version-bump-pr: | |
| needs: [extract-tag, build-and-publish-pypi] | |
| if: github.repository_owner == 'stanfordnlp' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| persist-credentials: false | |
| ref: main | |
| - name: Apply version bump for main | |
| env: | |
| VERSION: ${{ needs.extract-tag.outputs.version }} | |
| run: | | |
| sed -i "/#replace_package_version_marker/{n;s/version *= *\"[^\"]*\"/version=\"$VERSION\"/;}" pyproject.toml | |
| sed -i "/#replace_package_version_marker/{n;s/__version__ *= *\"[^\"]*\"/__version__=\"$VERSION\"/;}" ./dspy/__metadata__.py | |
| sed -i "/#replace_package_version_marker/{n;s/version *= *\"[^\"]*\"/version=\"$VERSION\"/;}" .github/.internal_dspyai/pyproject.toml | |
| sed -i "/#replace_dspy_version_marker/{n;s/dspy>=[^\"]*/dspy>=$VERSION/;}" .github/.internal_dspyai/pyproject.toml | |
| - name: Open version bump PR for main | |
| uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 | |
| with: | |
| branch: release-${{ needs.extract-tag.outputs.version }}-main-version-bump | |
| base: main | |
| add-paths: | | |
| pyproject.toml | |
| dspy/__metadata__.py | |
| .github/.internal_dspyai/pyproject.toml | |
| commit-message: Update versions for ${{ needs.extract-tag.outputs.version }} | |
| title: Update versions for ${{ needs.extract-tag.outputs.version }} | |
| body: | | |
| Updates main version metadata after publishing ${{ needs.extract-tag.outputs.version }}. |