⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 285890 in webkit


Ignore:
Timestamp:
Nov 16, 2021, 2:55:52 PM (5 years ago)
Author:
Jonathan Bedard
Message:

[git-webkit] Mark landed changes as merged
https://bugs.webkit.org/show_bug.cgi?id=233056
<rdar://problem/85351564>

Reviewed by Dewei Zhu.

For BitBucket and GitHub to recognize a pull-request as merged, the target
branch must be updated with the exact commit to be merged as the merge occurs.

  • Scripts/libraries/webkitscmpy/setup.py: Bump version.
  • Scripts/libraries/webkitscmpy/webkitscmpy/init.py: Ditto.
  • Scripts/libraries/webkitscmpy/webkitscmpy/program/land.py:

(Land.main): Update source branch when merging commits to target branch.

  • Scripts/libraries/webkitscmpy/webkitscmpy/remote/bitbucket.py:

(BitBucket.PRGenerator.update): Only delete values if they exist.

  • Scripts/libraries/webkitscmpy/webkitscmpy/test/land_unittest.py:

(TestLand):
(TestLandGitHub):
(TestLandBitBucket):

Canonical link: https://commits.webkit.org/244312@main

Location:
trunk/Tools
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r285877 r285890  
     12021-11-12  Jonathan Bedard  <jbedard@apple.com>
     2
     3        [git-webkit] Mark landed changes as merged
     4        https://bugs.webkit.org/show_bug.cgi?id=233056
     5        <rdar://problem/85351564>
     6
     7        Reviewed by Dewei Zhu.
     8
     9        For BitBucket and GitHub to recognize a pull-request as merged, the target
     10        branch must be updated with the exact commit to be merged as the merge occurs.
     11
     12        * Scripts/libraries/webkitscmpy/setup.py: Bump version.
     13        * Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py: Ditto.
     14        * Scripts/libraries/webkitscmpy/webkitscmpy/program/land.py:
     15        (Land.main): Update source branch when merging commits to target branch.
     16        * Scripts/libraries/webkitscmpy/webkitscmpy/remote/bitbucket.py:
     17        (BitBucket.PRGenerator.update): Only delete values if they exist.
     18        * Scripts/libraries/webkitscmpy/webkitscmpy/test/land_unittest.py:
     19        (TestLand):
     20        (TestLandGitHub):
     21        (TestLandBitBucket):
     22
    1232021-11-16  Chris Dumez  <cdumez@apple.com>
    224
  • trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/land.py

    r285272 r285890  
    2828from .command import Command
    2929from .branch import Branch
     30from .pull_request import PullRequest
    3031from argparse import Namespace
    3132from webkitcorepy import arguments, run, string_utils, Terminal
    32 from webkitscmpy import local, log
     33from webkitscmpy import local, log, remote
    3334
    3435
     
    7677            return 1
    7778
    78         if not Branch.editable(repository.branch, repository=repository):
     79        source_branch = repository.branch
     80        if not Branch.editable(source_branch, repository=repository):
    7981            sys.stderr.write("Can only 'land' editable branches\n")
    8082            return 1
    8183        branch_point = Branch.branch_point(repository)
    82         commits = list(repository.commits(begin=dict(hash=branch_point.hash), end=dict(branch=repository.branch)))
     84        commits = list(repository.commits(begin=dict(hash=branch_point.hash), end=dict(branch=source_branch)))
    8385        if not commits:
    8486            sys.stderr.write('Failed to find commits to land\n')
     
    8890        rmt = repository.remote()
    8991        if rmt and rmt.pull_requests:
    90             candidates = list(rmt.pull_requests.find(opened=True, head=repository.branch))
     92            candidates = list(rmt.pull_requests.find(opened=True, head=source_branch))
    9193            if len(candidates) == 1:
    9294                pull_request = candidates[0]
    9395            elif candidates:
    94                 sys.stderr.write("Multiple pull-request match '{}'\n".format(repository.branch))
     96                sys.stderr.write("Multiple pull-request match '{}'\n".format(source_branch))
    9597
    9698        if pull_request and args.review:
     
    119121                        date='{} -{}'.format(int(time.time()), repository.gmtoffset())
    120122                    ), '--msg-filter', 'sed "s/NOBODY (OO*PP*S!*)/{}/g"'.format(string_utils.join([p.name for p in pull_request.approvers])),
    121                     '{}...{}'.format(repository.branch, branch_point.hash),
     123                    '{}...{}'.format(source_branch, branch_point.hash),
    122124                ], cwd=repository.root_path, env={'FILTER_BRANCH_SQUELCH_WARNING': '1'}, capture_output=True).returncode:
    123125                    sys.stderr.write('Failed to set reviewers\n')
    124126                    return 1
    125                 commits = list(repository.commits(begin=dict(hash=branch_point.hash), end=dict(branch=repository.branch)))
     127                commits = list(repository.commits(begin=dict(hash=branch_point.hash), end=dict(branch=source_branch)))
    126128                if not commits:
    127129                    sys.stderr.write('Failed to find commits after setting reviewers\n')
     
    129131
    130132        elif not pull_request:
    131             sys.stderr.write("Failed to find pull-request associated with '{}'\n".format(repository.branch))
     133            sys.stderr.write("Failed to find pull-request associated with '{}'\n".format(source_branch))
    132134
    133135        if not args.oops and any([cls.OOPS_RE.search(commit.message) for commit in commits]):
     
    136138
    137139        if not args.oops:
    138             for line in repository.diff_lines(branch_point.hash, repository.branch):
     140            for line in repository.diff_lines(branch_point.hash, source_branch):
    139141                if cls.OOPS_RE.search(line):
    140142                    sys.stderr.write("Found '(OOPS!)' in commit diff, please resolve before committing\n")
     
    142144
    143145        target = pull_request.base if pull_request else branch_point.branch
    144         log.warning("Rebasing '{}' from '{}' to '{}'...".format(repository.branch, branch_point.branch, target))
     146        log.warning("Rebasing '{}' from '{}' to '{}'...".format(source_branch, branch_point.branch, target))
    145147        if repository.fetch(branch=target, remote=cls.REMOTE):
    146148            sys.stderr.write("Failed to fetch '{}' from '{}'\n".format(target, cls.REMOTE))
    147149            return 1
    148         if repository.rebase(target=target, base=branch_point.branch, head=repository.branch):
    149             sys.stderr.write("Failed to rebase '{}' onto '{}', please resolve conflicts\n".format(repository.branch, target))
    150             return 1
    151         log.warning("Rebased '{}' from '{}' to '{}'!".format(repository.branch, branch_point.branch, target))
    152 
    153         if run([repository.executable(), 'branch', '-f', target, repository.branch], cwd=repository.root_path).returncode:
     150        if repository.rebase(target=target, base=branch_point.branch, head=source_branch):
     151            sys.stderr.write("Failed to rebase '{}' onto '{}', please resolve conflicts\n".format(source_branch, target))
     152            return 1
     153        log.warning("Rebased '{}' from '{}' to '{}'!".format(source_branch, branch_point.branch, target))
     154
     155        if run([repository.executable(), 'branch', '-f', target, source_branch], cwd=repository.root_path).returncode:
    154156            sys.stderr.write("Failed to move '{}' ref\n".format(target))
    155157            return 1
    156158
    157159        if identifier_template:
    158             source = repository.branch
    159160            repository.checkout(target)
    160161            if Canonicalize.main(Namespace(
     
    163164                sys.stderr.write("Failed to embed identifiers to '{}'\n".format(target))
    164165                return 1
    165             if run([repository.executable(), 'branch', '-f', source, target], cwd=repository.root_path).returncode:
     166            if run([repository.executable(), 'branch', '-f', source_branch, target], cwd=repository.root_path).returncode:
    166167                sys.stderr.write("Failed to move '{}' ref to the canonicalized head of '{}'\n".format(source, target))
    167168                return -1
     169
     170        # Need to compute the remote source
     171        remote_target = 'fork' if isinstance(rmt, remote.GitHub) else 'origin'
    168172
    169173        if canonical_svn:
     
    182186            while original.hash == latest.hash:
    183187                if time.time() - started > cls.MIRROR_TIMEOUT:
    184                     sys.stderr.write("Timed out waiting for the git-svn mirror, '{}' landed but not closed\n".format(pull_request or repository.branch))
     188                    sys.stderr.write("Timed out waiting for the git-svn mirror, '{}' landed but not closed\n".format(pull_request or source_branch))
    185189                    return 1
    186190                log.warning('    Verifying mirror processesed change')
    187191                time.sleep(5)
    188192                run([repository.executable(), 'pull'], cwd=repository.root_path)
    189                 original = repository.find('HEAD', include_log=False, include_identifier=False)
     193                latest = repository.find('HEAD', include_log=False, include_identifier=False)
     194            if pull_request:
     195                run([repository.executable(), 'branch', '-f', source_branch, target], cwd=repository.root_path)
     196                commits = list(repository.commits(begin=dict(argument='{}~{}'.format(source_branch, len(commits))), end=dict(branch=source_branch)))
     197                run([repository.executable(), 'push', '-f', remote_target, source_branch], cwd=repository.root_path)
     198                rmt.pull_requests.update(
     199                    pull_request=pull_request,
     200                    title=PullRequest.title_for(commits),
     201                    commits=commits,
     202                    base=branch_point.branch,
     203                    head=source_branch,
     204                )
    190205
    191206        else:
     207            if pull_request:
     208                log.warning("Updating '{}' to match landing commits...".format(pull_request))
     209                commits = list(repository.commits(begin=dict(argument='{}~{}'.format(source_branch, len(commits))), end=dict(branch=source_branch)))
     210                run([repository.executable(), 'push', '-f', remote_target, source_branch], cwd=repository.root_path)
     211                rmt.pull_requests.update(
     212                    pull_request=pull_request,
     213                    title=PullRequest.title_for(commits),
     214                    commits=commits,
     215                    base=branch_point.branch,
     216                    head=source_branch,
     217                )
     218
    192219            if run([repository.executable(), 'push', cls.REMOTE, target], cwd=repository.root_path).returncode:
    193220                sys.stderr.write("Failed to push '{}' to '{}'\n".format(target, cls.REMOTE))
    194221                return 1
     222            repository.checkout(target)
    195223
    196224        commit = repository.commit(branch=target, include_log=False)
     
    203231        if pull_request:
    204232            pull_request.comment(land_message)
    205             pull_request.close()
    206 
     233
     234        if args.defaults or Terminal.choose("Delete branch '{}'?".format(source_branch), default='Yes') == 'Yes':
     235            run([repository.executable(), 'branch', '-D', source_branch], cwd=repository.root_path)
     236            run([repository.executable(), 'push', remote_target, '--delete', source_branch], cwd=repository.root_path)
    207237        return 0
  • trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/bitbucket.py

    r284892 r285890  
    203203                return None
    204204            data = response.json()
    205             del data['author']
    206             del data['participants']
     205            data.pop('author', None)
     206            data.pop('participants', None)
    207207            data.update(to_change)
    208208
  • trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/land_unittest.py

    r285272 r285890  
    9191
    9292    def test_default(self):
    93         with OutputCapture() as captured, repository(self.path, has_oops=False), mocks.local.Svn():
     93        with OutputCapture() as captured, repository(self.path, has_oops=False), mocks.local.Svn(), MockTerminal.input('n'):
    9494            self.assertEqual(0, program.main(
    9595                args=('land',),
     
    110110            "Failed to find pull-request associated with 'eng/example'\n",
    111111        )
    112         self.assertEqual(captured.stdout.getvalue(), 'Landed a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd!\n')
     112        self.assertEqual(
     113            captured.stdout.getvalue(),
     114            'Landed a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd!\n'
     115            "Delete branch 'eng/example'? (Yes/No): \n",
     116        )
    113117
    114118    def test_canonicalize(self):
    115         with OutputCapture() as captured, repository(self.path, has_oops=False), mocks.local.Svn():
     119        with OutputCapture() as captured, repository(self.path, has_oops=False), mocks.local.Svn(), MockTerminal.input('n'):
    116120            self.assertEqual(0, program.main(
    117121                args=('land',),
     
    146150            'Rewrite a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd (1/1) (--- seconds passed, remaining --- predicted)\n'
    147151            '1 commit successfully canonicalized!\n'
    148             'Landed https://commits.webkit.org/6@main (a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd)!\n',
     152            'Landed https://commits.webkit.org/6@main (a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd)!\n'
     153            "Delete branch 'eng/example'? (Yes/No): \n",
    149154        )
    150155
     
    164169
    165170    def test_svn(self):
    166         self.maxDiff = None
    167         with MockTime, OutputCapture() as captured, repository(self.path, has_oops=False, git_svn=True), mocks.local.Svn():
     171        with MockTime, OutputCapture() as captured, repository(self.path, has_oops=False, git_svn=True), mocks.local.Svn(), MockTerminal.input('n'):
    168172            self.assertEqual(0, program.main(
    169173                args=('land',),
     
    187191        self.assertEqual(
    188192            captured.stdout.getvalue(),
    189             'Landed a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd!\n',
     193            'Landed a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd!\n'
     194            "Delete branch 'eng/example'? (Yes/No): \n",
    190195        )
    191196
     
    282287
    283288    def test_insert_review(self):
    284         with OutputCapture() as captured, MockTerminal.input('y'), self.webserver(approved=True) as remote, \
     289        with OutputCapture() as captured, MockTerminal.input('y', 'n'), self.webserver(approved=True) as remote, \
    285290                repository(self.path, has_oops=True, remote='https://{}'.format(remote.remote)), mocks.local.Svn():
    286291            self.assertEqual(0, program.main(
     
    303308                "Rebasing 'eng/example' from 'main' to 'main'...",
    304309                "Rebased 'eng/example' from 'main' to 'main'!",
     310                "Updating 'PR 1 | Example Change' to match landing commits...",
    305311            ],
    306312        )
     
    309315            captured.stdout.getvalue(),
    310316            "Set 'Ricky Reviewer' as your reviewer? (Yes/No): \n"
    311             'Landed a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd!\n',
     317            'Landed a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd!\n'
     318            "Delete branch 'eng/example'? (Yes/No): \n",
    312319        )
    313320
     
    407414
    408415    def test_insert_review(self):
    409         with OutputCapture() as captured, MockTerminal.input('y'), self.webserver(approved=True) as remote, repository(
     416        with OutputCapture() as captured, MockTerminal.input('y', 'n'), self.webserver(approved=True) as remote, repository(
    410417                self.path, has_oops=True, remote='ssh://git@{}/{}/{}.git'.format(
    411418                    remote.hosts[0], remote.project.split('/')[1], remote.project.split('/')[3],
     
    430437                "Rebasing 'eng/example' from 'main' to 'main'...",
    431438                "Rebased 'eng/example' from 'main' to 'main'!",
     439                "Updating 'PR 1 | Example Change' to match landing commits...",
    432440            ],
    433441        )
     
    436444            captured.stdout.getvalue(),
    437445            "Set 'Ricky Reviewer' as your reviewer? (Yes/No): \n"
    438             'Landed a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd!\n',
    439         )
     446            'Landed a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd!\n'
     447            "Delete branch 'eng/example'? (Yes/No): \n",
     448        )
Note: See TracChangeset for help on using the changeset viewer.