From 71f0da3e9392be24fbfac48a3238ee73a9ba3349 Mon Sep 17 00:00:00 2001 From: Andrii Shyshkalov Date: Mon, 15 Jul 2019 22:45:18 +0000 Subject: [PATCH] git-cl: add --preserve-tryjobs option for upload command. CQ will soon start canceling tryjobs it triggered on no-longer-latest patchsets if these tryjobs won't be re-used. New option can be used by developers who upload new patchsets but actually care for prior CQ-triggered tryjobs to complete. This footer is effectively sticky, unless someone removes it by hand later. We need to have the footer one way or another to tell the CQ what to do (and provide a visible audit trail). We may revisit the stickiness later based on accumulated usage data s.t. the following uploads remove the footer unless the flag is passed. Bug: 909895 Test: git cl upload --preserve-tryjobs Change-Id: Ibbc6e917504c31eab8ab85296b3ecafd3add46df Cq-Do-Not-Cancel-Tryjobs: true Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/1701506 Reviewed-by: Edward Lesmes Reviewed-by: Dirk Pranke Commit-Queue: Andrii Shyshkalov --- git_cl.py | 14 ++++++++++++++ tests/git_cl_test.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/git_cl.py b/git_cl.py index 9c7f76ff1..9b06bc0c8 100755 --- a/git_cl.py +++ b/git_cl.py @@ -2766,6 +2766,8 @@ class _GerritChangelistImpl(_ChangelistCodereviewBase): if options.reviewers or options.tbrs or options.add_owners_to: change_desc.update_reviewers(options.reviewers, options.tbrs, options.add_owners_to, change) + if options.preserve_tryjobs: + change_desc.set_preserve_tryjobs() remote, upstream_branch = self.FetchUpstreamTuple(self.GetBranch()) parent = self._ComputeParent(remote, upstream_branch, custom_cl_base, @@ -3239,6 +3241,14 @@ class ChangeDescription(object): if new_tbr_line: self.append_footer(new_tbr_line) + def set_preserve_tryjobs(self): + """Ensures description footer contains 'Cq-Do-Not-Cancel-Tryjobs: true'.""" + footers = git_footers.parse_footers(self.description) + for v in footers.get('Cq-Do-Not-Cancel-Tryjobs', []): + if v.lower() == 'true': + return + self.append_footer('Cq-Do-Not-Cancel-Tryjobs: true') + def prompt(self, bug=None, git_footer=True): """Asks the user to update the description.""" self.set_description([ @@ -4751,6 +4761,10 @@ def CMDupload(parser, args): action='store_true', help='Send the patchset to do a CQ dry run right after ' 'upload.') + parser.add_option('--preserve-tryjobs', action='store_true', + help='instruct the CQ to let tryjobs running even after ' + 'new patchsets are uploaded instead of canceling ' + 'prior patchset\' tryjobs') parser.add_option('--dependencies', action='store_true', help='Uploads CLs of all the local branches that depend on ' 'the current branch') diff --git a/tests/git_cl_test.py b/tests/git_cl_test.py index 286e14cd1..84da76321 100755 --- a/tests/git_cl_test.py +++ b/tests/git_cl_test.py @@ -210,6 +210,34 @@ class TestGitClBasic(unittest.TestCase): 'Gnarly-Dude: beans', ]) + def test_set_preserve_tryjobs(self): + d = git_cl.ChangeDescription('Simple.') + d.set_preserve_tryjobs() + self.assertEqual(d.description.splitlines(), [ + 'Simple.', + '', + 'Cq-Do-Not-Cancel-Tryjobs: true', + ]) + before = d.description + d.set_preserve_tryjobs() + self.assertEqual(before, d.description) + + d = git_cl.ChangeDescription('\n'.join([ + 'One is enough', + '', + 'Cq-Do-Not-Cancel-Tryjobs: dups not encouraged, but don\'t hurt', + 'Change-Id: Ideadbeef', + ])) + d.set_preserve_tryjobs() + self.assertEqual(d.description.splitlines(), [ + 'One is enough', + '', + 'Cq-Do-Not-Cancel-Tryjobs: dups not encouraged, but don\'t hurt', + 'Change-Id: Ideadbeef', + 'Cq-Do-Not-Cancel-Tryjobs: true', + ]) + + def test_get_bug_line_values(self): f = lambda p, bugs: list(git_cl._get_bug_line_values(p, bugs)) self.assertEqual(f('', ''), [])