Support squash merge in Github
Many projects running on Github want to use the squash merge strategy of github to keep their history clean. Now that the github reporter forwards the merge-mode that can be configured on a project it is easy to also support squash merge. Change-Id: I1f4131002dd380f2860557a9aebcc0bcf4dc2af8
This commit is contained in:
parent
3f485be486
commit
d221171e62
|
@ -1369,6 +1369,11 @@ pipeline.
|
|||
Cherry-picks each change onto the branch rather than
|
||||
performing any merges. This is not supported by Github.
|
||||
|
||||
.. value:: squash-merge
|
||||
|
||||
Squash merges each change onto the branch. This maps to the
|
||||
merge mode ``squash`` in Github.
|
||||
|
||||
.. attr:: vars
|
||||
:default: None
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
The merge-mode ``squash-merge`` is now supported for Github.
|
|
@ -0,0 +1,38 @@
|
|||
- pipeline:
|
||||
name: gate
|
||||
manager: dependent
|
||||
trigger:
|
||||
github:
|
||||
- event: pull_request
|
||||
action:
|
||||
- opened
|
||||
- changed
|
||||
- reopened
|
||||
branch: ^master$
|
||||
success:
|
||||
github:
|
||||
status: success
|
||||
merge: true
|
||||
failure:
|
||||
github: {}
|
||||
|
||||
- job:
|
||||
name: base
|
||||
parent: null
|
||||
run: playbooks/base.yaml
|
||||
|
||||
- job:
|
||||
name: project-test1
|
||||
run: playbooks/project-test1.yaml
|
||||
|
||||
- job:
|
||||
name: project-test2
|
||||
run: playbooks/project-test2.yaml
|
||||
|
||||
- project:
|
||||
name: org/project
|
||||
merge-mode: squash-merge
|
||||
gate:
|
||||
jobs:
|
||||
- project-test1
|
||||
- project-test2
|
|
@ -1126,6 +1126,36 @@ class TestGithubDriver(ZuulTestCase):
|
|||
self.assertFalse(A.is_merged)
|
||||
self.assertIn('Merge Failed', A.comments[1])
|
||||
|
||||
@simple_layout('layouts/gate-github-squash-merge.yaml', driver='github')
|
||||
def test_merge_method_squash_merge(self):
|
||||
"""
|
||||
Tests that the merge mode gets forwarded to the reporter and the
|
||||
merge fails because cherry-pick is not supported by github.
|
||||
"""
|
||||
github = self.fake_github.getGithubClient()
|
||||
github._data.required_contexts[('org/project', 'master')] = [
|
||||
'tenant-one/check',
|
||||
'tenant-one/gate']
|
||||
|
||||
A = self.fake_github.openFakePullRequest('org/project', 'master', 'A')
|
||||
self.fake_github.emitEvent(A.getPullRequestOpenedEvent())
|
||||
self.waitUntilSettled()
|
||||
|
||||
repo = github.repo_from_project('org/project')
|
||||
repo.create_status(A.head_sha, 'success', 'example.com', 'description',
|
||||
'tenant-one/check')
|
||||
|
||||
self.fake_github.emitEvent(A.getPullRequestOpenedEvent())
|
||||
self.waitUntilSettled()
|
||||
|
||||
# the change should have entered the gate
|
||||
self.assertEqual(2, len(self.history))
|
||||
|
||||
# now check if the merge was done via rebase
|
||||
merges = [report for report in self.fake_github.reports
|
||||
if report[2] == 'merge']
|
||||
assert(len(merges) == 1 and merges[0][3] == 'squash')
|
||||
|
||||
|
||||
class TestGithubUnprotectedBranches(ZuulTestCase):
|
||||
config_file = 'zuul-github-driver.conf'
|
||||
|
|
|
@ -1020,7 +1020,7 @@ class ProjectParser(object):
|
|||
'vars': ansible_vars_dict,
|
||||
'templates': [str],
|
||||
'merge-mode': vs.Any('merge', 'merge-resolve',
|
||||
'cherry-pick'),
|
||||
'cherry-pick', 'squash-merge'),
|
||||
'default-branch': str,
|
||||
str: pipeline_contents,
|
||||
'_source_context': model.SourceContext,
|
||||
|
|
|
@ -17,7 +17,8 @@ import voluptuous as v
|
|||
import time
|
||||
|
||||
from zuul.lib.logutil import get_annotated_logger
|
||||
from zuul.model import MERGER_MERGE_RESOLVE, MERGER_MERGE, MERGER_MAP
|
||||
from zuul.model import MERGER_MERGE_RESOLVE, MERGER_MERGE, MERGER_MAP, \
|
||||
MERGER_SQUASH_MERGE
|
||||
from zuul.reporter import BaseReporter
|
||||
from zuul.exceptions import MergeFailure
|
||||
from zuul.driver.util import scalar_or_list
|
||||
|
@ -34,6 +35,7 @@ class GithubReporter(BaseReporter):
|
|||
merge_modes = {
|
||||
MERGER_MERGE: 'merge',
|
||||
MERGER_MERGE_RESOLVE: 'merge',
|
||||
MERGER_SQUASH_MERGE: 'squash',
|
||||
}
|
||||
|
||||
def __init__(self, driver, connection, pipeline, config=None):
|
||||
|
|
|
@ -420,6 +420,18 @@ class Repo(object):
|
|||
repo.git.merge(*args)
|
||||
return repo.head.commit
|
||||
|
||||
def squash_merge(self, item, zuul_event_id=None):
|
||||
log = get_annotated_logger(self.log, zuul_event_id)
|
||||
repo = self.createRepoObject(zuul_event_id)
|
||||
args = ['--squash', 'FETCH_HEAD']
|
||||
ref = item['ref']
|
||||
self.fetch(ref, zuul_event_id=zuul_event_id)
|
||||
log.debug("Squash-Merging %s with args %s", ref, args)
|
||||
repo.git.merge(*args)
|
||||
repo.index.commit(
|
||||
'Merge change %s,%s' % (item['number'], item['patchset']))
|
||||
return repo.head.commit
|
||||
|
||||
def fetch(self, ref, zuul_event_id=None):
|
||||
repo = self.createRepoObject(zuul_event_id)
|
||||
# NOTE: The following is currently not applicable, but if we
|
||||
|
@ -676,6 +688,9 @@ class Merger(object):
|
|||
elif mode == zuul.model.MERGER_CHERRY_PICK:
|
||||
commit = repo.cherryPick(item['ref'],
|
||||
zuul_event_id=zuul_event_id)
|
||||
elif mode == zuul.model.MERGER_SQUASH_MERGE:
|
||||
commit = repo.squash_merge(
|
||||
item, zuul_event_id=zuul_event_id)
|
||||
else:
|
||||
raise Exception("Unsupported merge mode: %s" % mode)
|
||||
except git.GitCommandError:
|
||||
|
|
|
@ -35,11 +35,13 @@ from zuul.lib.logutil import get_annotated_logger
|
|||
MERGER_MERGE = 1 # "git merge"
|
||||
MERGER_MERGE_RESOLVE = 2 # "git merge -s resolve"
|
||||
MERGER_CHERRY_PICK = 3 # "git cherry-pick"
|
||||
MERGER_SQUASH_MERGE = 4 # "git merge --squash"
|
||||
|
||||
MERGER_MAP = {
|
||||
'merge': MERGER_MERGE,
|
||||
'merge-resolve': MERGER_MERGE_RESOLVE,
|
||||
'cherry-pick': MERGER_CHERRY_PICK,
|
||||
'squash-merge': MERGER_SQUASH_MERGE,
|
||||
}
|
||||
|
||||
PRECEDENCE_NORMAL = 0
|
||||
|
|
Loading…
Reference in New Issue