From 8fb72cd69b8ffb75081ea3ae90d00e3989dbc1e2 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Thu, 15 Oct 2026 23:44:04 +0000 Subject: [PATCH] pyxdelta: add build-pyxdelta.yml for riscv64 wheels Adds a cibuildwheel-based riscv64 build for pyxdelta 0.2.3, mirroring upstream's own wheels.yml. Includes a licensing patch to ship the vendored xdelta3 (Apache-2.0) license text alongside pyxdelta's own MIT license in the wheel. Signed-off-by: Ludovic Henry --- .github/workflows/build-pyxdelta.yml | 108 ++++++++++ docs/packages/pyxdelta.yaml | 5 + ...pache-2.0-license-text-in-wheel-meta.patch | 202 ++++++++++++++++++ 3 files changed, 315 insertions(+) create mode 100644 .github/workflows/build-pyxdelta.yml create mode 100644 docs/packages/pyxdelta.yaml create mode 100644 patches/pyxdelta/0.2.3/0001-Ship-xdelta3-s-Apache-2.0-license-text-in-wheel-meta.patch diff --git a/.github/workflows/build-pyxdelta.yml b/.github/workflows/build-pyxdelta.yml new file mode 100644 index 000000000000..a03da0798907 --- /dev/null +++ b/.github/workflows/build-pyxdelta.yml @@ -0,0 +1,108 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +--- +# This workflow is based on the `build_wheels` job of +# https://github.com/Illidanz/pyxdelta/blob/v0.2.3/.github/workflows/wheels.yml +name: Build pyxdelta wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'Version glob to (re)build; empty builds every version of docs/packages/pyxdelta.yaml not released yet' + required: false + default: '' + pull_request: + branches: [main] + paths: + - '.github/workflows/build-pyxdelta.yml' + - 'docs/packages/pyxdelta.yaml' + - 'patches/pyxdelta/**' + push: + branches: [main] + paths: + - '.github/workflows/build-pyxdelta.yml' + - 'docs/packages/pyxdelta.yaml' + - 'patches/pyxdelta/**' + +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: pyxdelta + version: ${{ inputs.version }} + + build_wheels: + needs: [setup] + if: needs.setup.outputs.versions != '[]' + name: Build pyxdelta ${{ matrix.version }} ${{ matrix.python }}-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + python: ["cp312", "cp313", "cp314", "cp314t"] + + env: + PYXDELTA_VERSION: ${{ matrix.version }} + + steps: + - name: Checkout pyxdelta v${{ env.PYXDELTA_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: Illidanz/pyxdelta + ref: v${{ env.PYXDELTA_VERSION }} + submodules: recursive + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + - name: Apply patches + run: git apply python-wheels/patches/pyxdelta/${{ env.PYXDELTA_VERSION }}/*.patch + + - uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 + env: + CIBW_ARCHS: riscv64 + CIBW_BUILD: ${{ matrix.python }}-manylinux_riscv64 + CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} + CIBW_TEST_COMMAND: >- + python -c "import pyxdelta as m; assert m.__file__.endswith('.so'), m.__file__" && + python -c "import pyxdelta, tempfile, os; d = tempfile.mkdtemp(); src = os.path.join(d, 'src.bin'); tgt = os.path.join(d, 'tgt.bin'); patch = os.path.join(d, 'p.xdelta'); out = os.path.join(d, 'out.bin'); open(src, 'wb').write(b'hello world' * 100); open(tgt, 'wb').write(b'hello world' * 100 + b'extra'); assert pyxdelta.run(infile=src, outfile=tgt, patchfile=patch); assert pyxdelta.decode(infile=src, patchfile=patch, outfile=out); assert open(out, 'rb').read() == open(tgt, 'rb').read()" + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: pyxdelta-${{ env.PYXDELTA_VERSION }}-${{ matrix.python }}-manylinux_riscv64 + path: ./wheelhouse/*.whl + if-no-files-found: error + + publish: + name: Publish pyxdelta ${{ 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: pyxdelta-${{ matrix.version }}-*-manylinux_riscv64 diff --git a/docs/packages/pyxdelta.yaml b/docs/packages/pyxdelta.yaml new file mode 100644 index 000000000000..c7a9c629768b --- /dev/null +++ b/docs/packages/pyxdelta.yaml @@ -0,0 +1,5 @@ +package-name: pyxdelta +source-code: https://github.com/Illidanz/pyxdelta +license: MIT +versions: +- version: 0.2.3 diff --git a/patches/pyxdelta/0.2.3/0001-Ship-xdelta3-s-Apache-2.0-license-text-in-wheel-meta.patch b/patches/pyxdelta/0.2.3/0001-Ship-xdelta3-s-Apache-2.0-license-text-in-wheel-meta.patch new file mode 100644 index 000000000000..d93c677f58b9 --- /dev/null +++ b/patches/pyxdelta/0.2.3/0001-Ship-xdelta3-s-Apache-2.0-license-text-in-wheel-meta.patch @@ -0,0 +1,202 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 15 Oct 2026 23:43:02 +0000 +Subject: [PATCH] Ship xdelta3's Apache-2.0 license text in wheel metadata + +setup.py declares no license_files, so setuptools' default +LICEN[CS]E* glob only picks up the top-level LICENSE (pyxdelta's own +MIT text). pyxdelta.c directly #includes xdelta/xdelta3/xdelta3.c, so +the whole xdelta3 core (Apache-2.0, see xdelta/xdelta3/LICENSE) is +compiled straight into the extension, but that nested file is not at +the project root so the default glob misses it. Add a root-level copy +named LICENSE.xdelta3, which the default glob picks up automatically +with no setup.py change. + +Upstream-Status: To upstream [not submitted from this automated port run] +--- + LICENSE.xdelta3 | 176 ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 176 insertions(+) + create mode 100644 LICENSE.xdelta3 + +diff --git a/LICENSE.xdelta3 b/LICENSE.xdelta3 +new file mode 100644 +index 0000000..7a77415 +--- /dev/null ++++ b/LICENSE.xdelta3 +@@ -0,0 +1,176 @@ ++Apache License ++Version 2.0, January 2004 ++http://www.apache.org/licenses/ ++ ++TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION ++ ++1. Definitions. ++ ++"License" shall mean the terms and conditions for use, reproduction, ++and distribution as defined by Sections 1 through 9 of this document. ++ ++"Licensor" shall mean the copyright owner or entity authorized by ++the copyright owner that is granting the License. ++ ++"Legal Entity" shall mean the union of the acting entity and all ++other entities that control, are controlled by, or are under common ++control with that entity. For the purposes of this definition, ++"control" means (i) the power, direct or indirect, to cause the ++direction or management of such entity, whether by contract or ++otherwise, or (ii) ownership of fifty percent (50%) or more of the ++outstanding shares, or (iii) beneficial ownership of such entity. ++ ++"You" (or "Your") shall mean an individual or Legal Entity ++exercising permissions granted by this License. ++ ++"Source" form shall mean the preferred form for making modifications, ++including but not limited to software source code, documentation ++source, and configuration files. ++ ++"Object" form shall mean any form resulting from mechanical ++transformation or translation of a Source form, including but ++not limited to compiled object code, generated documentation, ++and conversions to other media types. ++ ++"Work" shall mean the work of authorship, whether in Source or ++Object form, made available under the License, as indicated by a ++copyright notice that is included in or attached to the work ++(an example is provided in the Appendix below). ++ ++"Derivative Works" shall mean any work, whether in Source or Object ++form, that is based on (or derived from) the Work and for which the ++editorial revisions, annotations, elaborations, or other modifications ++represent, as a whole, an original work of authorship. For the purposes ++of this License, Derivative Works shall not include works that remain ++separable from, or merely link (or bind by name) to the interfaces of, ++the Work and Derivative Works thereof. ++ ++"Contribution" shall mean any work of authorship, including ++the original version of the Work and any modifications or additions ++to that Work or Derivative Works thereof, that is intentionally ++submitted to Licensor for inclusion in the Work by the copyright owner ++or by an individual or Legal Entity authorized to submit on behalf of ++the copyright owner. For the purposes of this definition, "submitted" ++means any form of electronic, verbal, or written communication sent ++to the Licensor or its representatives, including but not limited to ++communication on electronic mailing lists, source code control systems, ++and issue tracking systems that are managed by, or on behalf of, the ++Licensor for the purpose of discussing and improving the Work, but ++excluding communication that is conspicuously marked or otherwise ++designated in writing by the copyright owner as "Not a Contribution." ++ ++"Contributor" shall mean Licensor and any individual or Legal Entity ++on behalf of whom a Contribution has been received by Licensor and ++subsequently incorporated within the Work. ++ ++2. Grant of Copyright License. Subject to the terms and conditions of ++this License, each Contributor hereby grants to You a perpetual, ++worldwide, non-exclusive, no-charge, royalty-free, irrevocable ++copyright license to reproduce, prepare Derivative Works of, ++publicly display, publicly perform, sublicense, and distribute the ++Work and such Derivative Works in Source or Object form. ++ ++3. Grant of Patent License. Subject to the terms and conditions of ++this License, each Contributor hereby grants to You a perpetual, ++worldwide, non-exclusive, no-charge, royalty-free, irrevocable ++(except as stated in this section) patent license to make, have made, ++use, offer to sell, sell, import, and otherwise transfer the Work, ++where such license applies only to those patent claims licensable ++by such Contributor that are necessarily infringed by their ++Contribution(s) alone or by combination of their Contribution(s) ++with the Work to which such Contribution(s) was submitted. If You ++institute patent litigation against any entity (including a ++cross-claim or counterclaim in a lawsuit) alleging that the Work ++or a Contribution incorporated within the Work constitutes direct ++or contributory patent infringement, then any patent licenses ++granted to You under this License for that Work shall terminate ++as of the date such litigation is filed. ++ ++4. Redistribution. You may reproduce and distribute copies of the ++Work or Derivative Works thereof in any medium, with or without ++modifications, and in Source or Object form, provided that You ++meet the following conditions: ++ ++(a) You must give any other recipients of the Work or ++Derivative Works a copy of this License; and ++ ++(b) You must cause any modified files to carry prominent notices ++stating that You changed the files; and ++ ++(c) You must retain, in the Source form of any Derivative Works ++that You distribute, all copyright, patent, trademark, and ++attribution notices from the Source form of the Work, ++excluding those notices that do not pertain to any part of ++the Derivative Works; and ++ ++(d) If the Work includes a "NOTICE" text file as part of its ++distribution, then any Derivative Works that You distribute must ++include a readable copy of the attribution notices contained ++within such NOTICE file, excluding those notices that do not ++pertain to any part of the Derivative Works, in at least one ++of the following places: within a NOTICE text file distributed ++as part of the Derivative Works; within the Source form or ++documentation, if provided along with the Derivative Works; or, ++within a display generated by the Derivative Works, if and ++wherever such third-party notices normally appear. The contents ++of the NOTICE file are for informational purposes only and ++do not modify the License. You may add Your own attribution ++notices within Derivative Works that You distribute, alongside ++or as an addendum to the NOTICE text from the Work, provided ++that such additional attribution notices cannot be construed ++as modifying the License. ++ ++You may add Your own copyright statement to Your modifications and ++may provide additional or different license terms and conditions ++for use, reproduction, or distribution of Your modifications, or ++for any such Derivative Works as a whole, provided Your use, ++reproduction, and distribution of the Work otherwise complies with ++the conditions stated in this License. ++ ++5. Submission of Contributions. Unless You explicitly state otherwise, ++any Contribution intentionally submitted for inclusion in the Work ++by You to the Licensor shall be under the terms and conditions of ++this License, without any additional terms or conditions. ++Notwithstanding the above, nothing herein shall supersede or modify ++the terms of any separate license agreement you may have executed ++with Licensor regarding such Contributions. ++ ++6. Trademarks. This License does not grant permission to use the trade ++names, trademarks, service marks, or product names of the Licensor, ++except as required for reasonable and customary use in describing the ++origin of the Work and reproducing the content of the NOTICE file. ++ ++7. Disclaimer of Warranty. Unless required by applicable law or ++agreed to in writing, Licensor provides the Work (and each ++Contributor provides its Contributions) on an "AS IS" BASIS, ++WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or ++implied, including, without limitation, any warranties or conditions ++of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A ++PARTICULAR PURPOSE. You are solely responsible for determining the ++appropriateness of using or redistributing the Work and assume any ++risks associated with Your exercise of permissions under this License. ++ ++8. Limitation of Liability. In no event and under no legal theory, ++whether in tort (including negligence), contract, or otherwise, ++unless required by applicable law (such as deliberate and grossly ++negligent acts) or agreed to in writing, shall any Contributor be ++liable to You for damages, including any direct, indirect, special, ++incidental, or consequential damages of any character arising as a ++result of this License or out of the use or inability to use the ++Work (including but not limited to damages for loss of goodwill, ++work stoppage, computer failure or malfunction, or any and all ++other commercial damages or losses), even if such Contributor ++has been advised of the possibility of such damages. ++ ++9. Accepting Warranty or Additional Liability. While redistributing ++the Work or Derivative Works thereof, You may choose to offer, ++and charge a fee for, acceptance of support, warranty, indemnity, ++or other liability obligations and/or rights consistent with this ++License. However, in accepting such obligations, You may act only ++on Your own behalf and on Your sole responsibility, not on behalf ++of any other Contributor, and only if You agree to indemnify, ++defend, and hold each Contributor harmless for any liability ++incurred by, or claims asserted against, such Contributor by reason ++of your accepting any such warranty or additional liability. ++ ++END OF TERMS AND CONDITIONS