Skip to content

Commit

Permalink
Merge pull request #13048 from sbidoul/trusted-publisher-sbi
Browse files Browse the repository at this point in the history
Add trusted publisher release workfiow
  • Loading branch information
sbidoul authored Jan 24, 2025
2 parents c7fb1e1 + 1801d83 commit 6b0fb90
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 9 deletions.
6 changes: 5 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
interval: "weekly"
groups:
github-actions:
patterns:
- "*"
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
44 changes: 44 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Publish Python 🐍 distribution 📦 to PyPI

on:
push:
tags:
- "*"

jobs:
build:
name: Build distribution 📦
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
persist-credentials: false
- name: Build a binary wheel and a source tarball
run: ./build-project.py
- name: Store the distribution packages
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4
with:
name: python-package-distributions
path: dist/

publish-to-pypi:
name: >-
Publish Python 🐍 distribution 📦 to PyPI
needs:
- build
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/project/pip/${{ github.ref_name }}
permissions:
id-token: write # IMPORTANT: mandatory for trusted publishing

steps:
- name: Download all the dists
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4
with:
name: python-package-distributions
path: dist/
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@67339c736fd9354cd4f8cb0b744f2b82a74b5c70 # release/v1
4 changes: 4 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ include README.rst
include SECURITY.md
include pyproject.toml

include build-requirements.in
include build-requirements.txt
include build-project.py

include src/pip/_vendor/README.rst
include src/pip/_vendor/vendor.txt
recursive-include src/pip/_vendor *LICENSE*
Expand Down
67 changes: 67 additions & 0 deletions build-project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env python3
"""Build pip using pinned build requirements."""

import subprocess
import tempfile
import venv
from os import PathLike
from pathlib import Path
from types import SimpleNamespace


class EnvBuilder(venv.EnvBuilder):
"""A subclass of venv.EnvBuilder that exposes the python executable command."""

def ensure_directories(
self, env_dir: str | bytes | PathLike[str] | PathLike[bytes]
) -> SimpleNamespace:
context = super().ensure_directories(env_dir)
self.env_exec_cmd = context.env_exec_cmd
return context


def get_git_head_timestamp() -> str:
return subprocess.run(
[
"git",
"log",
"-1",
"--pretty=format:%ct",
],
text=True,
stdout=subprocess.PIPE,
).stdout.strip()


def main() -> None:
with tempfile.TemporaryDirectory() as build_env:
env_builder = EnvBuilder(with_pip=True)
env_builder.create(build_env)
subprocess.run(
[
env_builder.env_exec_cmd,
"-Im",
"pip",
"install",
"--no-deps",
"--only-binary=:all:",
"--require-hashes",
"-r",
Path(__file__).parent / "build-requirements.txt",
],
check=True,
)
subprocess.run(
[
env_builder.env_exec_cmd,
"-Im",
"build",
"--no-isolation",
],
check=True,
env={"SOURCE_DATE_EPOCH": get_git_head_timestamp()},
)


if __name__ == "__main__":
main()
2 changes: 2 additions & 0 deletions build-requirements.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build
setuptools
24 changes: 24 additions & 0 deletions build-requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --allow-unsafe --generate-hashes build-requirements.in
#
build==1.2.2.post1 \
--hash=sha256:1d61c0887fa860c01971625baae8bdd338e517b836a2f70dd1f7aa3a6b2fc5b5 \
--hash=sha256:b36993e92ca9375a219c99e606a122ff365a760a2d4bba0caa09bd5278b608b7
# via -r build-requirements.in
packaging==24.2 \
--hash=sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759 \
--hash=sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f
# via build
pyproject-hooks==1.2.0 \
--hash=sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8 \
--hash=sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913
# via build

# The following packages are considered to be unsafe in a requirements file:
setuptools==75.8.0 \
--hash=sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6 \
--hash=sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3
# via -r build-requirements.in
7 changes: 2 additions & 5 deletions docs/html/development/release-process.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions news/13048.process.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Started releasing to PyPI from a GitHub Actions CI/CD workflow that implements trusted publishing and bundles :pep:`740` digital attestations.

In addition to being signed, the released distribution packages are now reproducible through the commit timestamp.
6 changes: 3 additions & 3 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ def build_release(session: nox.Session) -> None:
)

session.log("# Install dependencies")
session.install("build", "twine")
session.install("twine")

with release.isolated_temporary_checkout(session, version) as build_dir:
session.log(
Expand Down Expand Up @@ -375,11 +375,11 @@ def build_dists(session: nox.Session) -> List[str]:
)

session.log("# Build distributions")
session.run("python", "-m", "build", silent=True)
session.run("python", "build-project.py", silent=True)
produced_dists = glob.glob("dist/*")

session.log(f"# Verify distributions: {', '.join(produced_dists)}")
session.run("twine", "check", *produced_dists, silent=True)
session.run("twine", "check", "--strict", *produced_dists, silent=True)

return produced_dists

Expand Down

0 comments on commit 6b0fb90

Please sign in to comment.