Skip to content

Commit 45bd17d

Browse files
committed
ssh-python: Add version 1.2.0.post1
1 parent 6d2d8ef commit 45bd17d

2 files changed

Lines changed: 225 additions & 0 deletions

File tree

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# SPDX-FileCopyrightText: 2026 The RISE Project
2+
# SPDX-License-Identifier: MIT
3+
---
4+
# Based on the `manylinux-*`/`python_test` jobs of
5+
# https://github.com/ParallelSSH/ssh-python/blob/1.2.0.post1/.circleci/config.yml
6+
name: Build ssh-python wheels (riscv64)
7+
8+
on:
9+
workflow_dispatch:
10+
inputs:
11+
version:
12+
description: 'Version glob to (re)build; empty builds every version of docs/packages/ssh-python.yaml not released yet'
13+
required: false
14+
default: ''
15+
pull_request:
16+
branches: [main]
17+
paths:
18+
- '.github/workflows/build-ssh-python.yml'
19+
- 'docs/packages/ssh-python.yaml'
20+
push:
21+
branches: [main]
22+
paths:
23+
- '.github/workflows/build-ssh-python.yml'
24+
- 'docs/packages/ssh-python.yaml'
25+
26+
concurrency:
27+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
28+
cancel-in-progress: true
29+
30+
permissions:
31+
contents: read # to fetch code (actions/checkout)
32+
33+
env:
34+
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64
35+
36+
jobs:
37+
setup:
38+
uses: $/.github/workflows/_setup.yml
39+
with:
40+
package: ssh-python
41+
version: ${{ inputs.version }}
42+
43+
build_wheels:
44+
needs: [setup]
45+
if: needs.setup.outputs.versions != '[]'
46+
name: Build ssh-python ${{ matrix.version }} ${{ matrix.python }}-manylinux_riscv64
47+
runs-on: ubuntu-24.04-riscv
48+
timeout-minutes: 60
49+
strategy:
50+
fail-fast: false
51+
matrix:
52+
version: ${{ fromJSON(needs.setup.outputs.versions) }}
53+
python: ["cp312", "cp313", "cp314", "cp314t"]
54+
55+
env:
56+
SSH_PYTHON_VERSION: ${{ matrix.version }}
57+
58+
steps:
59+
- name: Checkout ssh-python ${{ env.SSH_PYTHON_VERSION }}
60+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
61+
with:
62+
repository: ParallelSSH/ssh-python
63+
ref: ${{ env.SSH_PYTHON_VERSION }}
64+
persist-credentials: false
65+
66+
- name: Stage the licence-collection script
67+
run: |
68+
cat > collect-licenses.sh <<'COLLECT_EOF'
69+
#!/bin/bash
70+
# SPDX-FileCopyrightText: 2026 The RISE Project
71+
# SPDX-License-Identifier: MIT
72+
#
73+
# Stage, at the project root, the licence of libssh (built from the
74+
# vendored libssh/ tree) and of every shared library auditwheel vendors
75+
# out of the build image alongside it (OpenSSL and the krb5 GSSAPI stack).
76+
# setuptools' default LICEN[CS]E* glob copies them into the wheel.
77+
set -euo pipefail
78+
79+
project="${1:?usage: collect-licenses.sh <project-dir>}"
80+
81+
cp "$project/libssh/COPYING" "$project/LICENSE.libssh"
82+
cp "$project/libssh/BSD" "$project/LICENSE.libssh.BSD"
83+
84+
mapfile -t libs < <(
85+
for root in /usr/lib64/libgssapi_krb5.so /usr/lib64/libcrypto.so; do
86+
ldd "$root" | tr ' ' '\n' | grep '^/'
87+
readlink -f "$root"
88+
done | sort -u
89+
)
90+
91+
# glibc, the gcc runtime and zlib are on auditwheel's manylinux allowlist.
92+
mapfile -t pkgs < <(
93+
rpm -qf --qf '%{NAME}\n' "${libs[@]}" 2>/dev/null |
94+
grep -E '^[A-Za-z0-9._+-]+$' | sort -u |
95+
grep -vE '^(glibc|libgcc|libstdc\+\+|gcc|zlib-ng-compat)$'
96+
)
97+
98+
for pkg in "${pkgs[@]}"; do
99+
rpm -q --qf '%{NAME}: %{LICENSE}\n' "$pkg"
100+
mapfile -t files < <(rpm -q --licensefiles "$pkg" 2>/dev/null || true)
101+
102+
if [ -z "${files[0]:-}" ]; then
103+
srpm=$(rpm -q --qf '%{SOURCERPM}\n' "$pkg")
104+
mapfile -t files < <(
105+
rpm -qa --qf '%{SOURCERPM} %{NAME}\n' |
106+
awk -v s="$srpm" '$1 == s { print $2 }' |
107+
xargs -r rpm -q --licensefiles 2>/dev/null | sort -u
108+
)
109+
fi
110+
111+
if [ -z "${files[0]:-}" ]; then
112+
dnf -y --disablerepo=extras reinstall --setopt=tsflags= "$pkg" >/dev/null
113+
mapfile -t files < <(rpm -qd "$pkg" | grep -iE '/(LICEN[CS]E|COPYING|NOTICE)')
114+
fi
115+
116+
for f in "${files[@]}"; do
117+
[ -f "$f" ] || continue
118+
cp "$f" "$project/LICENSE.${pkg}.$(basename "$f")"
119+
done
120+
compgen -G "$project/LICENSE.$pkg.*" >/dev/null ||
121+
{ echo "no licence file found for $pkg" >&2; exit 1; }
122+
done
123+
124+
ls -1 "$project"/LICENSE.* | sed "s|$project/||"
125+
COLLECT_EOF
126+
127+
- name: Build wheels
128+
uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0
129+
with:
130+
output-dir: wheelhouse/
131+
only: ${{ matrix.python }}-manylinux_riscv64
132+
env:
133+
CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }}
134+
# Replaces upstream's custom image, which builds OpenSSL 3.4.0 and krb5
135+
# 1.21.3 from source (gotcha 46) and preinstalls libssh (SYSTEM_LIBSSH=1):
136+
# Rocky 10's own openssl-devel/krb5-devel are current, and setup.py's
137+
# default embedded build compiles the same vendored libssh/ tree with the
138+
# same WITH_GSSAPI=ON cmake flags.
139+
CIBW_BEFORE_ALL_LINUX: >-
140+
dnf -y install openssl-devel krb5-devel zlib-devel &&
141+
bash {project}/collect-licenses.sh {project}
142+
CIBW_ENVIRONMENT: PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/
143+
CIBW_TEST_REQUIRES: pytest pytest-rerunfailures
144+
# tests/ is a package whose sibling ssh/ source dir would shadow the
145+
# installed wheel (gotcha 25); setup.cfg carries upstream's pytest addopts.
146+
CIBW_TEST_SOURCES: tests setup.cfg
147+
CIBW_TEST_COMMAND: >-
148+
python -c 'from ssh.session import Session; Session()' &&
149+
python -m pytest tests
150+
151+
- name: Check the wheel ships the extensions, libssh and the licences
152+
run: |
153+
python3 - wheelhouse/*.whl <<'EOF'
154+
import sys, zipfile
155+
for whl in sys.argv[1:]:
156+
names = zipfile.ZipFile(whl).namelist()
157+
assert any(n.startswith("ssh/session") and n.endswith(".so") for n in names), names
158+
assert any("libssh" in n and ".so" in n for n in names), names
159+
lic = {n.rsplit("/", 1)[1] for n in names if ".dist-info/licenses/" in n} - {""}
160+
print(whl, sorted(lic))
161+
assert {"LICENSE", "COPYING", "LICENSE.libssh", "LICENSE.libssh.BSD"} <= lic, lic
162+
pkgs = {f.split(".", 2)[1] for f in lic if f.startswith("LICENSE.") and f.count(".") >= 2}
163+
assert {"openssl-libs", "krb5-libs", "libcom_err", "keyutils-libs"} <= pkgs, pkgs
164+
EOF
165+
166+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
167+
with:
168+
name: ssh-python-${{ env.SSH_PYTHON_VERSION }}-${{ matrix.python }}-manylinux_riscv64
169+
path: wheelhouse/*.whl
170+
if-no-files-found: error
171+
172+
gpl_sources:
173+
needs: [setup]
174+
if: needs.setup.outputs.versions != '[]'
175+
strategy:
176+
fail-fast: false
177+
matrix:
178+
version: ${{ fromJSON(needs.setup.outputs.versions) }}
179+
name: Collect GPL sources for ssh-python ${{ matrix.version }}
180+
runs-on: ubuntu-24.04-riscv
181+
182+
env:
183+
SSH_PYTHON_VERSION: ${{ matrix.version }}
184+
185+
steps:
186+
- name: Checkout python-wheels
187+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
188+
with:
189+
persist-credentials: false
190+
191+
- uses: ./actions/collect-gpl-sources
192+
with:
193+
image: ${{ env.MANYLINUX_RISCV64_IMAGE }}
194+
packages: gcc keyutils-libs
195+
output: gpl-sources.tar
196+
197+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
198+
with:
199+
name: ssh-python-${{ env.SSH_PYTHON_VERSION }}-gpl-sources
200+
path: gpl-sources.tar
201+
if-no-files-found: error
202+
203+
publish:
204+
name: Publish ssh-python ${{ matrix.version }}
205+
needs: [setup, build_wheels, gpl_sources]
206+
if: needs.setup.outputs.versions != '[]'
207+
strategy:
208+
fail-fast: false
209+
matrix:
210+
version: ${{ fromJSON(needs.setup.outputs.versions) }}
211+
permissions:
212+
contents: write
213+
pull-requests: write
214+
uses: $/.github/workflows/_publish-wheel.yml
215+
secrets:
216+
app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }}
217+
with:
218+
artifact-pattern: ssh-python-${{ matrix.version }}-*-manylinux_riscv64
219+
gpl-sources-artifact: ssh-python-${{ matrix.version }}-gpl-sources
220+
gpl-sources-description: gcc and the copyleft libraries bundled in the wheel

‎docs/packages/ssh-python.yaml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package-name: ssh-python
2+
source-code: https://github.com/ParallelSSH/ssh-python
3+
license: LGPL-2.1-only
4+
versions:
5+
- version: 1.2.0.post1

0 commit comments

Comments
 (0)