| 1 | #!/usr/bin/env bash |
| 2 | |
| 3 | set -e |
| 4 | |
| 5 | BUCKET="vllm-wheels" |
| 6 | SUBPATH=$BUILDKITE_COMMIT |
| 7 | S3_COMMIT_PREFIX="s3://$BUCKET/$SUBPATH/" |
| 8 | |
| 9 | RELEASE_VERSION=$(buildkite-agent meta-data get release-version) |
| 10 | GIT_VERSION=$(git describe --exact-match --tags "$BUILDKITE_COMMIT" 2>/dev/null) |
| 11 | |
| 12 | echo "Release version from Buildkite: $RELEASE_VERSION" |
| 13 | |
| 14 | if [[ -z "$GIT_VERSION" ]]; then |
| 15 | echo "[FATAL] Not on a git tag, cannot create release." |
| 16 | exit 1 |
| 17 | else |
| 18 | echo "Git version for commit $BUILDKITE_COMMIT: $GIT_VERSION" |
| 19 | fi |
| 20 | # sanity check for version mismatch |
| 21 | if [[ "$RELEASE_VERSION" != "$GIT_VERSION" ]]; then |
| 22 | if [[ "$FORCE_RELEASE_IGNORE_VERSION_MISMATCH" == "true" ]]; then |
| 23 | echo "[WARNING] Force release and ignore version mismatch" |
| 24 | else |
| 25 | echo "[FATAL] Release version from Buildkite does not match Git version." |
| 26 | exit 1 |
| 27 | fi |
| 28 | fi |
| 29 | PURE_VERSION=${RELEASE_VERSION#v} # remove leading 'v' |
| 30 | |
| 31 | # check pypi token |
| 32 | if [[ -z "$PYPI_TOKEN" ]]; then |
| 33 | echo "[FATAL] PYPI_TOKEN is not set." |
| 34 | exit 1 |
| 35 | else |
| 36 | export TWINE_USERNAME="__token__" |
| 37 | export TWINE_PASSWORD="$PYPI_TOKEN" |
| 38 | fi |
| 39 | |
| 40 | set -x # avoid printing secrets above |
| 41 | |
| 42 | # install uv if not already available |
| 43 | if ! command -v uv &> /dev/null; then |
| 44 | curl -LsSf https://astral.sh/uv/install.sh | UV_VERSION=0.11.14 sh |
| 45 | export PATH="$HOME/.local/bin:$PATH" |
| 46 | fi |
| 47 | |
| 48 | # install twine and sdist build prerequisites using uv with Python 3.12 |
| 49 | uv venv --python 3.12 /tmp/vllm-release-env |
| 50 | source /tmp/vllm-release-env/bin/activate |
| 51 | uv pip install twine |
| 52 | uv pip install -r requirements/build/cuda.txt |
| 53 | python3 -m twine --version |
| 54 | |
| 55 | # copy release wheels to local directory |
| 56 | DIST_DIR=/tmp/vllm-release-dist |
| 57 | echo "Existing wheels on S3:" |
| 58 | aws s3 ls "$S3_COMMIT_PREFIX" |
| 59 | echo "Copying wheels to local directory" |
| 60 | mkdir -p $DIST_DIR |
| 61 | # include only wheels for the release version, ignore all files with "dev" or "rc" in the name (without excluding 'aarch64') |
| 62 | aws s3 cp --recursive --exclude "*" --include "vllm-${PURE_VERSION}*.whl" --exclude "*dev*" --exclude "*rc[0-9]*" "$S3_COMMIT_PREFIX" $DIST_DIR |
| 63 | echo "Wheels copied to local directory" |
| 64 | # generate source distribution using setup.py |
| 65 | python setup.py sdist --dist-dir=$DIST_DIR |
| 66 | ls -la $DIST_DIR |
| 67 | |
| 68 | SDIST_FILE=$(find $DIST_DIR -name "vllm*.tar.gz") |
| 69 | echo "Found sdist: $SDIST_FILE" |
| 70 | |
| 71 | # upload wheels to PyPI (only default variant, i.e. files without '+' in the name) |
| 72 | PYPI_WHEEL_FILES=$(find $DIST_DIR -name "vllm-${PURE_VERSION}*.whl" -not -name "*+*") |
| 73 | if [[ -z "$PYPI_WHEEL_FILES" ]]; then |
| 74 | echo "No default variant wheels found, quitting..." |
| 75 | exit 1 |
| 76 | fi |
| 77 | |
| 78 | python3 -m twine check "$PYPI_WHEEL_FILES" "$SDIST_FILE" |
| 79 | python3 -m twine upload --non-interactive --verbose "$PYPI_WHEEL_FILES" "$SDIST_FILE" |
| 80 | echo "Wheels and source distribution uploaded to PyPI" |