Repository navigation
Don't read 'C' + number glyph names as a Macintosh glyph index #38
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
| name: Python wheels | |
| # Wheels are built on every push so a break in the packaging shows up with the | |
| # commit that caused it, and published to PyPI only from a v* tag — the same | |
| # trigger the C++ release in ci-build.yml uses. | |
| on: | |
| push: | |
| branches: ['**'] | |
| tags: ['v*'] | |
| pull_request: | |
| workflow_dispatch: | |
| inputs: | |
| publish-to-testpypi: | |
| description: 'Upload the result to TestPyPI (a rehearsal for the real release)' | |
| type: boolean | |
| default: false | |
| version: | |
| description: 'Version for the rehearsal, e.g. 0.6.3.dev1. An index refuses a version it already holds and never lets it be reused, so give a fresh one each time. Leave empty to use the version in CMakeLists.txt.' | |
| type: string | |
| default: '' | |
| permissions: | |
| contents: read | |
| jobs: | |
| wheels: | |
| name: ${{ matrix.label }} | |
| strategy: | |
| matrix: | |
| # The same runners as ci-build.yml's matrix | |
| # ( self-hosted, macos-latest, ubuntu-24.04-arm, macos-15-intel ), | |
| # paired with the label the artifact is named after. | |
| include: | |
| - os: self-hosted | |
| label: linux-x86_64 | |
| - os: ubuntu-24.04-arm | |
| label: linux-aarch64 | |
| - os: macos-latest | |
| label: macos-arm64 | |
| - os: macos-15-intel | |
| label: macos-x86_64 | |
| fail-fast: false | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| # cibuildwheel needs a reasonably recent Python of its own to run under; | |
| # it is present on the GitHub-hosted images but not guaranteed on a | |
| # self-hosted one. | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| # cibuildwheel copies the whole workspace into the build container, and a | |
| # self-hosted runner reuses that workspace across workflows. ci-build.yml | |
| # builds in-source on the same machine, with libfontconfig-dev present, | |
| # leaving xpdf-4.06/aconf.h behind with HAVE_FONTCONFIG set. xpdf's | |
| # include path puts the source tree ahead of the build directory, so that | |
| # stale header wins over the freshly generated one and GlobalParams.cc | |
| # fails on <fontconfig/fontconfig.h>, which the manylinux image does not | |
| # have. aconf.h is listed in the submodule's .gitignore, so -x is what | |
| # makes it go; a plain clean leaves it in place. | |
| - name: Remove generated files left behind by other builds | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| git clean -ffdx | |
| git submodule foreach --recursive git clean -ffdx | |
| # A rehearsal uploads a pre-release version such as 0.6.3.dev1, which | |
| # CMakeLists.txt cannot hold (CMake versions are numeric). Only ever runs | |
| # for a manual dispatch that asked for one; a tag push takes its version | |
| # from CMakeLists.txt as usual. | |
| - name: Pin the rehearsal version | |
| if: inputs.version != '' | |
| shell: bash | |
| run: python3 scripts/set_python_version.py '${{ inputs.version }}' | |
| # Each runner builds only for its own architecture; there is no | |
| # cross-compilation and no QEMU, which keeps this matrix aligned with | |
| # the one in ci-build.yml and with the prebuilt static libraries under | |
| # libs/*/{linux,mac}/{64,arm64}. | |
| # | |
| # The Linux jobs build inside a manylinux container, so their runner | |
| # needs a usable Docker. | |
| - name: Build and test wheel | |
| uses: pypa/cibuildwheel@v4.2.0 | |
| - name: Upload wheel | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: wheel-${{ matrix.label }} | |
| path: wheelhouse/*.whl | |
| sdist: | |
| name: sdist | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| # A rehearsal uploads a pre-release version such as 0.6.3.dev1, which | |
| # CMakeLists.txt cannot hold (CMake versions are numeric). Only ever runs | |
| # for a manual dispatch that asked for one; a tag push takes its version | |
| # from CMakeLists.txt as usual. | |
| - name: Pin the rehearsal version | |
| if: inputs.version != '' | |
| shell: bash | |
| run: python3 scripts/set_python_version.py '${{ inputs.version }}' | |
| - name: Build sdist | |
| run: pipx run build --sdist | |
| # A source build has to work for the platforms with no wheel, so check | |
| # that the sdist alone is enough to produce a working install. | |
| - name: Install from the sdist and run the tests | |
| run: | | |
| set -euo pipefail | |
| python -m venv /tmp/sdist-venv | |
| /tmp/sdist-venv/bin/pip install dist/*.tar.gz pytest | |
| /tmp/sdist-venv/bin/python -m pytest python/tests -q | |
| - name: Upload sdist | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: sdist | |
| path: dist/*.tar.gz | |
| # A rehearsal of the release, run by hand from the Actions tab: same build, | |
| # same artifacts, same trusted-publishing path, pointed at TestPyPI. Give it a | |
| # pre-release version (0.6.3.dev1, then .dev2, ...) -- an index refuses a | |
| # version it already holds and never lets it be reused, even after a delete. | |
| publish-testpypi: | |
| name: Publish to TestPyPI | |
| needs: [wheels, sdist] | |
| if: inputs.publish-to-testpypi | |
| runs-on: ubuntu-24.04 | |
| environment: testpypi | |
| permissions: | |
| # Trusted publishing; no API token is stored in the repository. Configure | |
| # the publisher once at | |
| # https://test.pypi.org/manage/account/publishing/ | |
| # with owner kermitt2, repository pdfalto, workflow ci-python.yml, | |
| # environment testpypi. | |
| id-token: write | |
| steps: | |
| - name: Download wheels | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: 'wheel-*' | |
| path: dist | |
| merge-multiple: true | |
| - name: Download sdist | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: sdist | |
| path: dist | |
| - name: Show what will be uploaded | |
| run: ls -lh dist/ | |
| - name: Publish | |
| uses: pypa/gh-action-pypi-publish@v1.14.2 | |
| with: | |
| repository-url: https://test.pypi.org/legacy/ | |
| publish: | |
| name: Publish to PyPI | |
| needs: [wheels, sdist] | |
| # Only a tag push. The event check matters: without it, dispatching this | |
| # workflow by hand while a v* tag is checked out would upload to the real | |
| # PyPI, which is exactly what a rehearsal is trying to avoid. | |
| if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') | |
| runs-on: ubuntu-24.04 | |
| environment: pypi | |
| permissions: | |
| # Required by PyPI trusted publishing; no API token is stored in the | |
| # repository. Configure the publisher once at | |
| # https://pypi.org/manage/project/pdfalto/settings/publishing/ | |
| # with owner kermitt2, repository pdfalto, workflow ci-python.yml, | |
| # environment pypi. | |
| id-token: write | |
| steps: | |
| - name: Download all distributions | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: 'wheel-*' | |
| path: dist | |
| merge-multiple: true | |
| - name: Download sdist | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: sdist | |
| path: dist | |
| - name: Show what will be uploaded | |
| run: ls -lh dist/ | |
| - name: Publish | |
| uses: pypa/gh-action-pypi-publish@v1.14.2 |