python-gdcm: Add version 3.2.6 #1
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # SPDX-FileCopyrightText: 2026 The RISE Project | |
| # SPDX-License-Identifier: MIT | |
| --- | |
| # This workflow is based on: https://github.com/tfmoraes/python-gdcm/blob/v3.2.6/.github/workflows/wheels.yml | |
| name: Build python-gdcm wheels (riscv64) | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version glob to (re)build; empty builds every version of docs/packages/python-gdcm.yaml not released yet' | |
| required: false | |
| default: '' | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - '.github/workflows/build-python-gdcm.yml' | |
| - 'docs/packages/python-gdcm.yaml' | |
| push: | |
| branches: [main] | |
| paths: | |
| - '.github/workflows/build-python-gdcm.yml' | |
| - 'docs/packages/python-gdcm.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: python-gdcm | |
| version: ${{ inputs.version }} | |
| build_wheels: | |
| needs: [setup] | |
| if: needs.setup.outputs.versions != '[]' | |
| name: Build python-gdcm ${{ matrix.version }} ${{ matrix.python }}-manylinux_riscv64 | |
| runs-on: ubuntu-24.04-riscv | |
| timeout-minutes: 360 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| version: ${{ fromJSON(needs.setup.outputs.versions) }} | |
| python: | |
| - "cp312" | |
| - "cp313" | |
| - "cp314" | |
| - "cp314t" | |
| env: | |
| PYTHON_GDCM_VERSION: ${{ matrix.version }} | |
| steps: | |
| - name: Checkout python-gdcm ${{ env.PYTHON_GDCM_VERSION }} | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| repository: tfmoraes/python-gdcm | |
| ref: v${{ env.PYTHON_GDCM_VERSION }} | |
| submodules: true | |
| 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 -v python-wheels/patches/python-gdcm/${{ env.PYTHON_GDCM_VERSION }}/*.patch | |
| - name: Write the wheel test | |
| run: | | |
| cat > test_python_gdcm.py <<'EOF' | |
| import importlib.metadata | |
| import os | |
| import subprocess | |
| import tempfile | |
| import gdcm | |
| assert gdcm.Version.GetVersion() == "${{ env.PYTHON_GDCM_VERSION }}", gdcm.Version.GetVersion() | |
| assert gdcm.Global.GetInstance().GetDicts().GetDictEntry( | |
| gdcm.Tag(0x0010, 0x0010)).GetName() == "Patient's Name" | |
| licenses = sorted( | |
| str(f) for f in importlib.metadata.files("python-gdcm") if "/licenses/" in str(f)) | |
| assert len(licenses) == 14, licenses | |
| assert any(f.endswith("/licenses/LICENSE.openssl") for f in licenses), licenses | |
| WIDTH = HEIGHT = 64 | |
| PIXELS = bytes(bytearray(((x * 3 + y * 5) % 256) for y in range(HEIGHT) for x in range(WIDTH))) | |
| def buffer_of(image): | |
| return image.GetBuffer().encode("utf-8", "surrogateescape") | |
| with tempfile.TemporaryDirectory() as directory: | |
| writer = gdcm.ImageWriter() | |
| image = writer.GetImage() | |
| image.SetNumberOfDimensions(2) | |
| image.SetDimension(0, WIDTH) | |
| image.SetDimension(1, HEIGHT) | |
| pixel_format = gdcm.PixelFormat() | |
| pixel_format.SetScalarType(gdcm.PixelFormat.UINT8) | |
| image.SetPixelFormat(pixel_format) | |
| image.SetPhotometricInterpretation( | |
| gdcm.PhotometricInterpretation(gdcm.PhotometricInterpretation.MONOCHROME2)) | |
| pixeldata = gdcm.DataElement(gdcm.Tag(0x7fe0, 0x0010)) | |
| pixeldata.SetByteStringValue(PIXELS) | |
| image.SetDataElement(pixeldata) | |
| path = os.path.join(directory, "raw.dcm") | |
| writer.SetFileName(path) | |
| writer.SetImage(image) | |
| assert writer.Write() | |
| reader = gdcm.ImageReader() | |
| reader.SetFileName(path) | |
| assert reader.Read() | |
| assert reader.GetImage().GetDimension(0) == WIDTH | |
| assert reader.GetImage().GetDimension(1) == HEIGHT | |
| assert buffer_of(reader.GetImage()) == PIXELS | |
| for name in ("DeflatedExplicitVRLittleEndian", "RLELossless", | |
| "JPEGLSLossless", "JPEG2000Lossless"): | |
| change = gdcm.ImageChangeTransferSyntax() | |
| change.SetTransferSyntax(gdcm.TransferSyntax(getattr(gdcm.TransferSyntax, name))) | |
| change.SetInput(reader.GetImage()) | |
| assert change.Change(), name | |
| compressed = os.path.join(directory, name + ".dcm") | |
| encoder = gdcm.ImageWriter() | |
| encoder.SetFileName(compressed) | |
| encoder.SetImage(change.GetOutput()) | |
| assert encoder.Write(), name | |
| decoder = gdcm.ImageReader() | |
| decoder.SetFileName(compressed) | |
| assert decoder.Read(), name | |
| assert buffer_of(decoder.GetImage()) == PIXELS, name | |
| print(name, "ok") | |
| gdcmdump = os.path.join(os.path.dirname(gdcm.__file__), "_gdcm", "gdcmdump") | |
| dump = subprocess.run( | |
| [gdcmdump, path], check=True, capture_output=True, text=True).stdout | |
| assert "(7fe0,0010)" in dump, dump | |
| 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_BUILD_FRONTEND: build | |
| # Rocky 10 ships swig, so upstream's from-source SWIG build - its | |
| # fallback for images without one - is not needed. | |
| CIBW_BEFORE_ALL: >- | |
| dnf -y install openssl-devel swig && | |
| cp /usr/share/licenses/openssl-libs/LICENSE.txt {project}/LICENSE.openssl | |
| # cmake and ninja have no riscv64 wheel on public PyPI; PIP_ONLY_BINARY | |
| # keeps pip from source-building a newer one than our registry's. | |
| CIBW_ENVIRONMENT: >- | |
| CMAKE_ARGS="-DGDCM_USE_SYSTEM_OPENSSL:BOOL=ON" | |
| PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ | |
| PIP_ONLY_BINARY=cmake,ninja | |
| CIBW_TEST_SOURCES: test_python_gdcm.py | |
| CIBW_TEST_COMMAND: python test_python_gdcm.py | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: python-gdcm-${{ env.PYTHON_GDCM_VERSION }}-${{ matrix.python }}-manylinux_riscv64 | |
| path: wheelhouse/*.whl | |
| if-no-files-found: error | |
| publish: | |
| name: Publish python-gdcm ${{ 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: python-gdcm-${{ matrix.version }}-*-manylinux_riscv64 |