Build, test, and publish packages #4
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: Build, test, and upload PyPI package | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - "release-**" | |
| tags: | |
| - "v*" | |
| pull_request: | |
| branches: | |
| - main | |
| - "release-**" | |
| release: | |
| types: | |
| - published | |
| schedule: | |
| # Nightly at midnight UTC - for test.pypi.org publishing | |
| - cron: '0 0 * * *' | |
| env: | |
| LC_ALL: en_US.UTF-8 | |
| defaults: | |
| run: | |
| shell: bash | |
| permissions: | |
| contents: read | |
| jobs: | |
| # Build and validate release artifacts | |
| build-package: | |
| name: Build and check packages | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| include: | |
| - package: llama-stack-api | |
| path: src/llama_stack_api | |
| - package: llama-stack | |
| path: . | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| with: | |
| # for setuptools-scm | |
| fetch-depth: 0 | |
| - name: Install dependent PRs if needed | |
| uses: depends-on/depends-on-action@61cb3f4a0e2c8ae4b90c9448dc57c7ba9ca24c35 # main | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set up Python | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 | |
| with: | |
| python-version: "3.12" | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0 | |
| - name: Install build dependencies | |
| run: uv pip install --system setuptools wheel | |
| - name: Check for missing package entries (llama-stack-api) | |
| if: matrix.package == 'llama-stack-api' | |
| working-directory: src/llama_stack_api | |
| run: | | |
| for f in *.py; do | |
| [[ "$f" == "__init__.py" ]] && continue | |
| grep -q "llama_stack_api.${f%.py}" pyproject.toml || echo "::warning::Missing from py-modules: ${f%.py}" | |
| done | |
| for d in */; do | |
| [[ "$d" =~ ^(__pycache__|dist|build|.*egg-info|\..*)/$ ]] && continue | |
| grep -q "llama_stack_api.${d%/}" pyproject.toml || echo "::warning::Missing from packages: ${d%/}" | |
| done | |
| - name: Build package | |
| run: uv build --out-dir dist --no-build-isolation | |
| working-directory: ${{ matrix.path }} | |
| - name: Install validation tools | |
| run: uv pip install --system twine check-wheel-contents | |
| - name: Check wheel contents | |
| # Ignore pre-existing warnings: | |
| # W002: Duplicate files - many __init__.py files have identical content | |
| # W004: Non-importable paths - distribution dirs use hyphens (e.g., meta-reference-gpu, starter-gpu) | |
| run: check-wheel-contents --ignore W002,W004 ${{ matrix.path }}/dist/*.whl | |
| - name: Validate package with twine | |
| run: twine check ${{ matrix.path }}/dist/* | |
| - name: List dist contents | |
| run: ls -la ${{ matrix.path }}/dist/ | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 | |
| with: | |
| name: Packages-${{ matrix.package }} | |
| path: ${{ matrix.path }}/dist/* | |
| # Functional tests - install and verify packages work | |
| test-package: | |
| name: Test packages (Python ${{ matrix.python-version }}) | |
| runs-on: ubuntu-latest | |
| needs: build-package | |
| strategy: | |
| matrix: | |
| python-version: ['3.12', '3.13'] | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Download llama-stack-api artifacts | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 | |
| with: | |
| name: Packages-llama-stack-api | |
| path: dist-api | |
| - name: Download llama-stack artifacts | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 | |
| with: | |
| name: Packages-llama-stack | |
| path: dist-stack | |
| - name: Create venv and install packages | |
| run: | | |
| uv venv .venv | |
| source .venv/bin/activate | |
| uv pip install dist-api/*.whl dist-stack/*.whl | |
| - name: List Wheel Contents | |
| run: | | |
| source .venv/bin/activate | |
| python -m zipfile -l dist-api/*.whl | |
| - name: Verify Llama Stack package | |
| run: | | |
| source .venv/bin/activate | |
| uv pip list | |
| uv pip show llama-stack | |
| command -v llama | |
| llama stack list-apis | |
| llama stack list-providers inference | |
| llama stack list-deps starter | |
| - name: Verify packages are importable | |
| run: | | |
| source .venv/bin/activate | |
| python -c "import llama_stack; print(f'llama_stack imported successfully from {llama_stack.__file__}')" | |
| python -c "import llama_stack_api; print(f'llama_stack_api imported successfully from {llama_stack_api.__file__}')" | |
| # push to Test PyPI on | |
| # - a new GitHub release is published | |
| # - nightly schedule (to be friendly to test.pypi.org infra) | |
| # Note: llama-stack-api must be published first since llama-stack depends on it | |
| publish-test-pypi: | |
| name: Publish ${{ matrix.package }} to test.pypi.org | |
| # environment: publish-test-pypi | |
| if: | | |
| github.repository_owner == 'llamastack' && ( | |
| github.event.action == 'published' || | |
| github.event_name == 'schedule' | |
| ) | |
| permissions: | |
| contents: read | |
| # see https://docs.pypi.org/trusted-publishers/ | |
| id-token: write | |
| runs-on: ubuntu-latest | |
| needs: test-package | |
| strategy: | |
| max-parallel: 1 | |
| matrix: | |
| package: | |
| - llama-stack-api | |
| - llama-stack | |
| steps: | |
| - name: Fetch build artifacts | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 | |
| with: | |
| name: Packages-${{ matrix.package }} | |
| path: dist | |
| - name: Upload to Test PyPI | |
| uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 | |
| with: | |
| repository-url: https://test.pypi.org/legacy/ | |
| verbose: true | |
| # push to Production PyPI on | |
| # - a new GitHub release is published | |
| # Note: llama-stack-api must be published first since llama-stack depends on it | |
| publish-pypi: | |
| name: Publish ${{ matrix.package }} to pypi.org | |
| # environment: publish-pypi | |
| if: | | |
| github.repository_owner == 'llamastack' && github.event.action == 'published' | |
| permissions: | |
| # see https://docs.pypi.org/trusted-publishers/ | |
| id-token: write | |
| # allow gh release upload | |
| contents: write | |
| runs-on: ubuntu-latest | |
| needs: test-package | |
| strategy: | |
| max-parallel: 1 | |
| matrix: | |
| package: | |
| - llama-stack-api | |
| - llama-stack | |
| steps: | |
| - name: Fetch build artifacts | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 | |
| with: | |
| name: Packages-${{ matrix.package }} | |
| path: dist | |
| - uses: sigstore/gh-action-sigstore-python@f7ad0af51a5648d09a20d00370f0a91c3bdf8f84 # v3.0.1 | |
| with: | |
| inputs: >- | |
| ./dist/*.tar.gz | |
| ./dist/*.whl | |
| release-signing-artifacts: false | |
| - name: Upload artifacts and signatures to GitHub release | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| run: | | |
| gh release upload '${{ github.ref_name }}' dist/* --repo '${{ github.repository }}' | |
| # PyPI does not accept .sigstore artifacts and | |
| # gh-action-pypi-publish has no option to ignore them. | |
| - name: Remove sigstore signatures before uploading to PyPI | |
| run: rm ./dist/*.sigstore.json | |
| - name: Upload to PyPI | |
| uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 | |
| with: | |
| verbose: true |