def paginate(url, token): url = hammock(url, auth=("github-actions", token)).GET() if url.links == {}: return url.json() else: container = url.json() while url.links.get("next"): url = hammock(url.links["next"]["url"], auth=("github-actions", token)).GET() container += url.json() return container
def upload_release_asset(release_id, token, file_path: Path): upload_url = hammock("https://api.github.com/repos/dortania/build-repo/releases/" + str(release_id), auth=("github-actions", token)).GET().json() upload_url = upload_url["upload_url"] mime_type = mime.from_file(str(file_path.resolve())) if not mime_type[0]: print("Failed to guess mime type!") return False asset_upload = hammock(str(purl.Template(upload_url).expand({"name": file_path.name, "label": file_path.name})), auth=("github-actions", token)).POST( data=file_path.read_bytes(), headers={"content-type": mime_type} ) return asset_upload.json()["browser_download_url"]
def add_commit_url(name, version): if version.get("commit", {}).get("url", None) and version.get( "commit", {}).get("tree_url", None): return version else: organization = repo = None for plugin in plugins["Plugins"]: if name == "AppleSupportPkg": repo = name organization = "acidanthera" break if plugin["Name"] == name: organization, repo = plugin["URL"].strip().replace( "https://github.com/", "").split("/") break if not repo: print("Product " + name + " not found") raise Exception html_url = json.loads( hammock("https://api.github.com").repos( organization, repo).commits(version["commit"]["sha"]).GET( auth=("github-actions", token)).text)["html_url"] version["commit"]["url"] = html_url version["commit"]["tree_url"] = html_url.replace("/commit/", "/tree/") return version
def add_commit_date(name, version): if version.get("datecommitted", None): return version else: organization = repo = None for plugin in plugins["Plugins"]: if name == "AppleSupportPkg": repo = name organization = "acidanthera" break if plugin["Name"] == name: organization, repo = plugin["URL"].strip().replace( "https://github.com/", "").split("/") break if not repo: print("Product " + name + " not found") raise Exception commit_date = dateutil.parser.parse( json.loads( hammock("https://api.github.com").repos( organization, repo).commits(version["commit"]).GET( auth=("github-actions", token)).text)["commit"]["committer"]["date"]) version["datecommitted"] = commit_date.isoformat() return version
def get_current_run_link(token): global JOB_LINK if JOB_LINK: return JOB_LINK this_run = hammock(f"https://api.github.com/repos/{os.environ['GITHUB_REPOSITORY']}/actions/runs/{os.environ['GITHUB_RUN_ID']}/jobs", auth=("github-actions", token)).GET() try: this_run.raise_for_status() except requests.HTTPError as err: print(err) return this_job = [i for i in this_run.json()["jobs"] if i["name"] == os.environ['JOB_NAME']][0] JOB_LINK = this_job["html_url"] return JOB_LINK
Path("Config/last_updated.txt").touch() # date_to_compare = datetime.datetime(1970, 1, 1, tzinfo=datetime.timezone.utc) date_to_compare = datetime.datetime(2020, 1, 16, tzinfo=datetime.timezone.utc) Path("last_updated.txt").write_text(date_to_compare.isoformat()) print("Last update date is " + date_to_compare.isoformat()) token = sys.argv[1].strip() for plugin in plugins: organization, repo = plugin["URL"].strip().replace("https://github.com/", "").split("/") base_url = hammock("https://api.github.com") releases_url = base_url.repos(organization, repo).releases.GET(auth=("github-actions", token), params={"per_page": 100}) releases = json.loads(releases_url.text or releases_url.content) if releases_url.headers.get("Link"): print(releases_url.headers["Link"]) commits_url = base_url.repos(organization, repo).commits.GET(auth=("github-actions", token), params={"per_page": 100}) commits = json.loads(commits_url.text or commits_url.content) if releases_url.headers.get("Link"):
def add_built(plugin, token): plugin_info = plugin["plugin"] commit_info = plugin["commit"] files = plugin["files"] script_dir = Path(__file__).parent.absolute() config_path = script_dir / Path("Config/config.json") config_path.touch() config = json.load(config_path.open()) name = plugin_info["Name"] plugin_type = plugin_info.get("Type", "Kext") ind = None if not config.get(name, None): config[name] = {} if not config[name].get("type", None): config[name]["type"] = plugin_type if not config[name].get("versions", None): config[name]["versions"] = [] release = {} if config[name]["versions"]: config[name]["versions"] = [i for i in config[name]["versions"] if not (i.get("commit", {}).get("sha", None) == commit_info["sha"])] release["commit"] = {"sha": commit_info["sha"], "message": commit_info["commit"]["message"], "url": commit_info["html_url"], "tree_url": commit_info["html_url"].replace("/commit/", "/tree/")} release["version"] = files["version"] release["dateadded"] = datetime.datetime.now(tz=datetime.timezone.utc).isoformat() release["datecommitted"] = dateutil.parser.parse(commit_info["commit"]["committer"]["date"]).isoformat() release["source"] = "built" releases_url = hammock("https://api.github.com/repos/dortania/build-repo/releases", auth=("github-actions", token)) # Delete previous releases for i in paginate("https://api.github.com/repos/dortania/build-repo/releases", token): if i["name"] == (name + " " + release["commit"]["sha"][:7]): print("\tDeleting previous release...") releases_url(i["id"]).DELETE() time.sleep(3) # Prevent race conditions # Delete tags check_tag = hammock("https://api.github.com/repos/dortania/build-repo/git/refs/tags/" + name + "-" + release["commit"]["sha"][:7], auth=("github-actions", token)) if check_tag.GET().status_code != 404: print("\tDeleting previous tag...") check_tag.DELETE() time.sleep(3) # Prevent race conditions # Create release create_release = releases_url.POST(json={ "tag_name": name + "-" + release["commit"]["sha"][:7], "target_commitish": "builds", "name": name + " " + release["commit"]["sha"][:7] }) # print(create_release.json()["id"]) release["release"] = {"id": create_release.json()["id"], "url": create_release.json()["html_url"]} if not release.get("hashes", None): release["hashes"] = {"debug": {"sha256": ""}, "release": {"sha256": ""}} release["hashes"]["debug"] = {"sha256": hash_file(files["debug"])} release["hashes"]["release"] = {"sha256": hash_file(files["release"])} if files["extras"]: for file in files["extras"]: release["hashes"][file.name] = {"sha256": hash_file(file)} if not release.get("links", None): release["links"] = {} for i in ["debug", "release"]: release["links"][i] = upload_release_asset(release["release"]["id"], token, files[i]) if files["extras"]: if not release.get("extras", None): release["extras"] = {} for file in files["extras"]: release["extras"][file.name] = upload_release_asset(release["release"]["id"], token, file) new_line = "\n" # No escapes in f-strings release["release"]["description"] = f"""**Changes:** {release['commit']['message'].strip()} [View on GitHub]({release['commit']['url']}) ([browse tree]({release['commit']['tree_url']})) **Hashes**: **Debug:** {files["debug"].name + ': ' + release['hashes']['debug']["sha256"]} **Release:** {files["release"].name + ': ' + release['hashes']['release']["sha256"]} {'**Extras:**' if files["extras"] else ''} {new_line.join([(file.name + ': ' + release['hashes'][file.name]['sha256']) for file in files["extras"]]) if files["extras"] else ''} """.strip() hammock("https://api.github.com/repos/dortania/build-repo/releases/" + str(release["release"]["id"]), auth=("github-actions", token)).POST(json={ "body": release["release"]["description"] }) config[name]["versions"].insert(0, release) config[name]["versions"].sort(key=lambda x: x["datecommitted"], reverse=True) json.dump(config, config_path.open(mode="w"), indent=2, sort_keys=True) repo = git.Repo(script_dir / Path("Config")) repo.git.add(all=True) repo.git.commit(message="Deploying to builds") repo.git.push() return release
import json import distutils.util import zipfile from pathlib import Path from hammock import Hammock as hammock plugins = hammock("https://raw.githubusercontent.com/dortania/build-repo/github-actions/plugins.json").GET() plugins = json.loads(plugins.text) config = hammock("https://raw.githubusercontent.com/dortania/build-repo/builds/config.json").GET() config = json.loads(config.text) print("Global Settings: ") ensure_latest = bool(distutils.util.strtobool(input("Ensure latest? (\"true\" or \"false\") ").lower())) unzip = bool(distutils.util.strtobool(input("Unzip automatically and delete zip? (\"true\" or \"false\") ").lower())) extract_dir = input("Put files in directory (leave blank for current dir): ") if unzip else None while True: target = input("Enter product to download (case sensitive): ") dbg = input("Debug or release? (\"debug\" or \"release\") ").lower() try: if ensure_latest: organization = repo = None for plugin in plugins["Plugins"]: if plugin["Name"] == target: organization, repo = plugin["URL"].strip().replace("https://github.com/", "").split("/") break if not repo: print("Product " + target + " not available\n") continue commits_url = hammock("https://api.github.com").repos(organization, repo).commits.GET(params={"per_page": 100}) commit_hash = json.loads(commits_url.text or commits_url.content)[0]["sha"] to_dl = None
for k in config[i]["versions"][j]["hashes"]: if type(config[i]["versions"][j]["hashes"][k]) != dict: hashes[k] = {"sha256": config[i]["versions"][j]["hashes"][k]} config[i]["versions"][j]["hashes"] = hashes for j, item in [(j, item) for (j, item) in enumerate(config[i]["versions"]) if not type(item.get("commit")) == dict]: sha = config[i]["versions"][j].pop("commit") desc = config[i]["versions"][j].pop("description") config[i]["versions"][j]["commit"] = {"sha": sha, "message": desc} for j, item in [(j, item) for (j, item) in enumerate(config[i]["versions"]) if item.get("release", {}).get("id", None) and ( not item.get("release", {}).get("description", None) or not item.get("release", {}).get("url", None))]: rel = json.loads( hammock( "https://api.github.com/repos/dortania/build-repo/releases/" + str(config[i]["versions"][j]["release"]["id"]), auth=("github-actions", token)).GET().text) config[i]["versions"][j]["release"][ "description"] = rel["body"] if rel.get("body") else None config[i]["versions"][j]["release"][ "url"] = rel["html_url"] if rel.get("html_url") else None config[i]["versions"] = [ i for i in config[i]["versions"] if i.get("release", {}).get("url", True) ] for j, item in [(j, item) for (j, item) in enumerate(config[i]["versions"]) if item.get("extras", None)]: item["extras"] = {i: v for i, v in item["extras"].items() if v} for j, item in [(j, item) for (j, item) in enumerate(config[i]["versions"]) if not item.get("extras", True)]: item.pop("extras", False)
import json import os import sys import time from hammock import Hammock as hammock token = sys.argv[1].strip() this_run = hammock(f"https://api.github.com/repos/{os.environ['GITHUB_REPOSITORY']}/actions/runs/{os.environ['GITHUB_RUN_ID']}", auth=("github-actions", token)) workflow_url = this_run.GET().json()["workflow_url"] #workflow_output = hammock(workflow_url).GET(auth=("github-actions", token)) #workflow_id = json.loads(workflow_output.text or workflow_url.content)["id"] runs = hammock(workflow_url, auth=("github-actions", token)).runs.GET().json() run_index = None for run in runs["workflow_runs"]: if str(run["id"]) == str(os.environ["GITHUB_RUN_ID"]): run_index = runs["workflow_runs"].index(run) for run in runs["workflow_runs"]: if runs["workflow_runs"].index(run) > run_index and str(run["id"]) != str(os.environ["GITHUB_RUN_ID"]) and run["status"] != "completed": print(f"Another build ({run['id']} with status {run['status']}) is running, cancelling this one...") cancel_request = this_run.cancel.POST() if cancel_request.status_code != 202: sys.exit("Status code did not match: " + cancel_request.status_code) else: print("Cancel request acknowledged, sleeping 10 seconds to account for delay...") time.sleep(10) sys.exit(0)
import sys from hammock import Hammock as hammock token = sys.argv[1].strip() eee = hammock("https://api.github.com/rate_limit").GET(auth=("github-actions", token)) print(eee.text or eee.content)