Repository navigation
docs: Update projects #41
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 | |
| --- | |
| name: Build cchardet wheels (riscv64) | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version glob to (re)build; empty builds every version of docs/packages/cchardet.yaml not released yet' | |
| required: false | |
| default: '' | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - '.github/workflows/build-cchardet.yml' | |
| - 'docs/packages/cchardet.yaml' | |
| push: | |
| branches: [main] | |
| paths: | |
| - '.github/workflows/build-cchardet.yml' | |
| - 'docs/packages/cchardet.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: cchardet | |
| version: ${{ inputs.version }} | |
| build_sdist: | |
| needs: [setup] | |
| if: needs.setup.outputs.versions != '[]' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| version: ${{ fromJSON(needs.setup.outputs.versions) }} | |
| name: Build cchardet ${{ matrix.version }} sdist | |
| runs-on: ubuntu-latest | |
| env: | |
| CCHARDET_VERSION: ${{ matrix.version }} | |
| steps: | |
| # Upstream tagged releases bare up to 2.1.7 and v-prefixed from 2.2.0 on. | |
| - name: Resolve the cChardet tag | |
| id: tag | |
| run: | | |
| for ref in "v$CCHARDET_VERSION" "$CCHARDET_VERSION"; do | |
| if git ls-remote --exit-code --tags https://github.com/PyYoshi/cChardet "refs/tags/$ref" >/dev/null; then | |
| echo "name=$ref" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| done | |
| echo "::error::PyYoshi/cChardet has no tag for $CCHARDET_VERSION" | |
| exit 1 | |
| - name: Checkout cChardet ${{ env.CCHARDET_VERSION }} | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| repository: PyYoshi/cChardet | |
| ref: ${{ steps.tag.outputs.name }} | |
| submodules: recursive | |
| persist-credentials: false | |
| - name: Install Python | |
| uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 | |
| with: | |
| python-version: '3.12' | |
| activate-environment: true | |
| enable-cache: false | |
| - name: Build sdist | |
| id: sdist | |
| # This tag ships no pyproject.toml: setup.py cythonises _cchardet.pyx | |
| # itself whenever Cython is importable, so Cython has to be | |
| # preinstalled with isolation off, or the bundled .cpp is whatever a | |
| # bare `setuptools`+`wheel` env leaves behind (nothing, in practice). | |
| run: | | |
| uv pip install cython setuptools wheel build twine | |
| python -m build --sdist --no-isolation | |
| twine check dist/* | |
| - name: Upload sdist artifact | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: cchardet-${{ env.CCHARDET_VERSION }}-sdist | |
| path: dist/*.tar.gz | |
| if-no-files-found: error | |
| build_wheels: | |
| needs: [setup, build_sdist] | |
| if: needs.setup.outputs.versions != '[]' | |
| name: Build cchardet ${{ matrix.version }} ${{ matrix.python }}-manylinux_riscv64 | |
| runs-on: ubuntu-24.04-riscv | |
| timeout-minutes: 90 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| version: ${{ fromJSON(needs.setup.outputs.versions) }} | |
| python: ["cp312", "cp313", "cp314", "cp314t"] | |
| env: | |
| CCHARDET_VERSION: ${{ matrix.version }} | |
| steps: | |
| - name: Download sdist | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: cchardet-${{ env.CCHARDET_VERSION }}-sdist | |
| path: dist/ | |
| - name: Extract sdist and stage the wheel smoke test | |
| # Upstream's own cibuildwheel config (test-command/test-sources in | |
| # pyproject.toml) runs tools/wheel_smoke.py, but MANIFEST.in doesn't | |
| # ship tools/ in the sdist, so this reproduces that same script here. | |
| run: | | |
| mkdir pkg | |
| tar xzf dist/*.tar.gz --strip-components=1 -C pkg | |
| cat > pkg/riscv64_test_cchardet.py <<'EOF' | |
| import json | |
| import os | |
| import subprocess | |
| import sys | |
| import sysconfig | |
| import tempfile | |
| from pathlib import Path | |
| import cchardet | |
| def main() -> None: | |
| # Upstream only added this assertion in tools/wheel_smoke.py starting at | |
| # v2.3.0; v2.2.0's _cchardet extension doesn't declare free-threading | |
| # support, so CPython 3.14t legitimately re-enables the GIL on import. | |
| version = tuple(int(p) for p in os.environ["CCHARDET_VERSION"].split(".")) | |
| if sysconfig.get_config_var("Py_GIL_DISABLED") and version >= (2, 3, 0): | |
| assert not getattr(sys, "_is_gil_enabled")() | |
| package_dir = Path(cchardet.__file__).parent | |
| assert (package_dir / "py.typed").is_file() | |
| assert (package_dir / "_cchardet.pyi").is_file() | |
| expected = cchardet.detect(b"plain ASCII") | |
| assert expected["encoding"] == "ASCII" | |
| assert cchardet.detect(bytearray(b"plain ASCII")) == expected | |
| assert cchardet.detect(memoryview(b"plain ASCII"), max_bytes=32) == expected | |
| french = ("Français, où êtes-vous ? Voilà l'été.").encode( | |
| "windows-1252" | |
| ) | |
| candidates = cchardet.detect_all(french) | |
| assert candidates | |
| assert candidates[0] == cchardet.detect(french) | |
| assert candidates[0]["language"] == "fr" | |
| detector = cchardet.UniversalDetector() | |
| detector.feed(french[:10]) | |
| detector.feed(french[10:]) | |
| detector.close() | |
| assert detector.result == candidates[0] | |
| with tempfile.TemporaryDirectory() as directory: | |
| sample = Path(directory) / "sample.txt" | |
| sample.write_bytes(french) | |
| output = subprocess.check_output( | |
| [sys.executable, "-m", "cchardet", "--json", str(sample)], | |
| text=True, | |
| ) | |
| assert json.loads(output)["language"] == "fr" | |
| if __name__ == "__main__": | |
| main() | |
| EOF | |
| - name: Build and test wheels | |
| uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 | |
| with: | |
| package-dir: pkg | |
| output-dir: wheelhouse/ | |
| only: ${{ matrix.python }}-manylinux_riscv64 | |
| env: | |
| CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} | |
| # CIBW_TEST_SOURCES is relative to the cwd, not package-dir, hence "pkg/". | |
| CIBW_TEST_SOURCES: pkg/riscv64_test_cchardet.py | |
| CIBW_TEST_COMMAND: python pkg/riscv64_test_cchardet.py | |
| # A job-level `env:` never reaches the Linux container (gotcha 129), so the | |
| # test script's os.environ["CCHARDET_VERSION"] read needs it via CIBW_ENVIRONMENT. | |
| CIBW_ENVIRONMENT: CCHARDET_VERSION=${{ env.CCHARDET_VERSION }} | |
| - name: Verify the wheel ships the compiled extension | |
| run: | | |
| python3 - wheelhouse/*.whl <<'EOF' | |
| import sys, zipfile | |
| names = zipfile.ZipFile(sys.argv[1]).namelist() | |
| assert any(n.startswith("cchardet/_cchardet") and n.endswith(".so") for n in names), names | |
| assert any(n.endswith(".dist-info/licenses/COPYING") for n in names), names | |
| print("ok") | |
| EOF | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: cchardet-${{ matrix.version }}-${{ matrix.python }}-manylinux_riscv64 | |
| path: wheelhouse/*.whl | |
| if-no-files-found: error | |
| publish: | |
| name: Publish cchardet ${{ matrix.version }} | |
| needs: [setup, build_sdist, 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: cchardet-${{ matrix.version }}-*-manylinux_riscv64 |