stanfordnlp/dspy

4 workflows · maturity 33% · 2 patterns · GitHub ↗

Security 0/100

Practices

✓ Matrix○ Permissions○ Security scan○ AI review✓ Cache○ Concurrency○ Reusable workflows

Detected patterns

Security dimensions

permissions
0
security scan
0
supply chain
0
secret handling
0
harden runner
0

Workflows (4)

build_and_release .github/workflows/build_and_release.yml
Triggers
push
Runs on
ubuntu-latest, ubuntu-latest, ubuntu-latest
Jobs
extract-tag, build-and-publish-test-pypi, build-and-publish-pypi
Actions
denoland/setup-deno, pypa/gh-action-pypi-publish, denoland/setup-deno, pypa/gh-action-pypi-publish, pypa/gh-action-pypi-publish, stefanzweifel/git-auto-commit-action
Commands
  • echo "tag=$(echo $GITHUB_REF | cut -d / -f 3)" >> "$GITHUB_OUTPUT"
  • python3 -m pip install --upgrade setuptools wheel twine build semver packaging
  • VERSION=${{ needs.extract-tag.outputs.version }} PACKAGE_NAME="dspy-ai-test" 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"
  • sed -i '/#replace_package_version_marker/{n;s/version="[^"]*"/version="${{ steps.check_version.outputs.version }}"/;}' pyproject.toml
  • sed -i '/#replace_package_name_marker/{n;s/name="[^"]*"/name="dspy-ai-test"/;}' pyproject.toml
  • python3 -m build
  • python -m venv test_before_testpypi
  • source test_before_testpypi/bin/activate # Install the locally built wheel and testing dependencies pip install dist/*.whl pytest pytest-asyncio pytest tests/metadata/test_metadata.py tests/predict deactivate
View raw YAML
---
name: Publish Python 🐍 distributions 📦 to PyPI
on:
  push:
    tags:
      - "*"
jobs:
  extract-tag:
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.extract_tag.outputs.tag }}
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
      - id: extract_tag
        name: Extract tag name
        run: echo "tag=$(echo $GITHUB_REF | cut -d / -f 3)" >> "$GITHUB_OUTPUT"

  build-and-publish-test-pypi:
    needs: extract-tag
    runs-on: ubuntu-latest
    environment:
      name: pypi
    permissions:
      id-token: write # IMPORTANT: mandatory for trusted publishing
      contents: write
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
      - name: Set up Python 3.11
        uses: actions/setup-python@3542bca2639a428e1796aaa6a2ffef0c0f575566 # v3
        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@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb # v2.0.3
        with:
          deno-version: v2.7.7
      - name: Get correct version for TestPyPI release
        id: check_version
        run: |
          VERSION=${{ needs.extract-tag.outputs.version }}  
          PACKAGE_NAME="dspy-ai-test"
          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
        run: sed -i '/#replace_package_version_marker/{n;s/version="[^"]*"/version="${{ steps.check_version.outputs.version }}"/;}' pyproject.toml
      - name: Update package name in pyproject.toml
        run: sed -i '/#replace_package_name_marker/{n;s/name="[^"]*"/name="dspy-ai-test"/;}' pyproject.toml
      - name: Build a binary wheel
        run: python3 -m build
      # 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 tests/metadata/test_metadata.py tests/predict
          deactivate
      # Publish to test-PyPI
      - name: Publish distribution 📦 to test-PyPI
        uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # 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:
      id-token: write # IMPORTANT: mandatory for trusted publishing
      contents: write
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
      - name: Set up Python 3.11
        uses: actions/setup-python@3542bca2639a428e1796aaa6a2ffef0c0f575566 # v3
        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@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb # v2.0.3
        with:
          deno-version: v2.7.7
      - name: Update version in pyproject.toml
        run: sed -i '/#replace_package_version_marker/{n;s/version *= *"[^"]*"/version="${{ needs.extract-tag.outputs.version }}"/;}' pyproject.toml
      - name: Update version in __metadata__.py
        run: sed -i '/#replace_package_version_marker/{n;s/__version__ *= *"[^"]*"/__version__="${{ needs.extract-tag.outputs.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
      # 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 tests/metadata/test_metadata.py tests/predict
          deactivate
          rm -r test_before_pypi
      - name: Publish distribution 📦 to PyPI (dspy)
        uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # 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
        run: sed -i '/#replace_package_version_marker/{n;s/version *= *"[^"]*"/version="${{ needs.extract-tag.outputs.version }}"/;}' .github/.internal_dspyai/pyproject.toml
      - name: Update dspy dependency for dspy-ai release
        run: |
          sed -i '/#replace_dspy_version_marker/{n;s/dspy>=[^"]*/dspy>=${{ needs.extract-tag.outputs.version }}/;}' .github/.internal_dspyai/pyproject.toml
      - name: Build a binary wheel (dspy-ai)
        run: python3 -m build .github/.internal_dspyai/
      - name: Publish distribution 📦 to PyPI (dspy-ai)
        uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
        with:
          attestations: false
          packages-dir: .github/.internal_dspyai/dist/
      - uses: stefanzweifel/git-auto-commit-action@b863ae1933cb653a53c021fe36dbb774e1fb9403 # v5 # auto commit changes to main
        with:
          commit_message: Update versions
          create_branch: true
          branch: release-${{ needs.extract-tag.outputs.version }}
      - name: Checkout main branch
        run: |
          git fetch origin
          git checkout main
      - name: Configure git user
        run: |
          git config --global user.email "actions@github.com"
          git config --global user.name "Github Actions"
      - name: Merge release branch into main
        run: |
          git merge --no-ff release-${{ needs.extract-tag.outputs.version }}
      - name: Push changes to main
        run: |
          git push origin main
docs-push .github/workflows/docs-push.yml
Triggers
push, pull_request
Runs on
ubuntu-latest, ubuntu-latest
Jobs
build-test, update-docs-subtree
Actions
cpina/github-action-push-to-another-repository
Commands
  • cd docs pip install -r requirements.txt mkdocs build
View raw YAML
name: Update DSPy Docs

on:
  push:
    branches:
      - main
    paths:
      - "docs/**"
  pull_request:
    paths:
      - "docs/**"

jobs:
  build-test:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
      - name: Set up Node.js
        uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 # v3.9.1
        with:
          node-version: "18"
      - name: Install dependencies and build
        run: |
          cd docs
          pip install -r requirements.txt
          mkdocs build

  update-docs-subtree:
    if: github.event_name == 'push' && github.repository == 'stanfordnlp/dspy'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
        with:
          fetch-depth: 0
      - name: Push docs to separate repo
        uses: cpina/github-action-push-to-another-repository@55306faa4ed53b815ae49e564af8cfb359d32ae2 # main
        env:
          API_TOKEN_GITHUB: ${{ secrets.GH_PAT }}
        with:
          source-directory: "docs"
          destination-github-username: "krypticmouse"
          destination-repository-name: "dspy-docs"
          user-email: github-actions@github.com
          target-branch: master
precommits_check .github/workflows/precommits_check.yml
Triggers
workflow_dispatch
Runs on
ubuntu-latest
Jobs
pre-commit-checks
Actions
Slashgear/action-check-pr-title, jitterbit/get-changed-files
Commands
  • echo "Changed files" echo ${{ steps.files.outputs.all }} echo "GitHub Client version" echo $(gh --version)
  • python -m pip install --upgrade pip pip install pre-commit echo "Running pre-commit scans:" # adding log display in case of pre-commit errors pre-commit run -v --files ${{ steps.files.outputs.all }}
View raw YAML
name: Pre-commit checks
on:
  workflow_dispatch:

jobs:
  pre-commit-checks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
      - name: Set up Python
        uses: actions/setup-python@7f4fc3e22c37d6ff65e88745f38bd3157c663f7c # v4
        with:
          python-version: "3.10"
          cache: "pip"
      - name: Check Pull Request Title
        uses: Slashgear/action-check-pr-title@76166c63ec0b25cdbe693e5e972e83ca186313fb # main
        with:
          regexp: '(break|build|ci|docs|feat|fix|perf|refactor|style|test|ops|hotfix|release|maint|init|enh|revert)\([a-z,A-Z,0-9,\-,\_,\/,:]+\)(:)\s{1}([\w\s]+)' # Regex the title should match.
      - name: Getting changed files list
        id: files
        uses: jitterbit/get-changed-files@b17fbb00bdc0c0f63fcf166580804b4d2cdc2a42 # v1
      - name: Checking changed files
        shell: bash
        run: |
          echo "Changed files"
          echo ${{ steps.files.outputs.all }}
          echo "GitHub Client version"
          echo $(gh --version)
      - name: Pre-Commit Checks
        run: |
          python -m pip install --upgrade pip
          pip install pre-commit
          echo "Running pre-commit scans:"
          # adding log display in case of pre-commit errors
          pre-commit run -v --files ${{ steps.files.outputs.all }}
        shell: bash
run_tests matrix .github/workflows/run_tests.yml
Triggers
push, pull_request
Runs on
ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest
Jobs
fix, test, llm_call_test, build_package
Matrix
python-version→ 3.10, 3.11, 3.12, 3.13, 3.14
Actions
astral-sh/setup-uv, denoland/setup-deno, astral-sh/setup-uv, chartboost/ruff-action, astral-sh/setup-uv, astral-sh/setup-uv
Commands
  • uv venv .venv echo "${{ github.workspace }}/.venv/bin" >> $GITHUB_PATH
  • uv sync --dev -p .venv --extra dev
  • ruff check --fix-only --diff --exit-non-zero-on-fix || ( echo "" echo "❌ Ruff found issues that can be fixed automatically." echo "💡 To fix them locally, run:" echo "" echo " pre-commit run --all-files" echo "" echo "Then commit and push the changes." exit 1 )
  • deno --version
  • uv venv .venv echo "${{ github.workspace }}/.venv/bin" >> $GITHUB_PATH
  • uv sync --dev -p .venv --extra dev uv pip list
  • uv run -p .venv pytest -vv tests/
  • uv sync -p .venv --extra dev --extra test_extras
View raw YAML
name: Lint, Test, and Build

on:
  push:
    branches:
      - main
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  fix:
    name: Check Ruff Fix
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
      - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
        with:
          python-version: "3.11"
      - name: Install uv with caching
        uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
        with:
          enable-cache: true
          cache-dependency-glob: |
            **/pyproject.toml
            **/uv.lock
      - name: Create and activate virtual environment
        run: |
          uv venv .venv
          echo "${{ github.workspace }}/.venv/bin" >> $GITHUB_PATH
      - name: Install dependencies
        run: uv sync --dev -p .venv --extra dev
      - name: Ruff Check
        run: |
          ruff check --fix-only --diff --exit-non-zero-on-fix || (
            echo ""
            echo "❌ Ruff found issues that can be fixed automatically."
            echo "💡 To fix them locally, run:"
            echo ""
            echo "    pre-commit run --all-files"
            echo ""
            echo "Then commit and push the changes."
            exit 1
          )

  test:
    name: Run Tests
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
      - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install Deno
        uses: denoland/setup-deno@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb # v2.0.3
        with:
          deno-version: v2.7.7
      - name: Verify Deno installation
        run: deno --version
      - name: Install uv with caching
        uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
        with:
          enable-cache: true
          cache-dependency-glob: |
            **/pyproject.toml
            **/uv.lock
      - name: Create and activate virtual environment
        run: |
          uv venv .venv
          echo "${{ github.workspace }}/.venv/bin" >> $GITHUB_PATH
      - name: Install dependencies
        run: |
          uv sync --dev -p .venv --extra dev
          uv pip list
      - name: Run lint with tests
        uses: chartboost/ruff-action@e18ae971ccee1b2d7bbef113930f00c670b78da4 # v1
        with:
          args: check --fix-only
      - name: Run tests with pytest
        run: uv run -p .venv pytest -vv tests/
      - name: Install optional dependencies
        run: uv sync -p .venv --extra dev --extra test_extras
      - name: Run extra and deno tests
        run: uv run -p .venv pytest tests/ -m 'extra or deno' --extra --deno
  
  llm_call_test:
    name: Run Tests with Real LM
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
      - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
        with:
          python-version: 3.11
      - name: Install uv with caching
        uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
        with:
          enable-cache: true
          cache-dependency-glob: |
            **/pyproject.toml
            **/uv.lock
      - name: Create and activate virtual environment
        run: |
          uv venv .venv
          echo "${{ github.workspace }}/.venv/bin" >> $GITHUB_PATH
      - name: Install dependencies
        run: |
          uv sync --dev -p .venv --extra dev
          uv pip list
      - name: Cache Ollama models
        id: cache-ollama
        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
        with:
          path: ollama-data
          key: ollama-llama3.2-3b-${{ runner.os }}-v1
      - name: Start Ollama service
        run: |
          mkdir -p ollama-data
          docker run -d --name ollama \
            -p 11434:11434 \
            -v ${{ github.workspace }}/ollama-data:/root/.ollama \
            ollama/ollama:latest
          timeout 60 bash -c 'until curl -f http://localhost:11434/api/version; do sleep 2; done'
      - name: Pull LLM
        if: steps.cache-ollama.outputs.cache-hit != 'true'
        run: docker exec ollama ollama pull llama3.2:3b
      - name: Set LM environment variable
        run: echo "LM_FOR_TEST=ollama/llama3.2:3b" >> $GITHUB_ENV
      - name: Run tests
        run: uv run -p .venv pytest -m llm_call --llm_call -vv --durations=5 tests/
      - name: Fix permissions for cache
        if: always()
        run: sudo chown -R $USER:$USER ollama-data || true
      - name: Stop Ollama service
        if: always()
        run: docker stop ollama && docker rm ollama

  build_package:
    name: Build Package
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
      - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install uv with caching
        uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5
        with:
          enable-cache: true
          cache-dependency-glob: |
            **/pyproject.toml
            **/uv.lock
      - name: Create and activate virtual environment
        run: |
          uv venv .venv
          echo "${{ github.workspace }}/.venv/bin" >> $GITHUB_PATH
      - name: Install dependencies
        run: uv sync --dev -p .venv --extra dev
      - name: Build
        run: uv run -p .venv python -m build
      - name: Install built package
        run: uv pip install dist/*.whl -p .venv
      - name: Test import dspy
        run: uv run -p .venv python -c "import dspy"