Skip to content

Commit

Permalink
Automate Release: From scratch builds (#1739)
Browse files Browse the repository at this point in the history
  • Loading branch information
msaroufim authored Aug 26, 2022
1 parent 696442b commit b62e5d7
Show file tree
Hide file tree
Showing 11 changed files with 328 additions and 268 deletions.
61 changes: 61 additions & 0 deletions .github/workflows/official_release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Make an official Release

on: workflow_dispatch

jobs:
official-release:
# creates workflows for the 3 OS: ubuntu, macOS & windows
runs-on: ${{ matrix.os }}

# The official-release environment requires 2 manual approvals
environment:
name: official-release
strategy:
fail-fast: true
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
steps:
- name: Setup Conda
uses: s-weigand/setup-conda@v1
- name: Setup Anaconda
run: |
conda --version
conda install -y conda-build anaconda-client
- name: Checkout TorchServe
uses: actions/checkout@v2
- name: Install dependencies
run: |
python ts_scripts/install_dependencies.py --environment=dev
pip install -e .
- name: Setup Java 11
uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: '11'
- name: Build PyPI & conda binaries
run: python binaries/build.py
- name: Push conda binaries
env:
ANACONDA_API_TOKEN: ${{ secrets.CONDA_PASSWORD }}
run: python binaries/upload.py --upload-conda-packages
- name: Push PyPI binaries
env:
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
if: matrix.os == 'ubuntu-latest'
run: python binaries/upload.py --upload-pypi-packages
- name: Login to Docker
env:
DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}}
run: docker login --username pytorchbot --password "$DOCKER_PASSWORD"
- name: Build & Upload pytorch/torchserve Docker images
if: matrix.os == 'ubuntu-latest'
run: |
cd docker
python build_upload_release.py
cd ..
- name: Build & Upload pytorch/torchserve-kfs Docker images
if: matrix.os == 'ubuntu-latest'
run: |
cd kubernetes/kserve
python build_upload_release.py
cd ..
49 changes: 30 additions & 19 deletions binaries/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ def build_dist_whl(args):
"""
Function to build the wheel files for torchserve, model-archiver and workflow-archiver
"""

binaries = ["torchserve", "torch-model-archiver", "torch-workflow-archiver"]
if args.nightly:
print(
Expand All @@ -29,7 +28,7 @@ def build_dist_whl(args):
create_wheel_cmd = "python setup.py "
else:
print("## Started torchserve, model-archiver and workflow-archiver build")
create_wheel_cmd = "python setup.py bdist_wheel --release --universal"
create_wheel_cmd = "python setup.py bdist_wheel --release"

for binary in binaries:

Expand All @@ -48,11 +47,12 @@ def build_dist_whl(args):

# Build wheel
print(f"## In directory: {os.getcwd()} | Executing command: {cur_wheel_cmd}")
build_exit_code = os.system(cur_wheel_cmd)

# If any one of the steps fail, exit with error
if build_exit_code != 0:
sys.exit(f"## {binary} build Failed !")
if not args.dry_run:
build_exit_code = os.system(cur_wheel_cmd)
# If any one of the steps fail, exit with error
if build_exit_code != 0:
sys.exit(f"## {binary} build Failed !")


def build(args):
Expand All @@ -62,30 +62,34 @@ def build(args):

os.chdir(REPO_ROOT)

ts_wheel_path = glob.glob(os.path.join(REPO_ROOT, "dist", "*.whl"))[0]
ma_wheel_path = glob.glob(
os.path.join(REPO_ROOT, "model-archiver", "dist", "*.whl")
)[0]
wa_wheel_path = glob.glob(
os.path.join(REPO_ROOT, "workflow-archiver", "dist", "*.whl")
)[0]
if not args.dry_run:
ts_wheel_path = glob.glob(os.path.join(REPO_ROOT, "dist", "*.whl"))[0]
ma_wheel_path = glob.glob(
os.path.join(REPO_ROOT, "model-archiver", "dist", "*.whl")
)[0]
wa_wheel_path = glob.glob(
os.path.join(REPO_ROOT, "workflow-archiver", "dist", "*.whl")
)[0]

else:
ts_wheel_path = os.path.join(REPO_ROOT, "dist", "*.whl")
ma_wheel_path = os.path.join("model-archiver", "dist", "*.whl")
wa_wheel_path = os.path.join("workflow-archiver", "dist", "*.whl")

print(f"## TorchServe wheel location: {ts_wheel_path}")
print(f"## Model archiver wheel location: {ma_wheel_path}")
print(f"## Workflow archiver wheel location: {ma_wheel_path}")

# Build TS & MA on Conda if available
conda_build_exit_code = 0
if not is_conda_env():
install_miniconda()
install_miniconda(args.dry_run)

if not is_conda_build_env():
install_conda_build()
install_conda_build(args.dry_run)

conda_build_exit_code = conda_build(
ts_wheel_path,
ma_wheel_path,
wa_wheel_path,
args.nightly,
ts_wheel_path, ma_wheel_path, wa_wheel_path, args.nightly, args.dry_run
)

# If conda build fails, exit with error
Expand All @@ -103,6 +107,13 @@ def build(args):
required=False,
help="specify nightly is being built",
)

parser.add_argument(
"--dry_run",
action="store_true",
help="dry_run will print the commands that will be run without running them",
)

args = parser.parse_args()

build(args)
59 changes: 37 additions & 22 deletions binaries/conda/build_packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import os
from datetime import date

from ts_scripts.utils import try_and_handle

conda_build_dir = os.path.dirname(os.path.abspath(__file__))
REPO_ROOT = os.path.join(conda_build_dir, "..", "..")
MINICONDA_DOWNLOAD_URL = (
Expand Down Expand Up @@ -29,7 +31,7 @@ def add_nightly_suffix_conda(binary_name: str) -> str:
return binary_name + ".dev" + todays_date


def install_conda_build():
def install_conda_build(dry_run):
"""
Install conda-build, required to create conda packages
"""
Expand All @@ -41,10 +43,12 @@ def install_conda_build():
f"'conda' already present on the system. Proceeding without a fresh conda installation."
)
return
os.system(f"{CONDA_BINARY} install python=3.8 conda-build anaconda-client -y")
try_and_handle(
f"{CONDA_BINARY} install python=3.8 conda-build anaconda-client -y", dry_run
)


def install_miniconda():
def install_miniconda(dry_run):
"""
Installs miniconda, a slimmer anaconda installation to build conda packages
"""
Expand All @@ -62,22 +66,27 @@ def install_miniconda():
)
return

os.system(f"rm -rf $HOME/miniconda")
exit_code = os.system(f"wget {MINICONDA_DOWNLOAD_URL} -O ~/miniconda.sh")
if exit_code != 0:
print(f"miniconda download failed")
return exit_code
os.system(f"bash ~/miniconda.sh -f -b -p $HOME/miniconda")
os.system(f"echo 'export PATH=$HOME/miniconda/bin:$PATH' >> ~/.bashrc")
os.system(f"ln -s $HOME/miniconda/bin/activate $HOME/miniconda/condabin/activate")
os.system(
f"ln -s $HOME/miniconda/bin/deactivate $HOME/miniconda/condabin/deactivate"
try_and_handle(f"rm -rf $HOME/miniconda", dry_run)
try_and_handle(f"wget {MINICONDA_DOWNLOAD_URL} -O ~/miniconda.sh", dry_run)

try_and_handle(f"bash ~/miniconda.sh -f -b -p $HOME/miniconda", dry_run)
try_and_handle(
f"echo 'export PATH=$HOME/miniconda/bin:$PATH' >> ~/.bashrc", dry_run
)
try_and_handle(
f"ln -s $HOME/miniconda/bin/activate $HOME/miniconda/condabin/activate", dry_run
)
try_and_handle(
f"ln -s $HOME/miniconda/bin/deactivate $HOME/miniconda/condabin/deactivate",
dry_run,
)

os.system(f"{CONDA_BINARY} init")
try_and_handle(f"{CONDA_BINARY} init", dry_run)


def conda_build(ts_wheel_path, ma_wheel_path, wa_wheel_path, conda_nightly=False):
def conda_build(
ts_wheel_path, ma_wheel_path, wa_wheel_path, conda_nightly=False, dry_run=False
):
"""
Build conda packages for different python versions
"""
Expand Down Expand Up @@ -123,10 +132,7 @@ def conda_build(ts_wheel_path, ma_wheel_path, wa_wheel_path, conda_nightly=False
output_dir = os.path.join(conda_build_dir, "output")
cmd = f"{CONDA_BINARY} build --output-folder {output_dir} --python={pyv} {pkg}"
print(f"## In directory: {os.getcwd()}; Executing command: {cmd}")
exit_code = os.system(cmd)
if exit_code != 0:
print("## Conda Build Failed !")
return exit_code
try_and_handle(cmd, dry_run)
return 0 # Used for sys.exit(0) --> to indicate successful system exit


Expand Down Expand Up @@ -158,11 +164,20 @@ def conda_build(ts_wheel_path, ma_wheel_path, wa_wheel_path, conda_nightly=False
required=False,
help="specify conda nightly is being built",
)

parser.add_argument(
"--dry_run",
action="store_true",
help="dry_run will print the commands that will be run without running them",
)

args = parser.parse_args()

if args.install_conda_dependencies:
install_miniconda()
install_conda_build()
install_miniconda(args.dry_run)
install_conda_build(args.dry_run)

if all([args.ts_wheel, args.ma_wheel, args.wa_wheel]):
conda_build(args.ts_wheel, args.ma_wheel, args.wa_wheel, args.nightly)
conda_build(
args.ts_wheel, args.ma_wheel, args.wa_wheel, args.nightly, args.dry_run
)
25 changes: 0 additions & 25 deletions binaries/pip/README.md

This file was deleted.

84 changes: 0 additions & 84 deletions binaries/pip/build_wheels.sh

This file was deleted.

Loading

0 comments on commit b62e5d7

Please sign in to comment.