Skip to content

Commit

Permalink
Add complete platform gen support.
Browse files Browse the repository at this point in the history
This includes a workflow that can be manually triggered to generate
complete platform files for all Pex scie platforms we support. The
workflow will be used via `tox -e gen-scie-platform -- --all ...`
in a follow up after experimenting with the action and its uploaded
artifacts.
  • Loading branch information
jsirois committed Sep 5, 2024
1 parent d11363b commit 2f06fc2
Show file tree
Hide file tree
Showing 3 changed files with 231 additions and 0 deletions.
71 changes: 71 additions & 0 deletions .github/workflows/gen-scie-platforms.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Generate Pex Scie Complete Platforms
on:
workflow_dispatch:
inputs:
dest-dir:
description: The directory to generate the complete platform files in.
default: package/complete-platforms
required: false
pbs-release:
description: The PBS release to use.
required: true
python-version:
description: The PBS Python version to use.
required: true
jobs:
gen-complete-platform:
name: Generate Pex Scie Complete Platform for ${{ matrix.platform }}
strategy:
matrix:
include:
- platform: Linux x86_64
os: ubuntu-22.04
docker-arch: amd64
- platform: Linux aarch64
os: ubuntu-22.04
docker-arch: arm64
- platform: macOS x86_64
os: macos-13
- platform: macOS arm64
os: macos-14
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Pex
uses: actions/checkout@v4
- name: Generate Generate Script
run: |
cat << EOF > ./gen-scie-platform.sh
#!/usr/bin/env bash
python -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -U tox
python -V
tox -e gen-scie-platform \
-d "${{ github.event.inputs.dest-dir }}" \
--pbs-release ${{ github.event.inputs.pbs-release }} \
--python-version ${{ github.event.inputs.python-version }}
EOF
chmod +x ./gen-scie-platform.sh
- name: Setup Docker QEMU Emulation
uses: docker/setup-qemu-action@v3
if: ${{ matrix.docker-arch }}
with:
platforms: linux/${{ matrix.docker-arch }}
- name: Generate Complete Platform
if: ${{ matrix.docker-arch }}
run: |
docker run \
--rm \
-v $PWD:/code \
-w /code \
--platform linux/${{ matrix.docker-arch }} \
python:3.12-slim-bullseye bash ./gen-scie-platform.sh
- name: Generate Complete Platform
if: ${{ ! matrix.docker-arch }}
run: ./gen-scie-platform.sh
- name: Upload Complete Platform File Artifact
uses: actions/upload-artifact@v4
with:
path: ${{ github.event.inputs.dest-dir }}/*
151 changes: 151 additions & 0 deletions scripts/gen_scie_platform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#!/usr/bin/env python3

from __future__ import annotations

import argparse
import json
import logging
import os.path
import platform
import subprocess
import sys
import tempfile
from argparse import ArgumentError, ArgumentTypeError
from contextlib import contextmanager
from pathlib import Path
from typing import IO, Iterable, Iterator

logger = logging.getLogger(__name__)


def create_all_complete_platforms(
_dest_dir: Path,
*,
_pbs_release: str,
_python_version: str,
) -> Iterable[Path]:
raise NotImplementedError(
"TODO(John Sirois): Implement triggering the gen-scie-platforms workflow via workflow "
"dispatch and then gathering the output artifacts to obtain the full suite of complete "
"platforms needed to generate all the Pex scies."
)


def current_platform() -> str:
system = platform.system().lower()
machine = platform.machine().lower()
if machine in ("aarch64", "arm64"):
return f"{system}-aarch64"
elif machine in ("amd64", "x86_64"):
return f"{system}-x86_64"
raise ValueError(f"Unexpected platform.machine(): {platform.machine()}")


@contextmanager
def pex3_binary(*, pbs_release: str, python_version: str) -> Iterator[str]:
with tempfile.TemporaryDirectory() as td:
pex3 = os.path.join(td, "pex3")
subprocess.run(
args=[
sys.executable,
"-m",
"pex",
".",
"-c",
"pex3",
"--scie",
"lazy",
"--scie-pbs-release",
pbs_release,
"--scie-python-version",
python_version,
"-o",
pex3,
],
check=True,
)
yield pex3


def create_complete_platform(
complete_platform_file: Path,
*,
pbs_release: str,
python_version: str,
comment: str | None = None
) -> None:
with pex3_binary(pbs_release=pbs_release, python_version=python_version) as pex3:
complete_platform = json.loads(
subprocess.run(
args=[pex3, "interpreter", "inspect", "--markers", "--tags"],
stdout=subprocess.PIPE,
check=True,
).stdout
)
path = complete_platform.pop("path")
if comment:
complete_platform["comment"] = comment
logger.info(f"Generating {complete_platform_file} using Python at:\n{path}")

complete_platform_file.parent.mkdir(parents=True, exist_ok=True)
with complete_platform_file.open("w") as fp:
json.dump(complete_platform, fp, indent=2, sort_keys=True)


def main(out: IO[str]) -> str | int | None:
try:
plat = current_platform()
except ValueError as e:
sys.exit((str(e)))

parser = argparse.ArgumentParser()
parser.add_argument(
"-d", "--dest-dir", type=Path, default=Path("package") / "complete-platforms"
)
parser.add_argument("--pbs-release", required=True)
parser.add_argument("--python-version", required=True)
parser.add_argument("--all", action="store_true")
parser.add_argument("-v", "--verbose", action="store_true")
try:
options = parser.parse_args()
except (ArgumentError, ArgumentTypeError) as e:
return str(e)

logging.basicConfig(level=logging.INFO if options.verbose else logging.WARNING)

generated_files: list[Path] = []
if options.all:
generated_files.extend(
create_all_complete_platforms(
_dest_dir=options.dest_dir,
_pbs_release=options.pbs_release,
_python_version=options.python_version,
)
)
else:
complete_platform_file = options.dest_dir / f"{plat}.json"
try:
create_complete_platform(
complete_platform_file=complete_platform_file,
pbs_release=options.pbs_release,
python_version=options.python_version,
comment=(
"DO NOT EDIT - Generated via: `tox -e gen-scie-platform -d {dest_dir} "
"--pbs-release {pbs_release} --python-version {python_version}`.".format(
dest_dir=options.dest_dir,
pbs_release=options.pbs_release,
python_version=options.python_version,
)
),
)
except subprocess.CalledProcessError as e:
return str(e)
generated_files.append(complete_platform_file)

for file in generated_files:
print(str(file), file=out)
return 0


if __name__ == "__main__":
sys.exit(main(out=sys.stdout))
9 changes: 9 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,15 @@ deps =
commands =
python scripts/build_docs.py {posargs}

[testenv:gen-scie-platform]
basepython = python3
skip_install = true
commands =
python scripts/gen_scie_platform.py \
--pbs-release 20240814 \
--python-version 3.12.5 \
{posargs}

[_package]
basepython = python3
deps =
Expand Down

0 comments on commit 2f06fc2

Please sign in to comment.