Skip to content

Commit d36954b

Browse files
illia-vhugovkAA-Turner
authored
gh-91172: Create a workflow for verifying bundled pip and setuptools (GH-31885)
Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com> Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
1 parent c029b55 commit d36954b

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Verify bundled pip and setuptools
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
paths:
7+
- 'Lib/ensurepip/_bundled/**'
8+
- '.github/workflows/verify-ensurepip-wheels.yml'
9+
- 'Tools/scripts/verify_ensurepip_wheels.py'
10+
pull_request:
11+
paths:
12+
- 'Lib/ensurepip/_bundled/**'
13+
- '.github/workflows/verify-ensurepip-wheels.yml'
14+
- 'Tools/scripts/verify_ensurepip_wheels.py'
15+
16+
permissions:
17+
contents: read
18+
19+
jobs:
20+
verify:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v3
24+
- uses: actions/setup-python@v4
25+
with:
26+
python-version: '3'
27+
- name: Compare checksums of bundled pip and setuptools to ones published on PyPI
28+
run: ./Tools/scripts/verify_ensurepip_wheels.py
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Create a GitHub Actions workflow for verifying bundled pip and setuptools.
2+
Patch by Illia Volochii and Adam Turner.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#! /usr/bin/env python3
2+
3+
"""
4+
Compare checksums for wheels in :mod:`ensurepip` against the Cheeseshop.
5+
6+
When GitHub Actions executes the script, output is formatted accordingly.
7+
https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-a-notice-message
8+
"""
9+
10+
import hashlib
11+
import json
12+
import os
13+
import re
14+
from pathlib import Path
15+
from urllib.request import urlopen
16+
17+
PACKAGE_NAMES = ("pip", "setuptools")
18+
ENSURE_PIP_ROOT = Path(__file__).parent.parent.parent / "Lib/ensurepip"
19+
WHEEL_DIR = ENSURE_PIP_ROOT / "_bundled"
20+
ENSURE_PIP_INIT_PY_TEXT = (ENSURE_PIP_ROOT / "__init__.py").read_text(encoding="utf-8")
21+
GITHUB_ACTIONS = os.getenv("GITHUB_ACTIONS") == "true"
22+
23+
24+
def print_notice(file_path: str, message: str) -> None:
25+
if GITHUB_ACTIONS:
26+
message = f"::notice file={file_path}::{message}"
27+
print(message, end="\n\n")
28+
29+
30+
def print_error(file_path: str, message: str) -> None:
31+
if GITHUB_ACTIONS:
32+
message = f"::error file={file_path}::{message}"
33+
print(message, end="\n\n")
34+
35+
36+
def verify_wheel(package_name: str) -> bool:
37+
# Find the package on disk
38+
package_path = next(WHEEL_DIR.glob(f"{package_name}*.whl"), None)
39+
if not package_path:
40+
print_error("", f"Could not find a {package_name} wheel on disk.")
41+
return False
42+
43+
print(f"Verifying checksum for {package_path}.")
44+
45+
# Find the version of the package used by ensurepip
46+
package_version_match = re.search(
47+
f'_{package_name.upper()}_VERSION = "([^"]+)', ENSURE_PIP_INIT_PY_TEXT
48+
)
49+
if not package_version_match:
50+
print_error(
51+
package_path,
52+
f"No {package_name} version found in Lib/ensurepip/__init__.py.",
53+
)
54+
return False
55+
package_version = package_version_match[1]
56+
57+
# Get the SHA 256 digest from the Cheeseshop
58+
try:
59+
raw_text = urlopen(f"https://pypi.org/pypi/{package_name}/json").read()
60+
except (OSError, ValueError):
61+
print_error(package_path, f"Could not fetch JSON metadata for {package_name}.")
62+
return False
63+
64+
release_files = json.loads(raw_text)["releases"][package_version]
65+
for release_info in release_files:
66+
if package_path.name != release_info["filename"]:
67+
continue
68+
expected_digest = release_info["digests"].get("sha256", "")
69+
break
70+
else:
71+
print_error(package_path, f"No digest for {package_name} found from PyPI.")
72+
return False
73+
74+
# Compute the SHA 256 digest of the wheel on disk
75+
actual_digest = hashlib.sha256(package_path.read_bytes()).hexdigest()
76+
77+
print(f"Expected digest: {expected_digest}")
78+
print(f"Actual digest: {actual_digest}")
79+
80+
if actual_digest != expected_digest:
81+
print_error(
82+
package_path, f"Failed to verify the checksum of the {package_name} wheel."
83+
)
84+
return False
85+
86+
print_notice(
87+
package_path,
88+
f"Successfully verified the checksum of the {package_name} wheel.",
89+
)
90+
return True
91+
92+
93+
if __name__ == "__main__":
94+
exit_status = 0
95+
for package_name in PACKAGE_NAMES:
96+
if not verify_wheel(package_name):
97+
exit_status = 1
98+
raise SystemExit(exit_status)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy