Bug 1879159 - [tb-rust ci] Check for open Phabricator revisions and abandon if needed. r=dandarnell
Differential Revision: https://phabricator.services.mozilla.com/D201837 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
0bbb3b54e2
Коммит
21f5a5388d
|
@ -14,7 +14,10 @@ from pathlib import Path
|
|||
sys.path.append(".")
|
||||
|
||||
from .support import ( # noqa: I001
|
||||
DevConduit,
|
||||
ExtendedConduit,
|
||||
TaskClusterSecrets,
|
||||
fetch_indexed_artifact,
|
||||
log,
|
||||
notify_sheriffs,
|
||||
run_cmd,
|
||||
|
@ -28,13 +31,14 @@ from .support import ( # noqa: I001
|
|||
|
||||
HOME_PATH = Path.home()
|
||||
GECKO_PATH = Path(os.environ.get("GECKO_PATH"))
|
||||
COMM_PATH = os.path.join(GECKO_PATH, "comm")
|
||||
COMM_PATH = GECKO_PATH / "comm"
|
||||
|
||||
OPERATING_MODE = (
|
||||
"prod"
|
||||
if os.environ.get("COMM_HEAD_REPOSITORY", "") == "https://hg.mozilla.org/comm-central"
|
||||
else "dev"
|
||||
)
|
||||
PROJECT = os.environ.get("COMM_HEAD_REPOSITORY", "/comm-central").split("/")[-1]
|
||||
|
||||
PROD_PHAB_URL = "https://phabricator.services.mozilla.com/api/"
|
||||
|
||||
|
@ -48,8 +52,6 @@ SECRET_PATH = f"project/comm/thunderbird/releng/build/level-{LEVEL}"
|
|||
|
||||
HG = shutil.which("hg")
|
||||
assert HG is not None
|
||||
MOZ_PHAB = shutil.which("moz-phab")
|
||||
assert MOZ_PHAB is not None
|
||||
|
||||
REVIEWERS = os.environ.get("REVIEWERS")
|
||||
if REVIEWERS is None:
|
||||
|
@ -65,22 +67,24 @@ def prepare():
|
|||
"""Retrieve secrets and write out config files."""
|
||||
# Get TC Secrets =======================================
|
||||
log("Operating mode is ", OPERATING_MODE)
|
||||
log("Getting secrets...")
|
||||
if OPERATING_MODE == "prod":
|
||||
log("Getting secrets from Taskcluster...")
|
||||
secret_mgr = TaskClusterSecrets(SECRET_PATH)
|
||||
phabricator_token = secret_mgr.get_secret("arc-phabricator-token")
|
||||
try_ssh = secret_mgr.get_secret("tbirdtry")
|
||||
try_ssh_user = try_ssh["user"]
|
||||
try_ssh_key = try_ssh["ssh_privkey"]
|
||||
|
||||
# Set Up Mercurial, SSH & Phabricator ==============================
|
||||
log("Setting up Mercurial user, ssh key, and Phabricator token...")
|
||||
ssh_key_file = write_ssh_key("ssh_id", try_ssh_key)
|
||||
write_hgrc_userinfo(try_ssh_user, ssh_key_file)
|
||||
write_arcrc(phabricator_url, phabricator_token)
|
||||
else:
|
||||
write_hgrc_userinfo("no hg user config", Path("/dev/null"))
|
||||
log(f"Skipping retrieving secrets in {OPERATING_MODE} mode.")
|
||||
log("Using fake secrets...")
|
||||
phabricator_token = "null"
|
||||
try_ssh_user = "nobody"
|
||||
try_ssh_key = "nokey"
|
||||
|
||||
# Set Up Mercurial, SSH & Phabricator ==============================
|
||||
log("Setting up Mercurial user, ssh key, and Phabricator token...")
|
||||
ssh_key_file = write_ssh_key("ssh_id", try_ssh_key)
|
||||
write_hgrc_userinfo(try_ssh_user, ssh_key_file)
|
||||
write_arcrc(phabricator_url, phabricator_token)
|
||||
|
||||
|
||||
def run_check_upstream() -> bool:
|
||||
|
@ -113,6 +117,13 @@ def run_vendor():
|
|||
raise Exception("Whoa there! No changes were found. ABORT ABORT ABORT ABORT ABORT!")
|
||||
|
||||
|
||||
def compare_checksums():
|
||||
log("Comparing checksums with previously submitted review request")
|
||||
old_checksums = open(HOME_PATH / "checksums.json").read()
|
||||
new_checksums = open(COMM_PATH / "rust/checksums.json").read()
|
||||
return old_checksums == new_checksums
|
||||
|
||||
|
||||
def commit_changes():
|
||||
os.chdir(COMM_PATH)
|
||||
run_cmd([HG, "addremove", "third_party/rust/", "rust/"])
|
||||
|
@ -131,12 +142,27 @@ comm-central: {COMM_HEAD_REV}
|
|||
|
||||
|
||||
def submit_phabricator():
|
||||
if OPERATING_MODE != "prod":
|
||||
log(f"Skipping moz-phab submission in {OPERATING_MODE} mode.")
|
||||
return
|
||||
previous_phabrev = fetch_indexed_artifact(PROJECT, "public/phab_rev_id.txt")
|
||||
conduit = get_conduit()
|
||||
|
||||
if previous_phabrev is not None:
|
||||
if conduit.is_revision_open(previous_phabrev):
|
||||
if compare_checksums():
|
||||
# checksums.json from earlier submitted rev is the same as
|
||||
# after running tb-rust vendor again. Do not submit a new
|
||||
# revision, exit cleanly.
|
||||
log(f"checksums.json from {previous_phabrev} is the same.")
|
||||
log("Exiting without submitting a new revision.")
|
||||
notify_sheriffs(f"Sheriffs: Please land {previous_phabrev} to fix Rust builds.")
|
||||
return
|
||||
else:
|
||||
log(
|
||||
f"Previous revision {previous_phabrev} is stale. Abandoning it and re-submitting."
|
||||
)
|
||||
conduit.abandon_revision(previous_phabrev)
|
||||
|
||||
os.chdir(COMM_PATH)
|
||||
result = run_cmd([MOZ_PHAB, "submit", "-s", "--no-lint"])
|
||||
result = conduit.submit()
|
||||
|
||||
# Look for the Phabricator revision URL on the last line of stdout
|
||||
if result.returncode == 0:
|
||||
|
@ -157,9 +183,12 @@ def submit_phabricator():
|
|||
def run_try_cc():
|
||||
os.chdir(COMM_PATH)
|
||||
log("Submitting try-comm-central build.")
|
||||
try_task_config = write_try_task_config(Path(COMM_PATH))
|
||||
try_task_config = write_try_task_config(COMM_PATH)
|
||||
run_cmd([HG, "add", try_task_config.name])
|
||||
run_cmd([HG, "push-to-try", "-s", "try-cc", "-m", "Automation: Rust build check"])
|
||||
if OPERATING_MODE == "prod":
|
||||
run_cmd([HG, "push-to-try", "-s", "try-cc", "-m", "Automation: Rust build check"])
|
||||
else:
|
||||
log("Skipping submit to try-comm-central...")
|
||||
|
||||
|
||||
def get_old_artifacts() -> dict:
|
||||
|
@ -174,6 +203,12 @@ def get_old_artifacts() -> dict:
|
|||
return rv
|
||||
|
||||
|
||||
def get_conduit():
|
||||
if OPERATING_MODE == "prod":
|
||||
return ExtendedConduit(COMM_PATH)
|
||||
return DevConduit(COMM_PATH)
|
||||
|
||||
|
||||
def main():
|
||||
prepare()
|
||||
previous_data = get_old_artifacts()
|
||||
|
|
|
@ -6,21 +6,30 @@
|
|||
Support functions for comm-central third party code management
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Union
|
||||
|
||||
import requests
|
||||
from mozphab.conduit import ConduitAPI
|
||||
from mozphab.detect_repository import repo_from_args
|
||||
|
||||
import taskcluster
|
||||
|
||||
SECRET_URL_BASE = "http://taskcluster/secrets/v1/secret/"
|
||||
NOTIFY_URL_BASE = "http://taskcluster/api/notify/v1/matrix"
|
||||
INDEX_URL_BASE = "http://taskcluster/api/index/v1/task"
|
||||
|
||||
TB_SHERIFF_MATRIX_ID = "!TWztIhgqLawNpRBZTC:mozilla.org"
|
||||
|
||||
MOZ_PHAB = shutil.which("moz-phab")
|
||||
assert MOZ_PHAB is not None
|
||||
|
||||
|
||||
def log(*args):
|
||||
print(*args)
|
||||
|
@ -131,3 +140,41 @@ def fetch_indexed_artifact(previous_task_id: str, artifact_path: str) -> str or
|
|||
return None
|
||||
raise
|
||||
return response.text
|
||||
|
||||
|
||||
class ExtendedConduit(ConduitAPI):
|
||||
def __init__(self, repo_root: Union[Path, None] = None) -> None:
|
||||
super().__init__()
|
||||
if repo_root is None:
|
||||
return
|
||||
repo = repo_from_args(argparse.Namespace(path=str(repo_root), safe_mode=False))
|
||||
self.set_repo(repo)
|
||||
|
||||
def is_revision_open(self, phab_rev_id: str) -> bool:
|
||||
rev_id = int(phab_rev_id[1:])
|
||||
revisions = self.get_revisions([rev_id])
|
||||
if revisions:
|
||||
return not revisions[0]["fields"]["status"]["closed"]
|
||||
|
||||
def abandon_revision(self, phab_rev_id: str):
|
||||
transactions = [
|
||||
{"type": "abandon", "value": True},
|
||||
]
|
||||
self.apply_transactions_to_revision(phab_rev_id, transactions)
|
||||
|
||||
def submit(self):
|
||||
return run_cmd([MOZ_PHAB, "submit", "-s", "--no-lint"])
|
||||
|
||||
|
||||
class DevConduit:
|
||||
def __init__(self, repo_root: Path) -> None:
|
||||
self.repo = str(repo_root)
|
||||
|
||||
def is_revision_open(self, phab_rev_id: str) -> bool:
|
||||
return False
|
||||
|
||||
def abandon_revision(self, phab_rev_id: str):
|
||||
return
|
||||
|
||||
def submit(self):
|
||||
return subprocess.CompletedProcess([], 0, stdout="output /D12345")
|
||||
|
|
Загрузка…
Ссылка в новой задаче