227 lines
8.4 KiB
Python
227 lines
8.4 KiB
Python
import os
|
|
import sys
|
|
import time
|
|
import json
|
|
import zipfile
|
|
import datetime
|
|
import subprocess
|
|
from allspice import AllSpice, DesignReview, Repository
|
|
from argparse import ArgumentParser
|
|
|
|
|
|
###############################################################################
|
|
GET_LAST_COMMIT_ON_DRAGDROP_ENDPOINT = """/repos/{owner}/{repo}/commits?sha={ref}&limit=1"""
|
|
GET_LATEST_DESIGN_REVIEW_ENDPOINT = """/repos/{owner}/{repo}/pulls/{base}/{head}"""
|
|
MERGE_DESIGN_REVIEW_ENDPOINT = """/repos/{owner}/{repo}/pulls/{index}/merge"""
|
|
|
|
|
|
###############################################################################
|
|
def extract_newly_added_zip_files(newly_added_zip_files):
|
|
print("- Extracting newly added zip files:")
|
|
# Extract the archives
|
|
for filepath in newly_added_zip_files:
|
|
with zipfile.ZipFile(filepath, "r") as zipper:
|
|
print(" > " + filepath)
|
|
zipper.extractall("./" + os.path.dirname(filepath))
|
|
# Delete the newly added zip files
|
|
os.remove(filepath)
|
|
|
|
|
|
###############################################################################
|
|
def get_new_zip_files_added_in_previous_commit():
|
|
git_log_output = subprocess.check_output(
|
|
["git log --name-status -1"], shell=True, encoding="utf-8"
|
|
)
|
|
git_log_filepaths = git_log_output.splitlines()[6:]
|
|
newly_added_files = []
|
|
for file in git_log_filepaths:
|
|
if file[0] == "A":
|
|
newly_added_files.append(file[2:])
|
|
newly_added_zip_files = [
|
|
file for file in newly_added_files if file.endswith(".zip")
|
|
]
|
|
return newly_added_zip_files
|
|
|
|
|
|
###############################################################################
|
|
def push_changes_on_dragdrop_branch(ref):
|
|
# Add files for commit
|
|
git_add_output = subprocess.check_output(
|
|
["git add ."], shell=True, encoding="utf-8"
|
|
)
|
|
# Add a commit message
|
|
git_commit_output = subprocess.check_output(
|
|
['git commit -m "Unpacked archives from commit ' + sha[0:10] + '"'],
|
|
shell=True,
|
|
encoding="utf-8",
|
|
)
|
|
# Push to remote
|
|
print("- Pushing extracted files to the '" + ref + "' branch")
|
|
git_push_process = subprocess.run(
|
|
"git push", capture_output=True, text=True, shell=True
|
|
)
|
|
|
|
|
|
###############################################################################
|
|
def set_git_config(name, email):
|
|
git_config_name_output = subprocess.check_output(
|
|
["git config --global user.name " + '"' + name + '"'],
|
|
shell=True,
|
|
encoding="utf-8",
|
|
)
|
|
git_config_email_output = subprocess.check_output(
|
|
["git config --global user.email " + '"' + email + '"'],
|
|
shell=True,
|
|
encoding="utf-8",
|
|
)
|
|
|
|
|
|
###############################################################################
|
|
def get_previous_commit_on_dragdrop_branch(client, repository, auth_token, ref):
|
|
time.sleep(0.1)
|
|
commits_json = client.requests_get(
|
|
GET_LAST_COMMIT_ON_DRAGDROP_ENDPOINT.format(
|
|
owner=repository.owner.username, repo=repository.name, token=auth_token, ref=ref
|
|
)
|
|
)
|
|
# Set author as the same person who made the previous commit
|
|
name = commits_json[0]["commit"]["committer"]["name"]
|
|
email = commits_json[0]["commit"]["committer"]["email"]
|
|
sha = commits_json[0]["sha"]
|
|
return name, email, sha
|
|
|
|
|
|
###############################################################################
|
|
def get_latest_design_review_dragdrop_to_develop(client, repository, ref):
|
|
time.sleep(0.1)
|
|
dr_json = client.requests_get(
|
|
GET_LATEST_DESIGN_REVIEW_ENDPOINT.format(
|
|
owner=repository.owner.username,
|
|
repo=repository.name,
|
|
base="develop",
|
|
head=ref,
|
|
)
|
|
)
|
|
# Get the latest DR
|
|
time.sleep(0.1)
|
|
dr = DesignReview.request(
|
|
allspice,
|
|
repository.owner.username,
|
|
repository.name,
|
|
str(dr_json["number"]),
|
|
)
|
|
return dr
|
|
|
|
|
|
###############################################################################
|
|
def merge_design_review(client, repository, dr):
|
|
retries = 1
|
|
merged = False
|
|
while not merged and retries < 6:
|
|
try:
|
|
time.sleep(0.1)
|
|
client.requests_post(
|
|
MERGE_DESIGN_REVIEW_ENDPOINT.format(
|
|
owner=repository.owner.username,
|
|
repo=repository.name,
|
|
index=dr.number,
|
|
),
|
|
data={"Do": "merge"},
|
|
)
|
|
merged = True
|
|
except Exception:
|
|
print("- Merge failed. Trying again in ", end="")
|
|
for t in range(0, 5, -1):
|
|
print(str(t) + "...")
|
|
print(" " + str(5 - retries) + " retries left", end="", flush=True)
|
|
time.sleep(5)
|
|
retries += 1
|
|
|
|
|
|
###############################################################################
|
|
def create_and_merge_design_review(client, repository, ref):
|
|
print("- Creating new design review...")
|
|
try:
|
|
dr = repository.create_design_review(
|
|
title="Automated merge on "
|
|
+ datetime.datetime.now().strftime("%Y-%m-%d @ %H:%M"),
|
|
head=ref,
|
|
base="develop",
|
|
)
|
|
print("- Design review #" + str(dr.number) + " created")
|
|
except allspice.exceptions.AlreadyExistsException:
|
|
dr = get_latest_design_review_dragdrop_to_develop(client, repository)
|
|
print("- Design review # " + str(dr.number) + " already exists")
|
|
|
|
# Merge the design review
|
|
print("- Merging design review " + ref + "->develop")
|
|
merge_design_review(client, repository, dr)
|
|
|
|
|
|
###############################################################################
|
|
if __name__ == "__main__":
|
|
# Initialize argument parser
|
|
parser = ArgumentParser()
|
|
parser.add_argument("repository", help="Repository object for the target repo")
|
|
parser.add_argument(
|
|
"--allspice_hub_url",
|
|
help="The URL of your AllSpice Hub instance. Defaults to https://hub.allspice.io.",
|
|
)
|
|
parser.add_argument(
|
|
"--dragdrop_branch_name",
|
|
help="Name of the drag-n-drop branch"
|
|
)
|
|
parser.add_argument(
|
|
"--unzip_new_archives",
|
|
help="Newly added zip files will be unzipped if this option is set",
|
|
action="store_true",
|
|
)
|
|
parser.add_argument(
|
|
"--upload_method_branch",
|
|
help="Newly added zip files will be unzipped if this option is set",
|
|
action="store_true",
|
|
)
|
|
parser.add_argument(
|
|
"--upload_method_issue",
|
|
help="Newly added zip files will be unzipped if this option is set",
|
|
action="store_true",
|
|
)
|
|
args = parser.parse_args()
|
|
# Can't use both issues and branches for uploads simultaneously
|
|
if args.upload_method_branch and args.upload_method_issue:
|
|
print(
|
|
"Cannot use branch file upload and issue attachment upload simultaneously. Choose either --upload_method_branch OR --upload_method_issue."
|
|
)
|
|
exit(1)
|
|
# Get auth token and hub url
|
|
auth_token = os.environ.get("ALLSPICE_AUTH_TOKEN")
|
|
if auth_token is None:
|
|
print("Please set the environment variable ALLSPICE_AUTH_TOKEN")
|
|
exit(1)
|
|
if args.allspice_hub_url is None:
|
|
allspice = AllSpice(token_text=auth_token)
|
|
else:
|
|
allspice = AllSpice(
|
|
token_text=auth_token,
|
|
allspice_hub_url=args.allspice_hub_url,
|
|
)
|
|
# Get the repository
|
|
repo_owner, repo_name = args.repository.split("/")
|
|
repository = allspice.get_repository(repo_owner, repo_name)
|
|
# If unzip_new_archives option is specified, unzip newly added archives
|
|
if args.unzip_new_archives:
|
|
# Get filepaths to any newly added zip files in the previous commmit
|
|
newly_added_zip_files = get_new_zip_files_added_in_previous_commit()
|
|
# Process extracting
|
|
if newly_added_zip_files:
|
|
# Extract and remove newly added zip files
|
|
extract_newly_added_zip_files(newly_added_zip_files)
|
|
# Get the previous commit
|
|
name, email, sha = get_previous_commit_on_dragdrop_branch(allspice, repository, auth_token, args.dragdrop_branch_name)
|
|
# Set git config user and email
|
|
set_git_config(name, email)
|
|
# Push changes to the drag-n-drop branch
|
|
push_changes_on_dragdrop_branch(args.dragdrop_branch_name)
|
|
# Create a design review to merge from drag-n-drop to develop branch
|
|
create_and_merge_design_review(allspice, repository, args.dragdrop_branch_name)
|