name: Create wheel on: # run when a release has been created release: types: [created] env: # set this so the sqlalchemy test uses the installed version and not the local one PYTHONNOUSERSITE: 1 # comment TWINE_REPOSITORY_URL to use the real pypi. NOTE: change also the secret used in TWINE_PASSWORD # TWINE_REPOSITORY_URL: https://test.pypi.org/legacy/ jobs: # two jobs are defined make-wheel-win-osx and make-wheel-linux. # they do the the same steps, but linux wheels need to be build to target manylinux make-wheel-win-osx: name: ${{ matrix.python-version }}-${{ matrix.architecture }}-${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: matrix: os: - "windows-latest" - "macos-latest" python-version: - "2.7" - "3.5" - "3.6" - "3.7" - "3.8" architecture: - x64 - x86 include: - python-version: "2.7" extra-requires: "mock" exclude: - os: "macos-latest" architecture: x86 fail-fast: false steps: - name: Checkout repo uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v1 with: python-version: ${{ matrix.python-version }} architecture: ${{ matrix.architecture }} - name: Remove tag_build from setup.cfg # sqlalchemy has `tag_build` set to `dev` in setup.cfg. We need to remove it before creating the weel # otherwise it gets tagged with `dev0` shell: pwsh # This is equivalent to the sed commands: # `sed -i '/tag_build=dev/d' setup.cfg` # `sed -i '/tag_build = dev/d' setup.cfg` # `-replace` uses a regexp match # alternative form: `(get-content setup.cfg) | foreach-object{$_ -replace "tag_build.=.dev",""} | set-content setup.cfg` run: | (cat setup.cfg) | %{$_ -replace "tag_build.?=.?dev",""} | set-content setup.cfg - name: Create wheel # create the wheel using --no-use-pep517 since locally we have pyproject # this flag should be removed once sqlalchemy supports pep517 # `--no-deps` is used to only generate the wheel for the current library. Redundant in sqlalchemy since it has no dependencies run: | python -m pip install --upgrade pip pip --version pip install setuptools wheel pip wheel -w dist --no-use-pep517 -v --no-deps . - name: Install wheel # install the created wheel without using the pypi index run: | pip install -f dist --no-index sqlalchemy - name: Check c extensions # on windows in python 2.7 and 3.5 the cextension fail to build. # for python 2.7 visual studio 9 is missing # for python 3.5 the linker has an error "cannot run 'rc.exe'" if: matrix.os != 'windows-latest' || ( matrix.python-version != '2.7' && matrix.python-version != '3.5' ) run: | python -c 'from sqlalchemy import cprocessors, cresultproxy, cutils' - name: Test created wheel # the mock reconnect test seems to fail on the ci in windows run: | pip install pytest pytest-xdist ${{ matrix.extra-requires }} pytest -n2 -q test -k 'not MockReconnectTest' --nomemory - name: Get wheel name id: wheel-name shell: bash # creates output from https://github.community/t5/GitHub-Actions/Using-the-output-of-run-inside-of-if-condition/td-p/33920 run: | echo ::set-output name=wheel::`ls dist` - name: Upload wheel to release # upload the generated wheel to the github release. uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: # this is a release to the event is called release: https://help.github.com/en/actions/reference/events-that-trigger-workflows#release-event-release # the release event has the structure of this response https://developer.github.com/v3/repos/releases/#create-a-release upload_url: ${{ github.event.release.upload_url }} asset_path: dist/${{ steps.wheel-name.outputs.wheel }} asset_name: ${{ steps.wheel-name.outputs.wheel }} asset_content_type: application/zip # application/octet-stream - name: Set up Python for twine # twine on py2 is very old and is no longer updated, so we change to python 3.8 before upload uses: actions/setup-python@v1 with: python-version: "3.8" - name: Publish wheel # the action https://github.com/marketplace/actions/pypi-publish runs only on linux and we cannot specify # additional options env: TWINE_USERNAME: __token__ # replace TWINE_PASSWORD with token for real pypi # TWINE_PASSWORD: ${{ secrets.test_pypi_token }} TWINE_PASSWORD: ${{ secrets.pypi_token }} run: | pip install -U twine twine upload --skip-existing dist/* make-wheel-linux: name: ${{ matrix.python-version }}-${{ matrix.architecture }}-${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: matrix: os: - "ubuntu-latest" python-version: # the versions are - as specified in PEP 425. - cp27-cp27m - cp27-cp27mu - cp35-cp35m - cp36-cp36m - cp37-cp37m - cp38-cp38 architecture: - x64 include: - python-version: "cp27-cp27m" extra-requires: "mock" - python-version: "cp27-cp27mu" extra-requires: "mock" fail-fast: false steps: - name: Checkout repo uses: actions/checkout@v2 - name: Get python version id: linux-py-version env: py_tag: ${{ matrix.python-version }} # the command `echo "::set-output ...` is used to create an step output that can be used in following steps # this is from https://github.community/t5/GitHub-Actions/Using-the-output-of-run-inside-of-if-condition/td-p/33920 run: | version="${py_tag: 2:1}.${py_tag: 3:1}" echo $version echo "::set-output name=python-version::$version" - name: Set up Python uses: actions/setup-python@v1 with: python-version: ${{ steps.linux-py-version.outputs.python-version }} architecture: ${{ matrix.architecture }} - name: Remove tag_build from setup.cfg # sqlalchemy has `tag_build` set to `dev` in setup.cfg. We need to remove it before creating the weel # otherwise it gets tagged with `dev0` shell: pwsh # This is equivalent to the sed commands: # `sed -i '/tag_build=dev/d' setup.cfg` # `sed -i '/tag_build = dev/d' setup.cfg` # `-replace` uses a regexp match # alternative form: `(get-content setup.cfg) | foreach-object{$_ -replace "tag_build.=.dev",""} | set-content setup.cfg` run: | (cat setup.cfg) | %{$_ -replace "tag_build.?=.?dev",""} | set-content setup.cfg - name: Create wheel for manylinux # this step uses the image provided by pypa here https://github.com/pypa/manylinux to generate the wheels on linux # the action uses the image for manylinux2010 but can generate also a manylinux1 wheel # change the tag of this image to change the image used # NOTE: the output folder is "wheelhouse", not the classic "dist" uses: RalfG/python-wheels-manylinux-build@v0.2.2-manylinux2010_x86_64 # this action generates 3 wheels in wheelhouse/. linux, manylinux1 and manylinux2010 with: # python-versions is the output of the previous step and is in the form -. Eg cp37-cp37mu python-versions: ${{ matrix.python-version }} build-requirements: "setuptools wheel" # Create the wheel using --no-use-pep517 since locally we have pyproject # This flag should be removed once sqlalchemy supports pep517 # `--no-deps` is used to only generate the wheel for the current library. Redundant in sqlalchemy since it has no dependencies pip-wheel-args: "--no-use-pep517 -v --no-deps" - name: Check created wheel # check that the wheel is compatible with the current installation. # If it is then does: # - install the created wheel without using the pypi index # - check the c extension # - runs the tests run: | pip install -q wheel version=`python -W ignore -c 'from wheel.pep425tags import get_abbr_impl, get_impl_ver, get_abi_tag; print("{0}{1}-{2}".format(get_abbr_impl(), get_impl_ver(), get_abi_tag()))'` echo Wheel tag ${{ matrix.python-version }}. Installed version $version. if [[ "${{ matrix.python-version }}" = "$version" ]] then pip install -f wheelhouse --no-index sqlalchemy python -c 'from sqlalchemy import cprocessors, cresultproxy, cutils' pip install pytest pytest-xdist ${{ matrix.extra-requires }} pytest -n2 -q test -k 'not MockReconnectTest' --nomemory else echo Not compatible. Skipping install. fi - name: Get wheel names id: wheel-name shell: bash # the wheel creation step generates 3 wheels: linux, manylinux1 and manylinux2010 # Pypi accepts only the manylinux versions run: | cd wheelhouse echo ::set-output name=wheel1::`ls *manylinux1*` echo ::set-output name=wheel2010::`ls *manylinux2010*` - name: Upload wheel manylinux1 to release # upload the generated manylinux1 wheel to the github release. Only a single file per step can be uploaded at the moment uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: # this is a release to the event is called release: https://help.github.com/en/actions/reference/events-that-trigger-workflows#release-event-release # the release event has the structure of this response https://developer.github.com/v3/repos/releases/#create-a-release upload_url: ${{ github.event.release.upload_url }} asset_path: wheelhouse/${{ steps.wheel-name.outputs.wheel1 }} asset_name: ${{ steps.wheel-name.outputs.wheel1 }} asset_content_type: application/zip # application/octet-stream - name: Upload wheel manylinux2010 to release # upload the generated manylinux2010 wheel to the github release. Only a single file per step can be uploaded at the moment uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: # this is a release to the event is called release: https://help.github.com/en/actions/reference/events-that-trigger-workflows#release-event-release # the release event has the structure of this response https://developer.github.com/v3/repos/releases/#create-a-release upload_url: ${{ github.event.release.upload_url }} asset_path: wheelhouse/${{ steps.wheel-name.outputs.wheel2010 }} asset_name: ${{ steps.wheel-name.outputs.wheel2010 }} asset_content_type: application/zip # application/octet-stream - name: Set up Python for twine # twine on py2 is very old and is no longer updated, so we change to python 3.8 before upload uses: actions/setup-python@v1 with: python-version: "3.8" - name: Publish wheel # the action https://github.com/marketplace/actions/pypi-publish runs only on linux and we cannot specify # additional options # We upload both manylinux1 and manylinux2010 wheels. pip will download the appropriate one according to the system. # manylinux1 is an older format and is now not very used since many environments can use manylinux2010 # currently (April 2020) manylinux2014 is still wip, so we do not generate it. env: TWINE_USERNAME: __token__ # replace TWINE_PASSWORD with token for real pypi # TWINE_PASSWORD: ${{ secrets.test_pypi_token }} TWINE_PASSWORD: ${{ secrets.pypi_token }} run: | pip install -U twine twine upload --skip-existing wheelhouse/*manylinux*