From 2ef4aa7caeb144f48e08e161f075b93d41835251 Mon Sep 17 00:00:00 2001 From: sashacmc Date: Thu, 4 Jun 2026 20:02:57 +0200 Subject: [PATCH 1/7] Add scripts and CI workflows to build debian package --- .github/workflows/release.yml | 58 +++++++++++++++++++++++++++++++++++ ci/scripts/wheel-to-deb.sh | 58 +++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100755 ci/scripts/wheel-to-deb.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index aed06819..09b3cfbb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -205,6 +205,46 @@ jobs: name: wheels-linux-armv6 path: dist + build-debian: + needs: [tag, build-linux, build-linux-aarch64] + runs-on: ubuntu-latest + strategy: + matrix: + include: + - artifact: wheels-linux-x86_64 + arch: amd64 + - artifact: wheels-linux-i686 + arch: i386 + - artifact: wheels-linux-armv7 + arch: armhf + - artifact: wheels-linux-aarch64 + arch: arm64 + steps: + - name: Checkout this repository + uses: actions/checkout@v4 + with: + ref: ${{ needs.tag.outputs.branch }} + + - name: Download wheel + uses: actions/download-artifact@v4 + with: + name: ${{ matrix.artifact }} + path: dist + + - name: Convert wheel to Debian package + run: | + bash ci/scripts/wheel-to-deb.sh \ + dist/eclipse_zenoh-*.whl \ + python3-eclipse-zenoh \ + ${{ needs.tag.outputs.version }} \ + ${{ matrix.arch }} + + - name: Upload Debian package artifact + uses: actions/upload-artifact@v4 + with: + name: deb-${{ matrix.arch }} + path: "*.deb" + publish-pypi: needs: [ @@ -253,3 +293,21 @@ jobs: branch: ${{ needs.tag.outputs.branch }} github-token: ${{ secrets.BOT_TOKEN_WORKFLOW }} archive-patterns: "^$" + + publish-debian-github: + needs: [tag, build-debian, publish-github] + runs-on: ubuntu-latest + steps: + - name: Download Debian packages + uses: actions/download-artifact@v4 + with: + pattern: deb-* + path: debs + merge-multiple: true + + - name: Upload Debian packages to GitHub release + if: ${{ inputs.live-run || false }} + run: gh release upload ${{ needs.tag.outputs.version }} debs/*.deb --clobber + env: + GH_TOKEN: ${{ secrets.BOT_TOKEN_WORKFLOW }} + GH_REPO: ${{ github.repository }} diff --git a/ci/scripts/wheel-to-deb.sh b/ci/scripts/wheel-to-deb.sh new file mode 100755 index 00000000..b9401230 --- /dev/null +++ b/ci/scripts/wheel-to-deb.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2026 ZettaScale Technology +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Public License 2.0 which is available at +# http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +# which is available at https://www.apache.org/licenses/LICENSE-2.0. +# +# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +# +# Contributors: +# ZettaScale Zenoh Team, +# +# Usage: wheel-to-deb.sh +# Example: +# wheel-to-deb.sh eclipse_zenoh-1.0.0-cp39-abi3-manylinux_2_17_x86_64.whl \ +# python3-eclipse-zenoh 1.0.0 amd64 + +set -euo pipefail + +WHEEL=$1 +PKG=$2 +VER=$3 +ARCH=$4 + +WORKDIR=$(mktemp -d) +trap 'rm -rf "$WORKDIR"' EXIT + +unzip -q "$WHEEL" -d "$WORKDIR/contents" + +DIST_PKG="$WORKDIR/deb/usr/lib/python3/dist-packages" +mkdir -p "$DIST_PKG" + +cp -r "$WORKDIR/contents/zenoh" "$DIST_PKG/" + +mkdir -p "$WORKDIR/deb/DEBIAN" +cat > "$WORKDIR/deb/DEBIAN/control" < +Depends: python3 (>= 3.9), libc6 +Section: python +Priority: optional +Homepage: https://zenoh.io +Description: Eclipse Zenoh Python bindings + Eclipse Zenoh: Zero Overhead Pub/sub, Store/Query and Compute. + . + This package provides the Python bindings for Eclipse Zenoh, enabling + pub/sub, queryable and geo-distributed storage in Python. + . + Built from manylinux wheels; requires Ubuntu 22.04+, Debian 12+, + or any distribution with glibc >= 2.17. +CTRL + +dpkg-deb --build --root-owner-group "$WORKDIR/deb" "${PKG}_${VER}_${ARCH}.deb" +echo "Built: ${PKG}_${VER}_${ARCH}.deb" From 69110d146b6795c037733b9aa0e7193f5e5eea72 Mon Sep 17 00:00:00 2001 From: sashacmc Date: Fri, 5 Jun 2026 09:31:05 +0200 Subject: [PATCH 2/7] fix: remove arch-specific glibc version from deb description --- ci/scripts/wheel-to-deb.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ci/scripts/wheel-to-deb.sh b/ci/scripts/wheel-to-deb.sh index b9401230..feb1a4a3 100755 --- a/ci/scripts/wheel-to-deb.sh +++ b/ci/scripts/wheel-to-deb.sh @@ -50,8 +50,7 @@ Description: Eclipse Zenoh Python bindings This package provides the Python bindings for Eclipse Zenoh, enabling pub/sub, queryable and geo-distributed storage in Python. . - Built from manylinux wheels; requires Ubuntu 22.04+, Debian 12+, - or any distribution with glibc >= 2.17. + Built from manylinux wheels. CTRL dpkg-deb --build --root-owner-group "$WORKDIR/deb" "${PKG}_${VER}_${ARCH}.deb" From ed2f824bce3d9b25c4b5a3ee407c1aed19fc9d0a Mon Sep 17 00:00:00 2001 From: sashacmc Date: Fri, 5 Jun 2026 09:42:15 +0200 Subject: [PATCH 3/7] fix: add argument validation and include dist-info in deb package --- ci/scripts/wheel-to-deb.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ci/scripts/wheel-to-deb.sh b/ci/scripts/wheel-to-deb.sh index feb1a4a3..555e3d3c 100755 --- a/ci/scripts/wheel-to-deb.sh +++ b/ci/scripts/wheel-to-deb.sh @@ -19,6 +19,12 @@ set -euo pipefail +if [[ $# -ne 4 ]]; then + echo "Usage: $0 " >&2 + echo "Example: $0 eclipse_zenoh-1.0.0-cp39-abi3-manylinux_2_17_x86_64.whl python3-eclipse-zenoh 1.0.0 amd64" >&2 + exit 1 +fi + WHEEL=$1 PKG=$2 VER=$3 @@ -34,6 +40,13 @@ mkdir -p "$DIST_PKG" cp -r "$WORKDIR/contents/zenoh" "$DIST_PKG/" +# Copy dist-info for importlib.metadata compatibility, omitting stale RECORD +DIST_INFO=$(find "$WORKDIR/contents" -maxdepth 1 -name "*.dist-info" -type d) +if [[ -n "$DIST_INFO" ]]; then + cp -r "$DIST_INFO" "$DIST_PKG/" + rm -f "$DIST_PKG/$(basename "$DIST_INFO")/RECORD" +fi + mkdir -p "$WORKDIR/deb/DEBIAN" cat > "$WORKDIR/deb/DEBIAN/control" < Date: Fri, 5 Jun 2026 10:21:07 +0200 Subject: [PATCH 4/7] fix: guard against multiple wheels matching glob in build-debian job --- .github/workflows/release.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 09b3cfbb..dbc8d64e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -233,8 +233,13 @@ jobs: - name: Convert wheel to Debian package run: | + wheels=(dist/eclipse_zenoh-*.whl) + if [[ ${#wheels[@]} -ne 1 ]]; then + echo "Expected exactly one wheel, found: ${wheels[*]}" >&2 + exit 1 + fi bash ci/scripts/wheel-to-deb.sh \ - dist/eclipse_zenoh-*.whl \ + "${wheels[0]}" \ python3-eclipse-zenoh \ ${{ needs.tag.outputs.version }} \ ${{ matrix.arch }} From 2ee0adc0217216cb4cd0a71bcd1e3a27481f6af4 Mon Sep 17 00:00:00 2001 From: sashacmc Date: Fri, 5 Jun 2026 10:48:07 +0200 Subject: [PATCH 5/7] fix: use array for dist-info lookup and enable nullglob for wheel glob --- .github/workflows/release.yml | 3 ++- ci/scripts/wheel-to-deb.sh | 12 ++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dbc8d64e..7fb1c482 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -233,9 +233,10 @@ jobs: - name: Convert wheel to Debian package run: | + shopt -s nullglob wheels=(dist/eclipse_zenoh-*.whl) if [[ ${#wheels[@]} -ne 1 ]]; then - echo "Expected exactly one wheel, found: ${wheels[*]}" >&2 + echo "Expected exactly one wheel, found: ${#wheels[@]} (${wheels[*]})" >&2 exit 1 fi bash ci/scripts/wheel-to-deb.sh \ diff --git a/ci/scripts/wheel-to-deb.sh b/ci/scripts/wheel-to-deb.sh index 555e3d3c..420514b0 100755 --- a/ci/scripts/wheel-to-deb.sh +++ b/ci/scripts/wheel-to-deb.sh @@ -41,10 +41,14 @@ mkdir -p "$DIST_PKG" cp -r "$WORKDIR/contents/zenoh" "$DIST_PKG/" # Copy dist-info for importlib.metadata compatibility, omitting stale RECORD -DIST_INFO=$(find "$WORKDIR/contents" -maxdepth 1 -name "*.dist-info" -type d) -if [[ -n "$DIST_INFO" ]]; then - cp -r "$DIST_INFO" "$DIST_PKG/" - rm -f "$DIST_PKG/$(basename "$DIST_INFO")/RECORD" +mapfile -t DIST_INFO_DIRS < <(find "$WORKDIR/contents" -maxdepth 1 -name "*.dist-info" -type d) +if [[ ${#DIST_INFO_DIRS[@]} -gt 1 ]]; then + echo "Expected at most one dist-info directory, found: ${DIST_INFO_DIRS[*]}" >&2 + exit 1 +fi +if [[ ${#DIST_INFO_DIRS[@]} -eq 1 ]]; then + cp -r "${DIST_INFO_DIRS[0]}" "$DIST_PKG/" + rm -f "$DIST_PKG/$(basename "${DIST_INFO_DIRS[0]}")/RECORD" fi mkdir -p "$WORKDIR/deb/DEBIAN" From 9ef9ea14b542a27302757d7386c327f77929d5eb Mon Sep 17 00:00:00 2001 From: sashacmc Date: Fri, 5 Jun 2026 11:25:25 +0200 Subject: [PATCH 6/7] fix: keep RECORD in dist-info and derive versioned libc6 dep from wheel filename --- ci/scripts/wheel-to-deb.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ci/scripts/wheel-to-deb.sh b/ci/scripts/wheel-to-deb.sh index 420514b0..ed4d1a51 100755 --- a/ci/scripts/wheel-to-deb.sh +++ b/ci/scripts/wheel-to-deb.sh @@ -40,7 +40,7 @@ mkdir -p "$DIST_PKG" cp -r "$WORKDIR/contents/zenoh" "$DIST_PKG/" -# Copy dist-info for importlib.metadata compatibility, omitting stale RECORD +# Copy dist-info for importlib.metadata and pip compatibility mapfile -t DIST_INFO_DIRS < <(find "$WORKDIR/contents" -maxdepth 1 -name "*.dist-info" -type d) if [[ ${#DIST_INFO_DIRS[@]} -gt 1 ]]; then echo "Expected at most one dist-info directory, found: ${DIST_INFO_DIRS[*]}" >&2 @@ -48,7 +48,13 @@ if [[ ${#DIST_INFO_DIRS[@]} -gt 1 ]]; then fi if [[ ${#DIST_INFO_DIRS[@]} -eq 1 ]]; then cp -r "${DIST_INFO_DIRS[0]}" "$DIST_PKG/" - rm -f "$DIST_PKG/$(basename "${DIST_INFO_DIRS[0]}")/RECORD" +fi + +# Derive minimum glibc version from the manylinux tag in the wheel filename +# e.g. manylinux_2_17 -> libc6 (>= 2.17), manylinux_2_28 -> libc6 (>= 2.28) +LIBC6_DEP="libc6" +if [[ "$WHEEL" =~ manylinux_([0-9]+)_([0-9]+) ]]; then + LIBC6_DEP="libc6 (>= ${BASH_REMATCH[1]}.${BASH_REMATCH[2]})" fi mkdir -p "$WORKDIR/deb/DEBIAN" @@ -57,7 +63,7 @@ Package: $PKG Version: $VER Architecture: $ARCH Maintainer: ZettaScale Zenoh Team -Depends: python3 (>= 3.9), libc6 +Depends: python3 (>= 3.9), $LIBC6_DEP Section: python Priority: optional Homepage: https://zenoh.io From 988efa3e51dda99b1f23506c6ffffbe296d26ec8 Mon Sep 17 00:00:00 2001 From: sashacmc Date: Fri, 5 Jun 2026 11:53:08 +0200 Subject: [PATCH 7/7] fix: add INSTALLER marker and quote version in workflow --- .github/workflows/release.yml | 6 +++--- ci/scripts/wheel-to-deb.sh | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7fb1c482..f9f61aa7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -242,8 +242,8 @@ jobs: bash ci/scripts/wheel-to-deb.sh \ "${wheels[0]}" \ python3-eclipse-zenoh \ - ${{ needs.tag.outputs.version }} \ - ${{ matrix.arch }} + "${{ needs.tag.outputs.version }}" \ + "${{ matrix.arch }}" - name: Upload Debian package artifact uses: actions/upload-artifact@v4 @@ -313,7 +313,7 @@ jobs: - name: Upload Debian packages to GitHub release if: ${{ inputs.live-run || false }} - run: gh release upload ${{ needs.tag.outputs.version }} debs/*.deb --clobber + run: gh release upload "${{ needs.tag.outputs.version }}" debs/*.deb --clobber env: GH_TOKEN: ${{ secrets.BOT_TOKEN_WORKFLOW }} GH_REPO: ${{ github.repository }} diff --git a/ci/scripts/wheel-to-deb.sh b/ci/scripts/wheel-to-deb.sh index ed4d1a51..73dd12e5 100755 --- a/ci/scripts/wheel-to-deb.sh +++ b/ci/scripts/wheel-to-deb.sh @@ -48,6 +48,8 @@ if [[ ${#DIST_INFO_DIRS[@]} -gt 1 ]]; then fi if [[ ${#DIST_INFO_DIRS[@]} -eq 1 ]]; then cp -r "${DIST_INFO_DIRS[0]}" "$DIST_PKG/" + # Mark as dpkg-managed so pip does not attempt to uninstall these files + echo "dpkg" > "$DIST_PKG/$(basename "${DIST_INFO_DIRS[0]}")/INSTALLER" fi # Derive minimum glibc version from the manylinux tag in the wheel filename