def do_retrigger(git_gecko, git_wpt, **kwargs): import errors import update import upstream from landing import load_sync_point, unlanded_with_type update_repositories(git_gecko, git_wpt, True) print("Retriggering upstream syncs with errors") for sync in upstream.UpstreamSync.load_all(git_gecko, git_wpt, status="open"): if sync.error: try: upstream.update_sync(git_gecko, git_wpt, sync) except errors.AbortError as e: print("Update failed:\n%s" % e) pass print("Retriggering downstream syncs on master") sync_point = load_sync_point(git_gecko, git_wpt) prev_wpt_head = sync_point["upstream"] unlandable = unlanded_with_type(git_gecko, git_wpt, None, prev_wpt_head) errors = update.retrigger(git_gecko, git_wpt, unlandable) if errors: print("The following PRs have errors:\n%s" % "\n".join(errors))
def __call__(self, git_gecko, git_wpt): logger.info("Running retrigger") update_repositories(git_gecko, git_wpt) sync_point = landing.load_sync_point(git_gecko, git_wpt) prev_wpt_head = sync_point["upstream"] unlanded = landing.unlanded_with_type(git_gecko, git_gecko, None, prev_wpt_head) update.retrigger(git_gecko, git_wpt, unlanded)
def __call__(self, git_gecko, git_wpt): newrelic.agent.set_transaction_name("RetriggerHandler") logger.info("Running retrigger") update_repositories(git_gecko, git_wpt) sync_point = landing.load_sync_point(git_gecko, git_wpt) prev_wpt_head = sync_point["upstream"] unlanded = landing.unlanded_with_type(git_gecko, git_gecko, None, prev_wpt_head) update.retrigger(git_gecko, git_wpt, unlanded)
def do_landable(git_gecko, git_wpt, *args, **kwargs): import update from base import LandableStatus from downstream import DownstreamAction, DownstreamSync from landing import load_sync_point, landable_commits, unlanded_with_type if kwargs["prev_wpt_head"] is None: sync_point = load_sync_point(git_gecko, git_wpt) prev_wpt_head = sync_point["upstream"] print("Last sync was to commit %s" % sync_point["upstream"]) else: prev_wpt_head = kwargs["prev_wpt_head"] landable = landable_commits( git_gecko, git_wpt, prev_wpt_head, include_incomplete=kwargs["include_incomplete"]) if landable is None: print("Landing will not add any new commits") wpt_head = None else: wpt_head, commits = landable print("Landing will update wpt head to %s, adding %i new PRs" % (wpt_head, len(commits))) if kwargs["all"] or kwargs["retrigger"]: unlandable = unlanded_with_type(git_gecko, git_wpt, wpt_head, prev_wpt_head) count = 0 for pr, _, status in unlandable: count += 1 msg = status.reason_str() if status == LandableStatus.missing_try_results: sync = DownstreamSync.for_pr(git_gecko, git_wpt, pr) next_action = sync.next_action reason = next_action.reason_str() if next_action == DownstreamAction.wait_try: latest_try_push = sync.latest_try_push reason = "%s %s" % (reason, latest_try_push.treeherder_url( latest_try_push.try_rev)) msg = "%s (%s)" % (msg, reason) elif status == LandableStatus.error: sync = DownstreamSync.for_pr(git_gecko, git_wpt, pr) msg = "%s (%s)" % (msg, sync.error["message"].split("\n")[0]) print("%s: %s" % (pr, msg)) print("%i PRs are unlandable:" % count) if kwargs["retrigger"]: errors = update.retrigger(git_gecko, git_wpt, unlandable) if errors: print("The following PRs have errors:\n%s" % "\n".join(errors))
def update_modified_sync(git_gecko, git_wpt, sync): assert sync._lock is not None if len(sync.gecko_commits) == 0: # In the case that there are no gecko commits, we presumably had a backout # In this case we don't touch the wpt commits, but just mark the PR # as closed. That's pretty counterintuitive, but it turns out that GitHub # will only let you reopen a closed PR if you don't change the branch head in # the meantime. So we carefully avoid touching the wpt side until something # relands and we have a chance to reopen the PR logger.info("Sync has no commits, so marking as incomplete") sync.status = "incomplete" if not sync.pr: logger.info( "Sync was already fully applied upstream, not creating a PR") return else: sync.status = "open" try: sync.update_wpt_commits() except AbortError: # If we got a merge conflict and the PR doesn't exist yet then try # recreating the commits on top of the current sync point in order that # we get a PR and it's visible that it fails if not sync.pr: logger.info("Applying to origin/master failed; " "retrying with the current sync point") from landing import load_sync_point sync_point = load_sync_point(git_gecko, git_wpt) sync.set_wpt_base(sync_point["upstream"]) try: sync.update_wpt_commits() except AbortError: # Reset the base to origin/master sync.set_wpt_base("origin/master") with env.bz.bug_ctx(sync.bug) as bug: bug.add_comment( "Failed to create upstream wpt PR due to " "merge conflicts. This requires fixup from a wpt sync " "admin.") needinfo_users = [ item.strip() for item in (env.config["gecko"]["needinfo"].get( "upstream", "").split(",")) ] needinfo_users = [ item for item in needinfo_users if item ] bug.needinfo(*needinfo_users) raise sync.update_github()
def unlanded_commits_same_files(self): import landing sync_point = landing.load_sync_point(self.git_gecko, self.git_wpt) base = sync_point["upstream"] head = "origin/master" changed = self.wpt_commits.files_changed commits = [] for commit in self.git_wpt.iter_commits("%s..%s" % (base, head), reverse=True, paths=list(changed)): commit = sync_commit.WptCommit(self.git_wpt, commit) # Check for same-pr rather than same-commit because we always # use the commits on the PR branch, not the merged commits. # The other option is to use the GH API to decide if the PR # merged and if so what the merge commit was, although in that # case we would still not know the commit prior to merge, which # is what we need if commit.pr() == str(self.pr): break commits.append(commit) return commits
def do_retrigger(git_gecko, git_wpt, **kwargs): import errors import update import upstream from landing import current, load_sync_point, unlanded_with_type update_repositories(git_gecko, git_wpt) if kwargs["upstream"]: print("Retriggering upstream syncs with errors") for sync in upstream.UpstreamSync.load_by_status( git_gecko, git_wpt, "open"): if sync.error: with SyncLock.for_process(sync.process_name) as lock: with sync.as_mut(lock): try: upstream.update_sync(git_gecko, git_wpt, sync, repo_update=False) except errors.AbortError as e: print("Update failed:\n%s" % e) pass if kwargs["downstream"]: print("Retriggering downstream syncs on master") current_landing = current(git_gecko, git_wpt) if current_landing is None: sync_point = load_sync_point(git_gecko, git_wpt) prev_wpt_head = sync_point["upstream"] else: prev_wpt_head = current_landing.wpt_commits.head.sha1 unlandable = unlanded_with_type(git_gecko, git_wpt, None, prev_wpt_head) errors = update.retrigger(git_gecko, git_wpt, unlandable) if errors: print("The following PRs have errors:\n%s" % "\n".join(errors))
def update_modified_sync(git_gecko, git_wpt, sync): if len(sync.gecko_commits) == 0: # In the case that there are no gecko commits, we presumably had a backout # In this case we don't touch the wpt commits, but just mark the PR # as closed. That's pretty counterintuitive, but it turns out that GitHub # will only let you reopen a closed PR if you don't change the branch head in # the meantime. So we carefully avoid touching the wpt side until something # relands and we have a chance to reopen the PR logger.info("Sync has no commits, so marking as incomplete") sync.status = "incomplete" if not sync.pr: logger.info( "Sync was already fully applied upstream, not creating a PR") return else: sync.status = "open" try: sync.update_wpt_commits() except AbortError: # If we got a merge conflict and the PR doesn't exist yet then try # recreating the commits on top of the current sync point in order that # we get a PR and it's visible that it fails if not sync.pr: logger.info("Applying to origin/master failed; " "retrying with the current sync point") from landing import load_sync_point sync_point = load_sync_point(git_gecko, git_wpt) sync.set_wpt_base(sync_point["upstream"]) try: sync.update_wpt_commits() except AbortError: # Reset the base to origin/master sync.set_wpt_base("origin/master") raise sync.update_github()
def update_pr(git_gecko, git_wpt, pr, force_rebase=False): sync = get_pr_sync(git_gecko, git_wpt, pr.number) if sync and sync.status == "complete": logger.info("Sync already landed") return if sync: logger.info("sync status %s" % sync.landable_status) sync_point = landing.load_sync_point(git_gecko, git_wpt) if not sync: # If this looks like something that came from gecko, create # a corresponding sync upstream_sync = upstream.UpstreamSync.from_pr(git_gecko, git_wpt, pr.number, pr.body) if upstream_sync is not None: upstream.update_pr(git_gecko, git_wpt, upstream_sync, pr.state, pr.merged) else: if pr.state != "open" and not pr.merged: return schedule_pr_task("opened", pr) update_for_status(pr) elif isinstance(sync, downstream.DownstreamSync): if force_rebase: sync.gecko_rebase(sync.gecko_integration_branch()) if len(sync.wpt_commits) == 0: sync.update_wpt_commits() if not sync.bug and not (pr.state == "closed" and not pr.merged): sync.create_bug(git_wpt, pr.number, pr.title, pr.body) if pr.state == "open" or pr.merged: if pr.head.sha != sync.wpt_commits.head: # Upstream has different commits, so run a push handler schedule_pr_task("push", pr) elif sync.latest_valid_try_push: if not sync.latest_valid_try_push.taskgroup_id: update_taskgroup_ids(git_gecko, git_wpt) if (sync.latest_valid_try_push.taskgroup_id and not sync.latest_valid_try_push.status == "complete"): update_tasks(git_gecko, git_wpt, sync=sync) if not pr.merged: update_for_status(pr) else: update_for_action(pr, "closed") elif isinstance(sync, upstream.UpstreamSync): merge_sha = pr.merge_commit_sha if pr.merged else None upstream.update_pr(git_gecko, git_wpt, sync, pr.state, merge_sha) sync.try_land_pr() if merge_sha: if git_wpt.is_ancestor(merge_sha, sync_point["upstream"]): # This sync already landed, so it should be finished sync.finish() else: if sync.status == "complete": # We bypass the setter here because we have some cases where the # status must go from complete to wpt-merged which is otherwise forbidden sync._process_name.status = "wpt-merged" else: sync.status = "wpt-merged"