mirror of
https://github.com/qdrant/qdrant.git
synced 2026-07-31 07:00:56 -05:00
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 8.3.2 to 9.0.0.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](11f9893b08...c771a70e62)
---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
dependency-version: 9.0.0
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
447 lines
17 KiB
YAML
447 lines
17 KiB
YAML
name: Qdrant Edge Release Build
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
publish:
|
|
description: 'Publish to PyPI'
|
|
type: boolean
|
|
default: false
|
|
required: true
|
|
push:
|
|
branches: [ dev ]
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: edge-py-release-${{ github.ref }}
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
edge-py-linux:
|
|
name: Build Python wheels [Linux]
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
strategy:
|
|
matrix:
|
|
# On `push` to `dev`, only build the single most popular flavor:
|
|
# x86_64 manylinux_2_17 (widest glibc compatibility). Thanks to
|
|
# abi3, that one wheel covers every CPython >= 3.10, including the
|
|
# latest. The full matrix (aarch64, manylinux_2_28, musl, PyPy)
|
|
# only runs on manual `workflow_dispatch` releases.
|
|
target: ${{ github.event_name == 'push' && fromJSON('["x86_64"]') || fromJSON('["x86_64", "aarch64"]') }}
|
|
manylinux: ${{ github.event_name == 'push' && fromJSON('["manylinux_2_17"]') || fromJSON('["manylinux_2_17", "manylinux_2_28"]') }}
|
|
python: ${{ github.event_name == 'push' && fromJSON('["python3.10"]') || fromJSON('["python3.10", "pypy3.11"]') }}
|
|
|
|
include: >-
|
|
${{ github.event_name == 'push' && fromJSON('[]') || fromJSON('[
|
|
{"arch": "x86_64", "target": "x86_64-unknown-linux-musl", "manylinux": "musllinux_1_2", "python": "python3.10"},
|
|
{"arch": "aarch64", "target": "aarch64-unknown-linux-musl", "manylinux": "musllinux_1_2", "python": "python3.10"}
|
|
]') }}
|
|
|
|
exclude:
|
|
- target: aarch64
|
|
manylinux: manylinux_2_17
|
|
|
|
steps:
|
|
- name: Checkout Qdrant
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
|
|
- name: Set pre-release version
|
|
# Bump the patch component and append a `-dev<run_number>` SemVer
|
|
# pre-release suffix so the dev version sorts strictly ABOVE the
|
|
# latest published stable (e.g. Cargo.toml `0.7.2` -> Cargo.toml
|
|
# `0.7.3-dev137` -> wheel `0.7.3.dev137`). Cargo rejects PEP 440
|
|
# syntax `.dev` because it isn't valid SemVer, so we write SemVer
|
|
# here and let maturin translate to PEP 440 when building the wheel.
|
|
# Combined with `pip install --pre`, this lets consumers pull "the
|
|
# current dev" without knowing the run number, and prevents pip
|
|
# from silently preferring the older stable release.
|
|
if: github.event_name == 'push'
|
|
shell: bash
|
|
working-directory: lib/edge/python
|
|
run: |
|
|
awk -v run="${GITHUB_RUN_NUMBER}" '
|
|
!patched && /^version = "/ {
|
|
# Assumes SemVer X.Y.Z inside the quotes; bump patch, append -devN.
|
|
split($0, quoted, "\"")
|
|
split(quoted[2], parts, ".")
|
|
parts[3] = parts[3] + 1
|
|
print "version = \"" parts[1] "." parts[2] "." parts[3] "-dev" run "\""
|
|
patched = 1
|
|
next
|
|
}
|
|
{ print }
|
|
' Cargo.toml > Cargo.toml.new
|
|
mv Cargo.toml.new Cargo.toml
|
|
grep '^version' Cargo.toml
|
|
|
|
- name: Build Python wheel
|
|
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
|
|
with:
|
|
command: build
|
|
args: --release --features abi3 --interpreter ${{ matrix.python }} --out dist
|
|
working-directory: lib/edge/python
|
|
target: ${{ matrix.target }}
|
|
manylinux: ${{ matrix.manylinux }}
|
|
|
|
- name: Upload Python wheel
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: qdrant-edge-${{ matrix.manylinux }}-${{ matrix.arch || matrix.target }}-${{ matrix.python }}
|
|
path: lib/edge/python/dist
|
|
|
|
|
|
edge-py-macos:
|
|
name: Build Python wheels [macOS]
|
|
|
|
runs-on: macos-latest
|
|
|
|
# Dev pushes only build Linux x86_64; the full platform matrix is
|
|
# reserved for manual `workflow_dispatch` releases.
|
|
if: github.event_name != 'push'
|
|
|
|
strategy:
|
|
matrix:
|
|
target: [x86_64, aarch64]
|
|
python:
|
|
- label: python3.10
|
|
version: '3.10'
|
|
- pypy3.11
|
|
|
|
steps:
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
|
|
|
|
- name: Install Python
|
|
id: setup-python
|
|
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
with:
|
|
python-version: ${{ matrix.python.version || matrix.python }}
|
|
|
|
- name: Checkout Qdrant
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
|
|
- name: Set pre-release version
|
|
# See the identical step on the Linux job for the rationale (SemVer
|
|
# `-dev<N>` + patch bump so maturin emits PEP 440 `X.Y.(Z+1).dev<N>`).
|
|
if: github.event_name == 'push'
|
|
shell: bash
|
|
working-directory: lib/edge/python
|
|
run: |
|
|
awk -v run="${GITHUB_RUN_NUMBER}" '
|
|
!patched && /^version = "/ {
|
|
split($0, quoted, "\"")
|
|
split(quoted[2], parts, ".")
|
|
parts[3] = parts[3] + 1
|
|
print "version = \"" parts[1] "." parts[2] "." parts[3] "-dev" run "\""
|
|
patched = 1
|
|
next
|
|
}
|
|
{ print }
|
|
' Cargo.toml > Cargo.toml.new
|
|
mv Cargo.toml.new Cargo.toml
|
|
grep '^version' Cargo.toml
|
|
|
|
- name: Build Python wheel
|
|
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
|
|
with:
|
|
command: build
|
|
args: --release --features abi3 --interpreter ${{ steps.setup-python.outputs.python-path }} --out dist
|
|
working-directory: lib/edge/python
|
|
target: ${{ matrix.target }}
|
|
|
|
- name: Upload Python wheel
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: qdrant-edge-macos-${{ matrix.target }}-${{ matrix.python.label || matrix.python }}
|
|
path: lib/edge/python/dist
|
|
|
|
|
|
edge-py-windows:
|
|
name: Build Python wheels [Windows]
|
|
|
|
runs-on: windows-latest
|
|
|
|
# Dev pushes only build Linux x86_64; the full platform matrix is
|
|
# reserved for manual `workflow_dispatch` releases.
|
|
if: github.event_name != 'push'
|
|
|
|
strategy:
|
|
matrix:
|
|
target: [x86_64]
|
|
python:
|
|
- label: python3.10
|
|
version: '3.10'
|
|
- pypy3.11
|
|
|
|
steps:
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
|
|
|
|
- name: Install Python
|
|
id: setup-python
|
|
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
with:
|
|
python-version: ${{ matrix.python.version || matrix.python }}
|
|
|
|
- name: Checkout Qdrant
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
|
|
- name: Set pre-release version
|
|
# See the identical step on the Linux job for the rationale (SemVer
|
|
# `-dev<N>` + patch bump so maturin emits PEP 440 `X.Y.(Z+1).dev<N>`).
|
|
if: github.event_name == 'push'
|
|
shell: bash
|
|
working-directory: lib/edge/python
|
|
run: |
|
|
awk -v run="${GITHUB_RUN_NUMBER}" '
|
|
!patched && /^version = "/ {
|
|
split($0, quoted, "\"")
|
|
split(quoted[2], parts, ".")
|
|
parts[3] = parts[3] + 1
|
|
print "version = \"" parts[1] "." parts[2] "." parts[3] "-dev" run "\""
|
|
patched = 1
|
|
next
|
|
}
|
|
{ print }
|
|
' Cargo.toml > Cargo.toml.new
|
|
mv Cargo.toml.new Cargo.toml
|
|
grep '^version' Cargo.toml
|
|
|
|
- name: Build Python wheel
|
|
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
|
|
with:
|
|
command: build
|
|
args: --release --features abi3 --interpreter ${{ steps.setup-python.outputs.python-path }} --out dist
|
|
working-directory: lib/edge/python
|
|
target: ${{ matrix.target }}
|
|
|
|
- name: Upload Python wheel
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: qdrant-edge-windows-${{ matrix.target }}-${{ matrix.python.label || matrix.python }}
|
|
path: lib/edge/python/dist
|
|
|
|
|
|
edge-py-test:
|
|
name: Test Python wheels [${{ matrix.os }}, ${{ matrix.python }}]
|
|
|
|
runs-on: ${{ matrix.os }}
|
|
needs:
|
|
- edge-py-linux
|
|
- edge-py-macos
|
|
- edge-py-windows
|
|
|
|
# macOS/Windows builds are intentionally skipped on `push`, which by
|
|
# default would skip this job too — override with `!cancelled()` and
|
|
# only require the jobs that were supposed to run.
|
|
if: >-
|
|
${{ !cancelled()
|
|
&& needs.edge-py-linux.result == 'success'
|
|
&& (github.event_name == 'push' || (needs.edge-py-macos.result == 'success' && needs.edge-py-windows.result == 'success')) }}
|
|
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
# Dev pushes test the single x86_64 Linux wheel on the latest
|
|
# stable Python only. Production releases (workflow_dispatch)
|
|
# verify the abi3 wheel against every stable CPython plus PyPy.
|
|
os: ${{ github.event_name == 'push' && fromJSON('["ubuntu-latest"]') || fromJSON('["macos-latest", "ubuntu-24.04-arm", "ubuntu-latest", "windows-latest"]') }}
|
|
python: ${{ github.event_name == 'push' && fromJSON('["3.14"]') || fromJSON('["3.10", "3.11", "3.12", "3.13", "3.14", "pypy3.11"]') }}
|
|
|
|
steps:
|
|
- name: Checkout Qdrant
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
|
|
- name: Install Just
|
|
uses: ./.github/actions/setup-just
|
|
|
|
- name: Install uv
|
|
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
|
|
- name: Install Python
|
|
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
with:
|
|
python-version: ${{ matrix.python }}
|
|
|
|
- name: Download wheels
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
pattern: qdrant-edge-*
|
|
merge-multiple: true
|
|
path: lib/edge/python/dist
|
|
|
|
- name: Setup Qdrant
|
|
uses: ./.github/actions/setup-qdrant
|
|
|
|
- name: Install and test wheel
|
|
working-directory: lib/edge/python
|
|
run: |
|
|
uv venv --allow-existing --python ${{ matrix.python }}
|
|
uv pip install --no-index --find-links dist/ qdrant-edge-py
|
|
uv pip install requests
|
|
just py-examples
|
|
|
|
|
|
merge-artifacts:
|
|
name: Merge release artifacts
|
|
|
|
runs-on: ubuntu-latest
|
|
needs:
|
|
- edge-py-linux
|
|
- edge-py-macos
|
|
- edge-py-windows
|
|
- edge-py-test
|
|
|
|
# `!cancelled()` because macOS/Windows builds are skipped on `push`;
|
|
# `edge-py-test` succeeding already implies every required build passed.
|
|
if: ${{ !cancelled() && needs.edge-py-test.result == 'success' && (inputs.publish || github.event_name == 'push') }}
|
|
|
|
steps:
|
|
- name: Merge release artifacts
|
|
uses: actions/upload-artifact/merge@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: qdrant-edge
|
|
pattern: qdrant-edge-*
|
|
delete-merged: false
|
|
|
|
|
|
publish:
|
|
name: Publish to PyPI
|
|
|
|
runs-on: ubuntu-latest
|
|
needs:
|
|
- merge-artifacts
|
|
|
|
# Stable releases go to PyPI via manual workflow_dispatch.
|
|
# Dev pre-releases from `push` to `dev` go to GCS instead (see publish-gcs).
|
|
if: inputs.publish
|
|
|
|
steps:
|
|
- name: Install Python
|
|
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
|
|
- name: Download release wheels
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: qdrant-edge
|
|
|
|
- name: Publish to PyPI
|
|
env:
|
|
TWINE_USERNAME: __token__
|
|
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN_EDGE }}
|
|
run: |
|
|
pip install --upgrade twine
|
|
twine upload --skip-existing *
|
|
|
|
|
|
publish-gcs:
|
|
name: Publish dev wheels to GCS
|
|
|
|
runs-on: ubuntu-latest
|
|
needs:
|
|
- merge-artifacts
|
|
|
|
# Only publish dev pre-releases (from push to `dev`) to the GCS bucket.
|
|
# Manual workflow_dispatch runs target PyPI via the `publish` job above.
|
|
if: github.event_name == 'push'
|
|
|
|
env:
|
|
GCS_BUCKET: qdrant-debug
|
|
GCS_ENDPOINT: https://storage.googleapis.com
|
|
# Sub-folder inside the same bucket used by debug-tools.yml
|
|
GCS_PREFIX: edge-py-dev
|
|
# GCS interop ignores the region, but the AWS CLI requires one to be set.
|
|
AWS_REGION: auto
|
|
|
|
steps:
|
|
- name: Download release wheels
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: qdrant-edge
|
|
path: dist
|
|
|
|
- name: Upload wheels and regenerate index
|
|
env:
|
|
# GCS HMAC interoperability keys (AWS-style), stored as repo secrets.
|
|
AWS_ACCESS_KEY_ID: ${{ secrets.GCS_ACCESS_KEY_ID }}
|
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.GCS_SECRET_ACCESS_KEY }}
|
|
# Recent AWS CLI adds default CRC32 integrity checksums that GCS's
|
|
# S3-compatible UploadPart rejects (SignatureDoesNotMatch). Opt out so
|
|
# multipart uploads of the larger wheels work.
|
|
AWS_REQUEST_CHECKSUM_CALCULATION: when_required
|
|
AWS_RESPONSE_CHECKSUM_VALIDATION: when_required
|
|
run: |
|
|
# Extract the current version from a freshly built wheel filename.
|
|
# Wheel filename format (PEP 427):
|
|
# {distribution}-{version}-{python-tag}-{abi-tag}-{platform-tag}.whl
|
|
# PEP 440 versions never contain `-`, so a simple field split is safe.
|
|
current_version=$(ls dist/*.whl | head -1 | sed 's|.*/qdrant_edge_py-\([^-]*\)-.*|\1|')
|
|
echo "Publishing qdrant-edge-py ${current_version}"
|
|
|
|
# Upload the freshly built wheels. Object overwrite is a no-op for the
|
|
# same content; different content would replace (unlike PyPI's immutable
|
|
# filenames), but our `.dev<run_number>` versioning gives every push a
|
|
# unique filename so collisions shouldn't happen.
|
|
aws s3 cp dist/ "s3://${GCS_BUCKET}/${GCS_PREFIX}/wheels/" \
|
|
--recursive --exclude '*' --include '*.whl' \
|
|
--endpoint-url "$GCS_ENDPOINT" --region "$AWS_REGION"
|
|
|
|
# Delete every wheel that doesn't belong to the current version, so
|
|
# only the latest dev release is kept in the bucket. Done AFTER upload
|
|
# so there's never a window with zero wheels available.
|
|
aws s3 ls "s3://${GCS_BUCKET}/${GCS_PREFIX}/wheels/" \
|
|
--endpoint-url "$GCS_ENDPOINT" --region "$AWS_REGION" \
|
|
| awk '{print $NF}' \
|
|
| grep '\.whl$' \
|
|
| grep -vF "qdrant_edge_py-${current_version}-" \
|
|
| while read -r stale; do
|
|
echo "Removing stale wheel: ${stale}"
|
|
aws s3 rm "s3://${GCS_BUCKET}/${GCS_PREFIX}/wheels/${stale}" \
|
|
--endpoint-url "$GCS_ENDPOINT" --region "$AWS_REGION"
|
|
done
|
|
|
|
# Regenerate the pip-compatible HTML index. After the cleanup above,
|
|
# only the current version's wheels remain in the bucket.
|
|
base_url="${GCS_ENDPOINT}/${GCS_BUCKET}/${GCS_PREFIX}/wheels"
|
|
{
|
|
echo '<!DOCTYPE html>'
|
|
echo '<html><body>'
|
|
aws s3 ls "s3://${GCS_BUCKET}/${GCS_PREFIX}/wheels/" \
|
|
--endpoint-url "$GCS_ENDPOINT" --region "$AWS_REGION" \
|
|
| awk '{print $NF}' \
|
|
| grep '\.whl$' \
|
|
| sort \
|
|
| while read -r wheel; do
|
|
echo "<a href=\"${base_url}/${wheel}\">${wheel}</a><br>"
|
|
done
|
|
echo '</body></html>'
|
|
} > qdrant-edge-py.html
|
|
|
|
aws s3 cp qdrant-edge-py.html "s3://${GCS_BUCKET}/${GCS_PREFIX}/qdrant-edge-py.html" \
|
|
--endpoint-url "$GCS_ENDPOINT" --region "$AWS_REGION" \
|
|
--content-type text/html
|
|
|
|
# Surface the install command in the job summary
|
|
index_url="${GCS_ENDPOINT}/${GCS_BUCKET}/${GCS_PREFIX}/qdrant-edge-py.html"
|
|
{
|
|
echo "## qdrant-edge-py dev wheels uploaded"
|
|
echo ""
|
|
echo "Published version: ${current_version}"
|
|
echo ""
|
|
echo "Index: <${index_url}>"
|
|
echo ""
|
|
echo "Install the current dev build (no version pin needed):"
|
|
echo '```'
|
|
echo "pip install --find-links ${index_url} qdrant-edge-py --pre"
|
|
echo '```'
|
|
echo ""
|
|
echo "Pin a specific dev version:"
|
|
echo '```'
|
|
echo "pip install --find-links ${index_url} qdrant-edge-py==${current_version}"
|
|
echo '```'
|
|
} >> "$GITHUB_STEP_SUMMARY"
|