Repository navigation
203 lines (180 loc) · 8.15 KB
/
Copy pathbuild-xrootd.yml
File metadata and controls
203 lines (180 loc) · 8.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# SPDX-FileCopyrightText: 2026 The RISE Project
# SPDX-License-Identifier: MIT
---
# This workflow is based on: https://github.com/xrootd/xrootd/blob/master/.github/workflows/python.yml
name: Build xrootd wheels (riscv64)
on:
workflow_dispatch:
inputs:
version:
description: 'Version glob to (re)build; empty builds every version of docs/packages/xrootd.yaml not released yet'
required: false
default: ''
pull_request:
branches: [main]
paths:
- '.github/workflows/build-xrootd.yml'
- 'docs/packages/xrootd.yaml'
push:
branches: [main]
paths:
- '.github/workflows/build-xrootd.yml'
- 'docs/packages/xrootd.yaml'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions:
contents: read # to fetch code (actions/checkout)
env:
MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64
jobs:
setup:
uses: $/.github/workflows/_setup.yml
with:
package: xrootd
version: ${{ inputs.version }}
build_wheels:
needs: [setup]
if: needs.setup.outputs.versions != '[]'
name: Build xrootd ${{ matrix.version }} ${{ matrix.python }}-manylinux_riscv64
runs-on: ubuntu-24.04-riscv
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
version: ${{ fromJSON(needs.setup.outputs.versions) }}
python: ["cp312", "cp313", "cp314", "cp314t"]
env:
XROOTD_VERSION: ${{ matrix.version }}
steps:
- name: Checkout xrootd v${{ env.XROOTD_VERSION }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: xrootd/xrootd
ref: v${{ env.XROOTD_VERSION }}
persist-credentials: false
# The tag's VERSION file is an unexpanded `git-archive` export-subst
# placeholder (`$Format:%(describe)$`); setup.py and CMake both fall
# back to `git describe`, which a shallow single-ref checkout can't
# answer. Writing the real version here is the officially supported
# override (cmake/XRootDVersion.cmake reads this file first).
- name: Set version from tag
run: echo -n '${{ env.XROOTD_VERSION }}' > VERSION
- name: Stage the licence-collection script
run: |
cat > collect-licenses.sh <<'COLLECT_EOF'
#!/bin/bash
# SPDX-FileCopyrightText: 2026 The RISE Project
# SPDX-License-Identifier: MIT
#
# Stage, at the project root, the licence of every shared library
# auditwheel vendors out of the build image alongside the XRootD
# client libraries (OpenSSL, Kerberos, libuuid and their closure).
# setuptools' default LICENSE* glob copies them into the wheel.
set -euo pipefail
project="${1:?usage: collect-licenses.sh <project-dir>}"
# ldd is transitive, so these roots cover their whole closure; ldd
# does not list the roots themselves, so resolve those too. libcrypt
# is not pulled in by any -devel package above: XrdUtils' own CMake
# probes for crypt() directly and links libc-adjacent libxcrypt,
# which the base image already ships.
mapfile -t libs < <(
{
for root in libssl.so libcrypto.so libkrb5.so libuuid.so libcrypt.so; do
path="/usr/lib64/${root}"
[ -e "${path}" ] || continue
ldd "${path}" | tr ' ' '\n' | grep '^/'
readlink -f "${path}"
done
} | sort -u
)
# `rpm -qf` reports unowned files on stdout, so keep only bare package names.
# glibc, the gcc runtime and zlib are on auditwheel's manylinux allowlist
# (confirmed against the upstream x86_64 wheel's auditwheel-vendored set)
# and are never vendored into the wheel; zlib-ng-compat also ships no
# licence file via any rpm metadata path, so it would break the loop below.
mapfile -t pkgs < <(
rpm -qf --qf '%{NAME}\n' "${libs[@]}" 2>/dev/null |
grep -E '^[A-Za-z0-9._+-]+$' | sort -u |
grep -vE '^(glibc|libgcc|libstdc\+\+|gcc|zlib-ng-compat)$'
)
for pkg in "${pkgs[@]}"; do
mapfile -t files < <(rpm -q --licensefiles "$pkg" 2>/dev/null || true)
# Some subpackages leave the licence to a sibling of the same source RPM.
if [ -z "${files[0]:-}" ]; then
srpm=$(rpm -q --qf '%{SOURCERPM}\n' "$pkg")
mapfile -t files < <(
rpm -qa --qf '%{SOURCERPM} %{NAME}\n' |
awk -v s="$srpm" '$1 == s { print $2 }' |
xargs -r rpm -q --licensefiles 2>/dev/null | sort -u
)
fi
# Others mark it %doc rather than %license, and the image installs no docs.
if [ -z "${files[0]:-}" ]; then
dnf -y --disablerepo=extras reinstall --setopt=tsflags= "$pkg" >/dev/null
mapfile -t files < <(rpm -qd "$pkg" | grep -iE '/(LICEN[CS]E|COPYING|NOTICE)')
fi
for f in "${files[@]}"; do
[ -f "$f" ] || continue
cp "$f" "$project/LICENSE.${pkg}.$(basename "$f")"
done
compgen -G "$project/LICENSE.$pkg.*" >/dev/null ||
{ echo "no licence file found for $pkg" >&2; exit 1; }
done
ls -1 "$project"/LICENSE.* | sed "s|$project/||"
COLLECT_EOF
- name: Build wheels
uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0
with:
output-dir: wheelhouse/
only: ${{ matrix.python }}-manylinux_riscv64
env:
CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }}
CIBW_BEFORE_ALL_LINUX: >-
dnf install -y krb5-devel libuuid-devel openssl-devel &&
bash {project}/collect-licenses.sh {project}
CIBW_ENVIRONMENT: CMAKE_ARGS=-DCMAKE_BUILD_TYPE=Release
# Upstream's own manylinux job test step (python.yml): import the
# extension and the pure-Python client, then build a FileSystem
# object (no network I/O, so no server needed).
CIBW_TEST_COMMAND: |
python -m pip show xrootd &&
python -c "import XRootD; print(XRootD)" &&
python -c "import pyxrootd; print(pyxrootd)" &&
python -c "from XRootD import client; help(client)" &&
python -c "from XRootD import client; print(client.FileSystem('root://localhost'))"
- name: Verify the wheel ships the compiled extension and licences
run: |
python3 - wheelhouse/*.whl <<'EOF'
import sys, zipfile
names = zipfile.ZipFile(sys.argv[1]).namelist()
sos = sorted(n for n in names if n.endswith(".so"))
print("\n".join(sos))
assert any("/client.cpython" in "/" + n for n in sos), sos
lic = sorted(n.split("/")[-1] for n in names if ".dist-info/licenses/" in n and not n.endswith("/"))
print("\n".join(lic))
expected_pkgs = {"openssl-libs", "krb5-libs", "libuuid", "libxcrypt"}
have_pkgs = {f.split(".", 2)[1] for f in lic if f.startswith("LICENSE.")}
assert expected_pkgs <= have_pkgs, expected_pkgs - have_pkgs
EOF
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: xrootd-${{ env.XROOTD_VERSION }}-${{ matrix.python }}-manylinux_riscv64
path: wheelhouse/*.whl
if-no-files-found: error
publish:
name: Publish xrootd ${{ matrix.version }}
needs: [setup, build_wheels]
if: needs.setup.outputs.versions != '[]'
strategy:
fail-fast: false
matrix:
version: ${{ fromJSON(needs.setup.outputs.versions) }}
permissions:
contents: write
pull-requests: write
uses: $/.github/workflows/_publish-wheel.yml
secrets:
app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }}
with:
artifact-pattern: xrootd-${{ matrix.version }}-*-manylinux_riscv64