name: Release PyPI PR Wheels on: workflow_dispatch: inputs: pr_number: description: 'PR number to build wheel for' required: true type: string pr_branch: description: 'PR branch name to build from (e.g., my-feature-branch or refs/pull/123/head)' required: true type: string concurrency: group: build-pr-wheel-${{ github.event.inputs.pr_number }} cancel-in-progress: true jobs: build-pr-wheel: if: github.repository == 'sgl-project/sglang' runs-on: ubuntu-latest outputs: wheel_version: ${{ steps.gen_version.outputs.wheel_version }} commit_hash: ${{ steps.gen_version.outputs.commit_hash }} build_date: ${{ steps.gen_version.outputs.build_date }} steps: - uses: actions/checkout@v4 with: ref: ${{ inputs.pr_branch }} fetch-depth: 0 # Need full history for version generation - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.10" - name: Generate PR wheel version id: gen_version run: | # Get base version from version.py BASE_VERSION=$(cat python/sglang/version.py | cut -d'"' -f2) # Get commit info COMMIT_HASH=$(git rev-parse --short HEAD) COMMIT_COUNT=$(git rev-list --count HEAD) # Get current date in YYYY-MM-DD format BUILD_DATE=$(date -u +%Y-%m-%d) # Always use pr-{number} format for suffix SUFFIX="pr-${{ inputs.pr_number }}" # Generate PR wheel version following PEP 440 # Format: {base_version}.dev{commit_count}+pr-{number}.g{commit_hash} WHEEL_VERSION="${BASE_VERSION}.dev${COMMIT_COUNT}+${SUFFIX}.g${COMMIT_HASH}" echo "Base version: ${BASE_VERSION}" echo "PR wheel version: ${WHEEL_VERSION}" echo "Commit: ${COMMIT_HASH}" echo "Build date: ${BUILD_DATE}" echo "wheel_version=${WHEEL_VERSION}" >> $GITHUB_OUTPUT echo "commit_hash=${COMMIT_HASH}" >> $GITHUB_OUTPUT echo "base_version=${BASE_VERSION}" >> $GITHUB_OUTPUT echo "build_date=${BUILD_DATE}" >> $GITHUB_OUTPUT - name: Update pyproject.toml with PR wheel version run: | cd python BASE_VERSION=$(cat sglang/version.py | cut -d'"' -f2) WHEEL_VERSION="${{ steps.gen_version.outputs.wheel_version }}" # Update version (temporary, not committed) sed -i "s/version = \"${BASE_VERSION}\"/version = \"${WHEEL_VERSION}\"/" pyproject.toml # Verify update echo "Updated version in pyproject.toml:" grep "^version" pyproject.toml - name: Install build dependencies run: | cd python pip install build wheel setuptools - name: Build wheel run: | cd python cp ../README.md ../LICENSE . python3 -m build --wheel # List built wheels echo "Built wheel:" ls -lh dist/ - name: Upload wheel artifact uses: actions/upload-artifact@v4 with: name: pr-wheel-${{ inputs.pr_number }} path: python/dist/*.whl retention-days: 30 release-pr-wheel: needs: build-pr-wheel runs-on: ubuntu-latest environment: 'prod' steps: - uses: actions/checkout@v4 - name: Download wheel artifact uses: actions/download-artifact@v4 with: name: pr-wheel-${{ inputs.pr_number }} path: dist/ - name: List downloaded wheels run: | echo "Downloaded wheel:" ls -lh dist/ - name: Create GitHub Release for PR wheel uses: softprops/action-gh-release@v2 with: tag_name: pr-${{ inputs.pr_number }}-${{ needs.build-pr-wheel.outputs.build_date }}-${{ needs.build-pr-wheel.outputs.commit_hash }} name: "PR #${{ inputs.pr_number }} Build (${{ needs.build-pr-wheel.outputs.commit_hash }})" repository: sgl-project/whl token: ${{ secrets.GH_PAT_FOR_WHL_RELEASE }} prerelease: true body: | PR wheel build from PR #${{ inputs.pr_number }} Commit: ${{ github.sha }} Build date: ${{ needs.build-pr-wheel.outputs.build_date }} Version: ${{ needs.build-pr-wheel.outputs.wheel_version }} **Installation via index:** ```bash pip install sglang=={version} --index-url https://sgl-project.github.io/whl/pr/ ``` **Direct installation:** ```bash pip install https://github.com/sgl-project/whl/releases/download/pr-${{ inputs.pr_number }}-${{ needs.build-pr-wheel.outputs.build_date }}-${{ needs.build-pr-wheel.outputs.commit_hash }}/sglang-${{ needs.build-pr-wheel.outputs.wheel_version }}-py3-none-any.whl ``` files: | dist/*.whl - name: Clone wheel index repository run: | git clone https://oauth2:${WHL_TOKEN}@github.com/sgl-project/whl.git sgl-whl cd sgl-whl git config --local user.name "sglang-bot" git config --local user.email "sglangbot@gmail.com" env: WHL_TOKEN: ${{ secrets.GH_PAT_FOR_WHL_RELEASE }} - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.10" - name: Update wheel index run: | python3 scripts/update_pr_whl_index.py \ --pr-number ${{ inputs.pr_number }} \ --commit-hash ${{ needs.build-pr-wheel.outputs.commit_hash }} \ --wheel-version ${{ needs.build-pr-wheel.outputs.wheel_version }} \ --build-date ${{ needs.build-pr-wheel.outputs.build_date }} - name: Push wheel index run: | cd sgl-whl git add -A git diff --staged --quiet || git commit -m "Update PR wheel index for PR #${{ inputs.pr_number }} (commit ${{ needs.build-pr-wheel.outputs.commit_hash }})" git push