|
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: |