Skip to content

Commit

Permalink
Target branch for PRs, call back function after pr is created
Browse files Browse the repository at this point in the history
* Using the target branch to create the PR

* Removing implicit parent
  • Loading branch information
AgarFu authored Jun 15, 2020
1 parent d9f690f commit 5222fca
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 13 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ env/
venv/

config.yaml

#vim
*.swp
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com),
and this project adheres to [Semantic Versioning](https://semver.org).

## [1.3.0] - 2020-06-13
### Added
- This changelog
- Support to call a function if the PR is created
- Target branch support, now you can create PR against any branch, not only master
### Changed
- Refactored `apply_transformations` function to simplify passing the list of repositories from a different source

21 changes: 16 additions & 5 deletions gordian/gordian.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ def get_basic_parser():
dest='branch',
help='Branch name to use'
)
parser.add_argument(
'-t', '--target-branch',
required=False,
default='master',
dest='target_branch',
help='Target branch'
)
parser.add_argument(
'--force-changelog',
required=False,
Expand Down Expand Up @@ -126,20 +133,24 @@ def create_parser(args):
return args


def apply_transformations(args, transformations):
def apply_transformations(args, transformations, pr_created_callback=None):
config = Config(args.config_file)
transform(args, transformations, config.get_data(), pr_created_callback=pr_created_callback)

data = config.get_data()
for repo_name in data:
def transform(args, transformations, repositories, pr_created_callback):
for repo_name in repositories:
logger.info(f'Processing repo: {repo_name}')
repo = Repo(repo_name, github_api_url=args.github_api, branch=args.branch, semver_label=args.semver_label)
repo = Repo(repo_name, github_api_url=args.github_api, branch=args.branch, semver_label=args.semver_label, target_branch=args.target_branch)
for transformation in transformations:
transformation(args, repo).run()
if repo.dirty:
repo.bump_version(args.dry_run)
if not args.dry_run:
try:
repo._repo.create_pull(args.pr_message, '', 'master', repo.branch_name)
pull_request = repo._repo.create_pull(args.pr_message, '', args.target_branch, repo.branch_name)
if pr_created_callback is not None:
logger.debug(f'Calling post pr created callback with: {pull_request}, {repo.branch_name}')
pr_created_callback(repo_name, pull_request)
logger.info(f'PR created: {args.pr_message}. Branch: {repo.branch_name}')
except GithubException as e:
logger.info(f'PR already exists for {repo.branch_name}')
Expand Down
14 changes: 10 additions & 4 deletions gordian/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

class Repo:

def __init__(self, repo_name, github_api_url=None, branch=None, git=None, files=None, semver_label=None):
def __init__(self, repo_name, github_api_url=None, branch=None, git=None, files=None, semver_label=None, target_branch='master'):
if github_api_url is None:
self.github_api_url = BASE_URL
else:
Expand All @@ -39,13 +39,19 @@ def __init__(self, repo_name, github_api_url=None, branch=None, git=None, files=
self.branch_exists = False
self.dirty = False
self.semver_label = semver_label
self.set_target_branch(target_branch)

logger.debug(f'Target ref: {target_branch}')
if branch:
self.branch_name = f"refs/heads/{branch}"
else:
self.branch_name = f"refs/heads/{datetime.datetime.now().strftime('%Y-%m-%d-%H%M%S.%f')}"
logger.debug(f'Branch name for this changes: {self.branch_name}')

def set_target_branch(self, branch):
self.target_branch = branch
self.target_ref = f"refs/heads/{self.target_branch}"

def get_objects(self, filename, klass=None):
file = self.find_file(filename)

Expand All @@ -70,15 +76,15 @@ def get_objects(self, filename, klass=None):
def get_files(self):
if not self.files:
logger.debug(f'Getting repo content')
contents = self._repo.get_contents('')
contents = self._repo.get_contents('', self.target_ref)
while contents:
file = contents.pop(0)
if file.path == 'version':
self.version_file = file
elif file.path == 'CHANGELOG.md':
self.changelog = ChangelogFile(file, self)
elif file.type == 'dir':
contents.extend(self._repo.get_contents(file.path))
contents.extend(self._repo.get_contents(file.path, self.target_ref))
else:
self.files.append(file)

Expand All @@ -92,7 +98,7 @@ def find_file(self, filename):
return file

def make_branch(self):
sb = self._repo.get_branch('master')
sb = self._repo.get_branch(self.target_branch)
try:
logger.debug(f'Creating branch {self.branch_name}')
ref = self._repo.create_git_ref(ref=self.branch_name, sha=sb.commit.sha)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
setup_reqs = ['pytest', 'pytest-cov', 'pytest-runner', 'flake8']
setuptools.setup(
name="gordian",
version="1.2.0",
version="1.3.0",
author="Intuit",
author_email="[email protected]",
description="A tool to search and replace files in a Git repo",
Expand Down
25 changes: 24 additions & 1 deletion tests/test_gordian.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@ def __init__(self, config_file='./tests/fixtures/test_config.yaml', dry_run = Fa
self.branch = 'test'
self.github_api = None
self.semver_label = None
self.target_branch = 'master'

def test_apply_transformations_without_changes(self):
with patch('gordian.gordian.Repo') as RepoMock, patch('gordian.transformations.Transformation') as TransformationMockClass:
instance = RepoMock.return_value
instance.dirty = False
apply_transformations(TestGordian.Args(), [TransformationMockClass])
RepoMock.assert_has_calls([call('testOrg/TestService1', github_api_url=None, branch='test', semver_label=None), call('testOrg/TestService2', github_api_url=None, branch='test', semver_label=None)], any_order=True)
RepoMock.assert_has_calls([
call('testOrg/TestService1', github_api_url=None, branch='test', semver_label=None, target_branch='master'),
call('testOrg/TestService2', github_api_url=None, branch='test', semver_label=None, target_branch='master')
])

def test_apply_transformations_with_changes(self):
with patch('gordian.gordian.Repo') as RepoMock, patch('gordian.transformations.Transformation', ) as TransformationMockClass:
Expand All @@ -40,3 +44,22 @@ def test_apply_transformations_with_changes_dry_run(self):
apply_transformations(TestGordian.Args(dry_run=True), [TransformationMockClass])
RepoMock.assert_has_calls([call().bump_version(True), call().bump_version(True)], any_order=True)
self.assertNotIn(call().repo.create_pull('test', '', 'master', ANY), RepoMock.mock_calls)

def test_apply_transformations_with_changes_and_callback(self):
with patch('gordian.gordian.Repo') as RepoMock, patch('gordian.transformations.Transformation', ) as TransformationMockClass:
instance = RepoMock.return_value
instance.dirty = True
callback_mock = MagicMock()
args = TestGordian.Args()
args.target_branch = 'target_branch'
apply_transformations(args, [TransformationMockClass], callback_mock)
pull_request = RepoMock.return_value._repo.create_pull.return_value
RepoMock.assert_has_calls([call().bump_version(False), call().bump_version(False)], any_order=True)
RepoMock.assert_has_calls([
call()._repo.create_pull('test', '', 'target_branch', ANY),
call()._repo.create_pull('test', '', 'target_branch', ANY)],
any_order=True)
callback_mock.assert_has_calls([
call('testOrg/TestService1', pull_request),
call('testOrg/TestService2', pull_request)]
)
13 changes: 11 additions & 2 deletions tests/test_repo.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import unittest
import pytest
from gordian.repo import Repo
from unittest.mock import MagicMock, patch
from unittest.mock import MagicMock, patch, call
from gordian.files import YamlFile
from .utils import Utils

Expand All @@ -26,7 +26,7 @@ def test_make_branch(self):
mock_branch.commit.sha = "5e69ff00a3be0a76b13356c6ff42af79ff469ef3"
self.instance.make_branch()
self.assertTrue(self.instance.branch_exists)
self.mock_repo.get_branch.assert_called_once()
self.mock_repo.get_branch.assert_called_once_with('master')
self.mock_repo.create_git_ref.assert_called_once()

def test_default_github_url(self):
Expand All @@ -49,3 +49,12 @@ def test_new_files_object(self):
repo_two = Repo('test_two', github_api_url='https://test.github.com', git=self.mock_git)
self.assertEquals(len(repo_two.files), 0)

def test_get_files(self):
self.repo.set_target_branch('target')
self.repo.files = []
self.repo._repo = MagicMock()
repository_file = MagicMock(path='afile.txt', type='not_dir')
self.repo._repo.get_contents.side_effect = [[MagicMock(path='directory', type='dir')],[repository_file]]
self.repo.get_files()
self.repo._repo.get_contents.assert_has_calls([call('', 'refs/heads/target'), call('directory', 'refs/heads/target')])
self.assertEquals(self.repo.files, [repository_file])

0 comments on commit 5222fca

Please sign in to comment.