Skip to content

Commit

Permalink
feat: auto detect commit sha, add shorthand -r flag (#119)
Browse files Browse the repository at this point in the history
  • Loading branch information
YOU54F committed Oct 14, 2023
1 parent d52a880 commit 1dac9f8
Show file tree
Hide file tree
Showing 10 changed files with 316 additions and 74 deletions.
14 changes: 7 additions & 7 deletions README.md
Expand Up @@ -59,18 +59,18 @@ In the next major version, an error will be raised by default.

```
Usage:
pact-broker publish PACT_DIRS_OR_FILES ... -a, --consumer-app-version=CONSUMER_APP_VERSION -b, --broker-base-url=BROKER_BASE_URL
pact-broker publish PACT_DIRS_OR_FILES ... -b, --broker-base-url=BROKER_BASE_URL
Options:
-a, --consumer-app-version=CONSUMER_APP_VERSION
-a, [--consumer-app-version=CONSUMER_APP_VERSION]
# The consumer application version
-h, [--branch=BRANCH]
# Repository branch of the consumer version
[--auto-detect-version-properties], [--no-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.
-r, [--auto-detect-version-properties], [--no-auto-detect-version-properties]
# Automatically detect the repository commit, branch and build
URL 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.
-t, [--tag=TAG]
# Tag name for consumer version. Can be specified multiple
times.
Expand Down
10 changes: 10 additions & 0 deletions example/scripts/publish-pact-rake.sh
@@ -0,0 +1,10 @@
#!/bin/bash
# assumes you've set PACT_BROKER_BASE_URL, PACT_BROKER_TOKEN already

bundle exec rake pact:publish:pactflow_auto_on_nil_commit_nil_branch
bundle exec rake pact:publish:pactflow_auto_on_user_commit_user_branch
bundle exec rake pact:publish:pactflow_auto_on_user_commit_nil_branch
bundle exec rake pact:publish:pactflow_auto_on_nil_commit_user_branch
bundle exec rake pact:publish:pactflow_auto_off_user_commit_nil_branch
bundle exec rake pact:publish:pactflow_auto_off_nil_commit_nil_branch
bundle exec rake pact:publish:pactflow_auto_off_empty_string_commit_nil_branch
26 changes: 25 additions & 1 deletion example/scripts/publish-pact.sh
@@ -1,3 +1,27 @@
# assumes you've set PACT_BROKER_BASE_URL, PACT_BROKER_USERNAME and PACT_BROKER_PASSWORD already
# Must be executed from root directory of project.

bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --consumer-app-version=1.0.0 --tag master --verbose
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --auto-detect-version-properties
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --auto-detect-version-properties --tag-with-git-branch
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --branch branch-user-override
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --branch branch-user-override --auto-detect-version-properties
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --branch branch-user-override --auto-detect-version-properties --tag-with-git-branch
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --consumer-app-version commit-user-override
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --consumer-app-version commit-user-override --branch branch-user-override
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --consumer-app-version commit-user-override --auto-detect-version-properties
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --consumer-app-version commit-user-override --auto-detect-version-properties --tag-with-git-branch
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --consumer-app-version commit-user-override --branch branch-user-override --auto-detect-version-properties
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json --consumer-app-version commit-user-override --branch branch-user-override --auto-detect-version-properties --tag-with-git-branch

bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -r
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -r -g
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -h branch-user-override
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -h branch-user-override -r
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -h branch-user-override -r -g
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -a commit-user-override
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -a commit-user-override -r
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -a commit-user-override -r -g
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -a commit-user-override -h branch-user-override
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -a commit-user-override -h branch-user-override -r
bundle exec bin/pact-broker publish $(dirname "$0")/pact.json -a commit-user-override -h branch-user-override -r -g
3 changes: 2 additions & 1 deletion example/scripts/publish-provider-contract.sh
@@ -1,4 +1,5 @@
# assumes you've set PACT_BROKER_BASE_URL, PACT_BROKER_USERNAME and PACT_BROKER_PASSWORD already
# Assumes you've set PACT_BROKER_BASE_URL, PACT_BROKER_USERNAME and PACT_BROKER_PASSWORD already
# Must be executed from root directory of project.

bundle exec bin/pactflow publish-provider-contract $(dirname "$0")/oas.yml \
--provider pactflow-cli-test-provider \
Expand Down
46 changes: 34 additions & 12 deletions lib/pact_broker/client/cli/pact_commands.rb
@@ -1,4 +1,5 @@
require "pact_broker/client/hash_refinements"
require 'pact_broker/client/string_refinements'

module PactBroker
module Client
Expand All @@ -8,13 +9,14 @@ class PactPublicationError < ::Thor::Error; end

module PactCommands
using PactBroker::Client::HashRefinements
using PactBroker::Client::StringRefinements

def self.included(thor)
thor.class_eval do
desc 'publish PACT_DIRS_OR_FILES ...', "Publish pacts to a Pact Broker."
method_option :consumer_app_version, required: true, aliases: "-a", desc: "The consumer application version"
method_option :consumer_app_version, aliases: "-a", desc: "The consumer application version"
method_option :branch, aliases: "-h", desc: "Repository branch of the consumer version"
method_option :auto_detect_version_properties, type: :boolean, default: false, desc: "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."
method_option :auto_detect_version_properties, aliases: "-r", type: :boolean, default: false, desc: "Automatically detect the repository commit, branch and build URL 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."
method_option :tag, aliases: "-t", type: :array, banner: "TAG", desc: "Tag name for consumer version. Can be specified multiple times."
method_option :tag_with_git_branch, aliases: "-g", type: :boolean, default: false, required: false, desc: "Tag consumer version with the name of the current git branch. Supports Buildkite, Circle CI, Travis CI, GitHub Actions, Jenkins, Hudson, AppVeyor, GitLab, CodeShip, Bitbucket and Azure DevOps. Default: false"
method_option :build_url, desc: "The build URL that created the pact"
Expand All @@ -23,8 +25,10 @@ def self.included(thor)
shared_authentication_options

def publish(*pact_files)
require 'pact_broker/client/error'
require "pact_broker/client/error"
require "pact_broker/client/git"
validate_credentials
validate_consumer_version
validate_pact_files(pact_files)
result = publish_pacts(pact_files)
$stdout.puts result.message
Expand All @@ -50,16 +54,21 @@ def validate_pact_files pact_files
end
end

def validate_consumer_version
if consumer_app_version.blank?
raise ::Thor::RequiredArgumentMissingError, "No value provided for required option --consumer-app-version"
end
end

def publish_pacts pact_files
require 'pact_broker/client/publish_pacts'

write_options = options[:merge] ? { write: :merge } : {}
consumer_version_params = {
number: options.consumer_app_version,
number: consumer_app_version,
branch: branch,
tags: tags,
build_url: options.build_url
build_url: build_url
}.compact

PactBroker::Client::PublishPacts.call(
Expand Down Expand Up @@ -98,25 +107,38 @@ def validate_pact_path_list(paths)
end

def tags
require 'pact_broker/client/git'

t = [*options.tag]
t << PactBroker::Client::Git.branch(raise_error: true) if options.tag_with_git_branch
t.compact.uniq
end

def branch
require 'pact_broker/client/git'

if options.branch.nil? && options.auto_detect_version_properties
PactBroker::Client::Git.branch(raise_error: explict_auto_detect_version_properties)
PactBroker::Client::Git.branch(raise_error: true)
else
options.branch
end
end

def explict_auto_detect_version_properties
@explict_auto_detect_version_properties ||= ARGV.include?("--auto-detect-version-properties")
def consumer_app_version
if defined?(@consumer_app_version)
@consumer_app_version
else
@consumer_app_version = if options.consumer_app_version.blank? && options.auto_detect_version_properties
PactBroker::Client::Git.commit(raise_error: true)
else
options.consumer_app_version
end
end

end

def build_url
if options.build_url.blank? && options.auto_detect_version_properties
PactBroker::Client::Git.build_url
else
options.build_url
end
end
end
end
Expand Down
23 changes: 20 additions & 3 deletions lib/pact_broker/client/git.rb
Expand Up @@ -2,7 +2,6 @@
require 'pact_broker/client/hash_refinements'

=begin
BUILDKITE_BRANCH BUILDKITE_COMMIT https://buildkite.com/docs/pipelines/environment-variables
CIRCLE_BRANCH CIRCLE_SHA1 https://circleci.com/docs/2.0/env-vars/
TRAVIS_COMMIT TRAVIS_BRANCH - TRAVIS_PULL_REQUEST_BRANCH TRAVIS_PULL_REQUEST_SHA https://docs.travis-ci.com/user/environment-variables/
Expand All @@ -26,18 +25,21 @@ module Git
using PactBroker::Client::HashRefinements

COMMAND = 'git rev-parse --abbrev-ref HEAD'.freeze
COMMIT_COMMAND = 'git rev-parse HEAD'.freeze
BRANCH_ENV_VAR_NAMES = %w{GITHUB_HEAD_REF GITHUB_REF BUILDKITE_BRANCH CIRCLE_BRANCH TRAVIS_BRANCH GIT_BRANCH GIT_LOCAL_BRANCH APPVEYOR_REPO_BRANCH CI_COMMIT_REF_NAME BITBUCKET_BRANCH BUILD_SOURCEBRANCHNAME CIRRUS_BRANCH}.freeze
COMMIT_ENV_VAR_NAMES = %w{GITHUB_SHA BUILDKITE_COMMIT CIRCLE_SHA1 TRAVIS_COMMIT GIT_COMMIT APPVEYOR_REPO_COMMIT CI_COMMIT_ID BITBUCKET_COMMIT BUILD_SOURCEVERSION CIRRUS_CHANGE_IN_REPO}
BUILD_URL_ENV_VAR_NAMES = %w{BUILDKITE_BUILD_URL CIRCLE_BUILD_URL TRAVIS_BUILD_WEB_URL BUILD_URL }

def self.commit
find_commit_from_env_vars
def self.commit(options)
find_commit_from_env_vars || commit_from_git_command(options[:raise_error])
end

def self.branch(options)
find_branch_from_known_env_vars || find_branch_from_env_var_ending_with_branch || branch_from_git_command(options[:raise_error])
end

# This does not belong in the Git module.
# TODO move it.
def self.build_url
github_build_url || BUILD_URL_ENV_VAR_NAMES.collect{ | name | value_from_env_var(name) }.compact.first
end
Expand Down Expand Up @@ -79,6 +81,10 @@ def self.branch_from_git_command(raise_error)
branch_names.size == 1 ? branch_names[0] : nil
end

def self.commit_from_git_command(raise_error)
execute_git_commit_command(raise_error)
end

def self.validate_branch_names(branch_names)
if branch_names.size == 0
raise PactBroker::Client::Error, "Command `#{COMMAND}` didn't return anything that could be identified as the current branch."
Expand All @@ -93,6 +99,17 @@ def self.execute_git_command
`#{COMMAND}`
end

def self.execute_git_commit_command(raise_error)
`#{COMMIT_COMMAND}`
rescue StandardError => e
if raise_error
raise PactBroker::Client::Error,
"Could not determine current git commit using command `#{COMMIT_COMMAND}`. #{e.class} #{e.message}"
else
return nil
end
end

def self.execute_and_parse_command(raise_error)
execute_git_command
.split("\n")
Expand Down
57 changes: 40 additions & 17 deletions lib/pact_broker/client/tasks/publication_task.rb
@@ -1,6 +1,8 @@
require 'rake/tasklib'
require 'pact_broker/client/git'
require 'pact_broker/client/hash_refinements'
require 'pact_broker/client/string_refinements'
require "pact_broker/client/error"

=begin
require pact_broker/client/tasks
Expand All @@ -19,9 +21,11 @@ module PactBroker
module Client
class PublicationTask < ::Rake::TaskLib
using PactBroker::Client::HashRefinements
using PactBroker::Client::StringRefinements

attr_accessor :pattern, :pact_broker_base_url, :consumer_version, :tag, :write_method, :tag_with_git_branch, :pact_broker_basic_auth, :pact_broker_token
attr_reader :auto_detect_version_properties, :branch, :build_url
attr_accessor :pattern, :pact_broker_base_url, :tag, :build_url, :write_method, :tag_with_git_branch, :pact_broker_basic_auth, :pact_broker_token
attr_reader :auto_detect_version_properties, :build_url
attr_writer :consumer_version, :branch
alias_method :tags=, :tag=
alias_method :tags, :tag

Expand All @@ -36,34 +40,33 @@ def initialize name = nil, &block
def auto_detect_version_properties= auto_detect_version_properties
@auto_detect_version_properties = auto_detect_version_properties
end

def branch= branch
@branch = branch
end

def build_url= build_url
@build_url = build_url
end


private

def rake_task &block
namespace :pact do
desc "Publish pacts to pact broker"
task task_name do
block.call(self)
validate!
require 'pact_broker/client/publish_pacts'
pact_broker_client_options = { write: write_method, token: pact_broker_token }
pact_broker_client_options[:basic_auth] = pact_broker_basic_auth if pact_broker_basic_auth && pact_broker_basic_auth.any?
pact_broker_client_options.compact!
consumer_version_params = { number: consumer_version, branch: the_branch, build_url: build_url, tags: all_tags }.compact
consumer_version_params = { number: consumer_version, branch: branch, build_url: build_url, tags: all_tags }.compact
result = PactBroker::Client::PublishPacts.new(pact_broker_base_url, FileList[pattern], consumer_version_params, {}, pact_broker_client_options).call
$stdout.puts result.message
raise "One or more pacts failed to be published" unless result.success
raise PactBroker::Client::Error.new("One or more pacts failed to be published") unless result.success
end
end
end

def validate!
if consumer_version.blank?
raise PactBroker::Client::Error.new("A consumer version must be provided")
end
end

def task_name
@name ? "publish:#{@name}" : "publish"
end
Expand All @@ -74,11 +77,31 @@ def all_tags
t.compact.uniq
end

def the_branch
if branch.nil? && auto_detect_version_properties != false
PactBroker::Client::Git.branch(raise_error: auto_detect_version_properties == true)
# Attempt to detect the branch automatically, but don't raise an error if the branch can't be found
# unless the user has explicitly enabled auto_detect_version_properties.
# This approach is an attempt to include the branch without the user having to explicitly
# set it, because people tend to not update things.
def branch
if @branch.nil? && auto_detect_version_properties != false
@branch = PactBroker::Client::Git.branch(raise_error: auto_detect_version_properties == true)
else
@branch
end
end

def consumer_version
if @consumer_version.nil? && @auto_detect_version_properties
@consumer_version = PactBroker::Client::Git.commit(raise_error: true)
else
@consumer_version
end
end

def build_url
if @build_url.nil? && @auto_detect_version_properties
@build_url = PactBroker::Client::Git.build_url
else
branch
@build_url
end
end
end
Expand Down

0 comments on commit 1dac9f8

Please sign in to comment.