Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/dev/sync.ini
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,5 @@ listener.interval = 60

[lando]
api_token=%SECRET%
api_url = https://lando.moz.tools/api
user_email=wptsync@mozilla.com
23 changes: 21 additions & 2 deletions sync/commit.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from . import log
from .env import Environment
from .errors import AbortError
from .lando import git2hg
from .repos import cinnabar, cinnabar_map, pygit2_get

from typing import Dict
Expand Down Expand Up @@ -544,8 +545,16 @@ def has_wpt_changes(self) -> bool:

@property
def is_backout(self) -> bool:
return self.is_hg_backout or self.is_git_revert

@property
def is_hg_backout(self) -> bool:
return commitparser.is_backout(self.msg)

@property
def is_git_revert(self) -> bool:
return commitparser.parse_reverts(self.msg) is not None

@property
def is_downstream(self) -> bool:
from . import downstream
Expand All @@ -563,7 +572,13 @@ def commits_backed_out(self) -> tuple[list[GeckoCommit], set[int]]:
commits: list[GeckoCommit] = []
bugs: list[int] = []
if self.is_backout:
nodes_bugs = commitparser.parse_backouts(self.msg)
nodes_bugs = None

if self.is_hg_backout:
nodes_bugs = commitparser.parse_backouts(self.msg)
elif self.is_git_revert:
nodes_bugs = commitparser.parse_reverts(self.msg)

if nodes_bugs is None:
# We think this a backout, but have no idea what it backs out
# it's not clear how to handle that case so for now we pretend it isn't
Expand All @@ -573,7 +588,11 @@ def commits_backed_out(self) -> tuple[list[GeckoCommit], set[int]]:
nodes, bugs = nodes_bugs
# Assuming that all commits are listed.
for node in nodes:
git_sha = cinnabar(self.repo).hg2git(node.decode("ascii"))
hg_revision = node.decode("ascii")
if self.is_git_revert:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Computing this over and over seems a bit wasteful, but isn't critical.

# Convert original git hash to mercurial
hg_revision = git2hg(hg_revision)
git_sha = cinnabar(self.repo).hg2git(hg_revision)
commits.append(GeckoCommit(self.repo, git_sha))

return commits, set(bugs)
Expand Down
21 changes: 21 additions & 0 deletions sync/lando.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import json
import urllib.request

from .env import Environment
from . import log

env = Environment()

logger = log.get_logger(__name__)


def git2hg(git_hash: str) -> str:
response = urllib.request.urlopen(
env.config["lando"]["api_url"] + "/git2hg/firefox/" + git_hash
) # nosec B310
data = response.read()
map = json.loads(data.decode("utf-8"))
assert isinstance(map, dict)
assert isinstance(map["hg_hash"], str)

return map["hg_hash"]
1 change: 1 addition & 0 deletions sync_prod.ini
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,5 @@ repo.url = https://github.com/web-platform-tests/wpt-metadata

[lando]
api_token=%SECRET%
api_url = https://lando.moz.tools/api
user_email=wptsync@mozilla.com
1 change: 1 addition & 0 deletions test/config/sync.ini
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,5 @@ listener.interval = 60

[lando]
api_token="%SECRET%"
api_url = https://lando.moz.tools/api
user_email="wptsync@mozilla.com"
15 changes: 15 additions & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import copy
import glob
import hashlib
import io
import json
import os
Expand Down Expand Up @@ -383,6 +384,20 @@ def inner(revs, bugs, message=None, bookmarks="mozilla/autoland"):
return inner


@pytest.fixture
def upstream_gecko_revert(env, hg_gecko_upstream):
def inner(message, rev, bookmarks="mozilla/autoland"):
# Git hash has to be converted to hg hash with API.
# Since we going to mock this API call, this git hash
# can have a random value that just looks like git hash.
random_hash = hashlib.sha1(os.urandom(20)).hexdigest()
commit_message = f"""Revert \"{message}\"\nThis reverts commit {random_hash}.""".encode()
hg_gecko_upstream.backout("--no-commit", rev)
return hg_commit(hg_gecko_upstream, commit_message, bookmarks)

return inner


@pytest.fixture
def gecko_worktree(env, git_gecko):
path = os.path.join(env.config["root"], env.config["paths"]["worktrees"], "gecko", "autoland")
Expand Down
40 changes: 40 additions & 0 deletions test/test_upstream.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from unittest.mock import patch

from sync import commit as sync_commit, upstream
from sync.gitutils import update_repositories
from sync.lock import SyncLock
Expand Down Expand Up @@ -84,6 +86,44 @@ def test_create_pr_backout(git_gecko, git_wpt, upstream_gecko_commit, upstream_g
assert backout_commit.upstream_sync(git_gecko, git_wpt) == sync


def test_create_pr_revert(git_gecko, git_wpt, upstream_gecko_commit, upstream_gecko_revert):
bug = 1234
test_changes = {"README": b"Change README\n"}
message = f"Bug {bug} - Change README"
rev = upstream_gecko_commit(test_changes=test_changes, bug=bug, message=message.encode())

update_repositories(git_gecko, git_wpt, wait_gecko_commit=rev)
upstream.gecko_push(git_gecko, git_wpt, "autoland", rev, raise_on_error=True)

syncs = upstream.UpstreamSync.for_bug(git_gecko, git_wpt, bug)
assert list(syncs.keys()) == ["open"]
assert len(syncs["open"]) == 1
sync = syncs["open"].pop()
assert sync.bug == 1234
assert sync.status == "open"
assert len(sync.gecko_commits) == 1
assert len(sync.wpt_commits) == 1
assert sync.pr

backout_rev = upstream_gecko_revert(message, rev)

update_repositories(git_gecko, git_wpt, wait_gecko_commit=backout_rev)
with patch("sync.commit.git2hg", return_value=rev):
upstream.gecko_push(git_gecko, git_wpt, "autoland", backout_rev, raise_on_error=True)
syncs = upstream.UpstreamSync.for_bug(git_gecko, git_wpt, bug)
assert list(syncs.keys()) == ["incomplete"]
assert len(syncs["incomplete"]) == 1
sync = syncs["incomplete"].pop()
assert sync.bug == 1234
with patch("sync.commit.git2hg", return_value=rev):
assert len(sync.gecko_commits) == 0
assert len(sync.wpt_commits) == 1
assert len(sync.upstreamed_gecko_commits) == 1
assert sync.status == "incomplete"
backout_commit = sync_commit.GeckoCommit(git_gecko, cinnabar(git_gecko).hg2git(rev))
assert backout_commit.upstream_sync(git_gecko, git_wpt) == sync


def test_create_pr_backout_reland(
git_gecko, git_wpt, upstream_gecko_commit, upstream_gecko_backout
):
Expand Down