Skip to content

Commit

Permalink
Merge pull request #7654 from webknjaz/misc/tmpdir-nox-build
Browse files Browse the repository at this point in the history
Make release task build dists @ clean tmp checkout
  • Loading branch information
pradyunsg authored Feb 10, 2020
2 parents 313740f + d772171 commit c24aba5
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 10 deletions.
44 changes: 35 additions & 9 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,21 +203,47 @@ def build_release(session):
session.log("# Install dependencies")
session.install("setuptools", "wheel", "twine")

session.log("# Checkout the tag")
session.run("git", "checkout", version, external=True, silent=True)
with release.isolated_temporary_checkout(session, version) as build_dir:
session.log(
"# Start the build in an isolated, "
f"temporary Git checkout at {build_dir!s}",
)
with release.workdir(session, build_dir):
tmp_dists = build_dists(session)

tmp_dist_paths = (build_dir / p for p in tmp_dists)
session.log(f"# Copying dists from {build_dir}")
shutil.rmtree('dist', ignore_errors=True) # remove empty `dist/`
for dist in tmp_dist_paths:
session.log(f"# Copying {dist}")
shutil.copy(dist, 'dist')


def build_dists(session):
"""Return dists with valid metadata."""
session.log(
"# Check if there's any Git-untracked files before building the wheel",
)

session.log("# Cleanup build/ before building the wheel")
if release.have_files_in_folder("build"):
shutil.rmtree("build")
has_forbidden_git_untracked_files = any(
# Don't report the environment this session is running in
not untracked_file.startswith('.nox/build-release/')
for untracked_file in release.get_git_untracked_files()
)
if has_forbidden_git_untracked_files:
session.error(
"There are untracked files in the working directory. "
"Remove them and try again",
)

session.log("# Build distributions")
session.run("python", "setup.py", "sdist", "bdist_wheel", silent=True)
produced_dists = glob.glob("dist/*")

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

session.log("# Checkout the master branch")
session.run("git", "checkout", "master", external=True, silent=True)
return produced_dists


@nox.session(name="upload-release")
Expand Down
61 changes: 60 additions & 1 deletion tools/automation/release/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
These are written according to the order they are called in.
"""

import contextlib
import io
import os
import pathlib
import subprocess
from typing import List, Optional, Set
import tempfile
from typing import Iterator, List, Optional, Set

from nox.sessions import Session

Expand Down Expand Up @@ -126,3 +129,59 @@ def have_files_in_folder(folder_name: str) -> bool:
if not os.path.exists(folder_name):
return False
return bool(os.listdir(folder_name))


@contextlib.contextmanager
def workdir(
nox_session: Session,
dir_path: pathlib.Path,
) -> Iterator[pathlib.Path]:
"""Temporarily chdir when entering CM and chdir back on exit."""
orig_dir = pathlib.Path.cwd()

nox_session.chdir(dir_path)
try:
yield dir_path
finally:
nox_session.chdir(orig_dir)


@contextlib.contextmanager
def isolated_temporary_checkout(
nox_session: Session,
target_ref: str,
) -> Iterator[pathlib.Path]:
"""Make a clean checkout of a given version in tmp dir."""
with tempfile.TemporaryDirectory() as tmp_dir_path:
tmp_dir = pathlib.Path(tmp_dir_path)
git_checkout_dir = tmp_dir / f'pip-build-{target_ref}'
nox_session.run(
'git', 'worktree', 'add', '--force', '--checkout',
str(git_checkout_dir), str(target_ref),
external=True, silent=True,
)

try:
yield git_checkout_dir
finally:
nox_session.run(
'git', 'worktree', 'remove', '--force',
str(git_checkout_dir),
external=True, silent=True,
)


def get_git_untracked_files() -> Iterator[str]:
"""List all local file paths that aren't tracked by Git."""
git_ls_files_cmd = (
"git", "ls-files",
"--ignored", "--exclude-standard",
"--others", "--", ".",
)
# session.run doesn't seem to return any output:
ls_files_out = subprocess.check_output(git_ls_files_cmd, text=True)
for file_name in ls_files_out.splitlines():
if file_name.strip(): # it's useless if empty
continue

yield file_name

0 comments on commit c24aba5

Please sign in to comment.