| Differences between
and this patch
- a/Tools/ChangeLog +32 lines
Lines 1-3 a/Tools/ChangeLog_sec1
1
2022-05-17  Jonathan Bedard  <jbedard@apple.com>
2
3
        [Commit-Queue] Forbid ChangeLog modification
4
        https://bugs.webkit.org/show_bug.cgi?id=240461
5
        <rdar://93351783>
6
7
        Reviewed by NOBODY (OOPS!).
8
    
9
        * CISupport/ews-build/factories.py:
10
        (CommitQueueFactory.__init__): Only accept patches with commit messages,
11
        respect those commit messages.
12
        (MergeQueueFactoryBase.__init__): Use commit author in commit.
13
        * CISupport/ews-build/factories_unittest.py:
14
        (TestExpectedBuildSteps.test_all_expected_steps):
15
        * CISupport/ews-build/steps.py:
16
        (CommitPatch): Add step which commits a patch, including it's commit message.
17
        (PushCommitToWebKitRepo.evaluateCommand): Use GitHub checkout on Commit-Queue.
18
        (ValidateSquashed.start): Support committed patches.
19
        (AddReviewerToCommitMessage.start): Ditto.
20
        (DetermineAuthor): Extract author from local commit.
21
        (AddAuthorToCommitMessage): Use 'author' property as set by 'DetermineAuthor'.
22
        (ValidateCommitMessage._files): Support patches.
23
        (ValidateCommitMessage.run): Support committed patches.
24
        (ValidateCommitMessage.getResultSummary): Support patches.
25
        (Canonicalize.run): Support committed patches.
26
        (ValidateSquashed.doStepIf): Deleted.
27
        (ValidateSquashed.hideStepIf): Deleted.
28
        (AddAuthorToCommitMessage.author): Deleted.
29
        (ValidateCommitMessage.doStepIf): Deleted.
30
        (ValidateCommitMessage.hideStepIf): Deleted.
31
        * CISupport/ews-build/steps_unittest.py:
32
1
2022-05-16  Wenson Hsieh  <wenson_hsieh@apple.com>
33
2022-05-16  Wenson Hsieh  <wenson_hsieh@apple.com>
2
34
3
        Demote -[WKWebView retrieveAccessibilityTreeData:] to SPI
35
        Demote -[WKWebView retrieveAccessibilityTreeData:] to SPI
- a/Tools/CISupport/ews-build/factories.py -12 / +16 lines
Lines 24-33 a/Tools/CISupport/ews-build/factories.py_sec1
24
from buildbot.process import factory
24
from buildbot.process import factory
25
from buildbot.steps import trigger
25
from buildbot.steps import trigger
26
26
27
from steps import (AddAuthorToCommitMessage, AddReviewerToCommitMessage, ApplyPatch, ApplyWatchList, Canonicalize,
27
from steps import (AddAuthorToCommitMessage, AddReviewerToCommitMessage, ApplyPatch, ApplyWatchList, Canonicalize, CommitPatch,
28
                   CheckOutPullRequest, CheckOutSource, CheckOutSpecificRevision, CheckChangeRelevance,
28
                   CheckOutPullRequest, CheckOutSource, CheckOutSpecificRevision, CheckChangeRelevance,
29
                   CheckPatchStatusOnEWSQueues, CheckStyle, CleanGitRepo, CompileJSC, CompileWebKit, ConfigureBuild, CreateLocalGITCommit,
29
                   CheckPatchStatusOnEWSQueues, CheckStyle, CleanGitRepo, CompileJSC, CompileWebKit, ConfigureBuild, CreateLocalGITCommit,
30
                   DownloadBuiltProduct, ExtractBuiltProduct, FetchBranches, FindModifiedChangeLogs, FindModifiedLayoutTests, GitSvnFetch,
30
                   DetermineAuthor, DownloadBuiltProduct, ExtractBuiltProduct, FetchBranches, FindModifiedChangeLogs, FindModifiedLayoutTests, GitSvnFetch,
31
                   InstallGtkDependencies, InstallWpeDependencies, KillOldProcesses, PrintConfiguration, PushCommitToWebKitRepo,
31
                   InstallGtkDependencies, InstallWpeDependencies, KillOldProcesses, PrintConfiguration, PushCommitToWebKitRepo,
32
                   RunAPITests, RunBindingsTests, RunBuildWebKitOrgUnitTests, RunBuildbotCheckConfigForBuildWebKit, RunBuildbotCheckConfigForEWS,
32
                   RunAPITests, RunBindingsTests, RunBuildWebKitOrgUnitTests, RunBuildbotCheckConfigForBuildWebKit, RunBuildbotCheckConfigForEWS,
33
                   RunEWSUnitTests, RunResultsdbpyTests, RunJavaScriptCoreTests, RunWebKit1Tests, RunWebKitPerlTests, RunWebKitPyPython2Tests,
33
                   RunEWSUnitTests, RunResultsdbpyTests, RunJavaScriptCoreTests, RunWebKit1Tests, RunWebKitPerlTests, RunWebKitPyPython2Tests,
Lines 292-306 class CommitQueueFactory(factory.BuildFactory): a/Tools/CISupport/ews-build/factories.py_sec2
292
        self.addStep(ValidateChange(verifycqplus=True))
292
        self.addStep(ValidateChange(verifycqplus=True))
293
        self.addStep(ValidateCommitterAndReviewer())
293
        self.addStep(ValidateCommitterAndReviewer())
294
        self.addStep(PrintConfiguration())
294
        self.addStep(PrintConfiguration())
295
        self.addStep(CleanGitRepo(default_branch='master'))
295
        self.addStep(CleanGitRepo())
296
        self.addStep(CheckOutSource(repourl='https://git.webkit.org/git/WebKit-https'))
296
        self.addStep(CheckOutSource())
297
        self.addStep(GitSvnFetch())  # FIXME: Remove when migrating to pure git
297
        self.addStep(FetchBranches())
298
        self.addStep(FetchBranches())
298
        self.addStep(ShowIdentifier())
299
        self.addStep(ShowIdentifier())
299
        self.addStep(VerifyGitHubIntegrity())
300
        self.addStep(VerifyGitHubIntegrity())
300
        self.addStep(UpdateWorkingDirectory())
301
        self.addStep(UpdateWorkingDirectory())
301
        self.addStep(ApplyPatch())
302
        self.addStep(CommitPatch())
302
        self.addStep(ValidateChangeLogAndReviewer())
303
303
        self.addStep(FindModifiedChangeLogs())
304
        self.addStep(ValidateSquashed())
305
        self.addStep(AddReviewerToCommitMessage())
306
        self.addStep(DetermineAuthor())
307
        self.addStep(AddAuthorToCommitMessage())
308
        self.addStep(ValidateCommitMessage())
309
304
        self.addStep(KillOldProcesses())
310
        self.addStep(KillOldProcesses())
305
        self.addStep(CompileWebKit(skipUpload=True))
311
        self.addStep(CompileWebKit(skipUpload=True))
306
        self.addStep(KillOldProcesses())
312
        self.addStep(KillOldProcesses())
Lines 308-318 class CommitQueueFactory(factory.BuildFactory): a/Tools/CISupport/ews-build/factories.py_sec3
308
        self.addStep(CheckPatchStatusOnEWSQueues())
314
        self.addStep(CheckPatchStatusOnEWSQueues())
309
        self.addStep(RunWebKitTests())
315
        self.addStep(RunWebKitTests())
310
        self.addStep(ValidateChange(addURLs=False, verifycqplus=True))
316
        self.addStep(ValidateChange(addURLs=False, verifycqplus=True))
311
        self.addStep(CheckOutSource(repourl='https://git.webkit.org/git/WebKit-https'))
317
312
        self.addStep(ShowIdentifier())
318
        self.addStep(Canonicalize())
313
        self.addStep(UpdateWorkingDirectory())
314
        self.addStep(ApplyPatch())
315
        self.addStep(CreateLocalGITCommit())
316
        self.addStep(PushCommitToWebKitRepo())
319
        self.addStep(PushCommitToWebKitRepo())
317
        self.addStep(SetBuildSummary())
320
        self.addStep(SetBuildSummary())
318
321
Lines 334-339 class MergeQueueFactoryBase(factory.BuildFactory): a/Tools/CISupport/ews-build/factories.py_sec4
334
        self.addStep(CheckOutPullRequest())
337
        self.addStep(CheckOutPullRequest())
335
        self.addStep(ValidateSquashed())
338
        self.addStep(ValidateSquashed())
336
        self.addStep(AddReviewerToCommitMessage())
339
        self.addStep(AddReviewerToCommitMessage())
340
        self.addStep(DetermineAuthor())
337
        self.addStep(AddAuthorToCommitMessage())
341
        self.addStep(AddAuthorToCommitMessage())
338
        self.addStep(ValidateCommitMessage())
342
        self.addStep(ValidateCommitMessage())
339
343
- a/Tools/CISupport/ews-build/factories_unittest.py -8 / +11 lines
Lines 604-616 class TestExpectedBuildSteps(unittest.TestCase): a/Tools/CISupport/ews-build/factories_unittest.py_sec1
604
            'configuration',
604
            'configuration',
605
            'clean-up-git-repo',
605
            'clean-up-git-repo',
606
            'clean-and-update-working-directory',
606
            'clean-and-update-working-directory',
607
            'git-svn-fetch',
607
            'fetch-branch-references',
608
            'fetch-branch-references',
608
            'show-identifier',
609
            'show-identifier',
609
            'verify-github-integrity',
610
            'verify-github-integrity',
610
            'update-working-directory',
611
            'update-working-directory',
611
            'apply-patch',
612
            'commit-patch',
612
            'validate-changelog-and-reviewer',
613
            'validate-squashed',
613
            'find-modified-changelogs',
614
            'add-reviewer-to-commit-message',
615
            'determine-author',
616
            'add-author-to-commit-message',
617
            'validate-commit-message',
614
            'kill-old-processes',
618
            'kill-old-processes',
615
            'compile-webkit',
619
            'compile-webkit',
616
            'kill-old-processes',
620
            'kill-old-processes',
Lines 618-628 class TestExpectedBuildSteps(unittest.TestCase): a/Tools/CISupport/ews-build/factories_unittest.py_sec2
618
            'check-status-on-other-ewses',
622
            'check-status-on-other-ewses',
619
            'layout-tests',
623
            'layout-tests',
620
            'validate-change',
624
            'validate-change',
621
            'clean-and-update-working-directory',
625
            'canonicalize-commit',
622
            'show-identifier',
623
            'update-working-directory',
624
            'apply-patch',
625
            'create-local-git-commit',
626
            'push-commit-to-webkit-repo',
626
            'push-commit-to-webkit-repo',
627
            'set-build-summary'
627
            'set-build-summary'
628
        ],
628
        ],
Lines 641-646 class TestExpectedBuildSteps(unittest.TestCase): a/Tools/CISupport/ews-build/factories_unittest.py_sec3
641
            'checkout-pull-request',
641
            'checkout-pull-request',
642
            'validate-squashed',
642
            'validate-squashed',
643
            'add-reviewer-to-commit-message',
643
            'add-reviewer-to-commit-message',
644
            'determine-author',
644
            'add-author-to-commit-message',
645
            'add-author-to-commit-message',
645
            'validate-commit-message',
646
            'validate-commit-message',
646
            'kill-old-processes',
647
            'kill-old-processes',
Lines 666-671 class TestExpectedBuildSteps(unittest.TestCase): a/Tools/CISupport/ews-build/factories_unittest.py_sec4
666
            'checkout-pull-request',
667
            'checkout-pull-request',
667
            'validate-squashed',
668
            'validate-squashed',
668
            'add-reviewer-to-commit-message',
669
            'add-reviewer-to-commit-message',
670
            'determine-author',
669
            'add-author-to-commit-message',
671
            'add-author-to-commit-message',
670
            'validate-commit-message',
672
            'validate-commit-message',
671
            'validate-change',
673
            'validate-change',
Lines 681-686 class TestExpectedBuildSteps(unittest.TestCase): a/Tools/CISupport/ews-build/factories_unittest.py_sec5
681
        loadConfig.loadBuilderConfig(self.config, is_test_mode_enabled=True, master_prefix_path=cwd)
683
        loadConfig.loadBuilderConfig(self.config, is_test_mode_enabled=True, master_prefix_path=cwd)
682
684
683
    def test_all_expected_steps(self):
685
    def test_all_expected_steps(self):
686
        self.maxDiff = None
684
        for builder in self.config['builders']:
687
        for builder in self.config['builders']:
685
            buildSteps = []
688
            buildSteps = []
686
            for step in builder['factory'].steps:
689
            for step in builder['factory'].steps:
- a/Tools/CISupport/ews-build/steps.py -56 / +131 lines
Lines 845-850 class ApplyPatch(shell.ShellCommand, CompositeStepMixin, ShellMixin): a/Tools/CISupport/ews-build/steps.py_sec1
845
        return rc
845
        return rc
846
846
847
847
848
class CommitPatch(steps.ShellSequence, CompositeStepMixin, ShellMixin):
849
    name = 'commit-patch'
850
    description = ['commit-patch']
851
    descriptionDone = ['Created commit from patch']
852
    haltOnFailure = True
853
    env = dict(FILTER_BRANCH_SQUELCH_WARNING='1')
854
    FILTER_BRANCH_PROGRAM = '''import re
855
import sys
856
857
lines = [l for l in sys.stdin]
858
for s in re.split(r' (Need the bug URL \(OOPS!\).)|(\S+:\/\/\S+)', lines[0].rstrip()):
859
    if s and s != ' ':
860
        print(s)
861
for l in lines[1:]:
862
    sys.stdout.write(l)
863
'''
864
865
    def __init__(self, **kwargs):
866
        super(CommitPatch, self).__init__(timeout=10 * 60, logEnviron=False, **kwargs)
867
868
    def doStepIf(self, step):
869
        return self.getProperty('patch_id', False)
870
871
    def _get_patch(self):
872
        sourcestamp = self.build.getSourceStamp(self.getProperty('codebase', ''))
873
        if not sourcestamp or not sourcestamp.patch:
874
            return None
875
        return sourcestamp.patch[1]
876
877
    def run(self):
878
        self.commands = []
879
        patch = self._get_patch()
880
881
        commands = []
882
        if not patch:
883
            commands += [['curl', '-L', 'https://bugs.webkit.org/attachment.cgi?id={}'.format(self.getProperty('patch_id', '')), '-o', '.buildbot-diff']]
884
        commands += [
885
            ['git', 'am', '.buildbot-diff'],
886
            ['git', 'filter-branch', '-f', '--msg-filter', 'python3 -c "{}"'.format(self.FILTER_BRANCH_PROGRAM), 'HEAD...HEAD~1'],
887
        ]
888
        for command in commands:
889
            self.commands.append(util.ShellArg(command=command, logname='stdio', haltOnFailure=True))
890
891
        return super(CommitPatch, self).run()
892
893
    def hideStepIf(self, results, step):
894
        return not self.doStepIf(step) or (results == SUCCESS and self.getProperty('sensitive', False))
895
896
    def getResultSummary(self):
897
        if self.results == SKIPPED:
898
            return {'step': "Skipping creating commitsince patch_id isn't provided"}
899
        if self.results != SUCCESS:
900
            return {'step': 'git am failed to apply patch to trunk'}
901
        return super(CommitPatch, self).getResultSummary()
902
903
848
class CheckOutPullRequest(steps.ShellSequence, ShellMixin):
904
class CheckOutPullRequest(steps.ShellSequence, ShellMixin):
849
    name = 'checkout-pull-request'
905
    name = 'checkout-pull-request'
850
    description = ['checking-out-pull-request']
906
    description = ['checking-out-pull-request']
Lines 4575-4586 class PushCommitToWebKitRepo(shell.ShellCommand): a/Tools/CISupport/ews-build/steps.py_sec2
4575
                    ])
4631
                    ])
4576
                else:
4632
                else:
4577
                    self.build.addStepsAfterCurrentStep([
4633
                    self.build.addStepsAfterCurrentStep([
4578
                        GitResetHard(),
4634
                        ResetGitSvn(),
4579
                        CheckOutSource(repourl='https://git.webkit.org/git/WebKit-https'),
4635
                        CleanGitRepo(),
4636
                        CheckOutSource(),
4637
                        GitSvnFetch(),
4580
                        ShowIdentifier(),
4638
                        ShowIdentifier(),
4581
                        UpdateWorkingDirectory(),
4639
                        UpdateWorkingDirectory(),
4582
                        ApplyPatch(),
4640
                        CommitPatch(),
4583
                        CreateLocalGITCommit(),
4641
                        AddReviewerToCommitMessage(),
4642
                        AddAuthorToCommitMessage(),
4643
                        ValidateChange(addURLs=False, verifycqplus=True),
4644
                        Canonicalize(),
4584
                        PushCommitToWebKitRepo(),
4645
                        PushCommitToWebKitRepo(),
4585
                    ])
4646
                    ])
4586
                return rc
4647
                return rc
Lines 4761-4768 class ValidateSquashed(shell.ShellCommand): a/Tools/CISupport/ews-build/steps.py_sec3
4761
        super(ValidateSquashed, self).__init__(logEnviron=False, **kwargs)
4822
        super(ValidateSquashed, self).__init__(logEnviron=False, **kwargs)
4762
4823
4763
    def start(self, BufferLogObserverClass=logobserver.BufferLogObserver):
4824
    def start(self, BufferLogObserverClass=logobserver.BufferLogObserver):
4764
        base_ref = self.getProperty('github.base.ref', DEFAULT_BRANCH)
4825
        base_ref = self.getProperty('github.base.ref', f'origin/{DEFAULT_BRANCH}')
4765
        head_ref = self.getProperty('github.head.ref', DEFAULT_BRANCH)
4826
        head_ref = self.getProperty('github.head.ref', 'HEAD')
4766
        self.command = ['git', 'log', '--oneline', head_ref, f'^{base_ref}', '--max-count=2']
4827
        self.command = ['git', 'log', '--oneline', head_ref, f'^{base_ref}', '--max-count=2']
4767
4828
4768
        self.log_observer = BufferLogObserverClass(wantStderr=True)
4829
        self.log_observer = BufferLogObserverClass(wantStderr=True)
Lines 4787-4798 class ValidateSquashed(shell.ShellCommand): a/Tools/CISupport/ews-build/steps.py_sec4
4787
            return SUCCESS
4848
            return SUCCESS
4788
        return FAILURE
4849
        return FAILURE
4789
4850
4790
    def doStepIf(self, step):
4791
        return self.getProperty('github.number')
4792
4793
    def hideStepIf(self, results, step):
4794
        return not self.doStepIf(step)
4795
4796
4851
4797
class AddReviewerMixin(object):
4852
class AddReviewerMixin(object):
4798
    NOBODY_SED = 's/NOBODY (OO*PP*S!*)/{}/g'
4853
    NOBODY_SED = 's/NOBODY (OO*PP*S!*)/{}/g'
Lines 4830-4837 class AddReviewerToCommitMessage(shell.ShellCommand, AddReviewerMixin): a/Tools/CISupport/ews-build/steps.py_sec5
4830
        super(AddReviewerToCommitMessage, self).__init__(logEnviron=False, timeout=60, **kwargs)
4885
        super(AddReviewerToCommitMessage, self).__init__(logEnviron=False, timeout=60, **kwargs)
4831
4886
4832
    def start(self, BufferLogObserverClass=logobserver.BufferLogObserver):
4887
    def start(self, BufferLogObserverClass=logobserver.BufferLogObserver):
4833
        base_ref = self.getProperty('github.base.ref', DEFAULT_BRANCH)
4888
        base_ref = self.getProperty('github.base.ref', f'origin/{DEFAULT_BRANCH}')
4834
        head_ref = self.getProperty('github.head.ref', DEFAULT_BRANCH)
4889
        head_ref = self.getProperty('github.head.ref', 'HEAD')
4835
4890
4836
        gmtoffset = int(time.localtime().tm_gmtoff * 100 / (60 * 60))
4891
        gmtoffset = int(time.localtime().tm_gmtoff * 100 / (60 * 60))
4837
        date = f'{int(time.time())} {gmtoffset}'
4892
        date = f'{int(time.time())} {gmtoffset}'
Lines 4855-4898 class AddReviewerToCommitMessage(shell.ShellCommand, AddReviewerMixin): a/Tools/CISupport/ews-build/steps.py_sec6
4855
        return super(AddReviewerToCommitMessage, self).getResultSummary()
4910
        return super(AddReviewerToCommitMessage, self).getResultSummary()
4856
4911
4857
    def doStepIf(self, step):
4912
    def doStepIf(self, step):
4858
        return self.getProperty('github.number') and self.getProperty('reviewers_full_names')
4913
        return self.getProperty('reviewers_full_names')
4859
4914
4860
    def hideStepIf(self, results, step):
4915
    def hideStepIf(self, results, step):
4861
        return not self.doStepIf(step)
4916
        return not self.doStepIf(step)
4862
4917
4863
4918
4864
class AddAuthorToCommitMessage(shell.ShellCommand, AddReviewerMixin):
4919
class DetermineAuthor(shell.ShellCommand, ShellMixin):
4865
    name = 'add-author-to-commit-message'
4920
    name = 'determine-author'
4866
    haltOnFailure = True
4921
    haltOnFailure = True
4922
    AUTHOR_RE = re.compile(r'Author:\s+(.+ <.+>)')
4867
4923
4868
    def __init__(self, **kwargs):
4924
    def __init__(self, **kwargs):
4869
        super(AddAuthorToCommitMessage, self).__init__(logEnviron=False, timeout=60, **kwargs)
4925
        super(DetermineAuthor, self).__init__(logEnviron=False, timeout=60, **kwargs)
4870
4926
4871
    def author(self):
4927
    def start(self, BufferLogObserverClass=logobserver.BufferLogObserver):
4872
        contributors, _ = Contributors.load()
4928
        self.command = self.shell_command("git log -1 | grep '^Author:'")
4873
        username = self.getProperty('github.head.user.login')
4874
        owners = self.getProperty('owners', [None])
4875
        for candidate in [username, owners[0]]:
4876
            if not candidate:
4877
                continue
4878
4929
4879
            name = contributors.get(candidate.lower(), {}).get('name', None)
4930
        self.log_observer = BufferLogObserverClass(wantStderr=True)
4880
            email = contributors.get(candidate.lower(), {}).get('email', None)
4931
        self.addLogObserver('stdio', self.log_observer)
4881
4932
4882
            if name and email:
4933
        return super(DetermineAuthor, self).start()
4883
                return name, email
4884
4934
4885
        return None, None
4935
    def getResultSummary(self):
4936
        name = self.getProperty('author')
4937
        if not name or self.results == FAILURE:
4938
            return {'step': 'Failed to find author'}
4939
        elif self.results == SUCCESS:
4940
            return {'step': f"Author is{name}"}
4941
        return super(DetermineAuthor, self).getResultSummary()
4942
4943
    def evaluateCommand(self, cmd):
4944
        rc = super(DetermineAuthor, self).evaluateCommand(cmd)
4945
        if rc != SUCCESS:
4946
            return rc
4947
4948
        log_text = self.log_observer.getStdout()
4949
        lines = log_text.splitlines()
4950
        if len(lines) != 1:
4951
            return FAILURE
4952
        match = self.AUTHOR_RE.match(lines[0])
4953
        if match:
4954
            self.setProperty('author', match.group(1))
4955
            return SUCCESS
4956
        return FAILURE
4957
4958
class AddAuthorToCommitMessage(shell.ShellCommand, AddReviewerMixin):
4959
    name = 'add-author-to-commit-message'
4960
    haltOnFailure = True
4961
4962
    def __init__(self, **kwargs):
4963
        super(AddAuthorToCommitMessage, self).__init__(logEnviron=False, timeout=60, **kwargs)
4886
4964
4887
    def start(self):
4965
    def start(self):
4888
        base_ref = self.getProperty('github.base.ref', DEFAULT_BRANCH)
4966
        base_ref = self.getProperty('github.base.ref', f'origin/{DEFAULT_BRANCH}')
4889
        head_ref = self.getProperty('github.head.ref', DEFAULT_BRANCH)
4967
        head_ref = self.getProperty('github.head.ref', 'HEAD')
4890
4968
4891
        gmtoffset = int(time.localtime().tm_gmtoff * 100 / (60 * 60))
4969
        gmtoffset = int(time.localtime().tm_gmtoff * 100 / (60 * 60))
4892
        timestamp = f'{int(time.time())} {gmtoffset}'
4970
        timestamp = f'{int(time.time())} {gmtoffset}'
4893
4971
4894
        name, email = self.author()
4972
        author = self.getProperty('author')
4895
        patch_by = f"Patch by {name} <{email}> on {date.today().strftime('%Y-%m-%d')}"
4973
        patch_by = f"Patch by {author} on {date.today().strftime('%Y-%m-%d')}"
4896
4974
4897
        self.command = [
4975
        self.command = [
4898
            'git', 'filter-branch', '-f',
4976
            'git', 'filter-branch', '-f',
Lines 4910-4925 class AddAuthorToCommitMessage(shell.ShellCommand, AddReviewerMixin): a/Tools/CISupport/ews-build/steps.py_sec7
4910
        if self.results == FAILURE:
4988
        if self.results == FAILURE:
4911
            return {'step': 'Failed to add author to commit message'}
4989
            return {'step': 'Failed to add author to commit message'}
4912
        elif self.results == SUCCESS:
4990
        elif self.results == SUCCESS:
4913
            name, _ = self.author()
4991
            author = self.getProperty('author')
4914
            return {'step': f"Added {name} as author"}
4992
            return {'step': f"Added {author} as author"}
4915
        return super(AddAuthorToCommitMessage, self).getResultSummary()
4993
        return super(AddAuthorToCommitMessage, self).getResultSummary()
4916
4994
4917
    def doStepIf(self, step):
4995
    def doStepIf(self, step):
4918
        if not self.getProperty('github.number'):
4996
        return self.getProperty('author')
4919
            return False
4920
4921
        name, email = self.author()
4922
        return name and email
4923
4997
4924
    def hideStepIf(self, results, step):
4998
    def hideStepIf(self, results, step):
4925
        return not self.doStepIf(step)
4999
        return not self.doStepIf(step)
Lines 4936-4941 class ValidateCommitMessage(steps.ShellSequence, ShellMixin): a/Tools/CISupport/ews-build/steps.py_sec8
4936
        'Rubber-stamped by',
5010
        'Rubber-stamped by',
4937
        'Rubber stamped by',
5011
        'Rubber stamped by',
4938
    )
5012
    )
5013
    RE_CHANGELOG = br'^(\+\+\+)\s+(.*ChangeLog.*)'
4939
5014
4940
    def __init__(self, **kwargs):
5015
    def __init__(self, **kwargs):
4941
        super(ValidateCommitMessage, self).__init__(logEnviron=False, timeout=60, **kwargs)
5016
        super(ValidateCommitMessage, self).__init__(logEnviron=False, timeout=60, **kwargs)
Lines 4944-4955 class ValidateCommitMessage(steps.ShellSequence, ShellMixin): a/Tools/CISupport/ews-build/steps.py_sec9
4944
        sourcestamp = self.build.getSourceStamp(self.getProperty('codebase', ''))
5019
        sourcestamp = self.build.getSourceStamp(self.getProperty('codebase', ''))
4945
        if sourcestamp and sourcestamp.changes:
5020
        if sourcestamp and sourcestamp.changes:
4946
            return sourcestamp.changes[0].files
5021
            return sourcestamp.changes[0].files
5022
        if sourcestamp and sourcestamp.patch:
5023
            files = []
5024
            for line in patch.splitlines():
5025
                match = re.search(self.RE_CHANGELOG, line)
5026
                if match:
5027
                    files.append(match.group(1))
5028
            return files
4947
        return []
5029
        return []
4948
5030
4949
    @defer.inlineCallbacks
5031
    @defer.inlineCallbacks
4950
    def run(self, BufferLogObserverClass=logobserver.BufferLogObserver):
5032
    def run(self, BufferLogObserverClass=logobserver.BufferLogObserver):
4951
        base_ref = self.getProperty('github.base.ref', DEFAULT_BRANCH)
5033
        base_ref = self.getProperty('github.base.ref', f'origin/{DEFAULT_BRANCH}')
4952
        head_ref = self.getProperty('github.head.ref', DEFAULT_BRANCH)
5034
        head_ref = self.getProperty('github.head.ref', 'HEAD')
4953
5035
4954
        self.commands = []
5036
        self.commands = []
4955
        commands = [
5037
        commands = [
Lines 4987-4993 class ValidateCommitMessage(steps.ShellSequence, ShellMixin): a/Tools/CISupport/ews-build/steps.py_sec10
4987
        if rc == FAILURE:
5069
        if rc == FAILURE:
4988
            self.setProperty('comment_text', f"{self.summary}, blocking PR #{self.getProperty('github.number')}")
5070
            self.setProperty('comment_text', f"{self.summary}, blocking PR #{self.getProperty('github.number')}")
4989
            self.setProperty('build_finish_summary', 'Commit message validation failed')
5071
            self.setProperty('build_finish_summary', 'Commit message validation failed')
4990
            self.build.addStepsAfterCurrentStep([LeaveComment(),  BlockPullRequest()])
5072
            self.build.addStepsAfterCurrentStep([LeaveComment(), SetCommitQueueMinusFlagOnPatch(), BlockPullRequest()])
4991
        return rc
5073
        return rc
4992
5074
4993
    def getResultSummary(self):
5075
    def getResultSummary(self):
Lines 4995-5006 class ValidateCommitMessage(steps.ShellSequence, ShellMixin): a/Tools/CISupport/ews-build/steps.py_sec11
4995
            return {'step': self.summary}
5077
            return {'step': self.summary}
4996
        return super(ValidateCommitMessage, self).getResultSummary()
5078
        return super(ValidateCommitMessage, self).getResultSummary()
4997
5079
4998
    def doStepIf(self, step):
4999
        return self.getProperty('github.number')
5000
5001
    def hideStepIf(self, results, step):
5002
        return not self.doStepIf(step)
5003
5004
5080
5005
class Canonicalize(steps.ShellSequence, ShellMixin):
5081
class Canonicalize(steps.ShellSequence, ShellMixin):
5006
    name = 'canonicalize-commit'
5082
    name = 'canonicalize-commit'
Lines 5016-5030 class Canonicalize(steps.ShellSequence, ShellMixin): a/Tools/CISupport/ews-build/steps.py_sec12
5016
        self.commands = []
5092
        self.commands = []
5017
5093
5018
        base_ref = self.getProperty('github.base.ref', DEFAULT_BRANCH)
5094
        base_ref = self.getProperty('github.base.ref', DEFAULT_BRANCH)
5019
        head_ref = self.getProperty('github.head.ref', DEFAULT_BRANCH)
5095
        head_ref = self.getProperty('github.head.ref', None)
5020
5096
5021
        commands = []
5097
        commands = []
5022
        if self.rebase_enabled:
5098
        if self.rebase_enabled:
5023
            commands = [
5099
            commands = [['git', 'pull', 'origin', base_ref, '--rebase']]
5024
                ['git', 'pull', 'origin', base_ref, '--rebase'],
5100
            if head_ref:
5025
                ['git', 'branch', '-f', base_ref, head_ref],
5101
                commands += [['git', 'branch', '-f', base_ref, head_ref]]
5026
                ['git', 'checkout', base_ref],
5102
            commands += [['git', 'checkout', base_ref]]
5027
            ]
5028
        commands.append(['python3', 'Tools/Scripts/git-webkit', 'canonicalize', '-n', '1' if self.rebase_enabled else '3'])
5103
        commands.append(['python3', 'Tools/Scripts/git-webkit', 'canonicalize', '-n', '1' if self.rebase_enabled else '3'])
5029
5104
5030
        for command in commands:
5105
        for command in commands:
- a/Tools/CISupport/ews-build/steps_unittest.py -31 / +39 lines
Lines 5827-5836 class TestValidateSquashed(BuildStepMixinAdditions, unittest.TestCase): a/Tools/CISupport/ews-build/steps_unittest.py_sec1
5827
    def tearDown(self):
5827
    def tearDown(self):
5828
        return self.tearDownBuildStep()
5828
        return self.tearDownBuildStep()
5829
5829
5830
    def test_skipped_patch(self):
5830
    def test_patch(self):
5831
        self.setupStep(ValidateSquashed())
5831
        self.setupStep(ValidateSquashed())
5832
        self.setProperty('patch_id', '1234')
5832
        self.setProperty('patch_id', '1234')
5833
        self.expectOutcome(result=SKIPPED, state_string='finished (skipped)')
5833
        self.expectRemoteCommands(
5834
            ExpectShell(workdir='wkdir',
5835
                        logEnviron=False,
5836
                        command=['git', 'log', '--oneline', 'HEAD', '^origin/main', '--max-count=2'],
5837
                        )
5838
            + 0
5839
            + ExpectShell.log('stdio', stdout='e1eb24603493 (HEAD -> eng/pull-request-branch) First line of commit\n'),
5840
        )
5841
        self.expectOutcome(result=SUCCESS, state_string='Verified branch is squashed')
5834
        return self.runStep()
5842
        return self.runStep()
5835
5843
5836
    def test_success(self):
5844
    def test_success(self):
Lines 5989-5997 class TestAddAuthorToCommitMessage(BuildStepMixinAdditions, unittest.TestCase): a/Tools/CISupport/ews-build/steps_unittest.py_sec2
5989
    def tearDown(self):
5997
    def tearDown(self):
5990
        return self.tearDownBuildStep()
5998
        return self.tearDownBuildStep()
5991
5999
5992
    def test_skipped_patch(self):
6000
    def test_skipped_no_author(self):
5993
        self.setupStep(AddAuthorToCommitMessage())
6001
        self.setupStep(AddAuthorToCommitMessage())
5994
        self.setProperty('patch_id', '1234')
5995
        self.expectOutcome(result=SKIPPED, state_string='finished (skipped)')
6002
        self.expectOutcome(result=SKIPPED, state_string='finished (skipped)')
5996
        return self.runStep()
6003
        return self.runStep()
5997
6004
Lines 6002-6012 class TestAddAuthorToCommitMessage(BuildStepMixinAdditions, unittest.TestCase): a/Tools/CISupport/ews-build/steps_unittest.py_sec3
6002
        time.time = lambda: fixed_time
6009
        time.time = lambda: fixed_time
6003
6010
6004
        self.setupStep(AddAuthorToCommitMessage())
6011
        self.setupStep(AddAuthorToCommitMessage())
6005
        self.setProperty('github.number', '1234')
6006
        self.setProperty('github.base.ref', 'main')
6012
        self.setProperty('github.base.ref', 'main')
6007
        self.setProperty('github.head.ref', 'eng/pull-request-branch')
6013
        self.setProperty('github.head.ref', 'eng/pull-request-branch')
6008
        self.setProperty('github.head.user.login', 'webkit-reviewer')
6009
        self.setProperty('owners', ['webkit-commit-queue'])
6014
        self.setProperty('owners', ['webkit-commit-queue'])
6015
        self.setProperty('author', 'WebKit Reviewer <reviewer@apple.com>')
6010
        self.expectRemoteCommands(
6016
        self.expectRemoteCommands(
6011
            ExpectShell(workdir='wkdir',
6017
            ExpectShell(workdir='wkdir',
6012
                        logEnviron=False,
6018
                        logEnviron=False,
Lines 6021-6056 class TestAddAuthorToCommitMessage(BuildStepMixinAdditions, unittest.TestCase): a/Tools/CISupport/ews-build/steps_unittest.py_sec4
6021
            + 0
6027
            + 0
6022
            + ExpectShell.log('stdio', stdout="Ref 'refs/heads/eng/pull-request-branch' was rewritten\n"),
6028
            + ExpectShell.log('stdio', stdout="Ref 'refs/heads/eng/pull-request-branch' was rewritten\n"),
6023
        )
6029
        )
6024
        self.expectOutcome(result=SUCCESS, state_string='Added WebKit Reviewer as author')
6030
        self.expectOutcome(result=SUCCESS, state_string='Added WebKit Reviewer <reviewer@apple.com> as author')
6025
        return self.runStep()
6031
        return self.runStep()
6026
6032
6027
    def test_success_fallback(self):
6033
    def test_success_patch(self):
6028
        gmtoffset = int(time.localtime().tm_gmtoff * 100 / (60 * 60))
6034
        gmtoffset = int(time.localtime().tm_gmtoff * 100 / (60 * 60))
6029
        fixed_time = int(time.time())
6035
        fixed_time = int(time.time())
6030
        timestamp = f'{int(time.time())} {gmtoffset}'
6036
        timestamp = f'{int(time.time())} {gmtoffset}'
6031
        time.time = lambda: fixed_time
6037
        time.time = lambda: fixed_time
6032
6038
6033
        self.setupStep(AddAuthorToCommitMessage())
6039
        self.setupStep(AddAuthorToCommitMessage())
6034
        self.setProperty('github.number', '1234')
6040
        self.setProperty('author', 'WebKit Reviewer <reviewer@apple.com>')
6035
        self.setProperty('github.base.ref', 'main')
6036
        self.setProperty('github.head.ref', 'eng/pull-request-branch')
6037
        self.setProperty('github.head.user.login', 'unregistered-author')
6038
        self.setProperty('owners', ['webkit-commit-queue'])
6039
        self.expectRemoteCommands(
6041
        self.expectRemoteCommands(
6040
            ExpectShell(workdir='wkdir',
6042
            ExpectShell(workdir='wkdir',
6041
                        logEnviron=False,
6043
                        logEnviron=False,
6042
                        env=self.ENV,
6044
                        env=dict(
6043
                        timeout=60,
6045
                            GIT_COMMITTER_EMAIL='ews@webkit.org',
6046
                            GIT_COMMITTER_NAME='EWS',
6047
                            FILTER_BRANCH_SQUELCH_WARNING='1',
6048
                        ), timeout=60,
6044
                        command=[
6049
                        command=[
6045
                            'git', 'filter-branch', '-f',
6050
                            'git', 'filter-branch', '-f',
6046
                            '--env-filter', f"GIT_AUTHOR_DATE='{timestamp}';GIT_COMMITTER_DATE='{timestamp}'",
6051
                            '--env-filter', f"GIT_AUTHOR_DATE='{timestamp}';GIT_COMMITTER_DATE='{timestamp}'",
6047
                            '--msg-filter', f'sed "1,/^$/ s/^$/\\nPatch by WebKit Committer <committer@webkit.org> on {date.today().strftime("%Y-%m-%d")}/g"',
6052
                            '--msg-filter', f'sed "1,/^$/ s/^$/\\nPatch by WebKit Reviewer <reviewer@apple.com> on {date.today().strftime("%Y-%m-%d")}/g"',
6048
                            'eng/pull-request-branch...main',
6053
                            'HEAD...origin/main',
6049
                        ])
6054
                        ])
6050
            + 0
6055
            + 0
6051
            + ExpectShell.log('stdio', stdout="Ref 'refs/heads/eng/pull-request-branch' was rewritten\n"),
6056
            + ExpectShell.log('stdio', stdout="Ref 'main' was rewritten\n"),
6052
        )
6057
        )
6053
        self.expectOutcome(result=SUCCESS, state_string='Added WebKit Committer as author')
6058
        self.expectOutcome(result=SUCCESS, state_string='Added WebKit Reviewer <reviewer@apple.com> as author')
6054
        return self.runStep()
6059
        return self.runStep()
6055
6060
6056
    def test_failure(self):
6061
    def test_failure(self):
Lines 6060-6070 class TestAddAuthorToCommitMessage(BuildStepMixinAdditions, unittest.TestCase): a/Tools/CISupport/ews-build/steps_unittest.py_sec5
6060
        time.time = lambda: fixed_time
6065
        time.time = lambda: fixed_time
6061
6066
6062
        self.setupStep(AddAuthorToCommitMessage())
6067
        self.setupStep(AddAuthorToCommitMessage())
6063
        self.setProperty('github.number', '1234')
6064
        self.setProperty('github.base.ref', 'main')
6068
        self.setProperty('github.base.ref', 'main')
6065
        self.setProperty('github.head.ref', 'eng/pull-request-branch')
6069
        self.setProperty('github.head.ref', 'eng/pull-request-branch')
6066
        self.setProperty('github.head.user.login', 'webkit-commit-queue')
6067
        self.setProperty('owners', ['webkit-commit-queue'])
6070
        self.setProperty('owners', ['webkit-commit-queue'])
6071
        self.setProperty('author', 'WebKit Committer <committer@webkit.org>')
6068
        self.expectRemoteCommands(
6072
        self.expectRemoteCommands(
6069
            ExpectShell(workdir='wkdir',
6073
            ExpectShell(workdir='wkdir',
6070
                        logEnviron=False,
6074
                        logEnviron=False,
Lines 6082-6094 class TestAddAuthorToCommitMessage(BuildStepMixinAdditions, unittest.TestCase): a/Tools/CISupport/ews-build/steps_unittest.py_sec6
6082
        self.expectOutcome(result=FAILURE, state_string='Failed to add author to commit message')
6086
        self.expectOutcome(result=FAILURE, state_string='Failed to add author to commit message')
6083
        return self.runStep()
6087
        return self.runStep()
6084
6088
6085
    def test_no_owner(self):
6086
        self.setupStep(AddAuthorToCommitMessage())
6087
        self.setProperty('github.number', '1234')
6088
        self.setProperty('github.base.ref', 'main')
6089
        self.expectOutcome(result=SKIPPED, state_string='finished (skipped)')
6090
        return self.runStep()
6091
6092
6089
6093
class TestValidateCommitMessage(BuildStepMixinAdditions, unittest.TestCase):
6090
class TestValidateCommitMessage(BuildStepMixinAdditions, unittest.TestCase):
6094
    def setUp(self):
6091
    def setUp(self):
Lines 6098-6107 class TestValidateCommitMessage(BuildStepMixinAdditions, unittest.TestCase): a/Tools/CISupport/ews-build/steps_unittest.py_sec7
6098
    def tearDown(self):
6095
    def tearDown(self):
6099
        return self.tearDownBuildStep()
6096
        return self.tearDownBuildStep()
6100
6097
6101
    def test_skipped_patch(self):
6098
    def test_patch(self):
6102
        self.setupStep(ValidateCommitMessage())
6099
        self.setupStep(ValidateCommitMessage())
6103
        self.setProperty('patch_id', '1234')
6100
        self.setProperty('patch_id', '1234')
6104
        self.expectOutcome(result=SKIPPED, state_string='finished (skipped)')
6101
        self.expectRemoteCommands(
6102
            ExpectShell(workdir='wkdir',
6103
                        logEnviron=False,
6104
                        timeout=60,
6105
                        command=['/bin/sh', '-c', "git log HEAD ^origin/main | grep -q 'OO*PP*S!' && echo 'Commit message contains (OOPS!)' || test $? -eq 1"])
6106
            + 0, ExpectShell(workdir='wkdir',
6107
                        logEnviron=False,
6108
                        timeout=60,
6109
                        command=['/bin/sh', '-c', "git log HEAD ^origin/main | grep -q '\\(Reviewed by\\|Unreviewed\\|Rubber-stamped by\\|Rubber stamped by\\)' || echo 'No reviewer information in commit message'"])
6110
            + 0
6111
            + ExpectShell.log('stdio', stdout=''),
6112
        )
6113
        self.expectOutcome(result=SUCCESS, state_string='Validated commit message')
6105
        return self.runStep()
6114
        return self.runStep()
6106
6115
6107
    def test_success(self):
6116
    def test_success(self):
6108
- 

Return to Bug 240461