From 0d10faf957a420dcc89629cf9ae0ad81edd96c7d Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Sat, 13 Nov 2021 11:55:53 -0500 Subject: [PATCH] docs: better deployment docs (#911) * docs: better deployment docs * Apply suggestions from code review Co-authored-by: Joe Rickerby * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Co-authored-by: Joe Rickerby Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- docs/deliver-to-pypi.md | 81 ++++++++++++++++++++++---- examples/github-deploy.yml | 12 +--- examples/travis-ci-test-and-deploy.yml | 22 +++---- 3 files changed, 80 insertions(+), 35 deletions(-) diff --git a/docs/deliver-to-pypi.md b/docs/deliver-to-pypi.md index 3d794f236..610fe6e5d 100644 --- a/docs/deliver-to-pypi.md +++ b/docs/deliver-to-pypi.md @@ -4,15 +4,16 @@ title: Delivering to PyPI After you've built your wheels, you'll probably want to deliver them to PyPI. -### Manual method +## Manual method -On your development machine, do the following... +On your development machine, install [pipx](https://pypa.github.io/pipx/) and do the following: ```bash +# Either download the SDist from your CI, or make it: # Clear out your 'dist' folder. rm -rf dist # Make a source distribution -python setup.py sdist +pipx run build --sdist # 🏃🏻 # Go and download your wheel files from wherever you put them. e.g. your CI @@ -20,17 +21,77 @@ python setup.py sdist # 'dist' folder. # Upload using 'twine' (you may need to 'pip install twine') -twine upload dist/* +pipx run twine upload dist/* ``` -### Semi-automatic method using wheelhouse-uploader +## Automatic method -Obviously, manual steps are for chumps, so we can automate this a little by using [wheelhouse-uploader](https://github.com/ogrisel/wheelhouse-uploader). +If you don't need much control over the release of a package, you can set up +cibuildwheel to deliver the wheels straight to PyPI. You just need to bump the +version and tag it. -> Quick note from me - using S3 as a storage didn't work due to a [bug](https://issues.apache.org/jira/browse/LIBCLOUD-792) in libcloud. Feel free to use my fork of that package that fixes the bug `pip install https://github.com/joerick/libcloud/archive/v1.5.0-s3fix.zip` +### Generic instructions -### Automatic method +Make your SDist with the [build](https://github.com/pypa/build) tool, and your wheels with cibuildwheel. If you can make the files available as +downloadable artifacts, this make testing before releases easier (depending on your CI provider's options). The "publish" job/step should collect the +files, and then run `twine upload ` (possibly via [pipx](https://github.com/pypa/pipx)); this should only happen on tags or "releases". -If you don't need much control over the release of a package, you can set up cibuildwheel to deliver the wheels straight to PyPI. This doesn't require anycloud storage to work - you just need to bump the version and tag it. +### GitHub Actions -See [`examples/travis-ci-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/main/examples/travis-ci-deploy.yml) and [`examples/github-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/main/examples/github-deploy.yml) for example configurations that automatically upload wheels to PyPI. +GitHub actions has pipx in all the runners as a supported package manager, as +well as several useful actions. Alongside your existing job(s) that runs cibuildwheel to make wheels, you will probably want to build an SDist: + +```yaml + make_sdist: + name: Make SDist + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # Optional, use if you use setuptools_scm + submodules: true # Optional, use if you have submodules + + - name: Build SDist + run: pipx run build --sdist + + - uses: actions/upload-artifact@v2 + with: + path: dist/*.tar.gz +``` + +Then, you need to publish the artifacts that the previous jobs have built. This final job should run only on release or tag, depending on your preference. It gathers the artifacts from the sdist and wheel jobs and uploads them to PyPI. + +This requires a [PyPI upload token](https://pypi.org/manage/account/token/), stored in your [GitHub repo's secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) as `pypi_password`. + +```yaml + upload_all: + needs: [build_wheels, make_sdist] + runs-on: ubuntu-latest + if: github.event_name == 'release' && github.event.action == 'published' + steps: + - uses: actions/download-artifact@v2 + with: + name: artifact + path: dist + + - uses: pypa/gh-action-pypi-publish@v1.4.2 + with: + user: __token__ + password: ${{ secrets.pypi_password }} +``` + +You should use dependabot to keep the publish action up to date. In the above +example, the same name (the default, "artifact" is used for all upload-artifact +runs, so we can just download all of the in one step into a common directory. + +See +[`examples/github-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/main/examples/github-deploy.yml) +for an example configuration that automatically upload wheels to PyPI. Also see +[scikit-hep.org/developer/gha_wheels](https://scikit-hep.org/developer/gha_wheels) +for a complete guide. + +### TravisCI + +See +[`examples/travis-ci-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/main/examples/travis-ci-deploy.yml) +for an example configuration. diff --git a/examples/github-deploy.yml b/examples/github-deploy.yml index 8f16439a9..ef4ec299a 100644 --- a/examples/github-deploy.yml +++ b/examples/github-deploy.yml @@ -21,11 +21,6 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - name: Install Python - with: - python-version: '3.8' - - name: Build wheels uses: pypa/cibuildwheel@v2.2.2 @@ -39,13 +34,8 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - name: Install Python - with: - python-version: '3.8' - - name: Build sdist - run: python setup.py sdist + run: pipx run build --sdist - uses: actions/upload-artifact@v2 with: diff --git a/examples/travis-ci-test-and-deploy.yml b/examples/travis-ci-test-and-deploy.yml index a538071fc..cb5563855 100644 --- a/examples/travis-ci-test-and-deploy.yml +++ b/examples/travis-ci-test-and-deploy.yml @@ -26,7 +26,7 @@ install: - python3 -m pip install pytest script: - - python3 setup.py install + - python3 -m pip install . - pytest stages: @@ -48,30 +48,24 @@ jobs: # Deploy source distribution - stage: deploy name: Deploy source distribution - install: skip - script: python3 setup.py sdist --formats=gztar - after_success: | - python3 -m pip install twine - python3 -m twine upload --skip-existing dist/*.tar.gz + install: python3 -m pip install build twine + script: python3 -m build --sdist --formats=gztar + after_success: python3 -m twine upload --skip-existing dist/*.tar.gz # Deploy on linux - stage: deploy name: Build and deploy Linux wheels services: docker - install: python3 -m pip install cibuildwheel==2.2.2 + install: python3 -m pip install cibuildwheel==2.2.2 twine script: python3 -m cibuildwheel --output-dir wheelhouse - after_success: | - python3 -m pip install twine - python3 -m twine upload --skip-existing wheelhouse/*.whl + after_success: python3 -m twine upload --skip-existing wheelhouse/*.whl # Deploy on windows - stage: deploy name: Build and deploy Windows wheels os: windows language: shell - install: python3 -m pip install cibuildwheel==2.2.2 + install: python3 -m pip install cibuildwheel==2.2.2 twine script: python3 -m cibuildwheel --output-dir wheelhouse - after_success: | - python3 -m pip install twine - python3 -m twine upload --skip-existing wheelhouse/*.whl + after_success: python3 -m twine upload --skip-existing wheelhouse/*.whl env: global: