From 29af9e3e3fb12beb9b58d9970534461f4bfa4b2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Sun, 27 Oct 2024 16:09:49 +0100 Subject: [PATCH] Add trusted publisher release workfiow --- .github/workflows/ci.yml | 4 +- .github/workflows/release.yml | 24 ++++++ docs/html/development/release-process.rst | 7 +- noxfile.py | 92 ----------------------- 4 files changed, 29 insertions(+), 98 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2af281c7027..4406706b4c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,7 +78,9 @@ jobs: - run: pip install nox - run: nox -s prepare-release -- 99.9 - - run: nox -s build-release -- 99.9 + - run: git checkout 99.9 + - run: pipx run build + - run: pipx run twine check dist/* - run: pipx run check-manifest vendoring: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000000..d96c6e4250c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,24 @@ +on: + push: + tags: + - "*" + +name: release + +jobs: + pypi: + name: upload release to PyPI + runs-on: ubuntu-latest + environment: release + permissions: + # Used to authenticate to PyPI via OIDC. + id-token: write + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.x" + - name: build + run: pipx run build + - name: publish + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/docs/html/development/release-process.rst b/docs/html/development/release-process.rst index 5bf0d278b71..77ee9b5d46b 100644 --- a/docs/html/development/release-process.rst +++ b/docs/html/development/release-process.rst @@ -146,11 +146,8 @@ Creating a new release This will update the relevant files and tag the correct commit. #. Submit the ``release/YY.N`` branch as a pull request and ensure CI passes. Merge the changes back into ``main`` and pull them back locally. -#. Build the release artifacts using ``nox -s build-release -- YY.N``. - This will checkout the tag, generate the distribution files to be - uploaded and checkout the main branch again. -#. Upload the release to PyPI using ``nox -s upload-release -- YY.N``. -#. Push the tag created by ``prepare-release``. +#. Push the tag created by ``prepare-release``. This will trigger the release + workflow on GitHub and publish to PyPI. #. Regenerate the ``get-pip.py`` script in the `get-pip repository`_ (as documented there) and commit the results. #. Submit a Pull Request to `CPython`_ adding the new version of pip diff --git a/noxfile.py b/noxfile.py index 2051362769c..48e44918446 100644 --- a/noxfile.py +++ b/noxfile.py @@ -2,7 +2,6 @@ """ import argparse -import glob import os import shutil import sys @@ -315,94 +314,3 @@ def prepare_release(session: nox.Session) -> None: next_dev_version = release.get_next_development_version(version) release.update_version_file(next_dev_version, VERSION_FILE) release.commit_file(session, VERSION_FILE, message="Bump for development") - - -@nox.session(name="build-release") -def build_release(session: nox.Session) -> None: - version = release.get_version_from_arguments(session) - if not version: - session.error("Usage: nox -s build-release -- YY.N[.P]") - - session.log("# Ensure no files in dist/") - if release.have_files_in_folder("dist"): - session.error( - "There are files in dist/. Remove them and try again. " - "You can use `git clean -fxdi -- dist` command to do this" - ) - - session.log("# Install dependencies") - session.install("build", "twine") - - with release.isolated_temporary_checkout(session, version) as build_dir: - session.log( - "# Start the build in an isolated, " - f"temporary Git checkout at {build_dir!s}", - ) - with release.workdir(session, build_dir): - tmp_dists = build_dists(session) - - tmp_dist_paths = (build_dir / p for p in tmp_dists) - session.log(f"# Copying dists from {build_dir}") - os.makedirs("dist", exist_ok=True) - for dist, final in zip(tmp_dist_paths, tmp_dists): - session.log(f"# Copying {dist} to {final}") - shutil.copy(dist, final) - - -def build_dists(session: nox.Session) -> List[str]: - """Return dists with valid metadata.""" - session.log( - "# Check if there's any Git-untracked files before building the wheel", - ) - - has_forbidden_git_untracked_files = any( - # Don't report the environment this session is running in - not untracked_file.startswith(".nox/build-release/") - for untracked_file in release.get_git_untracked_files() - ) - if has_forbidden_git_untracked_files: - session.error( - "There are untracked files in the working directory. " - "Remove them and try again", - ) - - session.log("# Build distributions") - session.run("python", "-m", "build", silent=True) - produced_dists = glob.glob("dist/*") - - session.log(f"# Verify distributions: {', '.join(produced_dists)}") - session.run("twine", "check", *produced_dists, silent=True) - - return produced_dists - - -@nox.session(name="upload-release") -def upload_release(session: nox.Session) -> None: - version = release.get_version_from_arguments(session) - if not version: - session.error("Usage: nox -s upload-release -- YY.N[.P]") - - session.log("# Install dependencies") - session.install("twine") - - distribution_files = glob.glob("dist/*") - session.log(f"# Distribution files: {distribution_files}") - - # Sanity check: Make sure there's 2 distribution files. - count = len(distribution_files) - if count != 2: - session.error( - f"Expected 2 distribution files for upload, got {count}. " - f"Remove dist/ and run 'nox -s build-release -- {version}'" - ) - # Sanity check: Make sure the files are correctly named. - distfile_names = (os.path.basename(fn) for fn in distribution_files) - expected_distribution_files = [ - f"pip-{version}-py3-none-any.whl", - f"pip-{version}.tar.gz", - ] - if sorted(distfile_names) != sorted(expected_distribution_files): - session.error(f"Distribution files do not seem to be for {version} release.") - - session.log("# Upload distributions") - session.run("twine", "upload", *distribution_files)