Skip to content

Commit e62fed6

Browse files
committed
ci: produce installation only .tar.gz archives
This should satisfy the feature request in #79. Closes #79.
1 parent 5ae072f commit e62fed6

File tree

5 files changed

+172
-0
lines changed

5 files changed

+172
-0
lines changed

.github/workflows/apple.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,3 +257,32 @@ jobs:
257257
with:
258258
name: ${{ matrix.build.py }}-${{ matrix.build.target_triple }}
259259
path: dist/*
260+
261+
install-only:
262+
needs:
263+
- build
264+
runs-on: 'ubuntu-20.04'
265+
steps:
266+
- uses: actions/checkout@v2
267+
with:
268+
fetch-depth: 0
269+
270+
- name: Install Python
271+
uses: actions/setup-python@v2
272+
with:
273+
python-version: '3.9'
274+
275+
- name: Download Python
276+
uses: actions/download-artifact@v2
277+
with:
278+
name: cpython-3.9-x86_64-apple-darwin
279+
280+
- name: Repack Distribution
281+
run: |
282+
./prune-distribution.py cpython-*-pgo+lto-*
283+
284+
- name: Upload Distribution
285+
uses: actions/upload-artifact@v2
286+
with:
287+
name: cpython-install-only
288+
path: cpython-*.tar.gz

.github/workflows/linux.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,3 +316,32 @@ jobs:
316316
with:
317317
name: ${{ matrix.build.py }}-${{ matrix.build.target_triple }}
318318
path: dist/*
319+
320+
install-only:
321+
needs:
322+
- build
323+
runs-on: 'ubuntu-20.04'
324+
steps:
325+
- uses: actions/checkout@v2
326+
with:
327+
fetch-depth: 0
328+
329+
- name: Install Python
330+
uses: actions/setup-python@v2
331+
with:
332+
python-version: '3.9'
333+
334+
- name: Download Python
335+
uses: actions/download-artifact@v2
336+
with:
337+
name: cpython-3.9-x86_64-unknown-linux-gnu
338+
339+
- name: Repack Distribution
340+
run: |
341+
./prune-distribution.py cpython-*-pgo+lto-*
342+
343+
- name: Upload Distribution
344+
uses: actions/upload-artifact@v2
345+
with:
346+
name: cpython-install-only
347+
path: cpython-*.tar.gz

.github/workflows/windows.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,32 @@ jobs:
9292
with:
9393
name: ${{ matrix.py }}-${{ matrix.vcvars }}
9494
path: dist/*
95+
96+
install-only:
97+
needs:
98+
- build
99+
runs-on: 'ubuntu-20.04'
100+
steps:
101+
- uses: actions/checkout@v2
102+
with:
103+
fetch-depth: 0
104+
105+
- name: Install Python
106+
uses: actions/setup-python@v2
107+
with:
108+
python-version: '3.9'
109+
110+
- name: Download Python
111+
uses: actions/download-artifact@v2
112+
with:
113+
name: cpython-3.9-vcvars64.bat
114+
115+
- name: Repack Distribution
116+
run: |
117+
./prune-distribution.py cpython-*-pgo-*
118+
119+
- name: Upload Distribution
120+
uses: actions/upload-artifact@v2
121+
with:
122+
name: cpython-install-only
123+
path: cpython-*.tar.gz

prune-distribution.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env python3
2+
# This Source Code Form is subject to the terms of the Mozilla Public
3+
# License, v. 2.0. If a copy of the MPL was not distributed with this
4+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
5+
6+
import os
7+
import pathlib
8+
import subprocess
9+
import sys
10+
import venv
11+
12+
13+
ROOT = pathlib.Path(os.path.abspath(__file__)).parent
14+
BUILD = ROOT / "build"
15+
VENV = BUILD / "venv"
16+
PIP = VENV / "bin" / "pip"
17+
PYTHON = VENV / "bin" / "python"
18+
REQUIREMENTS = ROOT / "requirements.txt"
19+
20+
21+
def bootstrap():
22+
BUILD.mkdir(exist_ok=True)
23+
24+
venv.create(VENV, with_pip=True)
25+
26+
subprocess.run([str(PIP), "install", "-r", str(REQUIREMENTS)], check=True)
27+
28+
os.environ["PYBUILD_BOOTSTRAPPED"] = "1"
29+
os.environ["PATH"] = "%s:%s" % (str(VENV / "bin"), os.environ["PATH"])
30+
os.environ["PYTHONPATH"] = str(ROOT)
31+
32+
args = [str(PYTHON), __file__, *sys.argv[1:]]
33+
34+
os.execv(str(PYTHON), args)
35+
36+
37+
def run():
38+
from pythonbuild.utils import prune_distribution_archive
39+
40+
for p in sys.argv[1:]:
41+
prune_distribution_archive(pathlib.Path(p))
42+
43+
44+
if __name__ == "__main__":
45+
try:
46+
if "PYBUILD_BOOTSTRAPPED" not in os.environ:
47+
bootstrap()
48+
else:
49+
run()
50+
except subprocess.CalledProcessError as e:
51+
sys.exit(e.returncode)

pythonbuild/utils.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,40 @@ def compress_python_archive(
390390
return dest_path
391391

392392

393+
def prune_distribution_archive(source_path: pathlib.Path):
394+
"""Prunes a full Python distribution archive into one with just a Python install."""
395+
name_parts = source_path.name.split("-")
396+
name_parts[-2] = "install_only"
397+
398+
dest_path = source_path.with_name("-".join(name_parts)).with_suffix(".gz")
399+
400+
with source_path.open("rb") as ifh, tarfile.open(dest_path, "w:gz") as otf:
401+
dctx = zstandard.ZstdDecompressor()
402+
with dctx.stream_reader(ifh) as tar_reader:
403+
with tarfile.open(fileobj=tar_reader, mode="r|") as itf:
404+
for member in itf:
405+
if not member.name.startswith("python/install/"):
406+
continue
407+
408+
member.name = "python/%s" % member.name[len("python/install/") :]
409+
410+
if member.pax_headers.get("path"):
411+
member.pax_headers["path"] = (
412+
"python/%s"
413+
% member.pax_headers["path"][len("python/install/") :]
414+
)
415+
416+
if member.issym():
417+
data = None
418+
else:
419+
data = itf.extractfile(member)
420+
421+
print("adding %s" % member.name)
422+
otf.addfile(member, data)
423+
424+
print("wrote %s" % dest_path)
425+
426+
393427
def add_licenses_to_extension_entry(entry, ignore_keys=None):
394428
"""Add licenses keys to a ``extensions`` entry for JSON distribution info."""
395429

0 commit comments

Comments
 (0)