pact_broker-client 1.45.0 → 1.48.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +15 -1
  3. data/CHANGELOG.md +31 -0
  4. data/README.md +51 -47
  5. data/doc/pacts/markdown/Pact Broker Client - Pact Broker.md +315 -1
  6. data/doc/pacts/markdown/Pact Broker Client - Pactflow.md +94 -0
  7. data/doc/pacts/markdown/README.md +1 -0
  8. data/lib/pact_broker/client/cli/broker.rb +9 -139
  9. data/lib/pact_broker/client/cli/custom_thor.rb +0 -16
  10. data/lib/pact_broker/client/cli/matrix_commands.rb +93 -0
  11. data/lib/pact_broker/client/cli/webhook_commands.rb +122 -0
  12. data/lib/pact_broker/client/deployments/record_support_ended.rb +1 -1
  13. data/lib/pact_broker/client/deployments/record_undeployment.rb +1 -1
  14. data/lib/pact_broker/client/matrix/resource.rb +4 -0
  15. data/lib/pact_broker/client/verification_required.rb +34 -0
  16. data/lib/pact_broker/client/version.rb +1 -1
  17. data/lib/pact_broker/client/webhooks/create.rb +14 -8
  18. data/script/record-deployment.sh +1 -1
  19. data/script/record-deployments-and-releases.sh +0 -2
  20. data/script/record-undeployment.sh +1 -1
  21. data/script/webhook-commands.sh +12 -0
  22. data/spec/lib/pact_broker/client/cli/broker_can_i_deploy_spec.rb +1 -1
  23. data/spec/lib/pact_broker/client/cli/broker_run_webhook_commands_spec.rb +4 -2
  24. data/spec/lib/pact_broker/client/deployments/record_support_ended_spec.rb +1 -1
  25. data/spec/lib/pact_broker/client/deployments/record_undeployment_spec.rb +1 -1
  26. data/spec/pacts/pact_broker_client-pact_broker.json +317 -1
  27. data/spec/pacts/pact_broker_client-pactflow.json +118 -0
  28. data/spec/service_providers/pact_helper.rb +15 -10
  29. data/spec/service_providers/pactflow_webhooks_create_spec.rb +86 -0
  30. data/spec/service_providers/record_deployment_spec.rb +1 -3
  31. data/spec/service_providers/record_release_spec.rb +1 -3
  32. data/spec/service_providers/record_undeployment_spec.rb +2 -4
  33. data/spec/service_providers/webhooks_create_spec.rb +1 -1
  34. data/spec/spec_helper.rb +1 -0
  35. metadata +12 -3
@@ -24,7 +24,7 @@ module PactBroker
24
24
  attr_reader :pacticipant_name, :environment_name, :version_number
25
25
 
26
26
  def currently_supported_versions_link
27
- environment_resource._link("pb:currently-supported-versions") or raise PactBroker::Client::Error.new(not_supported_message)
27
+ environment_resource._link("pb:currently-supported-released-versions", "pb:currently-supported-versions") or raise PactBroker::Client::Error.new(not_supported_message)
28
28
  end
29
29
 
30
30
  def currently_supported_version_entities_for_pacticipant_version
@@ -24,7 +24,7 @@ module PactBroker
24
24
  attr_reader :pacticipant_name, :environment_name, :target
25
25
 
26
26
  def currently_deployed_versions_link
27
- environment_resource._link("pb:currently-deployed-versions") or raise PactBroker::Client::Error.new(not_supported_message)
27
+ environment_resource._link("pb:currently-deployed-deployed-versions", "pb:currently-deployed-versions") or raise PactBroker::Client::Error.new(not_supported_message)
28
28
  end
29
29
 
30
30
  def currently_deployed_version_entities_for_pacticipant
@@ -30,6 +30,10 @@ module PactBroker
30
30
  end
31
31
  end
32
32
 
33
+ def no_results?
34
+ self[:summary][:success] == 0 && self[:summary][:failed] == 0
35
+ end
36
+
33
37
  def supports_unknown_count?
34
38
  !!(self[:summary] && Integer === self[:summary][:unknown] )
35
39
  end
@@ -0,0 +1,34 @@
1
+ require "pact_broker/client/can_i_deploy"
2
+
3
+ module PactBroker
4
+ module Client
5
+ class VerificationRequired < PactBroker::Client::CanIDeploy
6
+ def call
7
+ create_result(fetch_matrix_with_retries)
8
+ rescue StandardError => e
9
+ message = "Error determining if a verification already existed (#{e.message}) - verification should run just in case"
10
+ if options[:verbose]
11
+ message = "#{message}\n#{e.class} - #{e.backtrace.join("\n")}"
12
+ end
13
+ Result.new(true, message)
14
+ end
15
+
16
+ private
17
+
18
+ def create_result(matrix)
19
+ matrix_and_notices = format_matrix(matrix) + "\n\n" + remove_warnings(Term::ANSIColor.uncolor(notice_or_reason(matrix, :white)))
20
+ # If the specified version numbers do not exist, then all the counts come back 0. Can't just check for unknown to be 0.
21
+ # This command needs to handle "I screwed up the query"
22
+ if matrix.no_results?
23
+ Result.new(true, matrix_and_notices + "\n\nVerification is required.")
24
+ else
25
+ Result.new(false, matrix_and_notices + "\n\nNo verification is required.")
26
+ end
27
+ end
28
+
29
+ def remove_warnings(lines)
30
+ lines.split("\n").select{ | line | !line.include?("WARN:") }.join("\n")
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,5 @@
1
1
  module PactBroker
2
2
  module Client
3
- VERSION = '1.45.0'
3
+ VERSION = '1.48.0'
4
4
  end
5
5
  end
@@ -3,6 +3,7 @@ require 'pact_broker/client/hal'
3
3
  require 'ostruct'
4
4
  require 'json'
5
5
  require 'pact_broker/client/command_result'
6
+ require "pact_broker/client/backports"
6
7
 
7
8
  module PactBroker
8
9
  module Client
@@ -61,16 +62,17 @@ module PactBroker
61
62
 
62
63
  def request_body
63
64
  webhook_request_body = JSON.parse(params.body) rescue params.body
65
+ request_params = {
66
+ url: params.url,
67
+ method: params.http_method,
68
+ headers: params.headers,
69
+ body: webhook_request_body,
70
+ username: params.username,
71
+ password: params.password
72
+ }.compact
64
73
  {
65
74
  events: params.events.collect{ | event | { "name" => event }},
66
- request: {
67
- url: params.url,
68
- method: params.http_method,
69
- headers: params.headers,
70
- body: webhook_request_body,
71
- username: params.username,
72
- password: params.password
73
- }
75
+ request: request_params
74
76
  }.tap { |req| req[:description] = params.description if params.description }
75
77
  end
76
78
 
@@ -85,6 +87,10 @@ module PactBroker
85
87
  body[:provider] = { name: params.provider }
86
88
  end
87
89
 
90
+ if params.team_uuid
91
+ body[:teamUuid] = params.team_uuid
92
+ end
93
+
88
94
  body
89
95
  end
90
96
 
@@ -1,2 +1,2 @@
1
- PACT_BROKER_FEATURES=deployments bundle exec bin/pact-broker record-deployment \
1
+ bundle exec bin/pact-broker record-deployment \
2
2
  --pacticipant foo-consumer --version 1 --environment prod --broker-base-url http://localhost:9292
@@ -1,5 +1,3 @@
1
- export PACT_BROKER_FEATURES=deployments
2
-
3
1
  bundle exec bin/pact-broker create-or-update-pacticipant --name Foo
4
2
  bundle exec bin/pact-broker create-version-tag --pacticipant Foo --version 2 --tag main --auto-create-version
5
3
  bundle exec bin/pact-broker describe-version --pacticipant Foo --version 2
@@ -1,4 +1,4 @@
1
- PACT_BROKER_FEATURES=deployments bundle exec bin/pact-broker record-undeployment \
1
+ bundle exec bin/pact-broker record-undeployment \
2
2
  --pacticipant foo-consumer --version 1 --environment prod --broker-base-url http://localhost:9292 --output json --verbose
3
3
 
4
4
 
@@ -0,0 +1,12 @@
1
+ #!/bin/sh
2
+
3
+ bundle exec bin/pact-broker create-webhook \
4
+ 'https://api.github.com/repos/foo/bar/statuses/${pactbroker.consumerVersionNumber}' \
5
+ -X POST \
6
+ -H "Content-Type: application/json" \
7
+ -d '{ "state": "${pactbroker.githubVerificationStatus}", "description": "Pact Verification Tests ${pactbroker.providerVersionTags}", "context": "${pactbroker.providerName}", "target_url": "${pactbroker.verificationResultUrl}" }' \
8
+ --user username:password \
9
+ --description "Publish pact verification status to Github" \
10
+ --contract-published \
11
+ --provider-verification-published \
12
+ --team-uuid 4ac05ed8-9e3b-4159-96c0-ad19e3b93658
@@ -38,7 +38,7 @@ module PactBroker
38
38
  end
39
39
 
40
40
  it "invokes the CanIDeploy service" do
41
- expect(CanIDeploy).to receive(:call).with('http://pact-broker', version_selectors, { to_tag: nil, to_environment: nil, limit: 1000, ignore_selectors: []}, {output: 'table', retry_while_unknown: 1, retry_interval: 2, dry_run: false}, { pact_broker_base_url: 'http://pact-broker', verbose: 'verbose' })
41
+ expect(CanIDeploy).to receive(:call).with('http://pact-broker', version_selectors, { to_tag: nil, to_environment: nil, limit: 1000, ignore_selectors: []}, {output: 'table', retry_while_unknown: 1, retry_interval: 2, dry_run: false, verbose: "verbose"}, { pact_broker_base_url: 'http://pact-broker', verbose: 'verbose' })
42
42
  invoke_can_i_deploy
43
43
  end
44
44
 
@@ -33,7 +33,8 @@ module PactBroker
33
33
  broker_username: "username",
34
34
  broker_password: "password",
35
35
  contract_content_changed: true,
36
- verbose: true
36
+ verbose: true,
37
+ team_uuid: "1234"
37
38
  }
38
39
  end
39
40
 
@@ -49,7 +50,8 @@ module PactBroker
49
50
  body: "data",
50
51
  consumer: "consumer",
51
52
  provider: "provider",
52
- events: ["contract_content_changed"]
53
+ events: ["contract_content_changed"],
54
+ team_uuid: "1234"
53
55
  }.tap { |it| Pact::Fixture.add_fixture(:create_webhook_params, it) }
54
56
  end
55
57
 
@@ -46,7 +46,7 @@ module PactBroker
46
46
  let(:environment_hash) do
47
47
  {
48
48
  _links: {
49
- :'pb:currently-supported-versions' => {
49
+ :'pb:currently-supported-released-versions' => {
50
50
  href: currently_supported_versions_url
51
51
  }
52
52
  }
@@ -46,7 +46,7 @@ module PactBroker
46
46
  let(:environment_hash) do
47
47
  {
48
48
  _links: {
49
- :'pb:currently-deployed-versions' => {
49
+ :'pb:currently-deployed-deployed-versions' => {
50
50
  href: currently_deployed_versions_url
51
51
  }
52
52
  }
@@ -1638,6 +1638,323 @@
1638
1638
  }
1639
1639
  }
1640
1640
  },
1641
+ {
1642
+ "description": "a request for the index resource",
1643
+ "providerState": "the pb:pacticipant-version and pb:environments relations exist in the index resource",
1644
+ "request": {
1645
+ "method": "GET",
1646
+ "path": "/",
1647
+ "headers": {
1648
+ "Accept": "application/hal+json"
1649
+ }
1650
+ },
1651
+ "response": {
1652
+ "status": 200,
1653
+ "headers": {
1654
+ "Content-Type": "application/hal+json;charset=utf-8"
1655
+ },
1656
+ "body": {
1657
+ "_links": {
1658
+ "pb:pacticipant-version": {
1659
+ "href": "http://localhost:1234/HAL-REL-PLACEHOLDER-PB-PACTICIPANT-VERSION-{pacticipant}-{version}"
1660
+ },
1661
+ "pb:environments": {
1662
+ "href": "http://localhost:1234/HAL-REL-PLACEHOLDER-PB-ENVIRONMENTS"
1663
+ }
1664
+ }
1665
+ },
1666
+ "matchingRules": {
1667
+ "$.body._links.pb:pacticipant-version.href": {
1668
+ "match": "regex",
1669
+ "regex": "http:\\/\\/.*{pacticipant}.*{version}"
1670
+ },
1671
+ "$.body._links.pb:environments.href": {
1672
+ "match": "regex",
1673
+ "regex": "http:\\/\\/.*"
1674
+ }
1675
+ }
1676
+ }
1677
+ },
1678
+ {
1679
+ "description": "a request for a pacticipant version",
1680
+ "providerState": "version 5556b8149bf8bac76bc30f50a8a2dd4c22c85f30 of pacticipant Foo exists with a test environment available for deployment",
1681
+ "request": {
1682
+ "method": "GET",
1683
+ "path": "/HAL-REL-PLACEHOLDER-PB-PACTICIPANT-VERSION-Foo-5556b8149bf8bac76bc30f50a8a2dd4c22c85f30",
1684
+ "headers": {
1685
+ "Accept": "application/hal+json"
1686
+ }
1687
+ },
1688
+ "response": {
1689
+ "status": 200,
1690
+ "headers": {
1691
+ "Content-Type": "application/hal+json;charset=utf-8"
1692
+ },
1693
+ "body": {
1694
+ "_links": {
1695
+ "pb:record-deployment": [
1696
+ {
1697
+ "name": "test",
1698
+ "href": "http://localhost:1234/HAL-REL-PLACEHOLDER-PB-RECORD-DEPLOYMENT-FOO-5556B8149BF8BAC76BC30F50A8A2DD4C22C85F30-TEST"
1699
+ }
1700
+ ]
1701
+ }
1702
+ },
1703
+ "matchingRules": {
1704
+ "$.body._links.pb:record-deployment[0].href": {
1705
+ "match": "regex",
1706
+ "regex": "http:\\/\\/.*"
1707
+ }
1708
+ }
1709
+ }
1710
+ },
1711
+ {
1712
+ "description": "a request to record a deployment",
1713
+ "providerState": "version 5556b8149bf8bac76bc30f50a8a2dd4c22c85f30 of pacticipant Foo exists with a test environment available for deployment",
1714
+ "request": {
1715
+ "method": "POST",
1716
+ "path": "/HAL-REL-PLACEHOLDER-PB-RECORD-DEPLOYMENT-FOO-5556B8149BF8BAC76BC30F50A8A2DD4C22C85F30-TEST",
1717
+ "headers": {
1718
+ "Content-Type": "application/json",
1719
+ "Accept": "application/hal+json"
1720
+ },
1721
+ "body": {
1722
+ "target": "blue"
1723
+ }
1724
+ },
1725
+ "response": {
1726
+ "status": 201,
1727
+ "headers": {
1728
+ "Content-Type": "application/hal+json;charset=utf-8"
1729
+ },
1730
+ "body": {
1731
+ "target": "blue"
1732
+ }
1733
+ }
1734
+ },
1735
+ {
1736
+ "description": "a request for a pacticipant version",
1737
+ "providerState": "version 5556b8149bf8bac76bc30f50a8a2dd4c22c85f30 of pacticipant Foo exists with 2 environments that aren't test available for deployment",
1738
+ "request": {
1739
+ "method": "GET",
1740
+ "path": "/HAL-REL-PLACEHOLDER-PB-PACTICIPANT-VERSION-Foo-5556b8149bf8bac76bc30f50a8a2dd4c22c85f30",
1741
+ "headers": {
1742
+ "Accept": "application/hal+json"
1743
+ }
1744
+ },
1745
+ "response": {
1746
+ "status": 200,
1747
+ "headers": {
1748
+ "Content-Type": "application/hal+json;charset=utf-8"
1749
+ },
1750
+ "body": {
1751
+ "_links": {
1752
+ "pb:record-deployment": [
1753
+ {
1754
+ "name": "prod",
1755
+ "href": "href"
1756
+ },
1757
+ {
1758
+ "name": "dev",
1759
+ "href": "href"
1760
+ }
1761
+ ]
1762
+ }
1763
+ },
1764
+ "matchingRules": {
1765
+ "$.body._links.pb:record-deployment[0]": {
1766
+ "match": "type"
1767
+ },
1768
+ "$.body._links.pb:record-deployment[1]": {
1769
+ "match": "type"
1770
+ }
1771
+ }
1772
+ }
1773
+ },
1774
+ {
1775
+ "description": "a request for the environments",
1776
+ "providerState": "an environment with name test exists",
1777
+ "request": {
1778
+ "method": "GET",
1779
+ "path": "/HAL-REL-PLACEHOLDER-PB-ENVIRONMENTS",
1780
+ "headers": {
1781
+ "Accept": "application/hal+json"
1782
+ }
1783
+ },
1784
+ "response": {
1785
+ "status": 200,
1786
+ "headers": {
1787
+ "Content-Type": "application/hal+json;charset=utf-8"
1788
+ },
1789
+ "body": {
1790
+ "_links": {
1791
+ "pb:environments": [
1792
+ {
1793
+ "name": "test",
1794
+ "href": "href"
1795
+ }
1796
+ ]
1797
+ }
1798
+ },
1799
+ "matchingRules": {
1800
+ "$.body._links.pb:environments[0].href": {
1801
+ "match": "type"
1802
+ }
1803
+ }
1804
+ }
1805
+ },
1806
+ {
1807
+ "description": "a request for a pacticipant version",
1808
+ "providerState": "version 5556b8149bf8bac76bc30f50a8a2dd4c22c85f30 of pacticipant Foo exists with a test environment available for release",
1809
+ "request": {
1810
+ "method": "GET",
1811
+ "path": "/HAL-REL-PLACEHOLDER-PB-PACTICIPANT-VERSION-Foo-5556b8149bf8bac76bc30f50a8a2dd4c22c85f30",
1812
+ "headers": {
1813
+ "Accept": "application/hal+json"
1814
+ }
1815
+ },
1816
+ "response": {
1817
+ "status": 200,
1818
+ "headers": {
1819
+ "Content-Type": "application/hal+json;charset=utf-8"
1820
+ },
1821
+ "body": {
1822
+ "_links": {
1823
+ "pb:record-release": [
1824
+ {
1825
+ "name": "test",
1826
+ "href": "http://localhost:1234/HAL-REL-PLACEHOLDER-PB-RECORD-RELEASE-FOO-5556B8149BF8BAC76BC30F50A8A2DD4C22C85F30-TEST"
1827
+ }
1828
+ ]
1829
+ }
1830
+ },
1831
+ "matchingRules": {
1832
+ "$.body._links.pb:record-release[0].href": {
1833
+ "match": "regex",
1834
+ "regex": "http:\\/\\/.*"
1835
+ }
1836
+ }
1837
+ }
1838
+ },
1839
+ {
1840
+ "description": "a request to record a release",
1841
+ "providerState": "version 5556b8149bf8bac76bc30f50a8a2dd4c22c85f30 of pacticipant Foo exists with a test environment available for deployment",
1842
+ "request": {
1843
+ "method": "POST",
1844
+ "path": "/HAL-REL-PLACEHOLDER-PB-RECORD-RELEASE-FOO-5556B8149BF8BAC76BC30F50A8A2DD4C22C85F30-TEST",
1845
+ "headers": {
1846
+ "Content-Type": "application/json",
1847
+ "Accept": "application/hal+json"
1848
+ }
1849
+ },
1850
+ "response": {
1851
+ "status": 201,
1852
+ "headers": {
1853
+ "Content-Type": "application/hal+json;charset=utf-8"
1854
+ }
1855
+ }
1856
+ },
1857
+ {
1858
+ "description": "a request for an environment",
1859
+ "providerState": "an environment with name test and UUID 16926ef3-590f-4e3f-838e-719717aa88c9 exists",
1860
+ "request": {
1861
+ "method": "GET",
1862
+ "path": "/HAL-REL-PLACEHOLDER-PB-ENVIRONMENT-16926ef3-590f-4e3f-838e-719717aa88c9",
1863
+ "headers": {
1864
+ "Accept": "application/hal+json"
1865
+ }
1866
+ },
1867
+ "response": {
1868
+ "status": 200,
1869
+ "headers": {
1870
+ "Content-Type": "application/hal+json;charset=utf-8"
1871
+ },
1872
+ "body": {
1873
+ "_links": {
1874
+ "pb:currently-deployed-deployed-versions": {
1875
+ "href": "http://localhost:1234/PLACEHOLDER-ENVIRONMENT-CURRENTLY-DEPLOYED-16926ef3-590f-4e3f-838e-719717aa88c9"
1876
+ }
1877
+ }
1878
+ },
1879
+ "matchingRules": {
1880
+ "$.body._links.pb:currently-deployed-deployed-versions.href": {
1881
+ "match": "regex",
1882
+ "regex": "^http.*"
1883
+ }
1884
+ }
1885
+ }
1886
+ },
1887
+ {
1888
+ "description": "a request to list the versions deployed to an environment for a pacticipant name and target",
1889
+ "providerState": "an version is deployed to environment with UUID 16926ef3-590f-4e3f-838e-719717aa88c9 with target customer-1",
1890
+ "request": {
1891
+ "method": "GET",
1892
+ "path": "/PLACEHOLDER-ENVIRONMENT-CURRENTLY-DEPLOYED-16926ef3-590f-4e3f-838e-719717aa88c9",
1893
+ "query": "pacticipant=Foo",
1894
+ "headers": {
1895
+ "Accept": "application/hal+json"
1896
+ }
1897
+ },
1898
+ "response": {
1899
+ "status": 200,
1900
+ "headers": {
1901
+ "Content-Type": "application/hal+json;charset=utf-8"
1902
+ },
1903
+ "body": {
1904
+ "_embedded": {
1905
+ "deployedVersions": [
1906
+ {
1907
+ "target": "customer-1",
1908
+ "_links": {
1909
+ "self": {
1910
+ "href": "http://localhost:1234/PLACEHOLDER-DEPLOYED-VERSION-ff3adecf-cfc5-4653-a4e3-f1861092f8e0"
1911
+ }
1912
+ }
1913
+ }
1914
+ ]
1915
+ }
1916
+ },
1917
+ "matchingRules": {
1918
+ "$.body._embedded.deployedVersions[0]._links.self.href": {
1919
+ "match": "regex",
1920
+ "regex": "^http"
1921
+ }
1922
+ }
1923
+ }
1924
+ },
1925
+ {
1926
+ "description": "a request to mark a deployed version as not currently deploye",
1927
+ "providerState": "a currently deployed version exists",
1928
+ "request": {
1929
+ "method": "PATCH",
1930
+ "path": "/PLACEHOLDER-DEPLOYED-VERSION-ff3adecf-cfc5-4653-a4e3-f1861092f8e0",
1931
+ "headers": {
1932
+ "Content-Type": "application/merge-patch+json"
1933
+ },
1934
+ "body": {
1935
+ "currentlyDeployed": false
1936
+ }
1937
+ },
1938
+ "response": {
1939
+ "status": 200,
1940
+ "headers": {
1941
+ "Content-Type": "application/hal+json;charset=utf-8"
1942
+ },
1943
+ "body": {
1944
+ "currentlyDeployed": false,
1945
+ "_embedded": {
1946
+ "version": {
1947
+ "number": "2"
1948
+ }
1949
+ }
1950
+ },
1951
+ "matchingRules": {
1952
+ "$.body._embedded.version.number": {
1953
+ "match": "type"
1954
+ }
1955
+ }
1956
+ }
1957
+ },
1641
1958
  {
1642
1959
  "description": "a request to create a webhook with a JSON body for a consumer and provider",
1643
1960
  "providerState": "the 'Pricing Service' and 'Condor' already exist in the pact-broker",
@@ -1846,7 +2163,6 @@
1846
2163
  }
1847
2164
  ],
1848
2165
  "request": {
1849
- "url": null,
1850
2166
  "method": "POST",
1851
2167
  "headers": {
1852
2168
  "Foo": "bar",