Skip to content

Instantly share code, notes, and snippets.

@programmarchy
Created September 14, 2018 20:21
Show Gist options
  • Save programmarchy/e7bbcaf8cdc4005e9cdc413e5a58687e to your computer and use it in GitHub Desktop.
Save programmarchy/e7bbcaf8cdc4005e9cdc413e5a58687e to your computer and use it in GitHub Desktop.
A Fastlane action that publishes a Pact contract to a Pact broker. See https://pact.io for more details.
# Example Fastfile using the `publish_pact_to_broker` action.
#
# NOTE: Since Fastlane uses dotenv, create a `.env` file in the fastlane
# directory to set `PACT_BROKER_USERNAME` and `PACT_BROKER_PASSWORD` and
# keep it secret by adding it to .gitignore.
default_platform(:ios)
xcodeproj = "MyProject.xcodeproj"
slack_url = "https://hooks.slack.com/services/MY/SLACK/WEBHOOK"
pact_consumer = "my-project-consumer"
pact_provider = "my-project-provider"
pact_contract_file = "./pact/contracts/#{pact_consumer}-#{pact_provider).json"
pact_broker_url = "https://my-pact-ci.pact.dius.com.au"
platform :ios do
desc "Publish a new Pact consumer contract"
lane :pact do
publish_pact_to_broker(
contract_file: pact_contract_file,
app_version: get_version_number(xcodeproj: xcodeproj),
broker_url: pact_broker_url,
username: ENV['PACT_BROKER_USERNAME'],
password: ENV['PACT_BROKER_PASSWORD'],
consumer: pact_consumer,
provider: pact_provider
)
slack(
message: "Uploaded a new Pact consumer contract to the Pact broker!",
success: true,
slack_url: slack_url,
default_payloads: [:git_branch, :last_git_commit_message, :last_git_commit_hash, :git_author],
attachment_properties: {
fields: [{
title: "Pact Broker URL",
value: lane_context[SharedValues::PUBLISH_PACT_TO_BROKER_CONTRACT_URL]
},{
title: "Pact App Version",
value: lane_context[SharedValues::PUBLISH_PACT_TO_BROKER_APP_VERSION]
}]
}
)
end
end
module Fastlane
module Actions
module SharedValues
PUBLISH_PACT_TO_BROKER_CONTRACT_URL = :PUBLISH_PACT_TO_BROKER_CONTRACT_URL
PUBLISH_PACT_TO_BROKER_APP_VERSION = :PUBLISH_PACT_TO_BROKER_APP_VERSION
end
class PublishPactToBrokerAction < Action
def self.run(params)
contract_file = params[:contract_file]
app_version = params[:app_version]
broker_url = params[:broker_url].chomp('/')
username = params[:username]
password = params[:password]
consumer = params[:consumer]
provider = params[:provider]
if Actions.last_git_commit_hash(true)
app_version << "+" << Actions.last_git_commit_hash(short: true)
end
contract_url = "#{broker_url}/pacts/provider/#{provider}/consumer/#{consumer}"
cmd = "curl -X PUT -H \"Content-Type: application/json\" -d @#{contract_file}"
if username
if password
cmd << " -u #{username}:#{password}"
else
cmd << " -u #{username}"
end
end
cmd << " #{contract_url}/version/#{app_version}"
sh cmd
Actions.lane_context[SharedValues::PUBLISH_PACT_TO_BROKER_CONTRACT_URL] = "#{contract_url}/version/#{app_version}"
Actions.lane_context[SharedValues::PUBLISH_PACT_TO_BROKER_APP_VERSION] = app_version
end
#####################################################
# @!group Documentation
#####################################################
def self.description
"Publishes a Pact consumer contract to a Pact broker"
end
def self.details
"Given a path to a Pact consumer contract (e.g. generated with PactConsumerSwift) and credentials (optional), publishes the file to a Pact broker server. See https://pact.io for more information."
end
def self.available_options
[
FastlaneCore::ConfigItem.new(key: :contract_file,
description: "Use Pact contract file at path"),
# The `app_version` does not mean the version of the Pact contract, but rather the version of the contract participant (i.e. the application/consumer).
# For more information, see: https://github.com/pact-foundation/pact_broker/wiki/Pacticipant-version-numbers
FastlaneCore::ConfigItem.new(key: :app_version,
description: "The participant (application) version to associate with the Pact contract"),
FastlaneCore::ConfigItem.new(key: :broker_url,
description: "The Pact broker URL"),
FastlaneCore::ConfigItem.new(key: :username,
description: "Authenticate Pact broker with this username",
optional: true),
FastlaneCore::ConfigItem.new(key: :password,
description: "Authenticate Pact broker with this password",
optional: true),
FastlaneCore::ConfigItem.new(key: :consumer,
description: "The Pact contract consumer"),
FastlaneCore::ConfigItem.new(key: :provider,
description: "The Pact contract provider")
]
end
def self.output
[
['PUBLISH_PACT_TO_BROKER_CONTRACT_URL', 'A link to the latest contract represented on the Pact broker'],
['PUBLISH_PACT_TO_BROKER_APP_VERSION', 'The participant (application) version associated with the Pact contract']
]
end
def self.authors
["programmarchy"]
end
def self.is_supported?(platform)
platform == :ios
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment