diff --git a/.github/workflows/build-cffi.yml b/.github/workflows/build-cffi.yml new file mode 100644 index 0000000..eb66f3a --- /dev/null +++ b/.github/workflows/build-cffi.yml @@ -0,0 +1,152 @@ +--- +name: Build cffi wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'cffi version to build (git tag without leading v, e.g. 2.1.0)' + required: true + default: '2.1.0' + pull_request: + paths: + - '.github/workflows/build-cffi.yml' + +concurrency: + group: ${{ github.workflow }}-${{ inputs.version || '2.1.0' }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + CFFI_VERSION: ${{ inputs.version || '2.1.0' }} + UV_EXTRA_INDEX_URL: https://pypi.riseproject.dev/simple/ + UV_INDEX_STRATEGY: unsafe-best-match + UV_ONLY_BINARY: ':all:' + MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 + +jobs: + python_sdist: + runs-on: ubuntu-24.04-riscv + outputs: + sdist_artifact_name: ${{ steps.build_sdist.outputs.sdist_artifact_name }} + package_version: ${{ steps.build_sdist.outputs.package_version }} + steps: + - name: checkout cffi + uses: actions/checkout@v7 + with: + repository: python-cffi/cffi + ref: v${{ env.CFFI_VERSION }} + submodules: true + persist-credentials: false + + - name: setup uv + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + with: + python-version: '3.12' + activate-environment: true + enable-cache: false + + - name: build sdist + id: build_sdist + run: | + rm -rf dist/ + uv pip install build + python -m build --sdist + + echo "sdist_artifact_name=$(ls ./dist)" >> "$GITHUB_OUTPUT" + echo "package_version=$(ls ./dist | sed -En 's/cffi-(.+)\.tar\.gz/\1/p')" >> "$GITHUB_OUTPUT" + + - name: upload sdist artifact + uses: actions/upload-artifact@v7 + with: + name: ${{ steps.build_sdist.outputs.sdist_artifact_name }} + path: dist/${{ steps.build_sdist.outputs.sdist_artifact_name }} + if-no-files-found: error + # always upload the sdist artifact- all the wheel build jobs require it + + linux: + # Unlike upstream, we depend only on python_sdist, since we don't need to + # build a large matrix of targets + needs: [python_sdist] + name: Build cffi ${{ inputs.version || '2.1.0' }} ${{ matrix.python }}-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + strategy: + fail-fast: false + matrix: + python: ["cp312", "cp313", "cp314", "cp314t"] + + steps: + - name: fetch sdist artifact + id: fetch_sdist + uses: actions/download-artifact@v8 + with: + name: ${{ needs.python_sdist.outputs.sdist_artifact_name }} + + - name: setup uv + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + with: + python-version: '3.12' + activate-environment: true + enable-cache: false + + - name: build/test wheels + id: build + env: + CFLAGS: -Dffi_call=cffistatic_ffi_call # override name for ffi_call to break hard if we linked against someone else's libffi + CIBW_BUILD: ${{ matrix.python }}-manylinux_riscv64 + CIBW_ENVIRONMENT_PASS_LINUX: CFLAGS # ensure that the build container can see our overridden build config + CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} + CIBW_BEFORE_BUILD: | + set -eux && \ + curl -L -O https://github.com/libffi/libffi/archive/v3.4.6.tar.gz && \ + tar zxf v3.4.6.tar.gz && cd libffi-3.4.6 && \ + ((command -v apk && apk add libtool) || true) && \ + ./autogen.sh && \ + ./configure --without-gcc-arch --disable-docs --with-pic --enable-shared=no && \ + make install && \ + cd .. && \ + rm -rf libffi-3.4.6 + CIBW_TEST_REQUIRES: pytest setuptools meson-python ninja # 3.12+ no longer includes distutils, just always ensure setuptools is present + CIBW_TEST_COMMAND: PYTHONUNBUFFERED=1 python -m pytest {project} + run: | + set -eux + + mkdir cffi + + tar zxf ${{ steps.fetch_sdist.outputs.download-path }}/cffi*.tar.gz --strip-components=1 -C cffi + uv pip install --upgrade cibuildwheel + + # actually build libffi + wheel (using env tweaks above) + python -m cibuildwheel --output-dir dist ./cffi + + echo "artifact_name=$(ls ./dist/)" >> "$GITHUB_OUTPUT" + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: cffi-${{ env.CFFI_VERSION }}-${{ matrix.python }}-manylinux_riscv64 + path: ./dist/*.whl + if-no-files-found: error + + publish: + name: Publish cffi ${{ inputs.version || '2.1.0' }} to GitLab + needs: [linux] + # Only publish when the workflow was triggered from main with a specific + # version. Manual trigger is the only entry point, so checking the ref is + # enough to gate uploads. + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - name: Publish wheels and open docs PR + uses: riseproject-dev/python-wheels/actions/publish-wheels@main + with: + artifact-pattern: cffi-${{ env.CFFI_VERSION }}-*-manylinux_riscv64 + gitlab-username: ${{ vars.GITLAB_DEPLOY_USER }} + gitlab-token: ${{ secrets.GITLAB_DEPLOY_TOKEN }} + gitlab-project-id: ${{ vars.GITLAB_PROJECT_ID }} + gh-token: ${{ secrets.GITHUB_TOKEN }}