forked from Azure/azure-sdk-for-python
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add asset management script (Azure#27676)
Co-authored-by: scbedd <[email protected]>
- Loading branch information
Showing
2 changed files
with
161 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
# ------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for | ||
# license information. | ||
# -------------------------------------------------------------------------- | ||
|
||
import argparse | ||
import os | ||
import shlex | ||
import sys | ||
|
||
try: | ||
from dotenv import load_dotenv | ||
|
||
load_dotenv() | ||
except: | ||
pass | ||
|
||
import subprocess | ||
|
||
|
||
# This file contains a script for managing test recordings in the azure-sdk-assets repository with Docker. | ||
# | ||
# INSTRUCTIONS FOR USE: | ||
# | ||
# - Set GIT_TOKEN, GIT_COMMIT_OWNER, and GIT_COMMIT_EMAIL environment variables to authenticate git requests. | ||
# These can be set in-process or added to a .env file at the root of or directory above your local copy of the | ||
# azure-sdk-for-python repository. | ||
# - Set your working directory to be inside your local copy of the azure-sdk-for-python repository. | ||
# - Run the following command: | ||
# | ||
# `python {path to script}/manage_recordings.py {verb} {relative path to package's assets.json file}` | ||
# | ||
# For example, with the root of the azure-sdk-for-python repo as the working directory, you can push modified | ||
# azure-keyvault-keys recordings to the assets repo with: | ||
# | ||
# `python scripts/manage_recordings.py push sdk/keyvault/azure-keyvault-keys/assets.json` | ||
# | ||
# - In addition to "push", you can also use the "restore" or "reset" verbs in the same command format. | ||
# | ||
# * push: pushes recording updates to a new assets repo tag and updates the tag pointer in `assets.json`. | ||
# * restore: fetches recordings from the assets repo, based on the tag pointer in `assets.json`. | ||
# * reset: discards any pending changes to recordings, based on the tag pointer in `assets.json`. | ||
# | ||
# For more information about how recording asset synchronization, please refer to | ||
# https://github.com/Azure/azure-sdk-tools/blob/main/tools/test-proxy/documentation/asset-sync/README.md. | ||
|
||
# Load environment variables from user's .env file | ||
|
||
CONTAINER_NAME = "azsdkengsys.azurecr.io/engsys/test-proxy" | ||
GIT_TOKEN = os.getenv("GIT_TOKEN", "") | ||
GIT_OWNER = os.getenv("GIT_COMMIT_OWNER", "") | ||
GIT_EMAIL = os.getenv("GIT_COMMIT_EMAIL", "") | ||
|
||
|
||
# ----- HELPERS ----- # | ||
|
||
|
||
discovered_roots = [] | ||
|
||
|
||
def ascend_to_root(start_dir_or_file: str) -> str: | ||
""" | ||
Given a path, ascend until encountering a folder with a `.git` folder present within it. Return that directory. | ||
:param str start_dir_or_file: The starting directory or file. Either is acceptable. | ||
""" | ||
if os.path.isfile(start_dir_or_file): | ||
current_dir = os.path.dirname(start_dir_or_file) | ||
else: | ||
current_dir = start_dir_or_file | ||
|
||
while current_dir is not None and not (os.path.dirname(current_dir) == current_dir): | ||
possible_root = os.path.join(current_dir, ".git") | ||
|
||
# we need the git check to prevent ascending out of the repo | ||
if os.path.exists(possible_root): | ||
if current_dir not in discovered_roots: | ||
discovered_roots.append(current_dir) | ||
return current_dir | ||
else: | ||
current_dir = os.path.dirname(current_dir) | ||
|
||
raise Exception(f'Requested target "{start_dir_or_file}" does not exist within a git repo.') | ||
|
||
|
||
def delete_container() -> None: | ||
"""Delete container if it remained""" | ||
proc = subprocess.Popen( | ||
shlex.split(f"docker rm -f {CONTAINER_NAME}"), | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.PIPE, | ||
stdin=subprocess.DEVNULL, | ||
) | ||
output, stderr = proc.communicate(timeout=10) | ||
return None | ||
|
||
|
||
def get_image_tag(repo_root: str) -> str: | ||
"""Gets the test proxy Docker image tag from the target_version.txt file in /eng/common/testproxy""" | ||
version_file_location = os.path.relpath("eng/common/testproxy/target_version.txt") | ||
version_file_location_from_root = os.path.abspath(os.path.join(repo_root, version_file_location)) | ||
|
||
with open(version_file_location_from_root, "r") as f: | ||
image_tag = f.read().strip() | ||
|
||
return image_tag | ||
|
||
|
||
# ----- CORE LOGIC ----- # | ||
|
||
|
||
if not (GIT_TOKEN and GIT_OWNER and GIT_EMAIL): | ||
raise ValueError( | ||
"GIT_TOKEN, GIT_COMMIT_OWNER, and GIT_COMMIT_EMAIL environment variables must be set, " | ||
"either in-process or in a .env file" | ||
) | ||
|
||
# Prepare command arguments | ||
parser = argparse.ArgumentParser(description="Script for managing recording assets with Docker.") | ||
parser.add_argument("verb", help='The action verb for managing recordings: "restore", "push", or "reset".') | ||
parser.add_argument( | ||
"path", | ||
default="assets.json", | ||
help='The *relative* path to your package\'s `assets.json` file. Default is "assets.json".', | ||
) | ||
args = parser.parse_args() | ||
|
||
if args.verb and args.path: | ||
|
||
current_directory = os.getcwd() | ||
repo_root = ascend_to_root(current_directory) | ||
image_tag = get_image_tag(repo_root) | ||
|
||
root_path = os.path.abspath(repo_root) | ||
cwd_relpath = os.path.relpath(current_directory, root_path) | ||
assets_path = os.path.join(cwd_relpath, args.path).replace("\\", "/") | ||
|
||
delete_container() # Delete any lingering container so a new one can be created with necessary environment variables | ||
|
||
subprocess.run( | ||
shlex.split( | ||
f'docker run --rm -v "{repo_root}:/srv/testproxy" ' | ||
f'-e "GIT_TOKEN={GIT_TOKEN}" -e "GIT_COMMIT_OWNER={GIT_OWNER}" -e "GIT_COMMIT_EMAIL={GIT_OWNER}" ' | ||
f"{CONTAINER_NAME}:{image_tag} test-proxy {args.verb.lower()} -a {assets_path}" | ||
), | ||
stdout=sys.stdout, | ||
stderr=sys.stderr, | ||
) |