diff --git a/.github/workflows/release-pypi.yml b/.github/workflows/release-pypi.yml index 37dc48ee3..a0df86dc5 100644 --- a/.github/workflows/release-pypi.yml +++ b/.github/workflows/release-pypi.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-15-intel, macos-14, windows-latest] + os: [ubuntu-latest, ubuntu-22.04-arm, macos-15-intel, macos-15, windows-latest] runs-on: ${{ matrix.os }} steps: @@ -26,17 +26,17 @@ jobs: echo "version=$VERSION" >> "$GITHUB_OUTPUT" echo "Computed version: $VERSION" - - name: Build package and upload from docker (Linux) + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Build package and upload (Linux) if: runner.os == 'Linux' + run: bash release-pypi-linux.sh env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} - run: | - docker run --rm -v "${PWD}:/opt/OpenCC" \ - -e TWINE_USERNAME \ - -e TWINE_PASSWORD \ - -e VERSION=${VERSION} \ - ubuntu:22.04 /bin/bash /opt/OpenCC/release-pypi-linux.sh - name: Build package and upload (macOS) if: runner.os == 'macOS' @@ -47,9 +47,7 @@ jobs: - name: Build package and upload (Windows) if: runner.os == 'Windows' - run: | - C:\Miniconda/condabin/conda.bat init powershell - ./release-pypi-windows.cmd + run: ./release-pypi-windows.cmd env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} diff --git a/release-pypi-linux.sh b/release-pypi-linux.sh index d18a4efd9..477ea787a 100644 --- a/release-pypi-linux.sh +++ b/release-pypi-linux.sh @@ -1,53 +1,25 @@ #!/bin/sh set -e -# Different to release-pypi-win.cmd and release-pypi-osx.sh, -# this script has to be ran from a clean dockerfile - -# Random note: The reason why this script is being ran from within a container -# is to ensure glibc compatibility. From what I've seen so far, it appears -# that having multiple glibc versions is a somewhat convoluted process -# and I don't trust myself to be able to manage them well. - -# Download dependenciess -export DEBIAN_FRONTEND=noninteractive -apt update -apt install -y g++ make curl - -cd /opt/OpenCC - -# Download and init conda -MINICONDA_FILENAME=Miniconda3-latest-Linux-x86_64.sh -curl -L -o $MINICONDA_FILENAME \ - "https://repo.continuum.io/miniconda/$MINICONDA_FILENAME" -bash ${MINICONDA_FILENAME} -b -f -p $HOME/miniconda3 -export PATH=$HOME/miniconda3/bin:$PATH -eval "$(conda shell.bash hook)" - -# Accept conda Terms of Service for required channels -conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main -conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r - -for PYTHON_VERSION in 3.10 3.11 3.12 3.13 3.14; do - # Create and activate environment - conda config --add channels conda-forge - conda config --set channel_priority strict - conda create -y -n py$PYTHON_VERSION python=$PYTHON_VERSION - conda activate py$PYTHON_VERSION - - # Build and package - pip install --no-cache-dir build - python -m build \ - -C--plat-name="manylinux2014_$(uname --machine)" - - # Cleanup - conda deactivate - rm -rf build OpenCC.egg-info -done +# Linux wheels are built inside manylinux2014 containers managed by cibuildwheel. +python -m pip install --upgrade pip cibuildwheel twine build + +export CIBW_BUILD="cp310-* cp311-* cp312-* cp313-* cp314-*" +export CIBW_SKIP="*-musllinux_*" +export CIBW_MANYLINUX_X86_64_IMAGE="manylinux2014" +export CIBW_MANYLINUX_AARCH64_IMAGE="manylinux2014" +export CIBW_ENVIRONMENT="VERSION=\"${VERSION}\"" +export CIBW_TEST_REQUIRES="pytest" +export CIBW_TEST_COMMAND="pytest {project}/python/tests" + +python -m cibuildwheel --output-dir wheelhouse + +if [ "$(uname -m)" = "x86_64" ]; then + # Build sdist only once, to avoid duplicate uploads from matrix jobs. + python -m build --sdist --outdir wheelhouse +fi if [ "$1" != "testonly" ]; then # Upload to PyPI - conda activate py3.10 - python -m pip install twine - python -m twine upload dist/* + python -m twine upload wheelhouse/* fi diff --git a/release-pypi-macos.sh b/release-pypi-macos.sh index ee0349873..d1b95a9dc 100644 --- a/release-pypi-macos.sh +++ b/release-pypi-macos.sh @@ -1,47 +1,16 @@ #!/bin/sh set -e -# Different to release-pypi-win.cmd and release-pypi-osx.sh, -# this script has to be ran from a clean dockerfile +python -m pip install --upgrade pip cibuildwheel twine -# Download and init conda -# Detect architecture and set appropriate Miniconda filename -ARCH=$(uname -m) -if [ "$ARCH" = "arm64" ]; then - MINICONDA_FILENAME=Miniconda3-latest-MacOSX-arm64.sh -else - MINICONDA_FILENAME=Miniconda3-latest-MacOSX-x86_64.sh -fi - -curl -L -o $MINICONDA_FILENAME \ - "https://repo.continuum.io/miniconda/$MINICONDA_FILENAME" -bash ${MINICONDA_FILENAME} -b -f -p $HOME/miniconda3 -export PATH=$HOME/miniconda3/bin:$PATH -eval "$(conda shell.bash hook)" - -# Accept conda Terms of Service for required channels -conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main -conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r - -for PYTHON_VERSION in 3.10 3.11 3.12 3.13 3.14; do - # Create and activate environment - conda config --add channels conda-forge - conda config --set channel_priority strict - conda create -y -n py$PYTHON_VERSION python=$PYTHON_VERSION - conda activate py$PYTHON_VERSION - - # Build and package - pip install --no-cache-dir build - python -m build --wheel +export CIBW_BUILD="cp310-* cp311-* cp312-* cp313-* cp314-*" +export CIBW_ENVIRONMENT="VERSION=\"${VERSION}\"" +export CIBW_TEST_REQUIRES="pytest" +export CIBW_TEST_COMMAND="pytest {project}/python/tests" - # Cleanup - conda deactivate - rm -rf build OpenCC.egg-info -done +python -m cibuildwheel --output-dir wheelhouse if [ "$1" != "testonly" ]; then # Upload to PyPI - conda activate py3.10 - python -m pip install twine - python -m twine upload dist/* + python -m twine upload wheelhouse/*.whl fi diff --git a/release-pypi-windows.cmd b/release-pypi-windows.cmd index d4e439d43..f2a80874b 100644 --- a/release-pypi-windows.cmd +++ b/release-pypi-windows.cmd @@ -1,41 +1,19 @@ @echo off setlocal EnableDelayedExpansion -SET VERSIONS=3.10 3.11 3.12 3.13 3.14 -SET SOURCEDIR=%cd% +python -m pip install --upgrade pip cibuildwheel twine +if !ERRORLEVEL! NEQ 0 (EXIT !ERRORLEVEL!) -REM Accept conda Terms of Service for required channels -CALL C:\Miniconda/condabin/conda.bat tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main -CALL C:\Miniconda/condabin/conda.bat tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r +SET CIBW_BUILD=cp310-* cp311-* cp312-* cp313-* cp314-* +SET CIBW_ARCHS=AMD64 +SET CIBW_ENVIRONMENT=VERSION="%VERSION%" +SET CIBW_TEST_REQUIRES=pytest +SET CIBW_TEST_COMMAND=pytest {project}/python/tests -REM Build packages -for %%v in (%VERSIONS%) do ( - SET ENV_NAME=py%%v - - REM Create and activate environment - cd %ROOT_DIR% - CALL C:\Miniconda/condabin/conda.bat config --add channels conda-forge - CALL C:\Miniconda/condabin/conda.bat config --set channel_priority strict - - CALL C:\Miniconda/condabin/conda.bat create -y -n py%%v python=%%v - if !ERRORLEVEL! NEQ 0 (EXIT !ERRORLEVEL!) - CALL C:\Miniconda/condabin/conda.bat activate py%%v - if !ERRORLEVEL! NEQ 0 (EXIT !ERRORLEVEL!) - pip install --no-cache-dir build - if !ERRORLEVEL! NEQ 0 (EXIT !ERRORLEVEL!) - - REM Build and package - python -m build --wheel - if !ERRORLEVEL! NEQ 0 (EXIT !ERRORLEVEL!) - - REM Cleanup - CALL C:\Miniconda/condabin/conda.bat deactivate - rmdir /S /Q build OpenCC.egg-info -) +python -m cibuildwheel --output-dir wheelhouse +if !ERRORLEVEL! NEQ 0 (EXIT !ERRORLEVEL!) if NOT "%~1"=="testonly" ( REM Upload to PyPI - C:\Miniconda/condabin/conda.bat activate py3.10 - python -m pip install twine - python -m twine upload dist/* + python -m twine upload wheelhouse/*.whl )