diff --git a/.flake8 b/.flake8 index 52bdc4fba..2a063f543 100644 --- a/.flake8 +++ b/.flake8 @@ -1,5 +1,5 @@ [flake8] ignore = E226,E302,E41,W503 max-line-length = 160 -max-complexity = 10 +max-complexity = 15 exclude = .git,venv,.venv,.tox,.pytest_cache,.direnv \ No newline at end of file diff --git a/pact/broker.py b/pact/broker.py index c67b63275..644453361 100644 --- a/pact/broker.py +++ b/pact/broker.py @@ -49,7 +49,7 @@ def _normalize_consumer_name(name): return name.lower().replace(' ', '_') def publish(self, consumer_name, version, pact_dir=None, - tag_with_git_branch=None, consumer_tags=None): + tag_with_git_branch=None, consumer_tags=None, branch=None, build_url=None, auto_detect_version_properties=None): """Publish the generated pact files to the specified pact broker.""" if self.broker_base_url is None \ and "PACT_BROKER_BASE_URL" not in os.environ: @@ -85,6 +85,15 @@ def publish(self, consumer_name, version, pact_dir=None, for tag in consumer_tags: command.extend(['-t', tag]) + if branch: + command.extend(['--branch={}'.format(branch)]) + + if build_url: + command.extend(['--build-url={}'.format(build_url)]) + + if auto_detect_version_properties is True: + command.append('--auto-detect-version-properties') + log.debug(f"PactBroker publish command: {command}") publish_process = Popen(command) diff --git a/pact/consumer.py b/pact/consumer.py index a2d60d3ca..e2357a024 100644 --- a/pact/consumer.py +++ b/pact/consumer.py @@ -16,7 +16,7 @@ class Consumer(object): """ def __init__(self, name, service_cls=Pact, tags=None, - tag_with_git_branch=False, version='0.0.0'): + tag_with_git_branch=False, version='0.0.0', branch=None, build_url=None, auto_detect_version_properties=False): """ Create the Consumer class. @@ -37,12 +37,24 @@ def __init__(self, name, service_cls=Pact, tags=None, :type tag_with_git_branch: bool :param version: The version of this Consumer. This will be used when publishing pacts to a pact broker. Defaults to '0.0.0' + :param branch: The branch of this Consumer. + :type branch: str + :param build_url: The build URL that created the pact. + :type build_url: str + :param auto_detect_version_properties: Automatically detect the repository branch from known CI, + environment variables or git CLI. Supports Buildkite, Circle CI, Travis CI, GitHub Actions, + Jenkins, Hudson, AppVeyor, GitLab, CodeShip, Bitbucket and Azure DevOps.'. + Defaults to False. + :type auto_detect_version_properties: bool """ self.name = name self.service_cls = service_cls self.tags = tags self.tag_with_git_branch = tag_with_git_branch self.version = version + self.branch = branch + self.build_url = build_url + self.auto_detect_version_properties = auto_detect_version_properties def has_pact_with(self, provider, host_name='localhost', port=1234, log_dir=None, ssl=False, sslcert=None, sslkey=None, diff --git a/pact/message_consumer.py b/pact/message_consumer.py index ae230f2a4..97f1718b3 100644 --- a/pact/message_consumer.py +++ b/pact/message_consumer.py @@ -22,6 +22,9 @@ def __init__( tags=None, tag_with_git_branch=False, version="0.0.0", + branch=None, + build_url=None, + auto_detect_version_properties=False ): """ Create the Message Consumer class. @@ -43,12 +46,24 @@ def __init__( :type tag_with_git_branch: bool :param version: The version of this Consumer. This will be used when publishing pacts to a pact broker. Defaults to '0.0.0' + :param branch: The branch of this Consumer. + :type branch: str + :param build_url: The build URL that created the pact. + :type build_url: str + :param auto_detect_version_properties: Automatically detect the repository branch from known CI, + environment variables or git CLI. Supports Buildkite, Circle CI, Travis CI, GitHub Actions, + Jenkins, Hudson, AppVeyor, GitLab, CodeShip, Bitbucket and Azure DevOps.'. + Defaults to False. + :type auto_detect_version_properties: bool """ self.name = name self.service_cls = service_cls self.tags = tags self.tag_with_git_branch = tag_with_git_branch self.version = version + self.branch = branch + self.build_url = build_url + self.auto_detect_version_properties = auto_detect_version_properties def has_pact_with( self, diff --git a/pact/message_pact.py b/pact/message_pact.py index c12cece8f..b25673511 100644 --- a/pact/message_pact.py +++ b/pact/message_pact.py @@ -208,4 +208,7 @@ def __exit__(self, exc_type, exc_val, exc_tb): pact_dir=self.pact_dir, tag_with_git_branch=self.consumer.tag_with_git_branch, consumer_tags=self.consumer.tags, + branch=self.consumer.branch, + build_url=self.consumer.build_url, + auto_detect_version_properties=self.consumer.auto_detect_version_properties ) diff --git a/pact/pact.py b/pact/pact.py index bc9af31a0..638d9de78 100644 --- a/pact/pact.py +++ b/pact/pact.py @@ -245,7 +245,10 @@ def stop_service(self): self.consumer.version, tag_with_git_branch=self.consumer.tag_with_git_branch, consumer_tags=self.consumer.tags, - pact_dir=self.pact_dir + branch=self.consumer.branch, + pact_dir=self.pact_dir, + build_url=self.consumer.build_url, + auto_detect_version_properties=self.consumer.auto_detect_version_properties ) def upon_receiving(self, scenario): diff --git a/tests/test_broker.py b/tests/test_broker.py index 2659ab118..0cbdc3566 100644 --- a/tests/test_broker.py +++ b/tests/test_broker.py @@ -137,3 +137,48 @@ def test_manual_tagged_publish(self): './TestConsumer-TestProvider.json', '-t', 'tag1', '-t', 'tag2']) + + def test_branch_publish(self): + broker = Broker(broker_base_url="http://localhost") + + broker.publish("TestConsumer", + "2.0.1", + branch='consumer-branch', + pact_dir='.') + + self.mock_Popen.assert_called_once_with([ + BROKER_CLIENT_PATH, 'publish', + '--consumer-app-version=2.0.1', + '--broker-base-url=http://localhost', + './TestConsumer-TestProvider.json', + '--branch=consumer-branch']) + + def test_build_url_publish(self): + broker = Broker(broker_base_url="http://localhost") + + broker.publish("TestConsumer", + "2.0.1", + build_url='http://ci', + pact_dir='.') + + self.mock_Popen.assert_called_once_with([ + BROKER_CLIENT_PATH, 'publish', + '--consumer-app-version=2.0.1', + '--broker-base-url=http://localhost', + './TestConsumer-TestProvider.json', + '--build-url=http://ci']) + + def test_auto_detect_version_properties_publish(self): + broker = Broker(broker_base_url="http://localhost") + + broker.publish("TestConsumer", + "2.0.1", + auto_detect_version_properties=True, + pact_dir='.') + + self.mock_Popen.assert_called_once_with([ + BROKER_CLIENT_PATH, 'publish', + '--consumer-app-version=2.0.1', + '--broker-base-url=http://localhost', + './TestConsumer-TestProvider.json', + '--auto-detect-version-properties']) diff --git a/tests/test_message_pact.py b/tests/test_message_pact.py index 3d8e7bf6b..598a1d969 100644 --- a/tests/test_message_pact.py +++ b/tests/test_message_pact.py @@ -146,13 +146,24 @@ def setUp(self): def test_successful(self): pact = MessagePact( self.consumer, self.provider, publish_to_broker=True, - broker_base_url='http://localhost', broker_username='username', broker_password='password') + broker_base_url='http://localhost', broker_username='username', broker_password='password', + pact_dir='some_dir') with pact: pass self.write_to_pact_file.assert_called_once() - self.mock_publish.assert_called_once() + self.mock_publish.assert_called_once_with( + pact, + 'TestConsumer', + '0.0.0', + auto_detect_version_properties=False, + branch=None, + build_url=None, + consumer_tags=None, + pact_dir='some_dir', + tag_with_git_branch=False + ) def test_context_raises_error(self): pact = MessagePact( diff --git a/tests/test_pact.py b/tests/test_pact.py index af642c523..76e1e7059 100644 --- a/tests/test_pact.py +++ b/tests/test_pact.py @@ -390,7 +390,10 @@ def test_stop_windows(self): 'abc', consumer_tags=None, tag_with_git_branch=False, - pact_dir='some_dir') + pact_dir='some_dir', + branch=None, + build_url=None, + auto_detect_version_properties=False) def test_stop_fails_posix(self): self.mock_platform.return_value = 'Linux'